Skip to content

Commit

Permalink
Restores the fds after builtins finish executing (#3184)
Browse files Browse the repository at this point in the history
* Restores the fds after builtins finish executing

* Adds an extra test
  • Loading branch information
arcanis authored Jul 27, 2021
1 parent 7197a44 commit 344818b
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 1 deletion.
23 changes: 23 additions & 0 deletions .yarn/versions/8e84815d.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
releases:
"@yarnpkg/cli": patch
"@yarnpkg/shell": patch

declined:
- "@yarnpkg/plugin-compat"
- "@yarnpkg/plugin-constraints"
- "@yarnpkg/plugin-dlx"
- "@yarnpkg/plugin-essentials"
- "@yarnpkg/plugin-init"
- "@yarnpkg/plugin-interactive-tools"
- "@yarnpkg/plugin-nm"
- "@yarnpkg/plugin-npm-cli"
- "@yarnpkg/plugin-pack"
- "@yarnpkg/plugin-patch"
- "@yarnpkg/plugin-pnp"
- "@yarnpkg/plugin-stage"
- "@yarnpkg/plugin-typescript"
- "@yarnpkg/plugin-version"
- "@yarnpkg/plugin-workspace-tools"
- "@yarnpkg/builder"
- "@yarnpkg/core"
- "@yarnpkg/doctor"
14 changes: 13 additions & 1 deletion packages/yarnpkg-shell/sources/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -632,11 +632,23 @@ function makeCommandAction(args: Array<string>, opts: ShellOptions, state: Shell
throw new Error(`Assertion failed: A builtin should exist for "${name}"`);

return makeBuiltin(async ({stdin, stdout, stderr}) => {
const {
stdin: initialStdin,
stdout: initialStdout,
stderr: initialStderr,
} = state;

state.stdin = stdin;
state.stdout = stdout;
state.stderr = stderr;

return await builtin(rest, opts, state);
try {
return await builtin(rest, opts, state);
} finally {
state.stdin = initialStdin;
state.stdout = initialStdout;
state.stderr = initialStderr;
}
});
}

Expand Down
54 changes: 54 additions & 0 deletions packages/yarnpkg-shell/tests/shell.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,60 @@ describe(`Shell`, () => {
});
});

it(`shouldn't affect unrelated commands`, async () => {
await xfs.mktempPromise(async tmpDir => {
const file = ppath.join(tmpDir, `file` as Filename);

await expect(bufferResult(
`echo "hello world" > "${file}"; echo foo`,
)).resolves.toMatchObject({
stdout: `foo\n`,
});

await expect(xfs.readFilePromise(file, `utf8`)).resolves.toEqual(`hello world\n`);
});

await xfs.mktempPromise(async tmpDir => {
const file = ppath.join(tmpDir, `file` as Filename);

await expect(bufferResult(
`echo "hello world" > "${file}" && echo foo`,
)).resolves.toMatchObject({
stdout: `foo\n`,
});

await expect(xfs.readFilePromise(file, `utf8`)).resolves.toEqual(`hello world\n`);
});
});

it(`shouldn't do weird stuff when piping a builtin redirection`, async () => {
await xfs.mktempPromise(async tmpDir => {
const file1 = ppath.join(tmpDir, `file1` as Filename);
const file2 = ppath.join(tmpDir, `file2` as Filename);

await expect(bufferResult(
`echo "hello world" > "${file1}" | echo "foo bar" > "${file2}"; echo test`,
)).resolves.toMatchObject({
stdout: `test\n`,
});

await expect(xfs.readFilePromise(file1, `utf8`)).resolves.toEqual(`hello world\n`);
await expect(xfs.readFilePromise(file2, `utf8`)).resolves.toEqual(`foo bar\n`);
});

await xfs.mktempPromise(async tmpDir => {
const file = ppath.join(tmpDir, `file` as Filename);

await expect(bufferResult(
`echo "hello world" > "${file}" && echo foo`,
)).resolves.toMatchObject({
stdout: `foo\n`,
});

await expect(xfs.readFilePromise(file, `utf8`)).resolves.toEqual(`hello world\n`);
});
});

it(`should support output redirections from fd (stdout)`, async () => {
await xfs.mktempPromise(async tmpDir => {
const file = ppath.join(tmpDir, `file` as Filename);
Expand Down

0 comments on commit 344818b

Please sign in to comment.