From 172c7a7f5b8531f7ea1131ec036c376e20e6573b Mon Sep 17 00:00:00 2001 From: fatme Date: Thu, 18 Jul 2019 08:50:09 +0300 Subject: [PATCH] fix: parse options correctly Currently `tns run android --release` throws an error that `--hmr` and `--release` cannot be used simultaneously. After parsing `this.yargsArgv = yargs(process.argv.slice(2))` command line options, only `--release` option is true as it is expected to be. For some reason after calling `this.argv = this.yargsArgv.options(opts).argv`, `this.yargsArgv` is modified and `this.yargsArgv.hmr` is true which is not the expected behavior. It seems like a strange behavior of yargs. In order to fix it, we parse the command line only once and persist the `argv` object of initial parsed command line. --- lib/options.ts | 9 +++++---- test/options.ts | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/options.ts b/lib/options.ts index d352b62bf8..4c9d1fa83f 100644 --- a/lib/options.ts +++ b/lib/options.ts @@ -6,7 +6,6 @@ export class Options { private static NONDASHED_OPTION_REGEX = /(.+?)[-]([a-zA-Z])(.*)/; private optionsWhiteList = ["ui", "recursive", "reporter", "require", "timeout", "_", "$0"]; // These options shouldn't be validated - private yargsArgv: yargs.Argv; private globalOptions: IDictionary = { log: { type: OptionType.String, hasSensitiveValue: false }, verbose: { type: OptionType.Boolean, alias: "v", hasSensitiveValue: false }, @@ -19,6 +18,7 @@ export class Options { _: { type: OptionType.String, hasSensitiveValue: false } }; + private initialArgv: yargs.Arguments; public argv: yargs.Arguments; public options: IDictionary; @@ -31,7 +31,7 @@ export class Options { this.argv.bundle = "webpack"; // Check if the user has explicitly provide --hmr and --release options from command line - if (this.yargsArgv.argv.release && this.yargsArgv.argv.hmr) { + if (this.initialArgv.release && this.initialArgv.hmr) { this.$errors.failWithoutHelp("The options --release and --hmr cannot be used simultaneously."); } @@ -250,8 +250,9 @@ export class Options { opts[this.getDashedOptionName(key)] = value; }); - this.yargsArgv = yargs(process.argv.slice(2)); - this.argv = this.yargsArgv.options(opts).argv; + const parsed = yargs(process.argv.slice(2)); + this.initialArgv = parsed.argv; + this.argv = parsed.options(opts).argv; // For backwards compatibility // Previously profileDir had a default option and calling `this.$options.profileDir` always returned valid result. diff --git a/test/options.ts b/test/options.ts index 2ad685f0f0..92363d685d 100644 --- a/test/options.ts +++ b/test/options.ts @@ -292,7 +292,7 @@ describe("options", () => { name: "should set hmr to true by default", expectedHmrValue: true }, { - name: "set set hmr to false when --no-hmr is provided", + name: "should set hmr to false when --no-hmr is provided", args: ["--no-hmr"], expectedHmrValue: false }, { @@ -319,6 +319,7 @@ describe("options", () => { options.setupOptions(testCase.commandSpecificDashedOptions); assert.equal(testCase.expectedHmrValue, options.argv.hmr); + assert.isFalse(isExecutionStopped); (testCase.args || []).forEach(arg => process.argv.pop()); });