├── logos
├── logo-box-builtby.png
└── logo-box-madefor.png
├── .gitignore
├── package.json
├── boring.js
├── CHANGELOG.md
├── test
└── test.js
└── README.md
/logos/logo-box-builtby.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apostrophecms/boring/main/logos/logo-box-builtby.png
--------------------------------------------------------------------------------
/logos/logo-box-madefor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apostrophecms/boring/main/logos/logo-box-madefor.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | package-lock.json
2 | npm-debug.log
3 | *.DS_Store
4 | node_modules
5 | # We do not commit CSS, only LESS
6 | public/css/*.css
7 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "boring",
3 | "version": "1.1.1",
4 | "description": "A minimalist command line option parser.",
5 | "main": "boring.js",
6 | "scripts": {
7 | "test": "mocha test/test.js"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "https://github.com/apostrophecms/boring"
12 | },
13 | "keywords": [
14 | "minimalist",
15 | "command",
16 | "line",
17 | "options",
18 | "argv",
19 | "boring"
20 | ],
21 | "author": "Apostrophe Technologies, Inc.",
22 | "license": "MIT",
23 | "bugs": {
24 | "url": "https://github.com/apostrophecms/boring/issues"
25 | },
26 | "homepage": "https://github.com/apostrophecms/boring",
27 | "devDependencies": {
28 | "mocha": "^6.2.0"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/boring.js:
--------------------------------------------------------------------------------
1 | module.exports = function(options) {
2 | options = options || {};
3 | const args = process.argv.slice(2);
4 | const result = {
5 | _: []
6 | };
7 | let optionsEnded = false;
8 | for (let i = 0; (i < args.length); i++) {
9 | if (options.end && (args[i] === '--')) {
10 | optionsEnded = true;
11 | continue;
12 | }
13 | if (!optionsEnded) {
14 | let matches = args[i].match(/^--([^\s\=]+)=(.*)$/);
15 | if (matches) {
16 | result[matches[1]] = matches[2];
17 | continue;
18 | }
19 | matches = args[i].match(/^--(\S+)$/);
20 | if (matches) {
21 | result[matches[1]] = true;
22 | continue;
23 | }
24 | }
25 | result._.push(args[i]);
26 | }
27 | return result;
28 | };
29 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## 1.1.1
4 |
5 | * Edits project metadata and README.
6 |
7 | ## 1.1.0
8 |
9 | Added the `end` option, which can be used to indicate that no more named options should be parsed after `--` is encountered, and all remaining arguments should be captured in `argv._`, even if they begin with `--`. The `--` itself is not captured.
10 |
11 | ## 1.0.0
12 |
13 | Official stable release, four years after the "0.1.0" release, which was... well... boring and stable in its own right.
14 |
15 | However, we did fix two things:
16 |
17 | * `const` and `let` used in place of `var`; this is 2019.
18 | * `--uri=mongodb://something?foo=bar` now behaves sensibly, coming through as `argv.uri`. Formerly it was confused by the extra `=` in the query string of the uri.
19 |
20 | We hope you find this as boring as we do.
21 |
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | const assert = require('assert');
2 |
3 | describe('boring', function() {
4 | it('has the expected behavior with no arguments', function() {
5 | process.argv = [ 'ignore', 'ignore' ];
6 | const argv = require('../boring.js')();
7 | assert(argv);
8 | assert(argv._);
9 | assert(Array.isArray(argv._));
10 | assert(argv._.length === 0);
11 | for (const key in argv) {
12 | if (key !== '_') {
13 | assert(false);
14 | }
15 | }
16 | });
17 | it('has the expected behavior with double-hyphen arguments', function() {
18 | process.argv = [ 'ignore', 'ignore', '--foo', '--bar=whee', '--uri=mongodb://foo@baz/wozzle?something=something' ];
19 | const argv = require('../boring.js')();
20 | assert(argv);
21 | assert(argv._);
22 | assert(Array.isArray(argv._));
23 | assert(argv._.length === 0);
24 | assert(argv.foo === true);
25 | assert(argv.bar === 'whee');
26 | assert(argv.uri === 'mongodb://foo@baz/wozzle?something=something');
27 | const valid = {
28 | foo: 1,
29 | bar: 1,
30 | _: 1,
31 | uri: 1
32 | };
33 | for (const key in argv) {
34 | if (!valid[key]) {
35 | assert(false);
36 | }
37 | }
38 | });
39 | it('has the expected behavior with positional arguments in addition', function() {
40 | process.argv = [ 'ignore', 'ignore', 'jump', 'sideways', '--foo', '--bar=whee', '--super-cool=totally' ];
41 | const argv = require('../boring.js')();
42 | assert(argv);
43 | assert(argv._);
44 | assert(Array.isArray(argv._));
45 | assert(argv._.length === 2);
46 | assert(argv._[0] === 'jump');
47 | assert(argv._[1] === 'sideways');
48 | assert(argv.foo === true);
49 | assert(argv.bar === 'whee');
50 | assert(argv["super-cool"] === 'totally');
51 | const valid = {
52 | foo: 1,
53 | bar: 1,
54 | _: 1,
55 | "super-cool": 1
56 | };
57 | for (const key in argv) {
58 | if (!valid[key]) {
59 | assert(false);
60 | }
61 | }
62 | });
63 | it('treats arguments after an end marker as positional, even if they start with --', function() {
64 | process.argv = [ 'ignore', 'ignore', 'hello', '--pretty', '--', '--boring' ];
65 | const argv = require('../boring.js')({ end: true });
66 | assert(argv.pretty === true);
67 | assert(argv._.length === 2);
68 | assert(argv._[0] === 'hello');
69 | assert(argv._[1] === '--boring');
70 | });
71 | it('does not respect end markers if the end option is not used', function() {
72 | process.argv = [ 'ignore', 'ignore', 'hello', '--pretty', '--', '--boring' ];
73 | const argv = require('../boring.js')();
74 | assert(argv.boring === true);
75 | assert(argv.pretty === true);
76 | assert(argv._.length === 2);
77 | assert(argv._[0] === 'hello');
78 | assert(argv._[1] === '--');
79 | });
80 | });
81 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Boring
2 |
3 |
4 |
5 | A command line argument parser without pirates
6 |
7 | ## What you get with Boring
8 |
9 | Input:
10 |
11 | ```
12 | node app jump sideways --foo --bar=whee --super-cool=totally
13 | ```
14 |
15 | Response:
16 |
17 | ```javascript
18 | {
19 | _: [ "jump", "sideways"],
20 | foo: true,
21 | bar: "whee",
22 | "super-cool": "totally"
23 | }
24 | ```
25 |
26 | Notice that parameters without `--`, if any, go into the `_` array. Parameters with `--` become properties in their own right.
27 |
28 | ## How you get it
29 |
30 | ```javascript
31 | const argv = require('boring')({});
32 | ```
33 |
34 | The options object is optional.
35 |
36 | ## Options
37 |
38 | ### Passthrough
39 |
40 | It is a common convention to never treat any arguments that appear after a `--` placeholder (by itself) as named options, even if they start with `--`.
41 |
42 | Instead, the remainder are treated as positional arguments, no matter what.
43 |
44 | To get this behavior with Boring, pass the `end: true` option:
45 |
46 | ```javascript
47 | const argv = require('boring')({
48 | end: true
49 | });
50 | console.log(argv);
51 | ```
52 |
53 | Now, when you run this command:
54 |
55 | ```bash
56 | node app hello --pretty -- --boring
57 | ```
58 |
59 | You will get:
60 |
61 | ```javascript
62 | {
63 | _: [ 'hello', '--boring' ],
64 | pretty: true
65 | }
66 | ```
67 |
68 | ## What you don't get with boring
69 |
70 | ### Single hyphens: nope
71 |
72 | There is no support for old-fashioned "single-hyphen" options, like:
73 |
74 | ```
75 | -x 50
76 | ```
77 |
78 | Or:
79 |
80 | ```
81 | -h
82 | ```
83 |
84 | You can't tell which are boolean and which take arguments unless a specification is passed in. And that's not boring enough for us.
85 |
86 | ### Usage messages, strictness, etc.: nope
87 |
88 | These are very simple to implement, and if you're like us, you'd rather do it yourself.
89 |
90 | ## Philosophy
91 |
92 | We have nothing against full-featured, pirate-themed option parsers, which are very nice if you're into that sort of thing. We just find ourselves walking the plank when our options don't follow the pattern of what's easy to validate with piracy.
93 |
94 | This simple module is too dumb to break.
95 |
96 | ## About ApostropheCMS
97 |
98 | Boring was created for use in ApostropheCMS, an open-source content management system built on node.js. If you like Boring you should definitely [check out apostrophecms.org](http://apostrophecms.org).
99 |
100 | ## Support
101 |
102 | Feel free to open issues on [github](http://github.com/apostrophecms/boring).
103 |
104 |
105 |
--------------------------------------------------------------------------------