Last active
September 23, 2022 00:32
-
-
Save bakkot/d14826a356fa7ac7e5d9385c2c794432 to your computer and use it in GitHub Desktop.
how to implement subcommands with node's parseArgs argument parser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
let { parseArgs } = require('util'); | |
let mainOptions = { help: { type: 'boolean', short: 'h' } }; | |
let subCommands = { | |
__proto__: null, | |
foo: fooCommand, | |
bar: barCommand, | |
}; | |
// boilerplate for handling subcommands | |
let args = process.argv.slice(2); // would be easier with process.mainArgs... | |
let { tokens } = parseArgs({ options: mainOptions, args, strict: false, tokens: true }); | |
let cmdIndex = tokens.find(e => e.kind === 'positional')?.index ?? args.length; | |
let command = args[cmdIndex]; | |
let tail = args.slice(cmdIndex + 1); | |
// handle options intended for the main script, rather than for a subcommand | |
let { values } = parseArgs({ options: mainOptions, args: args.slice(0, cmdIndex) }); | |
if (values.help || command == null) { | |
console.log(`usage: | |
node parseargs-subcommands.js --help | |
node parseargs-subcommands.js foo | |
node parseargs-subcommands.js foo --foo-arg | |
node parseargs-subcommands.js bar positional positional2 | |
`); | |
process.exit(0); | |
} | |
// run subcommands | |
if (!subCommands[command]) { | |
throw new Error(`unknown command ${command}`) | |
} | |
subCommands[command](tail); | |
// subcommand implementations | |
// they can re-run the parser with whatever options they want | |
function fooCommand(args) { | |
let options = { 'foo-arg': { type: 'boolean' } }; | |
let { values } = parseArgs({ options, args }); | |
console.log(`foo subcommand, with foo-arg: ${!!values['foo-arg']}`); | |
} | |
function barCommand(args) { | |
let { positionals } = parseArgs({ options: {}, args, allowPositionals: true }); | |
console.log('bar subcommand'); | |
console.log(`bar subcommand, with positionals: ${positionals.join(', ')}`); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment