Skip to content

Commit

Permalink
fix: detect Duplex on pipe (#905)
Browse files Browse the repository at this point in the history
* fix: detect Duplex on pipe

closes #904

* test: add isStringLiteral test
  • Loading branch information
antongolub authored Sep 19, 2024
1 parent 01f744b commit bfff0ef
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 6 deletions.
5 changes: 2 additions & 3 deletions src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import {
chalk,
which,
ps,
isStringLiteral,
type ChalkInstance,
type RequestInfo,
type RequestInit,
Expand All @@ -43,6 +42,7 @@ import {
formatCmd,
getCallerLocation,
isString,
isStringLiteral,
noop,
parseDuration,
preferLocalBin,
Expand Down Expand Up @@ -325,7 +325,6 @@ export class ProcessPromise extends Promise<ProcessOutput> {
c
) => {
self._resolved = true

// Ensures EOL
if (stderr && !stderr.endsWith('\n')) c.on.stderr?.(eol, c)
if (stdout && !stdout.endsWith('\n')) c.on.stdout?.(eol, c)
Expand Down Expand Up @@ -466,7 +465,7 @@ export class ProcessPromise extends Promise<ProcessOutput> {
dest: Writable | ProcessPromise | TemplateStringsArray,
...args: any[]
): ProcessPromise {
if (isStringLiteral(dest))
if (isStringLiteral(dest, ...args))
return this.pipe($(dest as TemplateStringsArray, ...args))
if (isString(dest))
throw new Error('The pipe() method does not take strings. Forgot $?')
Expand Down
14 changes: 12 additions & 2 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import path from 'node:path'
import fs from 'node:fs'
import { chalk } from './vendor-core.js'

export { isStringLiteral } from './vendor-core.js'

export function tempdir(prefix = `zx-${randomId()}`) {
const dirpath = path.join(os.tmpdir(), prefix)
fs.mkdirSync(dirpath, { recursive: true })
Expand Down Expand Up @@ -47,6 +45,18 @@ export function isString(obj: any) {
return typeof obj === 'string'
}

export const isStringLiteral = (
pieces: any,
...rest: any[]
): pieces is TemplateStringsArray => {
return (
pieces?.length > 0 &&
pieces.raw?.length === pieces.length &&
Object.isFrozen(pieces) &&
rest.length + 1 === pieces.length
)
}

const pad = (v: string) => (v === ' ' ? ' ' : '')

export function preferLocalBin(
Expand Down
2 changes: 1 addition & 1 deletion src/vendor-core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

export { exec, buildCmd, isStringLiteral, type TSpawnStore } from 'zurk/spawn'
export { exec, buildCmd, type TSpawnStore } from 'zurk/spawn'

export type RequestInfo = Parameters<typeof globalThis.fetch>[0]
export type RequestInit = Parameters<typeof globalThis.fetch>[1]
Expand Down
7 changes: 7 additions & 0 deletions test/core.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,13 @@ describe('core', () => {
assert.equal(p.stdout.trim(), 'foo')
})

test('accepts stdout', async () => {
const p1 = $`echo pipe-to-stdout`
const p2 = p1.pipe(process.stdout)
assert.equal(p1, p2)
assert.equal((await p1).stdout.trim(), 'pipe-to-stdout')
})

test('checks argument type', async () => {
let err
try {
Expand Down
12 changes: 12 additions & 0 deletions test/util.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
errnoMessage,
formatCmd,
isString,
isStringLiteral,
noop,
parseDuration,
quote,
Expand Down Expand Up @@ -59,6 +60,17 @@ describe('util', () => {
assert.ok(!isString(1))
})

test('isStringLiteral()', () => {
const bar = 'baz'
assert.ok(isStringLiteral``)
assert.ok(isStringLiteral`foo`)
assert.ok(isStringLiteral`foo ${bar}`)

assert.ok(!isStringLiteral(''))
assert.ok(!isStringLiteral('foo'))
assert.ok(!isStringLiteral(['foo']))
})

test('quote()', () => {
assert.ok(quote('string') === 'string')
assert.ok(quote(`'\f\n\r\t\v\0`) === `$'\\'\\f\\n\\r\\t\\v\\0'`)
Expand Down

0 comments on commit bfff0ef

Please sign in to comment.