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

Enhance Option class to allow hiding help, specifying choices, and change how default value displayed in help #1331

Merged
merged 45 commits into from Sep 14, 2020

Conversation

shadowspawn
Copy link
Collaborator

@shadowspawn shadowspawn commented Aug 15, 2020

Pull Request

There are various requests for additional behaviours for options that are hard to add to the existing Command interface. This is an experiment to see whether turning Option into a richer class will allow adding new features in a tidy way by working directly with the option, rather than indirectly from the command.

Problem

Solution

Enhance Option with support for configuring custom behaviours. Add a created Option to command with .addOption().

Use like:

program
   .addOption(new Option('-s, --secret').hideHelp())
   .addOption(new Option('-t, --timeout <delay>', 'timeout in seconds').default(60, 'one minute'))
   .addOption(new Option('-s, --size <value>', 'drink size').choices(['big', 'little']));
$ node help.js -h
Usage: help [options]

Options:
  -t, --timeout <delay>  timeout in seconds (default: one minute)
  -s, --size <value>     drink size (choices: "big", "little")
  -h, --help             display help for command

ChangeLog

  • allow hiding options from help
  • allow restricting option arguments to a list of choices
  • allow setting how default value is shown in help

@shadowspawn shadowspawn changed the base branch from master to develop August 15, 2020 09:02
@shadowspawn shadowspawn changed the title Fluent options WIP: Fluent options Aug 15, 2020
@shadowspawn shadowspawn added the semver: major Releasing requires a major version bump, not backwards compatible label Aug 15, 2020
@shadowspawn shadowspawn changed the title WIP: Fluent options WIP: Enhance Option class Aug 16, 2020
@shadowspawn shadowspawn removed the semver: major Releasing requires a major version bump, not backwards compatible label Aug 16, 2020
@shadowspawn shadowspawn self-assigned this Aug 16, 2020
@Tbhesswebber
Copy link

This looks awesome! I'm not seeing any tests for things being chained together - what is the expected behavior if we provide defaults and hide the help like in the following?

program
   .addOption(new Option('-t, --timeout').hideHelp().default(60, 'one minute'));

It seems to me like anything not shown in help should require a default value - should that require .default to be called?

Also, I realize that I was part of the impetus for this PR and I explicitly asked for a way to hide options, but should there be some way to toggle exposure of the hidden options. Something like giving every program a --advancedHelp flag that shows hidden flags? Maybe hideHelp should take an options object that allows it to accept default values and a boolean representing if it should show in advanced usage?

Thanks so much for all of your work on this and I'm sorry that I'm constantly poking holes in things to see if they pop!

@shadowspawn
Copy link
Collaborator Author

Thanks @Tbhesswebber . No popping noises yet. 🎈

I'm not seeing any tests for things being chained together - what is the expected behavior if we provide defaults and hide the help like in the following?

These calls chain (like when configuring Command), so in your example the option will have a default value and be hidden.

It seems to me like anything not shown in help should require a default value

Why is it different to a non-hidden option? If I don't look in the help, then I may not know what other options exists or whether they have a default value.

but should there be some way to toggle exposure of the hidden options

You can arrange for this yourself by passing false into hideHelp. Say by testing an environment variable to see whether to show everything.

@Tbhesswebber
Copy link

Fantastic! I think I just naturally think of all things having defaults within a CLI in order to avoid having to handle multiple ways of tracking values (with the exception of anything that is provided by a config file), so you can ignore that point of mine!

Again, I really appreciate your efforts here!

@shadowspawn
Copy link
Collaborator Author

shadowspawn commented Sep 12, 2020

I made a bunch of tidies since review comment. (A couple related to previous PR, sorry! 😊 )

  • remove duplicated code by having .requiredOption() implemented using .option()
  • rename parseArgWith to argParser as more conventional name
  • improve JSDoc
  • describing deprecated features as legacy in the comments, since we won't delete them until there is a good reason
  • added @deprecated to TSDoc so get editor feedback (e.g. latest VSCode this week!)

@shadowspawn
Copy link
Collaborator Author

npm run typescript-checkJS is currently showing some errors, including from my latest changes. I will investigate...

@shadowspawn
Copy link
Collaborator Author

Fixed.

@shadowspawn
Copy link
Collaborator Author

describing deprecated features as legacy in the comments, since we won't delete them until there is a good reason

I revisited this today. I was worried "deprecated" meant "we will delete this" and was too strong. But deprecated also can mean "this was a bad idea" or "there is a better way now". I'll go back to calling things deprecated instead of legacy, it is the right word for the functionality we would like people to stop using and is supported with the @deprecated tag.

So I'll make some wording changes but not logic changes, again! Sorry for the churn, but I am pleased to get this sorted out in my mind. I have been wondering how best to talk about old code for a while. 🤔 💡

@shadowspawn
Copy link
Collaborator Author

Done. Back to "deprecated"!

Copy link
Collaborator

@abetomo abetomo left a comment

Choose a reason for hiding this comment

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

awesome!

@shadowspawn
Copy link
Collaborator Author

Thanks for review @abetomo , it was a big one! 🎉

@shadowspawn shadowspawn merged commit a05a8bc into tj:release/7.x Sep 14, 2020
@shadowspawn shadowspawn deleted the feature/fluent-options branch September 14, 2020 08:36
@shadowspawn shadowspawn added this to the v7.0.0 milestone Sep 14, 2020
@shadowspawn shadowspawn added the pending release Merged into a branch for a future release, but not released yet label Sep 14, 2020
@shadowspawn shadowspawn mentioned this pull request Sep 15, 2020
8 tasks
@shadowspawn shadowspawn removed the pending release Merged into a branch for a future release, but not released yet label Jan 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver: major Releasing requires a major version bump, not backwards compatible
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants