Commit d79a638
Changed files (7)
src
test
src/core.ts
@@ -14,7 +14,7 @@
import assert from 'node:assert'
import { spawn, spawnSync, StdioNull, StdioPipe } from 'node:child_process'
-import { AsyncLocalStorage, createHook } from 'node:async_hooks'
+import { AsyncHook, AsyncLocalStorage, createHook } from 'node:async_hooks'
import { Readable, Writable } from 'node:stream'
import { inspect } from 'node:util'
import {
@@ -38,6 +38,7 @@ import {
parseDuration,
quote,
quotePowerShell,
+ noquote,
} from './util.js'
export interface Shell {
@@ -74,14 +75,18 @@ export interface Options {
}
const storage = new AsyncLocalStorage<Options>()
-const hook = createHook({
+const cwdSyncHook: AsyncHook & { enabled?: boolean } = createHook({
init: syncCwd,
before: syncCwd,
promiseResolve: syncCwd,
after: syncCwd,
destroy: syncCwd,
})
-hook.enable()
+
+export function syncProcessCwd(flag: boolean = true) {
+ if (flag) cwdSyncHook.enable()
+ else cwdSyncHook.disable()
+}
export const defaults: Options = {
[processCwd]: process.cwd(),
@@ -94,9 +99,7 @@ export const defaults: Options = {
quiet: false,
prefix: '',
postfix: '',
- quote: () => {
- throw new Error('No quote function is defined: https://ï.at/no-quote-func')
- },
+ quote: noquote,
spawn,
spawnSync,
log,
@@ -104,14 +107,14 @@ export const defaults: Options = {
}
const isWin = process.platform == 'win32'
-export function setupPowerShell() {
+export function usePowerShell() {
$.shell = which.sync('powershell.exe')
$.prefix = ''
$.postfix = '; exit $LastExitCode'
$.quote = quotePowerShell
}
-export function setupBash() {
+export function useBash() {
$.shell = which.sync('bash')
$.prefix = 'set -euo pipefail;'
$.quote = quote
@@ -184,9 +187,8 @@ export const $: Shell & Options = new Proxy<Shell & Options>(
},
}
)
-
try {
- setupBash()
+ useBash()
} catch (err) {}
type Resolve = (out: ProcessOutput) => void
src/globals.ts
@@ -41,7 +41,8 @@ declare global {
var quote: typeof _.quote
var quotePowerShell: typeof _.quotePowerShell
var retry: typeof _.retry
- var setupPowerShell: typeof _.setupPowerShell
+ var usePowerShell: typeof _.usePowerShell
+ var useBash: typeof _.useBash
var sleep: typeof _.sleep
var spinner: typeof _.spinner
var stdin: typeof _.stdin
src/util.ts
@@ -42,6 +42,10 @@ export function normalizeMultilinePieces(
)
}
+export function noquote(): string {
+ throw new Error('No quote function is defined: https://ï.at/no-quote-func')
+}
+
export function quote(arg: string) {
if (/^[a-z0-9/_.\-@:=]+$/i.test(arg) || arg === '') {
return arg
test/smoke/win32.test.js
@@ -24,7 +24,7 @@ _describe('win32', () => {
assert.match(p.stdout, /bash/)
await within(async () => {
- setupPowerShell()
+ usePowerShell()
assert.match($.shell, /powershell/i)
const p = await $`get-host`
assert.match(p.stdout, /PowerShell/)
@@ -33,7 +33,7 @@ _describe('win32', () => {
test('quotePowerShell works', async () => {
await within(async () => {
- setupPowerShell()
+ usePowerShell()
const p = await $`echo ${`Windows 'rulez!'`}`
assert.match(p.stdout, /Windows 'rulez!'/)
})
test/core.test.js
@@ -263,25 +263,26 @@ describe('core', () => {
}
})
- test('cd() does affect parallel contexts', async () => {
+ test('cd() does not affect parallel contexts ($.cwdSyncHook enabled)', async () => {
+ syncProcessCwd()
const cwd = process.cwd()
try {
fs.mkdirpSync('/tmp/zx-cd-parallel/one/two')
await Promise.all([
within(async () => {
assert.equal(process.cwd(), cwd)
- await sleep(1)
cd('/tmp/zx-cd-parallel/one')
+ await sleep(Math.random() * 15)
assert.ok(process.cwd().endsWith('/tmp/zx-cd-parallel/one'))
}),
within(async () => {
assert.equal(process.cwd(), cwd)
- await sleep(2)
+ await sleep(Math.random() * 15)
assert.equal(process.cwd(), cwd)
}),
within(async () => {
assert.equal(process.cwd(), cwd)
- await sleep(3)
+ await sleep(Math.random() * 15)
$.cwd = '/tmp/zx-cd-parallel/one/two'
assert.equal(process.cwd(), cwd)
assert.ok(
@@ -297,6 +298,7 @@ describe('core', () => {
} finally {
fs.rmSync('/tmp/zx-cd-parallel', { recursive: true })
cd(cwd)
+ syncProcessCwd(false)
}
})
test/index.test.js
@@ -20,6 +20,9 @@ import {
$,
log,
cd,
+ syncProcessCwd,
+ usePowerShell,
+ useBash,
kill,
ProcessOutput,
ProcessPromise,
@@ -60,10 +63,13 @@ describe('index', () => {
assert(ProcessOutput)
assert(ProcessPromise)
assert(cd)
+ assert(syncProcessCwd)
assert(log)
assert(kill)
assert(defaults)
assert(within)
+ assert(usePowerShell)
+ assert(useBash)
// goods
assert(argv)
test/package.test.js
@@ -13,10 +13,12 @@
// limitations under the License.
import assert from 'node:assert'
-import { test, describe, beforeEach } from 'node:test'
+import { test, describe, beforeEach, before, after } from 'node:test'
import '../build/globals.js'
describe('package', () => {
+ before(() => syncProcessCwd())
+ after(() => syncProcessCwd(false))
beforeEach(async () => {
const pack = await $`npm pack`
await $`tar xf ${pack}`