diff --git a/index.js b/index.js index 6f5c076..86e45d3 100644 --- a/index.js +++ b/index.js @@ -280,7 +280,7 @@ function runCmd_ (cmd, pkg, env, wd, opts, stage, unsafe, uid, gid, cb_) { if (customShell) { sh = customShell - } else if (process.platform === 'win32') { + } else if (opts.isWindowsShell == null ? process.platform === 'win32' : opts.isWindowsShell) { sh = process.env.comspec || 'cmd' shFlag = '/d /s /c' conf.windowsVerbatimArguments = true diff --git a/lib/spawn.js b/lib/spawn.js index 30e5b81..2182fa7 100644 --- a/lib/spawn.js +++ b/lib/spawn.js @@ -2,8 +2,12 @@ module.exports = spawn +const os = require('os') +const fs = require('fs') +const path = require('path') const _spawn = require('child_process').spawn const EventEmitter = require('events').EventEmitter +const _spawnSync = require('child_process').spawnSync let progressEnabled let running = 0 @@ -29,7 +33,76 @@ function willCmdOutput (stdio) { return false } +function getGitDirByRegstry (arch) { + const args = [ + 'QUERY', + 'HKLM\\SOFTWARE\\GitForWindows', + '/v', + 'InstallPath' + ] + + if (arch) { + args.push('/reg:' + arch) + } + + const stdout = _spawnSync('reg.exe', args).stdout + + if (stdout && /^\s*InstallPath\s+REG(?:_[A-Z]+)+\s+(.+?)$/im.test(stdout.toString())) { + return RegExp.$1 + } else if (arch === 64) { + return getGitDirByRegstry(32) + } +} + +function getGitPath (cmd) { + let gitInstRoot + if ('GIT_INSTALL_ROOT' in process.env) { + gitInstRoot = process.env.GIT_INSTALL_ROOT + } else { + const osArch = /64$/.test(process.env.PROCESSOR_ARCHITEW6432 || process.arch) ? 64 : 32 + gitInstRoot = getGitDirByRegstry(osArch) + process.env.GIT_INSTALL_ROOT = gitInstRoot + if (gitInstRoot && !process.env.MSYSTEM) { + let binDir = [ + 'mingw64/bin', + 'usr/local/bin', + 'usr/bin', + 'bin', + 'usr/bin/vendor_perl', + 'usr/bin/core_perl' + ].map(function (dir) { + return path.join(gitInstRoot, dir) + }) + + if (!fs.existsSync(binDir[0])) { + binDir[0] = path.join(gitInstRoot, 'mingw32/bin') + } + + binDir.unshift(path.join(os.homedir(), 'bin')) + + const rawPath = process.env.PATH.split(path.delimiter) + + binDir = binDir.filter(function (dir) { + return rawPath.indexOf(dir) < 0 + }) + + binDir.push(process.env.PATH) + + process.env.PATH = binDir.join(path.delimiter) + } + } + + if (gitInstRoot) { + cmd = path.join(gitInstRoot, cmd) + } + return cmd +} + function spawn (cmd, args, options, log) { + if (process.platform === 'win32' && cmd[0] === '/') { + cmd = getGitPath(cmd) + } + const cmdWillOutput = willCmdOutput(options && options.stdio) if (cmdWillOutput) startRunning(log)