Commit b659bfb
Changed files (3)
test
src/cli.ts
@@ -21,7 +21,7 @@ import { basename, dirname, extname, join, resolve } from 'node:path'
import url from 'node:url'
import { $, argv, fetch, ProcessOutput, chalk } from './index.js'
import { startRepl } from './repl.js'
-import { randomId } from './util.js'
+import { randomId, stdin } from './util.js'
import './globals.js'
await (async function main() {
@@ -49,6 +49,16 @@ await (async function main() {
return (process.exitCode = 0)
}
}
+ if (argv.eval || argv.e) {
+ Object.defineProperty(global, 'stdin', {
+ configurable: false,
+ enumerable: true,
+ get: stdin,
+ })
+ let script = (argv.eval || argv.e).toString()
+ await runScript(addLogOnLastLine(script))
+ return (process.exitCode = 0)
+ }
let firstArg = process.argv.slice(2).find((a) => !a.startsWith('--'))
if (typeof firstArg === 'undefined' || firstArg === '-') {
let ok = await scriptFromStdin()
@@ -81,6 +91,17 @@ await (async function main() {
process.exitCode = 1
})
+function addLogOnLastLine(script: string) {
+ let lines = script.trim().split('\n')
+ return lines.slice(0, -1).join('\n') + '\n' + `console.log(${lines.at(-1)})`
+}
+
+async function runScript(script: string) {
+ let filepath = join(tmpdir(), randomId() + '.mjs')
+ await fs.mkdtemp(filepath)
+ await writeAndImport(script, filepath, join(process.cwd(), 'stdin.mjs'))
+}
+
async function scriptFromStdin() {
let script = ''
if (!process.stdin.isTTY) {
@@ -90,9 +111,7 @@ async function scriptFromStdin() {
}
if (script.length > 0) {
- let filepath = join(tmpdir(), randomId() + '.mjs')
- await fs.mkdtemp(filepath)
- await writeAndImport(script, filepath, join(process.cwd(), 'stdin.mjs'))
+ await runScript(script)
return true
}
}
@@ -236,6 +255,7 @@ function printUsage() {
--shell=<path> custom shell binary
--prefix=<command> prefix all commands
--interactive, -i start repl
+ --eval=<js>, -e evaluate script
--experimental enable new api proposals
--version, -v print current zx version
--help, -h print help
src/util.ts
@@ -97,3 +97,19 @@ export function exitCodeInfo(exitCode: number | null): string | undefined {
159: 'Bad syscall',
}[exitCode || -1]
}
+
+export function stdin() {
+ try {
+ if (process.env.FX_ASYNC_STDIN == 'true') throw 'yes'
+ return fs.readFileSync(process.stdin.fd).toString()
+ } catch (err) {
+ return (async function () {
+ let buf = ''
+ process.stdin.setEncoding('utf8')
+ for await (const chunk of process.stdin) {
+ buf += chunk
+ }
+ return buf
+ })()
+ }
+}
test/cli.test.js
@@ -118,4 +118,20 @@ test('exceptions are caught', async () => {
assert.match(out2.stderr, '42')
})
+test('eval works', async () => {
+ let { stdout } = await $`node build/cli.js --eval '69'`
+ assert.is(stdout, '69\n')
+})
+
+test('eval works with stdin', async () => {
+ let { stdout } =
+ await $`printf "Hello world" | node build/cli.js --eval='stdin'`
+ assert.is(stdout, 'Hello world\n')
+})
+
+test('--eval works with async stdin', async () => {
+ let p = $`(printf foo; sleep 0.1; printf bar) | FX_ASYNC_STDIN=true node build/cli.js --eval 'await stdin'`
+ assert.is((await p).stdout, 'foobar\n')
+})
+
test.run()