22
33module . exports = spawn
44
5+ const os = require ( 'os' )
6+ const fs = require ( 'fs' )
7+ const path = require ( 'path' )
58const _spawn = require ( 'child_process' ) . spawn
69const EventEmitter = require ( 'events' ) . EventEmitter
10+ const _spawnSync = require ( 'child_process' ) . spawnSync
711
812let progressEnabled
913let running = 0
@@ -29,7 +33,76 @@ function willCmdOutput (stdio) {
2933 return false
3034}
3135
36+ function getGitDirByRegstry ( arch ) {
37+ const args = [
38+ 'QUERY' ,
39+ 'HKLM\\SOFTWARE\\GitForWindows' ,
40+ '/v' ,
41+ 'InstallPath'
42+ ]
43+
44+ if ( arch ) {
45+ args . push ( '/reg:' + arch )
46+ }
47+
48+ const stdout = _spawnSync ( 'reg.exe' , args ) . stdout
49+
50+ if ( stdout && / ^ \s * I n s t a l l P a t h \s + R E G (?: _ [ A - Z ] + ) + \s + ( .+ ?) $ / im. test ( stdout . toString ( ) ) ) {
51+ return RegExp . $1
52+ } else if ( arch === 64 ) {
53+ return getGitDirByRegstry ( 32 )
54+ }
55+ }
56+
57+ function getGitPath ( cmd ) {
58+ let gitInstRoot
59+ if ( 'GIT_INSTALL_ROOT' in process . env ) {
60+ gitInstRoot = process . env . GIT_INSTALL_ROOT
61+ } else {
62+ const osArch = / 6 4 $ / . test ( process . env . PROCESSOR_ARCHITEW6432 || process . arch ) ? 64 : 32
63+ gitInstRoot = getGitDirByRegstry ( osArch )
64+ process . env . GIT_INSTALL_ROOT = gitInstRoot
65+ if ( gitInstRoot && ! process . env . MSYSTEM ) {
66+ let binDir = [
67+ 'mingw64/bin' ,
68+ 'usr/local/bin' ,
69+ 'usr/bin' ,
70+ 'bin' ,
71+ 'usr/bin/vendor_perl' ,
72+ 'usr/bin/core_perl'
73+ ] . map ( function ( dir ) {
74+ return path . join ( gitInstRoot , dir )
75+ } )
76+
77+ if ( ! fs . existsSync ( binDir [ 0 ] ) ) {
78+ binDir [ 0 ] = path . join ( gitInstRoot , 'mingw32/bin' )
79+ }
80+
81+ binDir . unshift ( path . join ( os . homedir ( ) , 'bin' ) )
82+
83+ const rawPath = process . env . PATH . split ( path . delimiter )
84+
85+ binDir = binDir . filter ( function ( dir ) {
86+ return rawPath . indexOf ( dir ) < 0
87+ } )
88+
89+ binDir . push ( process . env . PATH )
90+
91+ process . env . PATH = binDir . join ( path . delimiter )
92+ }
93+ }
94+
95+ if ( gitInstRoot ) {
96+ cmd = path . join ( gitInstRoot , cmd )
97+ }
98+ return cmd
99+ }
100+
32101function spawn ( cmd , args , options , log ) {
102+ if ( process . platform === 'win32' && cmd [ 0 ] === '/' ) {
103+ cmd = getGitPath ( cmd )
104+ }
105+
33106 const cmdWillOutput = willCmdOutput ( options && options . stdio )
34107
35108 if ( cmdWillOutput ) startRunning ( log )
0 commit comments