diff --git a/index.js b/index.js index 0a91e9a..997bad5 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,39 @@ 'use strict'; +function getMainArgs() { + // This function is a placeholder for proposed process.mainArgs. + // Work out where to slice process.argv for user supplied arguments. + + // Electron is an interested example, with work-arounds implemented in + // Commander and Yargs. Hopefully Electron would support process.mainArgs + // itself and render this work-around moot. + // + // In a bundled Electron app, the user CLI args directly + // follow executable. (No special processing required for unbundled.) + // 1) process.versions.electron is either set by electron, or undefined + // see https://github.com/electron/electron/blob/master/docs/api/process.md#processversionselectron-readonly + // 2) process.defaultApp is undefined in a bundled Electron app, and set + // in an unbundled Electron app + // see https://github.com/electron/electron/blob/master/docs/api/process.md#processversionselectron-readonly + // (Not included in tests as hopefully temporary example.) + /* c8 ignore next 3 */ + if (process.versions && process.versions.electron && !process.defaultApp) { + return process.argv.slice(1); + } + + // Check node options for scenarios where user CLI args follow executable. + const execArgv = process.execArgv; + if (execArgv.includes('-e') || execArgv.includes('--eval') || + execArgv.includes('-p') || execArgv.includes('--print')) { + return process.argv.slice(1); + } + + // Normally first two arguments are executable and script, then CLI arguments + return process.argv.slice(2); +} + const parseArgs = ( - argv = process.argv.slice(require.main ? 2 : 1), + argv = getMainArgs(), options = {} ) => { if (typeof options !== 'object' || options === null) { diff --git a/test/index.js b/test/index.js index f543f81..36eb4c6 100644 --- a/test/index.js +++ b/test/index.js @@ -68,19 +68,108 @@ test('args are passed "withValue" and "multiples"', function (t) { t.end() }) +test('correct default args when use node -p', function(t) { + const holdArgv = process.argv; + process.argv = [process.argv0, '--foo']; + const holdExecArgv = process.execArgv; + process.execArgv = ['-p', '0']; + const result = parseArgs(); + + const expected = { flags: { foo: true }, + values: { foo: [undefined] }, + positionals: [] }; + t.deepEqual(result, expected); + + t.end(); + process.argv = holdArgv; + process.execArgv = holdExecArgv; +}); + +test('correct default args when use node --print', function(t) { + const holdArgv = process.argv; + process.argv = [process.argv0, '--foo']; + const holdExecArgv = process.execArgv; + process.execArgv = ['--print', '0']; + const result = parseArgs(); + + const expected = { flags: { foo: true }, + values: { foo: [undefined] }, + positionals: [] }; + t.deepEqual(result, expected); + + t.end(); + process.argv = holdArgv; + process.execArgv = holdExecArgv; +}); + +test('correct default args when use node -e', function(t) { + const holdArgv = process.argv; + process.argv = [process.argv0, '--foo']; + const holdExecArgv = process.execArgv; + process.execArgv = ['-e', '0']; + const result = parseArgs(); + + const expected = { flags: { foo: true }, + values: { foo: [undefined] }, + positionals: [] }; + t.deepEqual(result, expected); + + t.end(); + process.argv = holdArgv; + process.execArgv = holdExecArgv; +}); + +test('correct default args when use node --eval', function(t) { + const holdArgv = process.argv; + process.argv = [process.argv0, '--foo']; + const holdExecArgv = process.execArgv; + process.execArgv = ['--eval', '0']; + const result = parseArgs(); + + const expected = { flags: { foo: true }, + values: { foo: [undefined] }, + positionals: [] }; + t.deepEqual(result, expected); + + t.end(); + process.argv = holdArgv; + process.execArgv = holdExecArgv; +}); + +test('correct default args when normal arguments', function(t) { + const holdArgv = process.argv; + process.argv = [process.argv0, 'script.js', '--foo']; + const holdExecArgv = process.execArgv; + process.execArgv = []; + const result = parseArgs(); + + const expected = { flags: { foo: true }, + values: { foo: [undefined] }, + positionals: [] }; + t.deepEqual(result, expected); + + t.end(); + process.argv = holdArgv; + process.execArgv = holdExecArgv; +}); + test('excess leading dashes on options are retained', function(t) { // Enforce a design decision for an edge case. const passedArgs = ['---triple']; const passedOptions = { }; - const expected = { flags: { '-triple': true}, values: { '-triple': [undefined]}, positionals: [] }; - const args = parseArgs(passedArgs, passedOptions); + const expected = { + flags: { '-triple': true }, + values: { '-triple': [undefined] }, + positionals: [] + }; + const result = parseArgs(passedArgs, passedOptions); - t.deepEqual(args, expected, 'excess option dashes are retained'); + t.deepEqual(result, expected, 'excess option dashes are retained'); t.end(); }); -//Test bad inputs +// Test bad inputs test('boolean passed to "withValue" option', function (t) { const passedArgs = ['--so=wat']