Skip to content

Commit

Permalink
feat: introduce $.preferLocal option (#798)
Browse files Browse the repository at this point in the history
* feat: introduce `$.preferLocal` option

* fix: handle $PATH on win32

* refactor: move `preferNmBin` to utils
  • Loading branch information
antongolub committed May 21, 2024
1 parent 01af3d5 commit ae55549
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 2 deletions.
4 changes: 4 additions & 0 deletions src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
quotePowerShell,
noquote,
ensureEol,
preferNmBin,
} from './util.js'

export interface Shell {
Expand Down Expand Up @@ -74,6 +75,7 @@ export interface Options {
quote: typeof quote
quiet: boolean
detached: boolean
preferLocal: boolean
spawn: typeof spawn
spawnSync: typeof spawnSync
log: typeof log
Expand Down Expand Up @@ -108,6 +110,7 @@ export const defaults: Options = {
postfix: '',
quote: noquote,
detached: false,
preferLocal: false,
spawn,
spawnSync,
log,
Expand Down Expand Up @@ -251,6 +254,7 @@ export class ProcessPromise extends Promise<ProcessOutput> {

if (input) this.stdio('pipe')
if ($.timeout) this.timeout($.timeout, $.timeoutSignal)
if ($.preferLocal) $.env = preferNmBin($.env, $.cwd, $[processCwd])

$.log({
kind: 'cmd',
Expand Down
22 changes: 22 additions & 0 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,28 @@ export function isString(obj: any) {

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

export function preferNmBin(
env: NodeJS.ProcessEnv,
...dirs: (string | undefined)[]
) {
const pathKey =
process.platform === 'win32'
? Object.keys(env)
.reverse()
.find((key) => key.toUpperCase() === 'PATH') || 'Path'
: 'PATH'
const pathValue = dirs
.map((c) => c && path.resolve(c as string, 'node_modules', '.bin'))
.concat(env[pathKey])
.filter(Boolean)
.join(path.delimiter)

return {
...env,
[pathKey]: pathValue,
}
}

export function normalizeMultilinePieces(
pieces: TemplateStringsArray
): TemplateStringsArray {
Expand Down
19 changes: 17 additions & 2 deletions test/core.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ describe('core', () => {
assert.equal(foo.stdout, 'foo\n')
})

test('env vars is safe to pass', async () => {
test('env vars are safe to pass', async () => {
process.env.ZX_TEST_BAR = 'hi; exit 1'
await $`echo $ZX_TEST_BAR`
const bar = await $`echo $ZX_TEST_BAR`
assert.equal(bar.stdout, 'hi; exit 1\n')
})

test('arguments are quoted', async () => {
Expand Down Expand Up @@ -205,6 +206,20 @@ describe('core', () => {
assert.equal(exitCode, null)
assert.equal(signal, 'SIGKILL')
})

test('`env` option', async () => {
const baz = await $({
env: { ZX_TEST_BAZ: 'baz' },
})`echo $ZX_TEST_BAZ`
assert.equal(baz.stdout, 'baz\n')
})

test('`preferLocal` preserves env', async () => {
const path = await $({
preferLocal: true,
})`echo $PATH`
assert(path.stdout.startsWith(`${process.cwd()}/node_modules/.bin:`))
})
})

test('accepts `stdio`', async () => {
Expand Down
9 changes: 9 additions & 0 deletions test/util.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
tempdir,
tempfile,
ensureEol,
preferNmBin,
} from '../build/util.js'

describe('util', () => {
Expand Down Expand Up @@ -183,3 +184,11 @@ test('ensureEol() should ensure buffer ends with a newline character', () => {
const result3 = ensureEol(buffer3).toString()
assert.strictEqual(result3, '\n')
})

test('preferNmBin()', () => {
const env = {
PATH: '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin',
}
const _env = preferNmBin(env, process.cwd())
assert.equal(_env.PATH, `${process.cwd()}/node_modules/.bin:${env.PATH}`)
})

0 comments on commit ae55549

Please sign in to comment.