22// See LICENSE in the project root for license information.
33
44import * as child_process from 'child_process' ;
5- import { IPackageDeps } from './IPackageDeps ' ;
5+ import { Executable } from '@microsoft/node-core-library ' ;
66
7- // 8191 is the longest supported command on Windows
8- const MAX_COMMAND_LENGTH : number = 8191 ;
7+ import { IPackageDeps } from './IPackageDeps' ;
98
109/**
1110 * Parses the output of the "git ls-tree" command
@@ -96,39 +95,32 @@ export function parseGitStatus(output: string, packagePath: string): Map<string,
9695export function getGitHashForFiles ( filesToHash : string [ ] , packagePath : string ) : Map < string , string > {
9796 const changes : Map < string , string > = new Map < string , string > ( ) ;
9897
99- let index : number = 0 ;
100- while ( index < filesToHash . length ) {
101- const HASH_OBJECT_COMMAND : string = 'git hash-object' ;
102- const filesInBatch : string [ ] = [ ] ;
103- let commandPartsTextLength : number = HASH_OBJECT_COMMAND . length ;
104-
105- for ( ; index < filesToHash . length ; index ++ ) {
106- const filePath : string = filesToHash [ index ] ;
107- // The "1" accounts for the space between commands
108- const newLength : number = commandPartsTextLength + 1 + filePath . length ;
109- if ( newLength > MAX_COMMAND_LENGTH ) {
110- break ;
111- }
98+ if ( filesToHash . length ) {
99+ const result : child_process . SpawnSyncReturns < string > = Executable . spawnSync (
100+ 'git' ,
101+ [ 'hash-object' , ...filesToHash ] ,
102+ { currentWorkingDirectory : packagePath }
103+ ) ;
112104
113- filesInBatch . push ( filePath ) ;
114- commandPartsTextLength = newLength ;
105+ if ( result . status !== 0 ) {
106+ throw new Error ( `git hash-object exited with status ${ result } : ${ result . stderr } ` ) ;
115107 }
116108
117- const hashStdout : string = child_process . execSync (
118- [ HASH_OBJECT_COMMAND , ...filesInBatch ] . join ( ' ' ) ,
119- { cwd : packagePath }
120- ) . toString ( ) . trim ( ) ;
109+ const hashStdout : string = result . stdout . trim ( ) ;
121110
111+ // The result of "git hash-object" will be a list of file hashes delimited by newlines
122112 const hashes : string [ ] = hashStdout . split ( '\n' ) ;
123- if ( hashes . length !== filesInBatch . length ) {
124- throw new Error ( `Passed ${ filesInBatch . length } file paths to Git to hash, but received ${ hashes . length } hashes.` ) ;
113+
114+ if ( hashes . length !== filesToHash . length ) {
115+ throw new Error ( `Passed ${ filesToHash . length } file paths to Git to hash, but received ${ hashes . length } hashes.` ) ;
125116 }
126117
127118 for ( let i : number = 0 ; i < hashes . length ; i ++ ) {
128119 const hash : string = hashes [ i ] ;
129- const filePath : string = filesInBatch [ i ] ;
120+ const filePath : string = filesToHash [ i ] ;
130121 changes . set ( filePath , hash ) ;
131122 }
123+
132124 }
133125
134126 return changes ;
@@ -138,24 +130,38 @@ export function getGitHashForFiles(filesToHash: string[], packagePath: string):
138130 * Executes "git ls-tree" in a folder
139131 */
140132export function gitLsTree ( path : string ) : string {
141- return child_process . execSync (
142- `git ls-tree HEAD -r` ,
133+ const result : child_process . SpawnSyncReturns < string > = Executable . spawnSync (
134+ 'git' ,
135+ [ 'ls-tree' , 'HEAD' , '-r' ] ,
143136 {
144- cwd : path ,
145- stdio : 'pipe'
146- } ) . toString ( ) ;
137+ currentWorkingDirectory : path
138+ }
139+ ) ;
140+
141+ if ( result . status !== 0 ) {
142+ throw new Error ( `git ls-tree exited with status ${ result } : ${ result . stderr } ` ) ;
143+ }
144+
145+ return result . stdout ;
147146}
148147
149148/**
150149 * Executes "git status" in a folder
151150 */
152151export function gitStatus ( path : string ) : string {
153- return child_process . execSync (
154- `git status -s -u .` ,
152+ const result : child_process . SpawnSyncReturns < string > = Executable . spawnSync (
153+ 'git' ,
154+ [ 'status' , '-s' , '-u' , '.' ] ,
155155 {
156- cwd : path ,
157- stdio : 'pipe'
158- } ) . toString ( ) ;
156+ currentWorkingDirectory : path
157+ }
158+ ) ;
159+
160+ if ( result . status !== 0 ) {
161+ throw new Error ( `git ls-tree exited with status ${ result } : ${ result . stderr } ` ) ;
162+ }
163+
164+ return result . stdout ;
159165}
160166
161167/**
0 commit comments