Skip to content

Commit 888ae01

Browse files
authored
feat(shell): support whitespace-only commands (#4864)
1 parent a75af3c commit 888ae01

File tree

6 files changed

+109
-23
lines changed

6 files changed

+109
-23
lines changed

Diff for: .yarn/versions/038526b5.yml

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
releases:
2+
"@yarnpkg/cli": minor
3+
"@yarnpkg/parsers": minor
4+
"@yarnpkg/shell": minor
5+
6+
declined:
7+
- "@yarnpkg/plugin-compat"
8+
- "@yarnpkg/plugin-constraints"
9+
- "@yarnpkg/plugin-dlx"
10+
- "@yarnpkg/plugin-essentials"
11+
- "@yarnpkg/plugin-init"
12+
- "@yarnpkg/plugin-interactive-tools"
13+
- "@yarnpkg/plugin-nm"
14+
- "@yarnpkg/plugin-npm-cli"
15+
- "@yarnpkg/plugin-pack"
16+
- "@yarnpkg/plugin-patch"
17+
- "@yarnpkg/plugin-pnp"
18+
- "@yarnpkg/plugin-pnpm"
19+
- "@yarnpkg/plugin-stage"
20+
- "@yarnpkg/plugin-typescript"
21+
- "@yarnpkg/plugin-version"
22+
- "@yarnpkg/plugin-workspace-tools"
23+
- "@yarnpkg/builder"
24+
- "@yarnpkg/core"
25+
- "@yarnpkg/doctor"
26+
- "@yarnpkg/sdks"

Diff for: CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ The following changes only affect people writing Yarn plugins:
7171

7272
- The patched filesystem now supports `fchown`.
7373

74+
### Shell
75+
76+
- The builtin shell now supports whitespace-only commands.
77+
7478
## 3.2.3
7579

7680
### Bugfixes

Diff for: packages/yarnpkg-parsers/sources/grammars/shell.js

+21-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: packages/yarnpkg-parsers/sources/grammars/shell.pegjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Start
2-
= line:ShellLine? { return line ? line : [] }
2+
= S* line:ShellLine? { return line ? line : [] }
33

44
ShellLine
55
= command:CommandLine S* type:ShellLineType then:ShellLineThen? { return [ { command, type } ].concat(then || []) }

Diff for: packages/yarnpkg-parsers/tests/shell.test.ts

+13-3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@ const VALID_COMMANDS = [
4545
];
4646

4747
const INVALID_COMMANDS = [
48+
// Empty shell lines
49+
...[
50+
// Only fish supports these
51+
`;;`,
52+
`echo foo;;`,
53+
// Only zsh and fish support these
54+
`; ;`,
55+
`echo foo; ;`,
56+
],
57+
4858
`echo }`,
4959
`echo foo}`,
5060

@@ -127,8 +137,8 @@ describe(`Shell parser`, () => {
127137
});
128138
});
129139

130-
describe(`String parse`, () => {
131-
it(`should parse parse double quote string currectly`, () => {
140+
describe(`Strings`, () => {
141+
it(`should parse double quoted strings correctly`, () => {
132142
for (const [original, raw] of DOUBLE_QUOTE_STRING_ESCAPE_TESTS) {
133143
expect(parseShell(`echo "${original}"`)).toStrictEqual([expect.objectContaining({
134144
command: expect.objectContaining({
@@ -143,7 +153,7 @@ describe(`Shell parser`, () => {
143153
}
144154
});
145155

146-
it(`should parse parse ANSI-C quote string currectly`, () => {
156+
it(`should parse ANSI-C strings correctly`, () => {
147157
for (const [original, raw] of ANSI_C_STRING_ESCAPE_TESTS) {
148158
expect(parseShell(`echo $'${original}'`)).toStrictEqual([expect.objectContaining({
149159
command: expect.objectContaining({

Diff for: packages/yarnpkg-shell/tests/shell.test.ts

+44-12
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,54 @@ const bufferResult = async (command: string, args: Array<string> = [], options:
8787

8888
describe(`Shell`, () => {
8989
describe(`Simple shell features`, () => {
90-
it(`should support an empty string`, async () => {
91-
await expect(bufferResult(
92-
``,
93-
)).resolves.toMatchObject({
90+
describe(`Empty commands`, () => {
91+
const EMPTY_COMMAND_RESULT = {
9492
exitCode: 0,
9593
stdout: ``,
94+
};
95+
96+
it(`should support an empty string`, async () => {
97+
await expect(bufferResult(
98+
``,
99+
)).resolves.toMatchObject(EMPTY_COMMAND_RESULT);
96100
});
97-
});
98101

99-
it(`should support an empty string when passing arguments`, async () => {
100-
await expect(bufferResult(
101-
``,
102-
[`hello`, `world`],
103-
)).resolves.toMatchObject({
104-
exitCode: 0,
105-
stdout: ``,
102+
it(`should support a whitespace-only string`, async () => {
103+
await expect(bufferResult(
104+
` `,
105+
)).resolves.toMatchObject(EMPTY_COMMAND_RESULT);
106+
107+
await expect(bufferResult(
108+
`\t`,
109+
)).resolves.toMatchObject(EMPTY_COMMAND_RESULT);
110+
111+
await expect(bufferResult(
112+
` \t \t \t `,
113+
)).resolves.toMatchObject(EMPTY_COMMAND_RESULT);
114+
});
115+
116+
it(`should support an empty string when passing arguments`, async () => {
117+
await expect(bufferResult(
118+
``,
119+
[`hello`, `world`],
120+
)).resolves.toMatchObject(EMPTY_COMMAND_RESULT);
121+
});
122+
123+
it(`should support a whitespace-only string when passing arguments`, async () => {
124+
await expect(bufferResult(
125+
` `,
126+
[`hello`, `world`],
127+
)).resolves.toMatchObject(EMPTY_COMMAND_RESULT);
128+
129+
await expect(bufferResult(
130+
`\t`,
131+
[`hello`, `world`],
132+
)).resolves.toMatchObject(EMPTY_COMMAND_RESULT);
133+
134+
await expect(bufferResult(
135+
` \t \t \t `,
136+
[`hello`, `world`],
137+
)).resolves.toMatchObject(EMPTY_COMMAND_RESULT);
106138
});
107139
});
108140

0 commit comments

Comments
 (0)