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

Deprecate version retrieval #1954

Conversation

shadowspawn
Copy link
Collaborator

@shadowspawn shadowspawn commented Aug 10, 2023

Pull Request

Problem

An early implementation of .version() acted a bit like a getter/setter for a version property:

For historical interest, in that code this._version also got used to decide whether to guess the version when .parse() was called! Long gone.

When .opts() got added, the version option/property got returned as well. [sic]

Retrieving the version property has never been documented, and the JSDoc and TypeScript typings define the version string parameter as required (so do not include the getter usage).

  1. I definitely don't think the version should be returned in .opts() (and that is only done when .storeOptionsAsProperties() is turned on, so already a legacy behaviour).

  2. I am dubious about supporting a getter for the version. I think of .version() as a convenience for adding the version option, and not as a getter for a version property. Because it has never been documented, I have never used it that way myself and don't recall any mention of it in issues. However, I feel less strongly about this than (1) and don't mind keeping it if people are using it.

Solution

Added to Deprecated documentation to make it explicit that may remove the functionality in future.

ChangeLog

  • deprecated retrieve version string using cmd.version() with no parameters
  • deprecated retrieve version string using cmd.opts().version (and .storeOptionsAsProperties())

@aweebit
Copy link
Contributor

aweebit commented Aug 12, 2023

  1. I definitely don't think the version should be returned in .opts() (and that is only done when .storeOptionsAsProperties() is turned on, so already a legacy behaviour).

I am totally in favor of deprecating it and removing in the next major release, which should hardly cause any migration complications because the feature has never been documented and is not very useful anyway, so unlikely to be relied on.

The fact that the version is included in the object returned from .opts() when using storeOptionsAsProperties was the reason why #1921 (comment) was so complex.

(By the way, still waiting for your reply in #1921. No hurry though, just reminding in case you forgot which I myself definitely would've considering the issue has been closed for a while now.)

  1. I am dubious about supporting a getter for the version. I think of .version() as a convenience for adding the version option, and not as a getter for a version property. Because it has never been documented, I have never used it that way myself and don't recall any mention of it in issues. However, I feel less strongly about this than (1) and don't mind keeping it if people are using it.

As far as I am concerned, we could just leave it. Doesn't harm, doesn't imply any complications for the implementation. Gives a meaning to an otherwise meaningless call. (A different meaning could be to delete the version option, but I don't think it is something you want to support because the fact you closed #1933 indicates that you don't want to make modifications to version options possible.)

@aweebit
Copy link
Contributor

aweebit commented Aug 12, 2023

Gives a meaning to an otherwise meaningless call. (A different meaning could be to delete the version option, but I don't think it is something you want to support because the fact you closed #1933 indicates that you don't want to make modifications to version options possible.)

Apropos meaningless calls, I still think the change from #1933 that enables updates to the version number should be accepted. All the other changes suggested there are not really important because they are just reinventions of the existing behavior of .version() that adds a new option when a value for the flags parameter is provided.

But this particular change would give meaning to repeated .version() calls with only a value for the first parameter provided. Its current behavior is very unintuitive: why would a duplicate version option be added? why would using it in the command result in the old version number being displayed?

PS: I am referring to this use case scenario from #1933:

var program = new Command();
program.version('1.0.0');
if ('EARLY_ADOPTER' in process.env) {
  program.version('2.0.0'); // expectation: the version number is simply updated
}
program.outputHelp(); // reality: contains version option twice if early adopter
program.parse(['--version'], { from: 'user' }); // output is always '1.0.0'

It is unsettling someone could write code like this unknowingly and get completely unexpected results.

@aweebit
Copy link
Contributor

aweebit commented Aug 14, 2023

An argument in defense of version retrieval via .version(): the call could be useful for developers of third-party hooks and subclasses that need the version number for some reason (e.g. a logging hook could call .name() and .version() to use the values in a prefix for the log entries).

@shadowspawn
Copy link
Collaborator Author

(e.g. a logging hook could call .name() and .version() to use the values in a prefix for the log entries).

I did wonder about that use case. However, not particularly useful currently as only defined on the program and not on subcommands.

@aweebit
Copy link
Contributor

aweebit commented Aug 14, 2023

(e.g. a logging hook could call .name() and .version() to use the values in a prefix for the log entries).

I did wonder about that use case. However, not particularly useful currently as only defined on the program and not on subcommands.

In preAction hooks added to the top level command, the version can always be accessed via thisCommand.version(), so I wouldn't say it is not useful. Also, one cam always walk to the root up the parent chain.

@shadowspawn shadowspawn marked this pull request as draft August 24, 2023 09:43
@shadowspawn
Copy link
Collaborator Author

The code search is getting useful!

https://github.com/search?q=%22program.version()%22%20%22commander%22%20(language%3Ajavascript%20OR%20language%3Atypescript)%20NOT%20is%3Afork&type=repositories

Somewhat annoyingly, I found an exercise saying to retrieve the version with program.version():

https://github.com/gangstead/comder/blob/41d762c65616366a1a94413ff425b8693b8f838d/exercises/hello_commander/problem.md

I'll try and get over my current annoyance... 😆

@shadowspawn shadowspawn deleted the feature/deprecate-version-retrieval branch November 10, 2023 22:08
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.

2 participants