Closed grallm closed 1 year ago
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 thevisibleArguments
method [...] The problem, I do not have any description for my argument and the implementation ofvisibleArguments
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?)
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 !
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
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
?
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()
?
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.
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.
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 │ │
└──────────────────────────────────┴───────────────────────────────────────────────────┴───────┘
I had another think about a public accessor, and came up with .declaredArguments
or .getArguments()
.
Adding .registeredArguments
in #2010 (as suggested in #1970)
Shipped in Commander v11.1.0
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:Screenshot of the Argument object
To not use a private property, I try to access this argument with the
Help
class and thevisibleArguments
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! 😁