Просмотр исходного кода

fix(subprocess): normalize PTY scope launcher environment

pku-xht 2 недель назад
Родитель
Сommit
e82e5ffd7a

+ 5 - 1
packages/subprocess/subprocess-local/src/index.ts

@@ -245,7 +245,11 @@ export class LocalSubprocessRuntime extends SubprocessRuntime {
     const inspector = this.terminalInspector ?? createProcessInspector()
     const containmentMode = this.selectContainmentMode('terminal')
     const scope = containmentMode === 'linux-scope'
-      ? prepareLinuxTerminalScope(spec, env)
+      ? prepareLinuxTerminalScope(spec, {
+        ...env,
+        PWD: spec.cwd,
+        TERM: 'dumb',
+      })
       : undefined
     if (scope !== undefined) {
       options.cwd = scope.cwd

+ 8 - 2
packages/subprocess/subprocess-local/tests/local.spec.ts

@@ -480,14 +480,20 @@ describe('LocalSubprocessRuntime', () => {
       runtime.internals = { platform: 'linux' }
       runtime.terminalInspector = inspector
 
+      const targetCwd = process.cwd()
       const handle = await runtime.spawnTerminal({
-        argv: ['shell', '--literal'], cwd: process.cwd(), rows: 24, cols: 80, graceMs: 10,
+        argv: ['shell', '--literal'],
+        cwd: targetCwd,
+        rows: 24,
+        cols: 80,
+        graceMs: 10,
+        env: { PWD: '/stale-parent-cwd', TERM: 'xterm-256color', TARGET_VALUE: 'preserved' },
       })
 
       expect(probeLinuxNative).toHaveBeenCalledOnce()
       expect(prepareLinuxTerminalScope).toHaveBeenCalledWith(
         expect.objectContaining({ argv: ['shell', '--literal'] }),
-        expect.any(Object),
+        expect.objectContaining({ PWD: targetCwd, TERM: 'dumb', TARGET_VALUE: 'preserved' }),
       )
       expect(nodePtySpawn).toHaveBeenCalledWith(
         '/usr/bin/systemd-run',

+ 18 - 15
packages/subprocess/subprocess-local/tests/native-windows.spec.ts

@@ -157,20 +157,21 @@ describe.skipIf(!windowsNative)('Windows Job native containment', () => {
       stdio: { stdin: 'ignore', stdout: 'pipe', stderr: 'pipe' } as const,
     }
     const handle = bindManagedProcess(request, launchWindowsJob(request, targetEnvironment(request)))
-    if (handle.stdout === undefined) throw new Error('expected piped stdout')
-    if (handle.stderr === undefined) throw new Error('expected piped stderr')
-    handle.stdout.resume()
-    handle.stderr.resume()
-    const stdoutEnded = new Promise<void>((resolve, reject) => {
-      handle.stdout?.once('end', resolve)
-      handle.stdout?.once('error', reject)
-    })
-    const stderrEnded = new Promise<void>((resolve, reject) => {
-      handle.stderr?.once('end', resolve)
-      handle.stderr?.once('error', reject)
-    })
-    const descendant = await waitForPid(pidFile)
+    let descendant: number | undefined
     try {
+      if (handle.stdout === undefined) throw new Error('expected piped stdout')
+      if (handle.stderr === undefined) throw new Error('expected piped stderr')
+      handle.stdout.resume()
+      handle.stderr.resume()
+      const stdoutEnded = new Promise<void>((resolve, reject) => {
+        handle.stdout?.once('end', resolve)
+        handle.stdout?.once('error', reject)
+      })
+      const stderrEnded = new Promise<void>((resolve, reject) => {
+        handle.stderr?.once('end', resolve)
+        handle.stderr?.once('error', reject)
+      })
+      descendant = await waitForPid(pidFile)
       await expect(handle.done).resolves.toEqual({ exitCode: 42, signal: null })
       await expect(Promise.race([
         Promise.all([stdoutEnded, stderrEnded]).then(() => true),
@@ -181,13 +182,15 @@ describe.skipIf(!windowsNative)('Windows Job native containment', () => {
         value: 'explicit',
         arg: 'literal $HOME ${UNCHANGED}',
       }))
-      rmSync(targetCwd, { recursive: true })
       await expect(handle.waitForExit(AbortSignal.timeout(30))).resolves.toBe(false)
       handle.terminate()
       await expect(handle.waitForExit()).resolves.toBe(true)
       await waitGone(descendant)
     } finally {
-      cleanup(descendant)
+      handle.terminate()
+      await Promise.allSettled([handle.done, handle.waitForExit()])
+      if (descendant !== undefined) cleanup(descendant)
+      rmSync(targetCwd, { recursive: true, force: true })
     }
   })