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

Never call preSubcommand hooks on help command #1956

Closed

Conversation

aweebit
Copy link
Contributor

@aweebit aweebit commented Aug 13, 2023

This PR builds upon the already approved #1930.

Diff only for the change introduced by this PR:
aweebit/commander.js@feature/fixes...feature/help-command-no-preSubcommand

Problem

Currently, there is an inconsistency between how ._dispatchHelpCommand() deals with regular options and those with an executable handler, which seems to have been missed in #1864.

// program.js
const { Command } = require('commander');

const program = new Command()
  .hook('preSubcommand', (_, sub) => {
    console.log(sub.name());
  });
program.command('regular');
program.command('executable', 'description');
program.parse();
// program-executable.js
const { Command } = require('commander');

const program = new Command();
program.parse();
node program help regular # only help
node program help executable # 'executable' logged before help

Solution

Call ._executeSubCommand() directly in ._dispatchHelpCommand().

This is technically a breaking change, but hey, are we really going to assume someone relied on preSubcommand hooks being called before help for just one particular kind of subcommands?

ChangeLog

Fixed

(or maybe Changed?)

  • do not call preSubcommand hooks when displaying help for an executable subcommand

@aweebit aweebit changed the title Feature/help command no pre subcommand Never call preSubcommand hooks on help command Aug 13, 2023
@aweebit
Copy link
Contributor Author

aweebit commented Aug 13, 2023

Posted too early by accident, the description is now complete.

@shadowspawn
Copy link
Collaborator

I haven't put a lot of thought into this yet, but my first reaction is I am more interested in making it consistent by calling the hook in both cases. Do you want to have a go at that as well? I am imagining a few lines to add the hook before the direct call to the subcommand in _dispatchHelpCommand, not a refactor. Would be a separate competing PR.

I think some people might try using the preSubcommand hook to do some lazy setup, and that might affect the help too.

@aweebit
Copy link
Contributor Author

aweebit commented Aug 13, 2023

I haven't put a lot of thought into this yet, but my first reaction is I am more interested in making it consistent by calling the hook in both cases.

I don't really like this idea for two reasons:

  • There is no Command instance that would be reasonable to pass to the preSubcommand hooks in the second parameter since the help command only exists virtually.

  • There would be a discrepancy between this and how the preAction hooks are not called when the help option is invoked (and that is a valid comparison because the help option would have to be implemented in the action handler just like the help command would have to be implemented in a subcommand if the convenience shortcuts were not offered by the library).

    try {
      const program = new Command()
        .exitOverride()
        .hook('preAction', () => console.log('preAction'))
        .action(() => {});
      program.parse(['--help'], { from: 'user' }); // 'preAction' not logged
    } catch {}
    
    try {
      const program = new Command()
        .exitOverride()
        .addHelpCommand('help')
        .hook('preSubcommand', () => console.log('preSubcommand'));
      program.parse(['help'], { from: 'user' }); // 'preSubcommand' would be logged
    } catch {}

Copy link
Collaborator

@shadowspawn shadowspawn left a comment

Choose a reason for hiding this comment

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

This has got 5 extra commits, some of which have landed.

Unless you are keen on cherry pick and rebase, I suggest perhaps redo the small relevant commit on the release 12.x branch (I have merged develop into release 12.x today).

77828ba

@shadowspawn
Copy link
Collaborator

I was thinking about this again today, and leaning towards triggering the hook again!

#1956 (comment)

@shadowspawn
Copy link
Collaborator

Interesting comparison with a "real" help command. I had not considered that model.

I think of the built-in prog help foo as equivalent to prog foo --help. I'm leaning towards calling preSubcommand, as it did before #1864.

(This is pretty obscure behaviour, no one may ever notice!)

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