npm / nopt Goto Github PK
View Code? Open in Web Editor NEWNode/npm Option Parsing
License: ISC License
Node/npm Option Parsing
License: ISC License
I'm wondering what is the expected way to handle arguments or options that are not supplied.
To give one example, I have an option which should be true by default:
const knownOpts = {headers: [Boolean]};
And this would be commonly used in the cmd line as --no-headers
. In the current scheme I will either have:
parsed.headers = undefined // falsy, but want it to be true
or
parsed.headers = false // definitely falsy
At the moment it feels like nopt creates an incomplete model of my options and I then have to pass to another function to normalise all incomplete values. Perhaps this is either a feature request or out of scope.
See this gist:
Many CLI tools use -
to represent stdin, cat
probably being the most well known. Pull request coming shortly.
I have the following case:
long args are
--account / -a
--credentials / -c
--options / -o
now If I pass "--acount bla" (typod) it does not report a unknown key but interprets it as:
"--account --credentials --options bla" which is entirely wrong
{ file:[ require("path") ] }
and
app --file asdf1 --file asdf2
results in
{ file:"/path/to/asdf2" }
I only get an array if I do
{ file:Array }
Boolean options should not swallow the following argument if it is false
or true
. This can occur coincidentally and is probably not what the user wants.
Consider a CLI tool that outputs the size of files, where each file is passed as a positional argument. The -h
or --human
flag causes it to output human-friendly values. ("1KB" instead of "1024")
$ file-sizes -h *
file-1 1MB
file-2 2.3MB
Now imagine that the files in CWD are "false", "foo", and "bar"
$ file-sizes -h *
foo 1035
bar 345
# Errors: -h flag isn't set; "false" is omitted
For this reason, boolean options should never interpret the following argument as their value.
# following positional argument should *never* be interpreted as a value for the `--human` flag
file-sizes --human true
Users can still pass --human
, --no-human
, --human=true
, or --human=false
to explicitly set the flag to true or false.
I'm still gathering details, but figured I'd go ahead and report it.
16:38:00 /usr/local/jenkins/workspace/ultra-learn-ultra-ui_develop-ui-test/node_modules/grunt-sass/node_modules/node-sass/node_modules/npmconf/node_modules/nopt/lib/nopt.js:210
16:38:00 if (t && ((type.name && t.type.name) ?
16:38:00 ^
16:38:00 TypeError: Cannot read property 'name' of null
16:38:00 at validate (/usr/local/jenkins/workspace/ultra-learn-ultra-ui_develop-ui-test/node_modules/grunt-sass/node_modules/node-sass/node_modules/npmconf/node_modules/nopt/lib/nopt.js:210:20)
16:38:00 at validate (/usr/local/jenkins/workspace/ultra-learn-ultra-ui_develop-ui-test/node_modules/grunt-sass/node_modules/node-sass/node_modules/npmconf/node_modules/nopt/lib/nopt.js:179:11)
16:38:00 at /usr/local/jenkins/workspace/ultra-learn-ultra-ui_develop-ui-test/node_modules/grunt-sass/node_modules/node-sass/node_modules/npmconf/node_modules/nopt/lib/nopt.js:101:12
16:38:00 at Array.map (native)
16:38:00 at /usr/local/jenkins/workspace/ultra-learn-ultra-ui_develop-ui-test/node_modules/grunt-sass/node_modules/node-sass/node_modules/npmconf/node_modules/nopt/lib/nopt.js:67:15
16:38:00 at Array.forEach (native)
16:38:00 at Function.clean (/usr/local/jenkins/workspace/ultra-learn-ultra-ui_develop-ui-test/node_modules/grunt-sass/node_modules/node-sass/node_modules/npmconf/node_modules/nopt/lib/nopt.js:55:21)
16:38:00 at /usr/local/jenkins/workspace/ultra-learn-ultra-ui_develop-ui-test/node_modules/grunt-sass/node_modules/node-sass/node_modules/npmconf/npmconf.js:411:10
16:38:00 at Array.forEach (native)
16:38:00 at validate (/usr/local/jenkins/workspace/ultra-learn-ultra-ui_develop-ui-test/node_modules/grunt-sass/node_modules/node-sass/node_modules/npmconf/npmconf.js:410:11)
If you use a set of short options as a single shell word, nopt will first try to find a long option name that completes the word instead of checking your short options match:
var nopt = require('nopt')
var options = { clear: Boolean,
config: Boolean,
length: Number
}
var shorts = { c: 'config', l: 'length' }
nopt(options, shorts, ['node', 'bin/foo', '-cl', '6'])
// -> { clear: true }
I was expecting this to return { config: true, length: 6 }
.
It's a good job I made my --clear
command prompt for confirmation, or I'd have lost a bunch of data ;)
I have the following case:
long args are
--account / -a
--credentials / -c
--options / -o
now If I pass "--acount bla" (typod) it does not report a unknown key but interprets it as:
"--account --credentials --options bla" which is entirely wrong
#31 Fixed the default type value of String
to be "" instead of "true". It seems that a single item array should be interpreted the same as a type that is not an array.
I was using the following code and I could have swore that it was working, but it does not seem to be working today. args["no-restart"]
and args["init-default"]
are always undefined even when they exist in process.argv
as '--init-default'
and '--no-restart'
.
Is this supported and if not, is there any reason that it should not be?
exports.known = {
help: Boolean,
"init-default": Boolean,
"no-restart": Boolean,
verbose: Boolean,
version: Boolean,
path: path
};
exports.aliases = {
h: '--help',
v: '--version',
V: '--verbose'
};
var args = nopt(exports.known, exports.aliases, process.argv, 2);
var remain = args.argv.remain;
if (remain && remain.length > 0) {
args.path = remain[0];
}
args.initDefault = args["init-default"];
args.noRestart = args["no-restart"];
// ...
So instead of doing something like this:
colorize --color blue --color red --color yellow
I would be able to do something like this:
colorize --color blue red yellow
and get the following object as the option: { colorize: ['blue', 'red', 'yellow'] }
Currently (v3.0.1), nopt invariably accepts unknown options and simply adds them to the object returned.
However, a typical use case for a CLI is to abort processing in case an unknown option is specified.
Thus, an .unknownHandler
property specifying a function to call on encountering an unknown option would be handy - analogous to the existing .invalidHandler
property for handling invalid option values.
I'd be happy to implement this.
Hello!
I have knownOptions set to: { config: String }
.
Then I run my program like this: ./test --config
I have in output { config: 'true', argv: { ... } }
that seems a bit strange, because I expected config
field set to empty string.
Is it a bug or maybe such behaviour is by design?
I actually wanted to have a flag called "no-restart", but instead nopt makes me name it "restart".
Is there an option to disable auto-negation?
If not, is there any objection to adding one?
I've been rickrolled by a node module.
I know this is going to be a little bit subjective, but perhaps you can help.
It's hard to pass a version number to nopt like -r=1.10
because it will treat that value as the number 1.1
and not the string "1.10"
. This can be worked around by prefixing it like -r=v1.10
but it's inconvenient to have to strip out the leading v
in that case if you don't need it.
Would it be possible for nopt to check to see if the value, once converted to a number and then back to a string matches the original string, Eg.
function getNumberOrString(str) {
var num = Number(str);
// Only return number if a) it's a valid number, and b) when coerced
// back to a string, that string is the same as the original string.
return !isNaN(num) && String(num) === str ? num : str;
}
getNumberOrString("1.23") // 1.23
getNumberOrString("1.10") // "1.10"
getNumberOrString("01234") // "01234"
What nopt currently does is something more like this:
function getNumberOrString(str) {
var num = Number(str);
// Only return number if it's a valid number.
return !isNaN(num) ? num : str;
}
getNumberOrString("1.23") // 1.23
getNumberOrString("1.10") // 1.1
getNumberOrString("01234") // 1234
Here's an example of this "bug" in action:
$ npm install nopt@latest
npm WARN package.json [email protected] No README.md file found!
npm http GET https://registry.npmjs.org/nopt
npm http 304 https://registry.npmjs.org/nopt
npm http GET https://registry.npmjs.org/abbrev
npm http 304 https://registry.npmjs.org/abbrev
[email protected] node_modules/nopt
└── [email protected]
$ node -pe "require('nopt')({}, {}, ['-a=1.23', '-b=1.10', '-c=01234'], 0)"
{ a: 1.23,
b: 1.1,
c: 1234,
argv:
{ remain: [],
cooked: [ '-a', '1.23', '-b', '1.10', '-c', '01234' ],
original: [ '-a=1.23', '-b=1.10', '-c=01234' ] } }
node-gyp uses any "unknown" flags as custom defines for gyp to use while building a native add-on (i.e. --with-jpeg
turns into a 'with_jpeg="true"' variable in gyp).
But if there's two unknown flags in a row, nopt treats the second flag like the value to the first one, rather then treating them as two separate flags.
$ node-gyp install canvas --with-jpeg --with-gif
Produces a gypi file containing:
...
"with_jpeg": "--with-gif"
...
Which is undesirable :(
I'm trying to allow the use of glob patterns but I'm having trouble getting it to work.
var options = require('nopt')({
file: String,
}, {
'f': '--file',
}, process.argv, 2);
index.js --file www/*.js
options.file
returns the first file in the directory as a string even if there are multiple files. And since it's returning a file and not the original string I can't manually glob the pattern. I've tried file: [require('path')]
but that just resolved first path it finds.
Is there a way to turn off the path coercion or have nopt correctly recognize glob patterns and return an array of paths?
If nothing is passed, I would think that it should either not be accepted or default to the cwd.
Here is an example
var nopt = require('nopt')
, path = require('path')
, knownOpts = { path: path
}
, shortHands = { p: ['--path']
}
, parsed = nopt(knownOpts, shortHands, process.argv, 2)
console.log(parsed)
If run like:
$ ./test --path
The output would be:
{ path: '/Users/evan/dev/code/node/tests/nopt_test/true',
argv: { remain: [], cooked: [ '--path' ], original: [ '-p' ] } }
Please clarify that you intent on making this code available under the MIT Open Source license. I assume that you are, but I'd rather not assume, and see the license explicitly . Thanks! Gil
Please consider this minimal example:
node << _EOT_
var nopt = require("nopt")
, parsed = nopt( {}, {}, [ 123 ], 0 )
;
_EOT_
Output:
... /node_modules/nopt/lib/nopt.js:239
if (arg.match(/^-{2,}$/)) {
^
TypeError: Object 123 has no method 'match'
at parse ( ... /node_modules/nopt/lib/nopt.js:239:13)
at nopt ( ... /node_modules/nopt/lib/nopt.js:40:3)
Contrived as this may seem, in the wild I found that yeoman-generator
actually does this.
I'm wondering if nopt could default to treating multiple args for the same option as an Array type. For example, when passing:
$ node app.js --log warn --log err
nopt currently returns true for log, but a more sensible default would be ['warn', 'error'] since multiple values were passed. Thoughts?
As of v3.0.1, README.md
states:
By default, nopt outputs a warning to standard error when invalid options are found.
Note that 'invalid option' refers to an invalid value specified for a known option in this context. I've submitted a PR to clarify this.
In practice, no such warning is printed. Nothing in nopt.js
suggests that even an attempt is made to do so.
As an aside, there's a remove
variable that doesn't seem to do anything.
Not sure what the actual intent is, but it looks like the warning was intentionally removed and that the read-me needs to be updated accordingly, including removing the following passage, which becomes moot:
If no nopt.invalidHandler is assigned, then it will console.error its whining. If it is assigned to boolean false then the warning is suppressed.
I've noticed a behavior change from [email protected] -> [email protected] with the parsing of unexpected arguments.
--
) were equivalent.--
) behave differently. Basically, -a a
works like -a
(setting prop a
to true
) but adds "a"
the the remain
array. Shouldn't both set prop a
to string "a"
?$ npm install nopt@~1.0.10
npm WARN package.json [email protected] No README.md file found!
npm http GET https://registry.npmjs.org/nopt
npm http 304 https://registry.npmjs.org/nopt
npm http GET https://registry.npmjs.org/abbrev
npm http 304 https://registry.npmjs.org/abbrev
[email protected] node_modules/nopt
└── [email protected]
$ node -pe "require('nopt')({}, {}, ['-a', 'a', '-b=b', '--c', 'c', '--d=d'], 0)"
{ a: 'a',
b: 'b',
c: 'c',
d: 'd',
argv:
{ remain: [],
cooked: [ '-a', 'a', '-b', 'b', '--c', 'c', '--d', 'd' ],
original: [ '-a', 'a', '-b=b', '--c', 'c', '--d=d' ],
toString: [Function] } }
$ npm install nopt@latest
npm WARN package.json [email protected] No README.md file found!
npm http GET https://registry.npmjs.org/nopt
npm http 304 https://registry.npmjs.org/nopt
npm http GET https://registry.npmjs.org/abbrev
npm http 304 https://registry.npmjs.org/abbrev
[email protected] node_modules/nopt
└── [email protected]
$ node -pe "require('nopt')({}, {}, ['-a', 'a', '-b=b', '--c', 'c', '--d=d'], 0)"
{ a: true,
b: 'b',
c: true,
d: 'd',
argv:
{ remain: [ 'a', 'c' ],
cooked: [ '-a', 'a', '-b', 'b', '--c', 'c', '--d', 'd' ],
original: [ '-a', 'a', '-b=b', '--c', 'c', '--d=d' ] } }
Latest release has the following bug:
[email protected] install /Users/dseeto/code/node_modules/node-sass
> node scripts/install.js
/Users/dseeto/code/node_modules/nopt/lib/nopt.js:210
if (t && ((type.name && t.type.name) ?
^
TypeError: Cannot read property 'name' of null
at validate (/Users/dseeto/code/node_modules/nopt/lib/nopt.js:210:20)
at validate (/Users/dseeto/code/node_modules/nopt/lib/nopt.js:179:11)
at /Users/dseeto/code/node_modules/nopt/lib/nopt.js:101:12
at Array.map (native)
at /Users/dseeto/code/node_modules/nopt/lib/nopt.js:67:15
at Array.forEach (native)
at Function.clean (/Users/dseeto/code/node_modules/nopt/lib/nopt.js:55:21)
at /Users/dseeto/code/node_modules/npmconf/npmconf.js:411:10
at Array.forEach (native)
at validate (/Users/dseeto/code/node_modules/npmconf/npmconf.js:410:11)
I am the following error when I try to install a program that has nopt as a dependency:
if (t && ((type.name && t.type.name) ?
^
TypeError: Cannot read property 'name' of null
at validate (/Users/davidhasenjaeger/Wirestorm/projects/costco-member-scheduling/client/node_modules/node-sass/node_modules/npmconf/node_modules/nopt/lib/nopt.js:210:20)
Feature request:
cmd generate project new_project
cmd destroy feature old_feature
I have this weird issue where Wrapper Objects do not equate with each other. I'm running babel, and I believe that it is overriding what is normally a Number, such that the template being passed in and the internal typeDefs do not match any more.
I can fix this by changing the line here to
if (t && ((type.name && t.type.name) ? (type.name === t.type.name) : (type === t.type))) {
This works, because the object types have a name describing them, which is a string which does a true equality test, and defaults to the old behaviour if this doesn't exist.
The validation doesn't rely on them being the same object - is this a valid thing to do?
Would be nice to have something that prints the usage statement nicely for you. Maybe even allow descriptions to be passed to the option definitions for this. Without a usage statement, most program options cannot be discovered and providing a common way to print a usage statement is nice since completion tools can be built around it.
Feature request:
Descriptions for my arguments so when I do "myapp --help" it will print out a nice description.
Using [email protected] and [email protected] and given the following source 'command'
#!/usr/bin/env /usr/bin/node
var path = require('path');
var nopt = require('nopt');
var parsed = nopt({
's': [path]
});
console.log(parsed);
By making this executable, I then invoke it by
./command -s /tmp -s /bin -s /var
The output will be
{ s: '/var',
argv:
{ remain: [],
cooked: [ '-s', '/tmp', '-s', '/bin', '-s', '/var' ],
original: [ '-s', '/tmp', '-s', '/bin', '-s', '/var' ] } }
I would have expected the following, though
{ s: ['/tmp', '/bin', '/var'],
argv:
{ remain: [],
cooked: [ '-s', '/tmp', '-s', '/bin', '-s', '/var' ],
original: [ '-s', '/tmp', '-s', '/bin', '-s', '/var' ] } }
Am I doing something wrong here?
I've noticed that nopt has changed the way it parses unexpected arguments from v1.0.x to v2.1.x. Now, this may be by design. If it is, please let me know and close the issue.
$ npm install nopt@~1.0.10
npm WARN package.json [email protected] No README.md file found!
npm http GET https://registry.npmjs.org/nopt
npm http 304 https://registry.npmjs.org/nopt
npm http GET https://registry.npmjs.org/abbrev
npm http 304 https://registry.npmjs.org/abbrev
[email protected] node_modules/nopt
└── [email protected]
$ node -pe "require('nopt')({}, {}, ['-r', '1.10'], 0).r"
1.1
$ node -pe "require('nopt')({}, {}, ['-r', 'v1.10'], 0).r"
v1.10
$ npm install nopt@latest
npm WARN package.json [email protected] No README.md file found!
npm http GET https://registry.npmjs.org/nopt
npm http 304 https://registry.npmjs.org/nopt
npm http GET https://registry.npmjs.org/abbrev
npm http 304 https://registry.npmjs.org/abbrev
[email protected] node_modules/nopt
└── [email protected]
$ node -pe "require('nopt')({}, {}, ['-r', '1.10'], 0).r"
true
$ node -pe "require('nopt')({}, {}, ['-r', 'v1.10'], 0).r"
true
This seems like:
"1.10"
was parsed into 1.1
and not left as a string.See gruntjs/grunt#894 for more details.
Thanks!
The purpose of "--no-myParam" is to allow setting a parameter to null instead of undefined, because "-myParam null" would set it to the string value 'null' instead of the javascript value null.
However, this feature is buggy for some typeDefs.
if typeDef is String
"--no-myParam" the parse() function sets it to false instead of null
However, clean() internally calls validateString() which changes it to 'false'
so, "--no-myParam" has no purpose in the case of typeDef String because i could have used "-myParam false" instead.
I haven't tested to see if the other typeDefs have similar issues, but it's possible.
When having this code:
// my-program.js
var output = nopt({
val: [Number, null]
}, {}, process.argv, 2);
then attempting this cli command:
$ node my-program.js
gives me:
var output = { "val" : null};
Which is okay. However, I dont think the following should happen, should it?:
output.val === null // => false
if you have a project that requires 'nopt' it will break if dependencies are committed to repo because abbrev will be ignored.
Hi,
If I understand correct, according to http://semver.org/:
'abbrev':'1'
means 'abbrev':'1.0.0', not 'abbrev':'1.x', right?
but abbrev's version starts from 1.0.3.
so actually you were requiring a version that never exists.
Marguerite
It makes sense to me that if you have a package that takes an options = {...}
object as a parameter, you'd want the same level of validation and error handeling than the one you'd have on CLI args.
Original issue: ember-cli/ember-cli#6970
Parsing options issues for a string with "options"
node test.js foo bar --options '--split 2 --random'
Issue after: 651d447.
https://regex101.com/r/aoa7GZ/1
Example test.js:
var nopt = require("nopt")
var knownOpts = { options: String };
var parsed = nopt( knownOpts, {}, process.argv, 0)
console.log("parsed: ", parsed);
console.log("parsed.options: ", parsed.options);
node test.js foo bar --options '--split 2 --random'
parsed: { options: '--split 2 --random',
argv:
{ remain: [],
cooked: [ '--options', '--split 2 --random' ],
original: [ '--options', '--split 2 --random' ] } }
parsed.options: --split 2 --random
node test.js foo bar --options '--split 2 --random'
parsed: { options: '',
'split 2 --random': true,
argv:
{ remain: [],
cooked: [ '--options', '--split 2 --random' ],
original: [ '--options', '--split 2 --random' ] } }
parsed.options:
Here's an example of everything working properly:
$ ./my-program.js --flag --foo hello
parsed =
{ flag: true,
foo: 'hello',
argv:
{ remain: [],
cooked: [ '--flag', '--foo', 'hello' ],
original: [ '--flag', '--foo', 'hello' ],
toString: [Function] } }
So far, so good. However, a mistaken name for the boolean option throws everything off, so if --myflag was mistakenly used instead of --flag, we get this:
$ ./my-program.js --myflag --foo hello
parsed =
{ myflag: '--foo',
argv:
{ remain: [ 'hello' ],
cooked: [ '--myflag', '--foo', 'hello' ],
original: [ '--myflag', '--foo', 'hello' ],
toString: [Function] } }
Note how the mistyped 'myflag' option has now consumed the --foo option as its value, leaving what was intended as foo's value as part of 'remain'.
Since it can't be determined whether an unknown option is intended to have a value or not, and since nopt is designed to allow for the use of unknown options, it would make sense to check a possible value for an unknown option to see if it may, in fact, be the name of a known option. In the above example, this would mean that 'foo' would be correctly identified as an option name rather than being consumed as a value.
We have known options:
var knownOptions = {
'508': String,
'wcag2': String,
'devmin': String
};
None of which require an argument.
cli --508 arg508 --wcag argWcag
works fine. It results in:
{508: "arg508", wcag: "argWcag"}
However, cli --508 --wcag
results in:
{508: "--wcag"}
but we want:
{508: "", wcag: ""}
We've tried making these options be of a custom type that validates the value is not itself a known option. However, that doesn't push the option pack into the parsed options; it just invokes the invalidOption handler and exits.
Is there a way to get this behavior such that the argument to the known options is optional?
I can't validate type [String,Array]
It should work with validate()
, but that function is not exposed.
I followed your example in the Readme but myapp --foo "hello" didn't work.
It's showing blank lines when I press enter.
Is that possible ?
var opts = {
"bloo" : [0, 1, 2]
};
It seems --bloo 1
isn't accepted when i do that.
for writing the best readme ever and i dont know where you are
See this set of options: https://github.com/jcoglan/vault/blob/176f5921f2654aaaab43f5f824ea56215d4ee0bf/node/cli.js#L37-L49
When I get this program to parse -X
, it sees that X
maps to --clear
. But, there are also short options called c
, l
, e
, a
, and r
, so I end up with [ '--config', '--length', '--export', '--add-source', '--repeat' ]
as the 'cooked' arguments, which makes no sense to my program.
Is this a bug or am I holding it wrong?
It seems like abbrev is hardcoded into nopt. Is it possible to provide a configuration to disable it? We already have the short options, not really sure why we still need abbrevs.
Hi there!
I have an issue with running Yeoman generator in WebStorm 11. Getting the following error:
events.js:141
throw er; // Unhandled 'error' event
^
TypeError: Cannot read property 'match' of undefined
at parse (/Users/ghaiklor/Library/Caches/WebStorm11/extLibs/yeoman/generators_local/generator-sails-rest-api/node_modules/nopt/lib/nopt.js:239:12)
at nopt (/Users/ghaiklor/Library/Caches/WebStorm11/extLibs/yeoman/generators_local/generator-sails-rest-api/node_modules/nopt/lib/nopt.js:40:3)
at ControllerGenerator.Base.parseOptions (/Users/ghaiklor/Library/Caches/WebStorm11/extLibs/yeoman/generators_local/generator-sails-rest-api/node_modules/yeoman-generator/lib/base.js:345:10)
at ControllerGenerator.option (/Users/ghaiklor/Library/Caches/WebStorm11/extLibs/yeoman/generators_local/generator-sails-rest-api/node_modules/yeoman-generator/lib/base.js:275:8)
at ControllerGenerator.Base (/Users/ghaiklor/Library/Caches/WebStorm11/extLibs/yeoman/generators_local/generator-sails-rest-api/node_modules/yeoman-generator/lib/base.js:85:8)
at new ControllerGenerator (/Users/ghaiklor/Library/Caches/WebStorm11/extLibs/yeoman/generators_local/generator-sails-rest-api/node_modules/generator-sails-rest-api/generators/controller/index.js:43:85)
at Environment.instantiate (/usr/local/lib/node_modules/yo/node_modules/yeoman-environment/lib/environment.js:297:10)
at Environment.create (/usr/local/lib/node_modules/yo/node_modules/yeoman-environment/lib/environment.js:274:15)
at AppGenerator.composeWith (/Users/ghaiklor/Library/Caches/WebStorm11/extLibs/yeoman/generators_local/generator-sails-rest-api/node_modules/yeoman-generator/lib/base.js:623:26)
at /Users/ghaiklor/Library/Caches/WebStorm11/extLibs/yeoman/generators_local/generator-sails-rest-api/node_modules/generator-sails-rest-api/generators/app/steps/default.js:49:11
I'd made a little research and seems that issue in parse
method - https://github.com/npm/nopt/blob/master/lib/nopt.js#L228
I'm wondering if this issues is nopt related, Yeoman or WebStorm itself.
app --path folder/file.ext
I'd like to get that raw path value for use in error messages because the resolved path is not only too long to read, it's not what the user typed (communication, blah blah). So far, I'm using argv.cooked
, but it seems redundant because nopt already performs/performed this logic (option type, etc). Is there a better way to do this, possibly using something in nopt?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.