Commit 1a9ced6

Anton Medvedev <anton@medv.io>
2022-06-06 15:29:55
Call process.chdir() on cd()
1 parent 345c23a
Changed files (3)
src/core.ts
@@ -14,7 +14,7 @@
 
 import { ChalkInstance } from 'chalk'
 import assert from 'node:assert'
-import { AsyncLocalStorage } from 'node:async_hooks'
+import { AsyncLocalStorage, createHook } from 'node:async_hooks'
 import { ChildProcess, spawn, StdioNull, StdioPipe } from 'node:child_process'
 import { Readable, Writable } from 'node:stream'
 import { inspect } from 'node:util'
@@ -36,6 +36,12 @@ type Options = {
 }
 
 const storage = new AsyncLocalStorage<Options>()
+const hook = createHook({
+  before() {
+    if ($.cwd != process.cwd()) process.chdir($.cwd)
+  },
+})
+hook.enable()
 
 function initStore(): Options {
   const context = {
@@ -337,5 +343,7 @@ export class ProcessOutput extends Error {
 }
 
 export function within<R>(callback: () => R): R {
-  return storage.run({ ...getStore() }, callback)
+  const result = storage.run({ ...getStore() }, callback)
+  if ($.cwd != process.cwd()) process.chdir($.cwd)
+  return result
 }
src/goods.ts
@@ -17,6 +17,7 @@ import minimist from 'minimist'
 import nodeFetch, { RequestInfo, RequestInit } from 'node-fetch'
 import { createInterface } from 'node:readline'
 import { setTimeout as sleep } from 'node:timers/promises'
+import { $ } from './core.js'
 import { isString, stringify } from './util.js'
 
 export { default as chalk } from 'chalk'
@@ -46,6 +47,7 @@ export async function fetch(url: RequestInfo, init?: RequestInit) {
 export function cd(dir: string) {
   $.log('cd', dir)
   $.cwd = path.resolve($.cwd, dir)
+  process.chdir($.cwd)
 }
 
 // A console.log() alternative which can take ProcessOutput.
test/index.test.js
@@ -298,15 +298,17 @@ test('cd() works with relative paths', async () => {
     cd('/tmp/zx-cd-test/one/two')
     let p1 = $`pwd`
     assert.match($.cwd, '/two')
-    assert.equal(process.cwd(), cwd)
+    assert.match(process.cwd(), '/two')
 
     cd('..')
     let p2 = $`pwd`
     assert.match($.cwd, '/one')
+    assert.match(process.cwd(), '/one')
 
     cd('..')
     let p3 = $`pwd`
     assert.match($.cwd, '/tmp/zx-cd-test')
+    assert.match(process.cwd(), '/tmp/zx-cd-test')
 
     let results = (await Promise.all([p1, p2, p3])).map((p) =>
       path.basename(p.stdout.trim())
@@ -333,13 +335,15 @@ test('cd() does affect parallel contexts', async () => {
       assert.equal($.cwd, cwd)
       await sleep(10)
       cd('/tmp/zx-cd-parallel')
-      assert.ok($.cwd.endsWith('/zx-cd-parallel'))
+      assert.match($.cwd, '/zx-cd-parallel')
+      assert.match(process.cwd(), '/zx-cd-parallel')
     })
 
     within(async () => {
       assert.equal($.cwd, cwd)
       await sleep(20)
-      assert.ok(!$.cwd.endsWith('/zx-cd-parallel'))
+      assert.not.match($.cwd, '/zx-cd-parallel')
+      assert.not.match(process.cwd(), '/zx-cd-parallel')
       resolve()
     })