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

List all command's arguments using Helper #1823

Closed
grallm opened this issue Nov 23, 2022 · 11 comments
Closed

List all command's arguments using Helper #1823

grallm opened this issue Nov 23, 2022 · 11 comments

Comments

@grallm
Copy link

grallm commented Nov 23, 2022

I want to list all the arguments (or sub-commands, not sure of the difference) of my command.

If I look the property _args, I can confirm my command has an argument:

[
  {
    "description": "",
    "variadic": false,
    "required": false,
    "_name": "commands"
  }
]
Screenshot of the Argument object image

To not use a private property, I try to access this argument with the Help class and the visibleArguments method (see the code)

The problem, I do not have any description for my argument and the implementation of visibleArguments requires one.

Is this a problem? If not, can someone explain it to me? Is there any other clean way?

Thank you! 😁

@shadowspawn
Copy link
Collaborator

I want to list all the arguments (or sub-commands, not sure of the difference) of my command.

When you type something on the command line like

git clone my-repo

clone is a subcommand, and my-repo is a command-argument.

To not use a private property, I try to access this argument with the Help class and the visibleArguments method [...]
The problem, I do not have any description for my argument and the implementation of visibleArguments requires one.

Using visibleArguments to get the argument objects is an intended as a way to access the arguments, but as you discovered the "visible" part is that they are only returned if at least one of them has a description so that they appear in the help.

There are not any other methods to return the arguments from the private property _args.

As a work-around, could you add a description to your arguments so visibleArguments returns them? (What are you listing them for?)

@grallm
Copy link
Author

grallm commented Nov 24, 2022

Thank you for your answer @shadowspawn 😄

clone is a subcommand, and my-repo is a command-argument.

The example is clear, but in the documentation of Commander I am just lost when speaking of sub-commands in the part of arguments while you can declare them with .command 😅

Is there an explanation of why a Visible Argument is one only with a description? I may have missed something in your explanation, but still, the argument is displayed in the usage part of the help 🤔

To describe my situation, I am using NestJS Console, based on top of Commander, and it seems I can't add argument description (it uses .arguments to define the arguments) 😊
For the listing part, I am trying to generate dynamic configuration files.

Thanks again for the answer !

@shadowspawn
Copy link
Collaborator

Is there an explanation of why a Visible Argument is one only with a description? I may have missed something in your explanation, but still, the argument is displayed in the usage part of the help 🤔

It comes from an existing behaviour that the arguments are only described in detail if there are some descriptions. I like the symmetry with visibleOptions and visibleCommands, but have to admit it does not make as much sense for arguments!

const { Command } = require('commander');
const program = new Command();
program.name('git');
program.command('clone')
  .argument('repo')
  .action((repo) => console.log(`Target repo is ${repo}`));
program.parse();
% node index.js clone --help
Usage: git clone [options] <repo>

Options:
  -h, --help  display help for command

But with .argument('repo', 'target repository') get

% node index.js clone --help
Usage: git clone [options] <repo>

Arguments:
  repo        target repository

Options:
  -h, --help  display help for command

@shadowspawn
Copy link
Collaborator

shadowspawn commented Nov 25, 2022

For the listing part, I am trying to generate dynamic configuration files.

With the current code, I think you may need to iterate through cmd._args to access the configured arguments.

If the _args property was renamed to be public, what should it be called? The other similar properties are options and commands, but arguments is already a method name. Maybe commandArguments?

@grallm
Copy link
Author

grallm commented Nov 25, 2022

Thanks again for your answers!

I see there is a method opts() to get the list of options as a Map, maybe a method args() ?

@shadowspawn
Copy link
Collaborator

There are already properties and methods on Command for:

  • args
  • processedArgs
  • rawArgs
  • argument()
  • arguments()

We can't use the same pattern as option()/options and command()/commands since arguments is not available.

@shadowspawn
Copy link
Collaborator

There is a shortcoming that there is not a public way to get the full array of Argument objects. I'll leave this issue open to see if this gets upvotes, and/or a nice suggestion for a property name.

@cenfun
Copy link

cenfun commented Mar 5, 2023

Although it is a private property, but believe it is pretty stable. just write a small tool to show all commands and options:

const { program } = require('commander');
const commanderHelp = require('commander-help');

program
    .name('cli-name')
    .description('CLI to some JavaScript string utilities')
    .argument('<username>', 'user to login')
    .argument('[password...]', 'password for user, if required', 'empty')
    .option('-t, --title <honorific>', 'title to use before name')
    .option('-d, --debug', 'display some debugging')
    .version('0.8.0', '-v, --version');

program.command('split')
    .description('Split a string into substrings')
    .argument('<string>', 'string to split')
    .alias('s')
    .option('--first', 'display just the first substring', '#')
    .option('-s, --separator <char>', 'separator character', ',')
    .action(() => {});

program
    .command('clone <source> [dest]')
    .description('clone a repository into a newly created directory')
    .alias('c')
    .action((source, destination) => {
        console.log('clone command called');
    });

program
    .command('start <service>', 'start named service')
    .command('stop [service...]', 'stop named service, or all if no name supplied');

// hide default help
program.helpInformation = function() {
    return '';
};
// custom help
program.on('--help', function() {
    console.log('Usage and help');
    commanderHelp(program);
});

program.parse();

Usage and help
┌──────────────────────────────────┬───────────────────────────────────────────────────┬───────┐
 Commands/Options                  Description                                        Alias 
├──────────────────────────────────┼───────────────────────────────────────────────────┼───────┤
  cli-name                        CLI to some JavaScript string utilities                  
    -t, --title <honorific>      title to use before name                                 
    -d, --debug                  display some debugging                                   
    -v, --version                output the version number                                
    -h, --help                   display help for command                                 
  cli-name <username>             user to login                                            
  cli-name [password...]          password for user, if required (default: empty)          
├──────────────────────────────────┼───────────────────────────────────────────────────┼───────┤
  cli-name split <string>         Split a string into substrings                     s     
    --first                      display just the first substring (default: #)            
    -s, --separator <char>       separator character (default: ,)                         
├──────────────────────────────────┼───────────────────────────────────────────────────┼───────┤
  cli-name clone <source> [dest]  clone a repository into a newly created directory  c     
├──────────────────────────────────┼───────────────────────────────────────────────────┼───────┤
  cli-name start <service>        start named service                                      
├──────────────────────────────────┼───────────────────────────────────────────────────┼───────┤
  cli-name stop [service...]      stop named service, or all if no name supplied           
└──────────────────────────────────┴───────────────────────────────────────────────────┴───────┘

https://github.com/cenfun/commander-help

@shadowspawn
Copy link
Collaborator

shadowspawn commented Apr 6, 2023

I had another think about a public accessor, and came up with .declaredArguments or .getArguments().

@shadowspawn
Copy link
Collaborator

Adding .registeredArguments in #2010 (as suggested in #1970)

@shadowspawn shadowspawn added the pending release Merged into a branch for a future release, but not released yet label Sep 12, 2023
@shadowspawn
Copy link
Collaborator

Shipped in Commander v11.1.0

@shadowspawn shadowspawn removed the pending release Merged into a branch for a future release, but not released yet label Oct 13, 2023
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