Commit ba7139f

Anton Golub <antongolub@antongolub.com>
2025-04-16 10:12:03
chore: minor goods imprs, md usage update (#1198) tag: 8.5.3
* refactor(util): shrink a few bytes * docs: describe markdown input
1 parent bb36df5
build/index.cjs
@@ -120,8 +120,7 @@ function fetch(url, init) {
   });
 }
 function echo(pieces, ...args) {
-  const lastIdx = pieces.length - 1;
-  const msg = (0, import_util.isStringLiteral)(pieces, ...args) ? args.map((a, i) => pieces[i] + stringify(a)).join("") + pieces[lastIdx] : [pieces, ...args].map(stringify).join(" ");
+  const msg = (0, import_util.isStringLiteral)(pieces, ...args) ? args.map((a, i) => pieces[i] + stringify(a)).join("") + (0, import_util.getLast)(pieces) : [pieces, ...args].map(stringify).join(" ");
   console.log(msg);
 }
 function stringify(arg) {
build/util.cjs
@@ -113,10 +113,7 @@ var proxyOverride = (origin, ...fallbacks) => new Proxy(origin, {
 var toCamelCase = (str) => str.toLowerCase().replace(/([a-z])[_-]+([a-z])/g, (_, p1, p2) => {
   return p1 + p2.toUpperCase();
 });
-var parseBool = (v) => {
-  var _a;
-  return (_a = { true: true, false: false }[v]) != null ? _a : v;
-};
+var parseBool = (v) => v === "true" || v !== "false" && v;
 var getLines = (chunk, next) => {
   const lines = ((next.pop() || "") + bufToString(chunk)).split(/\r?\n/);
   next.push(lines.pop());
docs/cli.md
@@ -30,6 +30,8 @@ zx --ext=mjs script.zx # OK
 ```
 
 ## Markdown
+The CLI supports [markdown](/markdown) files and interprets `ts`, `js` and `bash` code blocks as scripts.
+
 ```bash
 zx docs/markdown.md
 ```
docs/markdown.md
@@ -0,0 +1,42 @@
+# Markdown
+
+Imagine a script with code blocks, comments, schemas, illustrations, etc. Markdown is right for this purpose.
+Combine `ts`, `js`, `bash` sections to produce a single script. For example:
+
+````text
+# Some script
+`ls` — is an unix command to get directory contents. Let's see how to use it in `zx`:
+
+```js
+// ts, js, cjs, mjs, etc
+const {stdout} = await $`ls -l`
+console.log('directory contents:', stdout)
+```
+
+This part invokes the same command in a different way:
+```bash
+# bash syntax
+ls -l
+```
+````
+
+And how it looks like:
+
+> # Some script
+> `ls` — is an unix command to get directory contents. Let's see how to use it in `zx`:
+> ```js
+> // ts, js, cjs, mjs, etc
+> const {stdout} = await $`ls -l`
+> console.log('directory contents:', stdout)
+> ```
+>
+> This part invokes the same command in a different way:
+> ```bash
+> # bash syntax
+> ls -l
+> ```
+
+The rest is simple: just run via `zx` command:
+```bash 
+zx script.md
+```
src/goods.ts
@@ -18,6 +18,7 @@ import { Readable } from 'node:stream'
 import { $, within, ProcessOutput, type ProcessPromise } from './core.ts'
 import {
   type Duration,
+  getLast,
   identity,
   isStringLiteral,
   parseBool,
@@ -110,9 +111,8 @@ export function fetch(
 
 export function echo(...args: any[]): void
 export function echo(pieces: TemplateStringsArray, ...args: any[]) {
-  const lastIdx = pieces.length - 1
   const msg = isStringLiteral(pieces, ...args)
-    ? args.map((a, i) => pieces[i] + stringify(a)).join('') + pieces[lastIdx]
+    ? args.map((a, i) => pieces[i] + stringify(a)).join('') + getLast(pieces)
     : [pieces, ...args].map(stringify).join(' ')
 
   console.log(msg)
src/util.ts
@@ -168,7 +168,7 @@ export const toCamelCase = (str: string) =>
   })
 
 export const parseBool = (v: string): boolean | string =>
-  ({ true: true, false: false })[v] ?? v
+  v === 'true' || (v !== 'false' && v)
 
 export const getLines = (
   chunk: Buffer | string,
test/util.test.js
@@ -20,6 +20,7 @@ import {
   isStringLiteral,
   noop,
   parseDuration,
+  parseBool,
   quote,
   quotePowerShell,
   randomId,
@@ -28,6 +29,7 @@ import {
   tempfile,
   preferLocalBin,
   toCamelCase,
+  getLast,
 } from '../build/util.js'
 
 describe('util', () => {
@@ -120,4 +122,15 @@ describe('util', () => {
     assert.equal(toCamelCase('SOME_MORE_BIG_STR'), 'someMoreBigStr')
     assert.equal(toCamelCase('kebab-input-str'), 'kebabInputStr')
   })
+
+  test('parseBool()', () => {
+    assert.equal(parseBool('true'), true)
+    assert.equal(parseBool('false'), false)
+    assert.equal(parseBool('other'), 'other')
+  })
+
+  test('getLast()', () => {
+    assert.equal(getLast([1, 2, 3]), 3)
+    assert.equal(getLast([]), undefined)
+  })
 })