Skip to content

Commit 52a35c9

Browse files
authored
Fix: Prevents interpreting run options as yarn options (#4152)
* Prevents interpreting run options as yarn options * Implements a deprecation warning * Adds tests * Feedback * Wording * Enables a test on Linux * Disables the tests again on Windows
1 parent 2cb6dd6 commit 52a35c9

File tree

3 files changed

+73
-2
lines changed

3 files changed

+73
-2
lines changed

__tests__/integration.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,61 @@ test('--mutex network', async () => {
7373
]);
7474
});
7575

76+
// Windows could run these tests, but we currently suffer from an escaping issue that breaks them (#4135)
77+
if (process.platform !== 'win32') {
78+
test('yarn run <script> --opt', async () => {
79+
const cwd = await makeTemp();
80+
81+
await fs.writeFile(
82+
path.join(cwd, 'package.json'),
83+
JSON.stringify({
84+
scripts: {echo: `echo`},
85+
}),
86+
);
87+
88+
const command = path.resolve(__dirname, '../bin/yarn');
89+
const options = {cwd, env: {YARN_SILENT: 1}};
90+
91+
const {stderr: stderr, stdout: stdout} = execa(command, ['run', 'echo', '--opt'], options);
92+
93+
const stdoutPromise = misc.consumeStream(stdout);
94+
const stderrPromise = misc.consumeStream(stderr);
95+
96+
const [stdoutOutput, stderrOutput] = await Promise.all([stdoutPromise, stderrPromise]);
97+
98+
expect(stdoutOutput.toString().trim()).toEqual('--opt');
99+
expect(stderrOutput.toString()).not.toMatch(
100+
/From Yarn 1\.0 onwards, scripts don't require "--" for options to be forwarded/,
101+
);
102+
});
103+
104+
test('yarn run <script> -- --opt', async () => {
105+
const cwd = await makeTemp();
106+
107+
await fs.writeFile(
108+
path.join(cwd, 'package.json'),
109+
JSON.stringify({
110+
scripts: {echo: `echo`},
111+
}),
112+
);
113+
114+
const command = path.resolve(__dirname, '../bin/yarn');
115+
const options = {cwd, env: {YARN_SILENT: 1}};
116+
117+
const {stderr: stderr, stdout: stdout} = execa(command, ['run', 'echo', '--', '--opt'], options);
118+
119+
const stdoutPromise = misc.consumeStream(stdout);
120+
const stderrPromise = misc.consumeStream(stderr);
121+
122+
const [stdoutOutput, stderrOutput] = await Promise.all([stdoutPromise, stderrPromise]);
123+
124+
expect(stdoutOutput.toString().trim()).toEqual('--opt');
125+
expect(stderrOutput.toString()).toMatch(
126+
/From Yarn 1\.0 onwards, scripts don't require "--" for options to be forwarded/,
127+
);
128+
});
129+
}
130+
76131
test('cache folder fallback', async () => {
77132
const cwd = await makeTemp();
78133
const cacheFolder = path.join(cwd, '.cache');

src/cli/index.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,16 @@ export function main({
110110
command = commands.run;
111111
}
112112

113+
let warnAboutRunDashDash = false;
114+
// we are using "yarn <script> -abc" or "yarn run <script> -abc", we want -abc to be script options, not yarn options
115+
if (command === commands.run) {
116+
if (endArgs.length === 0) {
117+
endArgs = ['--', ...args.splice(1)];
118+
} else {
119+
warnAboutRunDashDash = true;
120+
}
121+
}
122+
113123
command.setFlags(commander);
114124
commander.parse([
115125
...startArgs,
@@ -119,7 +129,7 @@ export function main({
119129
...getRcArgs(commandName, args),
120130
...args,
121131
]);
122-
commander.args = commander.args.concat(endArgs);
132+
commander.args = commander.args.concat(endArgs.slice(1));
123133

124134
// we strip cmd
125135
console.assert(commander.args.length >= 1);
@@ -171,6 +181,11 @@ export function main({
171181
//
172182
const run = (): Promise<void> => {
173183
invariant(command, 'missing command');
184+
185+
if (warnAboutRunDashDash) {
186+
reporter.warn(reporter.lang('dashDashDeprecation'));
187+
}
188+
174189
return command.run(config, reporter, commander, commander.args).then(exitCode => {
175190
if (outputWrapper) {
176191
reporter.footer(false);
@@ -403,7 +418,7 @@ export default function start() {
403418
const doubleDashIndex = process.argv.findIndex(element => element === '--');
404419
const startArgs = process.argv.slice(0, 2);
405420
const args = process.argv.slice(2, doubleDashIndex === -1 ? process.argv.length : doubleDashIndex);
406-
const endArgs = doubleDashIndex === -1 ? [] : process.argv.slice(doubleDashIndex + 1, process.argv.length);
421+
const endArgs = doubleDashIndex === -1 ? [] : process.argv.slice(doubleDashIndex);
407422

408423
main({startArgs, args, endArgs});
409424
}

src/reporters/lang/en.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ const messages = {
188188

189189
execMissingCommand: 'Missing command name.',
190190

191+
dashDashDeprecation: `From Yarn 1.0 onwards, scripts don't require "--" for options to be forwarded. In a future version, any explicit "--" will be forwarded as-is to the scripts.`,
191192
commandNotSpecified: 'No command specified.',
192193
binCommands: 'Commands available from binary scripts: ',
193194
possibleCommands: 'Project commands',

0 commit comments

Comments
 (0)