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

Allow implies and conflicts to accept array values #922

Merged
merged 4 commits into from Sep 3, 2017

Conversation

MattSturgeon
Copy link
Contributor

@MattSturgeon MattSturgeon commented Jul 22, 2017

Fixes #921 and fixes #845

npm test passes, but I haven't tried to run yargs with the changes, nor added any new tests (sorry).

I've also not updated the docs.

@bcoe
Copy link
Member

bcoe commented Aug 15, 2017

@MattSturgeon should have checked open pulls before issues 😛

thanks for taking a stab at this; why don't you join the slack when you have a moment, and we can coordinate landing this feature.

@@ -318,7 +318,7 @@ module.exports = function (yargs, usage, y18n) {
conflicting[key] = []
}
if (Array.isArray(value)) {
conflicting[key].concat(value)
conflicting[key] = conflicting[key].concat(value)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

// Kinda sucks having to replace the array object instead of just mutating it,
// plus we have to type conflicting[key] twice
conflicting[key] = conflicting[key].concat(value)

// About the same speed as concat + assign, but we get to keep the same array
// object. Still kinda ugly though
Array.prototype.push.apply(conflicting[key], value)

// Twice as fast, less hacky than push.apply, but even more verbose
for (var i = 0, l = implied[key].length; i < l; i++) {
    implied[key].push(value[i])
}

// Should be similar to above, but slightly cleaner
// I think this is my favourite.
for (var i in value) {
    implied[key].push(i)
}

// I didn't consider forEach() since it is known to be way slower than a for loop

@MattSturgeon
Copy link
Contributor Author

MattSturgeon commented Aug 22, 2017

Rebased on master using ES6 style, added a check for valid implies/conflicts values which throws a YError if passed - this causes a test to fail, so I'll need to update the tests.

FYI the diff reads much better with whitespace ignored because some of the indention had to change.

} else if (typeof value === 'string') {
implied[key].push(value)
} else {
throw new YError('Invalid second argument passed to implied.' +
Copy link
Member

Choose a reason for hiding this comment

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

the reason that tests are failing is that there's this weird edge-case feature where an argument can imply a certain # of positional arguments in _:

yargs.implies({
  foo: 4
})

So the second argument can be a number, or a string, or an array with your design. Rather than pulling in the YError object and throwing your own error, I would pull in the argsert library and do this:

  self.implies = function implies (key, value) {
    argsert('<string|object> [array|number|string]', [key, value], arguments.length)

    if (typeof key === 'object') {
      Object.keys(key).forEach((k) => {
        self.implies(k, key[k])
      })
    } else {
      yargs.global(key)
      if (!implied[key]) {
        implied[key] = []
      }
      if (Array.isArray(value)) {
        value.forEach((i) => self.implies(key, i))
      } else {
        implied[key].push(value)
      }
    }
  }```

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion - it looks much cleaner now.

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.

this is looking pretty good 👍 we're definitely going to want to update docs to reflect this new feature, and to add a test that shows it off.

implies can accept a number, so argsert should allow passing a number
to it.

As per feedback, use argsert instead of manually throwing a YError.
Add some small tests for implies and conflicts using arrays. Conflicts
all works fine, but implies fails. I'm not sure if the test or the code
is at fault.
@bcoe bcoe merged commit abdc7da into yargs:master Sep 3, 2017
@bcoe
Copy link
Member

bcoe commented Sep 3, 2017

@MattSturgeon I've released your work to the next tag of yargs, I'd love your help testing (since the next release of yargs is pretty large).

npm i yargs@next --save

@Morishiri
Copy link
Contributor

I've found an issue here.

If you specify array value for implies and this implications are failed then we are getting output multiplied by array length.

For example:

.option('all', {
    describe: 'My description',
    boolean: true,
    implies: ['svn-url', 'svn-branch', 'svn-user', 'svn-password']
})

without specified any implied option will result in this error message:

Implications failed:
    all -> svn-url all -> svn-branch all -> svn-user all -> svn-password all -> svn-url all -> svn-branch all -> svn-user all -> svn-password all -> svn-url all -> svn-branch all -> svn-user all -> svn-password all -> svn-url all -> svn-branch all -> svn-user all -> svn-password

I will try to create pull request as soon as I will find a moment to do so if you are willing to accept one.

@MattSturgeon
Copy link
Contributor Author

@Morishiri you should probably open a new issue instead of commenting on this one. Are you saying the error message should be cleaned up and less verbose?

@Morishiri
Copy link
Contributor

Morishiri commented Sep 17, 2017

Yes, because now it shows all implications (not only failed) multiplied by implication count. I've created a pull request fixing this. #954 You may want to look into it.

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.

implies and conflicts should accept array values imply multiple dependencies
3 participants