Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix type "array" with "duplicate-arguments-array" #163

Closed
wants to merge 3 commits into from

Conversation

juergba
Copy link
Contributor

@juergba juergba commented Mar 22, 2019

Description

closes #162

The array type does not work consistently with option duplicate-arguments-array.
when duplicate-arguments-array === false

  • array of type string does reduce duplicate arguments
  • array of type number does not reduce duplicate arguments
  • array of type boolean only works with arguments provided in pairs, eg --foo true.
    A boolean without value (--foo --no-foo) results in various bugs as empty arrays, lost flags, lost array type and more.

Description of Change

  • duplicate-arguments-array has no effect on option type array anymore.
    even when duplicate-arguments-array === false, you are able to specify:
    (output depends on flatten-duplicate-arrays)
    • -x 1 -x 2 -x 3==> [1, 2, 3] or [[1], [2], [3]]
    • -x 1 2 -x 4 5==> [1, 2, 4, 5] or [[1, 2], [4, 5]]
  • option type number and string work consistently.
  • an array value is always an array, even if just one value is passed.
  • maybeCoerceNumber(): fix handling of arrays.
  • adapt existing tests, add new tests

Please note: the disabling of creating an array by -x a b c by default will be implemented in another PR.

@bcoe
Copy link
Member

bcoe commented May 5, 2019

@juergba thank you for all the wonderful contributions you've made recently, I will work on getting them merged as soon as possible; I've been buried on other projects and apologize.

@bcoe
Copy link
Member

bcoe commented Jun 7, 2019

@juergba could I bother you to rebase? I'm getting ready to release a new version of yargs and yargs-parser.

Copy link
Member

@bcoe bcoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my thinking is, if you've explicitly set type to array, we should still accept the option being set multiple times -- duplicate-arguments-array applying only to the behavior of keys you haven't explicitly set as an array.

Honestly, I'd kind of like to drop support for -x a b c, and make it so the only way to create an array is -x a -x b -x c; since type array does not mix well with positional arguments.

tldr; I think perhaps we need better documentation around arrays, and to perhaps rethink the behavior of the array option, but I'm so so on this patch.

@coreyfarrell @plroebuck @boneskull have any opinions about array behavior? mainly my idea of deprecating -x 2 3 3 in favor of the more explicit -x 2 -x 3 -x 3.

test/yargs-parser.js Outdated Show resolved Hide resolved
@juergba
Copy link
Contributor Author

juergba commented Jun 9, 2019

[...] duplicate-arguments-array applying only to the behavior of keys you haven't explicitly set as an array.

Agree, type array should precede duplicate-arguments-array.
For this PR:

  • behavior of number[] is correct
  • behavior of string[] has to be fixed, should match number[] pattern
    Note: this will probably "shock" many existing implementations / breaking change

Honestly, I'd kind of like to drop support for -x a b c

What about opts.narg then?

@coreyfarrell
Copy link
Contributor

my thinking is, if you've explicitly set type to array, we should still accept the option being set multiple times -- duplicate-arguments-array applying only to the behavior of keys you haven't explicitly set as an array.

Yes please. In the context of nyc I would like to block use of --temp-dir or --cwd multiple times but not block multiple use of use of --reporter.

Honestly, I'd kind of like to drop support for -x a b c, and make it so the only way to create an array is -x a -x b -x c; since type array does not mix well with positional arguments.

Maybe it would be better to disable -x a b c by default but still have a way to enable it? Worth considering that -x a b c -x d e f can mean x: [['a', 'b', 'c'], ['d', 'e', 'f']]?

@bcoe
Copy link
Member

bcoe commented Jun 9, 2019

what about opts.narg then?

I think narg would behave differently than array and just take the last set. so, if narg of x was set to 2, and you passed --x a b --x c d, you'd get c, d.

@coreyfarrell

Maybe it would be better to disable -x a b c by default but still have a way to enable it?

I agree with this, maybe a parameter called --positional-arrays, which we start to default to false? Then the array type can be used (by default) simply to imply:

  1. this value will always be an array, even if just one value is passed.
  2. even if you set duplicate-arguments-array to false, you will still be able to specify -x 1 -x 2 -x 3.

@juergba does this sound reasonable to you for mocha's needs? If so perhaps we could update this patch to reflect this world.

@juergba
Copy link
Contributor Author

juergba commented Jun 10, 2019

does this sound reasonable to you for mocha's needs?

afaik we don't use -x a b c in Mocha, we only use -x a -x b -x c or -x a,b,c.

If so perhaps we could update this patch to reflect this world.

Ok, I will give it a try. I'm not sure yet about the implications of "disabling -x a b c by default".
I will see ...

@juergba juergba changed the title Fix type "array" with "duplicate-arguments-array" WIP: Fix type "array" with "duplicate-arguments-array" Jun 10, 2019
@juergba juergba changed the title WIP: Fix type "array" with "duplicate-arguments-array" Fix type "array" with "duplicate-arguments-array" Jun 10, 2019
@juergba
Copy link
Contributor Author

juergba commented Jun 11, 2019

@bcoe The behavior of option type boolean[] seems to be completely buggy, even before this PR.

  • are option type boolean[] allowed?
  • is boolean[]'s expected behavior identical to number[] and string[]?

@bcoe
Copy link
Member

bcoe commented Jun 13, 2019

@juergba my thinking is we should make this a breaking change, and address some of these long standing issues. If you indicate something is an array, even a boolean, I think you should get an array out the other end, even if it's an empty array (if no argument is set) or an array of one item if only one item is provided.

It might break the internet too much to drop support for -x a b c, but perhaps we could at least add a config setting that allows this to be disabled? Then consider whether we drop the feature eventually, forcing -x a -x b -x c.

@juergba
Copy link
Contributor Author

juergba commented Jun 14, 2019

I understand your concerns with -x a b c and your plans for an additional config setting. IMO before doing this we should fix some bugs.

The current master shows following results:

var args = parse('--file --file', {
  'array': ['file'],
  'number': ['file'],           // { _: [], file: [ 0, 0, undefined ] }
  // 'string': ['file'],        // { _: [], file: [ [], [], '' ] }
  // 'boolean': ['file'],       // { _: [], file: [ [], [], [] ] }
  configuration: {
    'duplicate-arguments-array': true,
    'flatten-duplicate-arrays': false
  }
})
var args = parse('--file true --file true', {   // same result with '--file --file'
  'boolean': ['file'],    
  configuration: {
    'duplicate-arguments-array': true
  }
})           // { _: [], file: true }

We should address those bugs first, before adding new flags. boolean is a special option since the flag itself can carry its value, so --booly === --booly true.

@bcoe
Copy link
Member

bcoe commented Jun 16, 2019

@juergba I agree, let's start by fixing these bugs.

Do we want to close this issue, in favor of landing fixes like #184? and moving towards a better API for arrays in the long run?

@juergba
Copy link
Contributor Author

juergba commented Jun 17, 2019

Do we want to close this issue

No, please don't close. This issue covers its own topic, which got lost completely during -x a b c discussion.

[...] moving towards a better API for arrays in the long run?

Yes, landing fixes step by step is a good procedure.

@bcoe
Copy link
Member

bcoe commented Jul 29, 2019

@juergba any chance we can dust this PR off, I'd like to start working on getting a few more releases of yargs out the door.

@juergba
Copy link
Contributor Author

juergba commented Jul 29, 2019

Yes, I can make the original issue (type "array" with "duplicate-arguments-array") ready within a few days.

The disabling of creating an array by -x a b c by default is not part of this PR.

@bcoe
Copy link
Member

bcoe commented Jul 29, 2019

@juergba sounds good to me, I think that's @coreyfarrell's recommendation to make disable -x a b c by default might be smart honestly, but in a future PR ... my concern is this would likely bite quite a few folks, so it's worth opening a discussion.

@juergba
Copy link
Contributor Author

juergba commented Jul 30, 2019

my thinking is, if you've explicitly set type to array, we should still accept the option being set multiple times -- duplicate-arguments-array applying only to the behavior of keys you haven't explicitly set as an array.

@bcoe please confirm wether you really want above pattern:
(duplicate-arguments-array: false)
[-x 1 2 3 -x 2 3 4] => [[1, 2, 3], [2, 3, 4]]

In #75 the opposite was implemented:
[-x 1 2 3 -x 2 3 4] => [2, 3, 4]

@bcoe
Copy link
Member

bcoe commented Jul 30, 2019

@juergba if you have duplicate-arguments-array = true, and an option is an array, I feel it should be:

[[1, 2, 3], [2, 3, 4]]

If you have duplicate-arguments-array = false, and an option is an array I feel it should be:

[2, 3, 4].

This agrees with your thinking?

@juergba
Copy link
Contributor Author

juergba commented Jul 30, 2019

No, this is not what I'm thinking.

Neither after your comment:

my thinking is, if you've explicitly set type to array, we should still accept the option being set multiple times -- duplicate-arguments-array applying only to the behavior of keys you haven't explicitly set as an array.

Nor after @coreyfarrell 's comment:

Yes please. In the context of nyc I would like to block use of --temp-dir or --cwd multiple times but not block multiple use of use of --reporter.

@coreyfarrell can you help, please?

@bcoe
Copy link
Member

bcoe commented Jul 30, 2019

@juergba duplicate-arguments-array is a specific setting which indicates that the last time a value is set, like -x it should take precedence.

Therefore, in the edge case that you've set a array and duplicate-arguments-array it should have the same behavior:

-x 3 5 5 -x 4 3 2 in which the last -x is preferred, so:

x: [4, 3, 2].

I don't think we should change this behavior ... and it's pretty edge-casey to be honest (not something I've seen many issues about).

What I would be more willing to entertain would be a redefinition of what setting the type array means, i.e., getting rid of support for -x 3 2 4 entirely.

tldr; I'm not super excited about the changes proposed in this PR because it seems like thrash without solving much of a problem I've observed, I'd rather work to make the array setting less surprising (and perhaps retire some of the config settings around arrays in this process).

@bcoe
Copy link
Member

bcoe commented Jul 30, 2019

getting back to your original PR description:

If duplicate-arguments-array = false

  • -x a b c -x d e f and x = string, array = true, should result in [d, e, f]
  • -x 1 2 3 -x 4 5 6 and x = number, array = true, should result in [4, 5, 6].
  • -x a b c -x d e f and x = string, array = false, should result in d.
  • -x 1 2 3 -x 4 5 6 and x = number, array = false, should result in 4.
  • -x true true false -x false true true and x = boolean, array = false, should result in false.
  • -x true true false -x false true true and x = boolean, array = true, should result in [false, true, true].

If duplicate arguments-array = true

  • -x a b c -x d e f and x = string, array = true, should result in [[a, b, c], [d, e, f]]
  • -x 1 2 3 -x 4 5 6 and x = number, array = true, should result in [[1, 2, 3], [4, 5, 6]].
  • -x a b c -x d e f and x = string, array = false, should result in [a, d].
  • -x 1 2 3 -x 4 5 6 and x = number, array = false, should result in [1, 4].
  • -x a -x b -x c and x = string, array = false, should result in [a, b, c].
  • -x 1 -x 2 -x 3 and x = number, array = false, should result in [1, 2, 3].
  • -x true true false -x false true true and x = boolean, array = false, should result in [true, false].
  • -x true true false -x false true true and x = boolean, array = true, should result in [[true, true, false], [false, true, true]].

☝️ if there are any fixes we can make around these expectations let's make them 👌

And then I'd say, revisit the meaning of array in a separate issue (as I think it's confusing).

@juergba
Copy link
Contributor Author

juergba commented Jul 31, 2019

Meanwhile a few PR's refering boolean and array have been merged. This PR can be closed.

@juergba juergba closed this Jul 31, 2019
@juergba juergba deleted the issue/162 branch July 31, 2019 08:21
@bcoe
Copy link
Member

bcoe commented Aug 1, 2019

@juergba 👍 sorry for this dragging for so long, FYI any chance I could get you to join the slack here:

http://devtoolscommunity.herokuapp.com/

I'd like to roll out a new yargs with a bunch of your fixes, but would first like to make sure that it seems to behave nicely with mocha.

dgp1130 pushed a commit to angular/angular-cli that referenced this pull request Apr 11, 2022
With this change we add a Yargs middleware that normalizes non Array options when the argument has been provided multiple times.

By default, when an option is non array and it is provided multiple times in the command line, yargs
will not override it's value but instead it will be changed to an array unless `duplicate-arguments-array` is disabled.
But this option also have an effect on real array options which isn't desired.

See: yargs/yargs-parser#163 (comment)

Closes #22956
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

type "array" with "duplicate-arguments-array" works inconsistently
3 participants