ArgMate
Your go-to companion for lightning-fast CLI parameter parsing, enhanced with convenient features to make your development experience much smoother.
While developing tools like AlaSQL and RexReplace, I've often been torn between two types of CLI parsers. On one hand, there are feature-rich options like yargs and commander. Despite their heavy startup time, these parsers provide useful features like easy defaults, smooth validation, and well-structured CLI help text output. On the other hand, simpler alternatives like nopt and mri excel in performance but lack in development experience. After uncovering yet another performance hit from using a heavyweight parser, I decided to solve this issue once and for all.
Benchmark:
argMate 9,089,813 ops/sec ±2.15% (98 runs sampled) 1x
nopt 2,070,397 ops/sec ±1.21% (94 runs sampled) 4x
mri 1,832,768 ops/sec ±0.13% (99 runs sampled) 5x
minimist 706,265 ops/sec ±1.05% (94 runs sampled) 13x
yargs-parser 67,417 ops/sec ±0.39% (97 runs sampled) 135x
Meet ArgMate, a CLI parameter parser that's not just fast - it's 4-5 times faster than other parsers focused on speed, while still being feature-rich. But how?!? A computer processes instructions at a set pace. To get results faster, the only option is to do fewer things. By minimising how many times variables are touched and keeping those operations close together, the implementation enables efficient caching of data, resulting in fewer CPU cycles to get stuff done.
Installation
yarn add argmate
npm install argmate
Usage
argMate(arguments, [parameterDetails [, config ]]);
Examples
Getting started
ArgMate follows traditional CLI notations similar to yargs and mri. Here are some simple examples:
import ArgMate from 'ArgMate';
let argv;
argv = ArgMate(['--foo', 'bar']);
argv = ArgMate(['--foo=', 'bar']);
argv = ArgMate(['-i=123']);
argv = ArgMate(['--foo', 'bar2'], { foo: 'bar' });
argv = ArgMate(['--foo', 'bar'], { foo: { type: 'string' } });
argv = ArgMate(process.argv.slice(2));
Enforcing parameter types and limiting allowed values
You can provide default values and enforce that no other parameters are allowed:
import ArgMate from 'ArgMate';
const args = process.argv.slice(2);
const params = {
foo: 10,
bar: false
};
const config = {
allowUnknown: false
};
const argv = ArgMate(args, params, config);
Same example but a bit shorter
import ArgMate from 'ArgMate';
const argv = ArgMate(process.argv.slice(2),
{
foo: 10,
bar: false
}, {
allowUnknown: false
});
Real world example
Here's a more comprehensive example demonstrating additional features:
import ArgMate, { argInfo } from 'ArgMate';
const args = process.argv.slice(2);
const params = {
start: {
default: 0,
alias: ['s']
},
steps: {
type: 'number',
mandatory: true,
alias: ['l', 'loops'],
valid: v => v > 0
},
help: {
alias: ['h']
}
};
const config = {
allowUnknown: false,
error: msg => {
console.error('Error:', msg);
process.exit(1);
}
};
const argv = ArgMate(args, params, config);
if (argv.help) {
console.log(argInfo());
process.exit(0);
}
for (let i = argv.start; i < argv.start + argv.steps; i++) {
console.log(i);
}
Configuration
Params
const params = {
foo: {
type: 'string',
default: 'val',
mandatory: true,
alias: [],
conflict: [],
valid: () => {},
describe: 'Description here',
},
};
Config
const config = {
error: msg => {},
panic: msg => {},
allowUnknown: true,
no: true,
intro: 'Intro Text',
outro: 'Outro Text',
};
Help Text
You can call argInfo()
after invoking argMate()
to get a CLI-friendly description.
import argMate, {argInfo} from 'argmate';
const argv = argMate(
process.argv.slice(2),
{
foo: {type: 'string'},
foo2: {type: 'string'},
},
{
intro: 'Introduction here',
outro: 'See you later!',
}
);
console.log(
argInfo({
width: 100,
format: 'cli',
voidIntro: false,
voidOutro: false,
})
);
Notes
- If you provide array kind of types (like string[]) you can trust the value is alwas an array. If no values provided the array is emptly.
- If you provide the same alias to two parameters, the alias will stay with the first parameter you define.
Please note that argMate is an OPEN open source software project.
This means that individuals making significant and valuable contributions are given commit access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project.
License