diff options
author | isaacs <i@izs.me> | 2020-08-01 01:01:45 +0300 |
---|---|---|
committer | isaacs <i@izs.me> | 2020-08-04 11:03:20 +0300 |
commit | 3aba8d62f060753a089e7108130624722d32453a (patch) | |
tree | b19baed33b9f2fec26a9eaef6c77fb03a6774d7d /bin | |
parent | 87d27d389065609e94ee218ab001972fc0041fe9 (diff) |
npx: add install prompt, handle options correctly
- handle previous npx options that are still possible to be handled, and
print a warning if any deprecated/removed options are used.
- expand shorthands properly in npx command line.
- take existing npm options into account when determining placement of
the -- argument.
- document changes from previous versions of npx.
PR-URL: https://github.com/npm/cli/pull/1596
Credit: @isaacs
Close: #1596
Reviewed-by: @ruyadorno
Diffstat (limited to 'bin')
-rw-r--r-- | bin/npx-cli.js | 106 |
1 files changed, 102 insertions, 4 deletions
diff --git a/bin/npx-cli.js b/bin/npx-cli.js index dc2072ffd..716dc958e 100644 --- a/bin/npx-cli.js +++ b/bin/npx-cli.js @@ -6,20 +6,114 @@ const cli = require('../lib/cli.js') process.argv[1] = require.resolve('./npm-cli.js') process.argv.splice(2, 0, 'exec') +// TODO: remove the affordances for removed items in npm v9 +const removedSwitches = new Set([ + 'always-spawn', + 'ignore-existing', + 'shell-auto-fallback' +]) + +const removedOpts = new Set([ + 'npm', + 'node-arg', + 'n' +]) + +const removed = new Set([ + ...removedSwitches, + ...removedOpts +]) + +const { types, shorthands } = require('../lib/config/defaults.js') +const npmSwitches = Object.entries(types) + .filter(([key, type]) => type === Boolean || + (Array.isArray(type) && type.includes(Boolean))) + .map(([key, type]) => key) + +// things that don't take a value +const switches = new Set([ + ...removedSwitches, + ...npmSwitches, + 'no-install', + 'quiet', + 'q', + 'version', + 'v', + 'help', + 'h' +]) + +// things that do take a value +const opts = new Set([ + ...removedOpts, + 'package', + 'p', + 'cache', + 'userconfig', + 'call', + 'c', + 'shell', + 'npm', + 'node-arg', + 'n' +]) + // break out of loop when we find a positional argument or -- // If we find a positional arg, we shove -- in front of it, and // let the normal npm cli handle the rest. let i +let sawRemovedFlags = false for (i = 3; i < process.argv.length; i++) { const arg = process.argv[i] if (arg === '--') { break } else if (/^-/.test(arg)) { - // `--package foo` treated the same as `--package=foo` - if (!arg.includes('=')) { - i++ + const [key, ...v] = arg.replace(/^-+/, '').split('=') + + switch (key) { + case 'p': + process.argv[i] = ['--package', ...v].join('=') + break + + case 'shell': + process.argv[i] = ['--script-shell', ...v].join('=') + break + + case 'no-install': + process.argv[i] = '--yes=false' + break + + default: + // resolve shorthands and run again + if (shorthands[key] && !removed.has(key)) { + const a = [...shorthands[key]] + if (v.length) { + a.push(v.join('=')) + } + process.argv.splice(i, 1, ...a) + i-- + continue + } + break + } + + if (removed.has(key)) { + console.error(`npx: the --${key} argument has been removed.`) + sawRemovedFlags = true + process.argv.splice(i, 1) + i-- + } + + if (v.length === 0 && !switches.has(key) && + (opts.has(key) || !/^-/.test(process.argv[i + 1]))) { + // value will be next argument, skip over it. + if (removed.has(key)) { + // also remove the value for the cut key. + process.argv.splice(i + 1, 1) + } else { + i++ + } } - continue } else { // found a positional arg, put -- in front of it, and we're done process.argv.splice(i, 0, '--') @@ -27,4 +121,8 @@ for (i = 3; i < process.argv.length; i++) { } } +if (sawRemovedFlags) { + console.error('See `npm help exec` for more information') +} + cli(process) |