Skip to content

Commit

Permalink
feat(webpack-cli): allow negative property for cli-flags
Browse files Browse the repository at this point in the history
  • Loading branch information
snitin315 committed Jul 5, 2020
1 parent 7489e63 commit 80a7c9b
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 50 deletions.
101 changes: 53 additions & 48 deletions packages/webpack-cli/__tests__/arg-parser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,20 @@ const basicOptions = [
type: Boolean,
description: 'boolean flag',
},
{
name: 'specific-bool',
alias: 's',
usage: '--specific-bool',
type: Boolean,
description: 'boolean flag',
},
{
name: 'no-specific-bool',
usage: '--no-specific-bool',
type: Boolean,
description: 'boolean flag',
},
{
name: 'num-flag',
usage: '--num-flag <value>',
type: Number,
description: 'number flag',
},
{
name: 'neg-flag',
alias: 'n',
usage: '--neg-flag',
type: Boolean,
negative: true,
description: 'boolean flag',
},
{
name: 'string-flag',
usage: '--string-flag <value>',
Expand Down Expand Up @@ -150,16 +145,6 @@ describe('arg-parser', () => {
expect(warnMock.mock.calls.length).toEqual(0);
});

it('parses specified negated boolean flag', () => {
const res = argParser(basicOptions, ['--no-specific-bool'], true);
expect(res.unknownArgs.length).toEqual(0);
expect(res.opts).toEqual({
specificBool: false,
stringFlagWithDefault: 'default-value',
});
expect(warnMock.mock.calls.length).toEqual(0);
});

it('parses multi type flag as Boolean', () => {
const res = argParser(basicOptions, ['--multi-type'], true);
expect(res.unknownArgs.length).toEqual(0);
Expand All @@ -180,37 +165,15 @@ describe('arg-parser', () => {
expect(warnMock.mock.calls.length).toEqual(0);
});

it('warns on usage of both flag and same negated flag, setting it to false', () => {
const res = argParser(basicOptions, ['--specific-bool', '--no-specific-bool'], true);
expect(res.unknownArgs.length).toEqual(0);
expect(res.opts).toEqual({
specificBool: false,
stringFlagWithDefault: 'default-value',
});
expect(warnMock.mock.calls.length).toEqual(1);
expect(warnMock.mock.calls[0][0]).toContain('You provided both --specific-bool and --no-specific-bool');
});

it('warns on usage of both flag and same negated flag, setting it to true', () => {
const res = argParser(basicOptions, ['--no-specific-bool', '--specific-bool'], true);
expect(res.unknownArgs.length).toEqual(0);
expect(res.opts).toEqual({
specificBool: true,
stringFlagWithDefault: 'default-value',
});
expect(warnMock.mock.calls.length).toEqual(1);
expect(warnMock.mock.calls[0][0]).toContain('You provided both --specific-bool and --no-specific-bool');
});

it('warns on usage of both flag alias and same negated flag, setting it to true', () => {
const res = argParser(basicOptions, ['--no-specific-bool', '-s'], true);
const res = argParser(basicOptions, ['--no-neg-flag', '-n'], true);
expect(res.unknownArgs.length).toEqual(0);
expect(res.opts).toEqual({
specificBool: true,
negFlag: true,
stringFlagWithDefault: 'default-value',
});
expect(warnMock.mock.calls.length).toEqual(1);
expect(warnMock.mock.calls[0][0]).toContain('You provided both -s and --no-specific-bool');
expect(warnMock.mock.calls[0][0]).toContain('You provided both -n and --no-neg-flag');
});

it('parses string flag using equals sign', () => {
Expand Down Expand Up @@ -286,4 +249,46 @@ describe('arg-parser', () => {
expect(res.opts.stats).toEqual(true);
expect(warnMock.mock.calls.length).toEqual(0);
});

it('parses --neg-flag', () => {
const res = argParser(basicOptions, ['--neg-flag'], true);
expect(res.unknownArgs.length).toEqual(0);
expect(res.opts).toEqual({
negFlag: true,
stringFlagWithDefault: 'default-value',
});
expect(warnMock.mock.calls.length).toEqual(0);
});

it('parses --no-neg-flag', () => {
const res = argParser(basicOptions, ['--no-neg-flag'], true);
expect(res.unknownArgs.length).toEqual(0);
expect(res.opts).toEqual({
negFlag: false,
stringFlagWithDefault: 'default-value',
});
expect(warnMock.mock.calls.length).toEqual(0);
});

it('warns on usage of both --neg and --no-neg flag, setting it to false', () => {
const res = argParser(basicOptions, ['--neg-flag', '--no-neg-flag'], true);
expect(res.unknownArgs.length).toEqual(0);
expect(res.opts).toEqual({
negFlag: false,
stringFlagWithDefault: 'default-value',
});
expect(warnMock.mock.calls.length).toEqual(1);
expect(warnMock.mock.calls[0][0]).toContain('You provided both --neg-flag and --no-neg-flag');
});

it('warns on usage of both flag and same negated flag, setting it to true', () => {
const res = argParser(basicOptions, ['--no-neg-flag', '--neg-flag'], true);
expect(res.unknownArgs.length).toEqual(0);
expect(res.opts).toEqual({
negFlag: true,
stringFlagWithDefault: 'default-value',
});
expect(warnMock.mock.calls.length).toEqual(1);
expect(warnMock.mock.calls[0][0]).toContain('You provided both --neg-flag and --no-neg-flag');
});
});
10 changes: 8 additions & 2 deletions packages/webpack-cli/lib/utils/arg-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,14 @@ function argParser(options, args, argsOnly = false, name = '', helpFunction = un
let flagsWithType = option.type !== Boolean ? flags + ' <value>' : flags;
if (option.type === Boolean || option.type === String) {
if (!option.multiple) {
// Prevent default behavior for standalone options
parserInstance.option(flagsWithType, option.description, option.defaultValue).action(() => {});
if (option.negative) {
// commander requires explicitly adding the negated version of boolean flags
const negatedFlag = `--no-${option.name}`;
parserInstance.option(negatedFlag, `negates ${option.name}`).action(() => {});
} else {
// Prevent default behavior for standalone options
parserInstance.option(flagsWithType, option.description, option.defaultValue).action(() => {});
}
} else {
const multiArg = (value, previous = []) => previous.concat([value]);
parserInstance.option(flagsWithType, option.description, multiArg, option.defaultValue).action(() => {});
Expand Down
2 changes: 2 additions & 0 deletions packages/webpack-cli/lib/utils/cli-flags.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ module.exports = {
usage: '--hot',
alias: 'h',
type: Boolean,
negative: true,
group: ADVANCED_GROUP,
description: 'Enables Hot Module Replacement',
link: 'https://webpack.js.org/concepts/hot-module-replacement/',
Expand Down Expand Up @@ -242,6 +243,7 @@ module.exports = {
usage: '--stats <value>',
type: [String, Boolean],
group: DISPLAY_GROUP,
negative: true,
description: 'It instructs webpack on how to treat the stats e.g. verbose',
link: 'https://webpack.js.org/configuration/stats/#stats',
},
Expand Down

0 comments on commit 80a7c9b

Please sign in to comment.