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

add support for exclusive command line flags #677

Closed
bdehamer opened this issue May 18, 2023 · 4 comments
Closed

add support for exclusive command line flags #677

bdehamer opened this issue May 18, 2023 · 4 comments
Assignees

Comments

@bdehamer
Copy link

We have a handful of command line flags that we'd love to function as boolean-or-string values:

  • browser - Can be true/false or accept the path to the browser (currently configured as type: [null, Boolean, String] but doesn't really work as intended).
  • expect-entries - Can be true/false or specify the number of entries to match.
  • provenance - Currently accepts true/false, but would like the ability to accept the path to an externally-generated provenance statement.

There's some question as to whether this sort of overloading is even the right approach, but the bottom line is that nopt can't properly handle this use case.

As an alternative to overloaded flags, we could allow for sets of related flags that are mutually exclusive:

  • browser becomes browser OR browser-path
  • expected-entries becomes expected-entries OR expected-entries-count
  • provenance becomes provenance OR provenance-path

The feature we're missing is some way to indicate that the usage of flags within a given set is mutually exclusive -- preventing the user from specifying conflicting options (like generating provenance AND accepting an existing provenance)

Configuration

When defining command line flags we'll need some way to indicate the sets of mutually exclusive flags:

define('provenance', {
  default: false,
  type: Boolean,
  description: 'Generate provenance statement on publish',
  exclusive: ['provenance-path'],
})

define('provenance-path', {
  default: null,
  type: path,
  description: 'Path to provenance statement to publish with package',
  exclusive: ['provenance'],
})

Our existing examples all have a pair of related flags, but there's no reason we couldn't support larger sets of related flags -- using an Array for the exclusive attribute gives us flexibility to configure related flag sets of any size.

It should be encouraged (but not required) that each flag in an exclusive set list it's excluded partners. In the example above, each flag lists the other in the exclusive set, however, the behavior shouldn't change if we were to omit one of the exclusive attributes.

Either of the following configs should be functionally equivalent to the config show above:

define('provenance', {
  default: false,
  type: Boolean,
  description: 'Generate provenance statement on publish',
})

define('provenance-path', {
  default: null,
  type: path,
  description: 'Path to provenance statement to publish with package',
  exclusive: ['provenance'],
})
define('provenance', {
  default: false,
  type: Boolean,
  description: 'Generate provenance statement on publish',
  exclusive: ['provenance-path'],
})

define('provenance-path', {
  default: null,
  type: path,
  description: 'Path to provenance statement to publish with package',
})

Behavior

Help

When help is rendered for a command with exclusive flags, it would be helpful if the output conveyed that only one of the related flags can be specified at a time:

Publish a package

Usage:
npm publish <package-spec>

Options:
[--provenance | --provenance-path <provenance-file>] . . .

We may need to pick something other than | character to signal the "OR" relationship here since it's already being used show the short and long forms of a flag:

[-ws|--workspaces]

Would be nice to have this information surfaced in the detailed help as well:

   provenance

       •   Default: false

       •   Type: Boolean

       When publishing from a supported cloud CI/CD system, the package will be publicly linked to where it
       was built and published from.

       Cannot be used when any of the following flags are provided: "provenance-path"

Errors

If a user specifies any combination of flags that appear in the same exclusive set they should receive an error

$ npm publish --provenance-path /tmp/provenance --provenance

npm ERR! --provenance cannot be provided when using --provenance-path
@wraithgar
Copy link
Member

We may need to pick something other than | character to signal the "OR" relationship here since it's already being used show the short and long forms of a flag:

We can just add both to the output, no need to have them inside a [].

@wraithgar
Copy link
Member

#677

@ljharb
Copy link

ljharb commented May 23, 2023

Doesn't [] indicate optionality, pretty universally?

@wraithgar
Copy link
Member

This was included in npm/cli#6490 as it was needed to ship that feature

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

No branches or pull requests

3 participants