NodeJS commander.js的未命名参数(位置参数)

8yparm6h  于 2022-12-12  发布在  Node.js
关注(0)|答案(3)|浏览(146)

我目前正在研究commander.js,因为我希望使用Node.js实现CLI。
使用命名参数很容易,如“pizza”程序的示例所示:

program
  .version('0.0.1')
  .option('-p, --peppers', 'Add peppers')
  .option('-P, --pineapple', 'Add pineapple')
  .option('-b, --bbq', 'Add bbq sauce')
  .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')
  .parse(process.argv);

现在,例如,我可以使用以下语句调用程序:

$ app -p -b

但是对于未命名的参数呢?如果我想使用

$ app italian -p -b

?我认为这种情况并不罕见,因此为cp命令提供文件并不要求您也使用命名参数。

$ cp source target

而不是:

$ cp -s source -t target

如何使用commander.js实现这一点?
还有,我如何告诉commander.js需要未命名的参数?例如,如果你看一下cp命令,source和target是必需的。

2izufjch

2izufjch1#

在当前版本的commander中,可以使用位置参数。有关参数语法的详细信息,请参阅文档,但使用您的cp示例,它将类似于:

program
.version('0.0.1')
.arguments('<source> <target>')
.action(function(source, target) {
    // do something with source and target
})
.parse(process.argv);

如果两个参数都不存在,这个程序将发出警告,并给予相应的警告消息。

r6vfmomb

r6vfmomb2#

通过program.args获取所有未命名参数。

console.log(' args: %j', program.args);

当您使用-p -b -c gouda arg1 arg2运行应用程序时,您将获得

you ordered a pizza with:
- peppers
- bbq
- gouda cheese
args: ["arg1","arg2"]

然后你可以这样写

copy args[0] to args[1] // just to give an idea
qgzx9mmu

qgzx9mmu3#

program.argument('<myarg>') + program.namedArgs(从9.4.1版开始)用于位置参数

从commander 9.4.1开始测试,位置参数的最佳选择似乎是.argument函数。
该方法实现了您期望从一个像样的库中获得的基本特性:

  • 如果未传递强制参数,则会给出错误
  • 允许您设置默认值并执行自定义解析/检查,例如整数转换
  • 如果program.allowExcessArguments(false)的位置太多,则给予错误(可惜不是默认值)

我们使用program.namedArgs是因为program.args忽略了myParseInt或默认值。
TODO内置方式

  • 按名称而不是按索引(program.processedArgs[0])访问位置参数(例如program.processedArgs.arg1

样品使用:
positional.js

function myParseInt(value, dummyPrevious) {
  const parsedValue = parseInt(value, 10);
  if (isNaN(parsedValue)) {
    throw new commander.InvalidArgumentError('Not a number.');
  }
  return parsedValue;
}

const commander = require('commander');
const program = commander.program
program.option('-m --myopt <myopt>', 'doc for myopt', 'myopt-default');
program.argument('<arg1>', 'doc for arg1');
program.argument('<arg2>', 'doc for arg2');
program.argument('[arg3]', 'doc for arg3', myParseInt, 1);
program.allowExcessArguments(false);
program.parse(process.argv);
console.error(program.processedArgs.length);
console.error(program.args);
const [arg1, arg2, arg3] = program.processedArgs
const opts = program.opts()
console.error(`arg1: ${arg1} (${typeof arg1})`);
console.error(`arg2: ${arg2} (${typeof arg2})`);
console.error(`arg3: ${arg3} (${typeof arg3})`);
console.error(`myopt: ${opts.myopt} (${typeof opts.myopt})`);

示例调用:

$ ./positional.js 
error: missing required argument 'arg1'
$ ./positional.js a
error: missing required argument 'arg2'
$ ./positional.js a b
arg1: a (string)
arg2: b (string)
arg3: 1 (number)
myopt: myopt-default (string)
$ ./positional.js a b c
error: command-argument value 'c' is invalid for argument 'arg3'. Not a number.
$ ./positional.js a b 2
arg1: a (string)
arg2: b (string)
arg3: 2 (number)
myopt: myopt-default (string)
$ ./positional.js a b 2 c
error: too many arguments. Expected 3 arguments but got 4.
$ ./positional.js -m c a b 2
arg1: a (string)
arg2: b (string)
arg3: 2 (number)
myopt: c (string)
$ ./positional.js a b 2 -m c
arg1: a (string)
arg2: b (string)
arg3: 2 (number)
myopt: c (string)
$ ./positional.js -h
Usage: positional [options] <arg1> <arg2> [arg3]

Arguments:
  arg1                doc for arg1
  arg2                doc for arg2
  arg3                doc for arg3 (default: 1)

Options:
  -m --myopt <myopt>  doc for myopt (default: "myopt-default")
  -h, --help          display help for command

丑陋的原因:

program.action((..._args) => { args = _args })

而不是仅仅

program.args

program.args有错误,既不使用myParseInt(返回字符串),也不使用1的默认值(只是忽略参数)。

相关问题