This is an automated email from the ASF dual-hosted git repository. raphinesse pushed a commit to branch cross-spawn in repository https://gitbox.apache.org/repos/asf/cordova-common.git
commit 6e7177fa1a20c446fca2d419f050b9dc52affc09 Author: Raphael von der GrĂ¼n <[email protected]> AuthorDate: Sun Sep 9 13:44:26 2018 +0200 Use `cross-spawn` for platform-independent spawning --- package.json | 1 + spec/superspawn.spec.js | 21 +++++++++++++++++++++ src/superspawn.js | 50 +++---------------------------------------------- 3 files changed, 25 insertions(+), 47 deletions(-) diff --git a/package.json b/package.json index 19c5e27..1a1bcbb 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "dependencies": { "ansi": "^0.3.1", "bplist-parser": "^0.1.0", + "cross-spawn": "^6.0.5", "elementtree": "0.1.7", "endent": "^1.1.1", "fs-extra": "^6.0.1", diff --git a/spec/superspawn.spec.js b/spec/superspawn.spec.js index 5a63564..d506318 100644 --- a/spec/superspawn.spec.js +++ b/spec/superspawn.spec.js @@ -88,4 +88,25 @@ describe('spawn method', function () { }); }); + describe('operation on windows', () => { + const cp = require('child_process'); + + beforeEach(() => { + spyOn(cp, 'spawn').and.returnValue({ on: _ => _ }); + }); + + it('should escape arguments if `cmd` is not an *.exe', () => { + if (process.platform !== 'win32') { + pending('test should only run on windows'); + } + + superspawn.spawn('npm.cmd', [ 'install', 'foo@^1.2.3' ]); + expect(cp.spawn).toHaveBeenCalledWith( + 'cmd.exe', + [ '/d', '/s', '/c', '"npm.cmd ^"install^" ^"foo@^^1.2.3^""' ], + jasmine.objectContaining({ windowsVerbatimArguments: true }) + ); + }); + }); + }); diff --git a/src/superspawn.js b/src/superspawn.js index eae552c..7ddb89c 100644 --- a/src/superspawn.js +++ b/src/superspawn.js @@ -17,41 +17,13 @@ under the License. */ -var child_process = require('child_process'); +var crossSpawn = require('cross-spawn'); var fs = require('fs-extra'); -var path = require('path'); var _ = require('underscore'); var Q = require('q'); -var which = require('which'); var events = require('./events'); var iswin32 = process.platform === 'win32'; -// On Windows, spawn() for batch files requires absolute path & having the extension. -function resolveWindowsExe (cmd) { - var winExtensions = ['.exe', '.bat', '.cmd', '.js', '.vbs']; - function isValidExe (c) { - return winExtensions.includes(path.extname(c)) && fs.existsSync(c); - } - if (isValidExe(cmd)) { - return cmd; - } - cmd = which.sync(cmd, { nothrow: true }) || cmd; - if (!isValidExe(cmd)) { - winExtensions.some(function (ext) { - if (fs.existsSync(cmd + ext)) { - cmd = cmd + ext; - return true; - } - }); - } - return cmd; -} - -function maybeQuote (a) { - if (/^[^"].*[ &].*[^"]/.test(a)) return '"' + a + '"'; - return a; -} - /** * A special implementation for child_process.spawn that handles * Windows-specific issues with batch files and spaces in paths. Returns a @@ -91,22 +63,6 @@ exports.spawn = function (cmd, args, opts) { var spawnOpts = {}; var d = Q.defer(); - if (iswin32) { - cmd = resolveWindowsExe(cmd); - // If we couldn't find the file, likely we'll end up failing, - // but for things like "del", cmd will do the trick. - if (path.extname(cmd) !== '.exe') { - var cmdArgs = '"' + [cmd].concat(args).map(maybeQuote).join(' ') + '"'; - // We need to use /s to ensure that spaces are parsed properly with cmd spawned content - args = [['/s', '/c', cmdArgs].join(' ')]; - cmd = 'cmd'; - spawnOpts.windowsVerbatimArguments = true; - } else if (!fs.existsSync(cmd)) { - // We need to use /s to ensure that spaces are parsed properly with cmd spawned content - args = ['/s', '/c', cmd].concat(args).map(maybeQuote); - } - } - if (opts.stdio !== 'default') { // Ignore 'default' value for stdio because it corresponds to child_process's default 'pipe' option spawnOpts.stdio = opts.stdio; @@ -129,9 +85,9 @@ exports.spawn = function (cmd, args, opts) { } } - events.emit(opts.printCommand ? 'log' : 'verbose', 'Running command: ' + maybeQuote(cmd) + ' ' + args.map(maybeQuote).join(' ')); + events.emit(opts.printCommand ? 'log' : 'verbose', 'Running command: ' + cmd + ' ' + args.join(' ')); - var child = child_process.spawn(cmd, args, spawnOpts); + var child = crossSpawn.spawn(cmd, args, spawnOpts); var capturedOut = ''; var capturedErr = ''; --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
