@@ -68,7 +68,7 @@ export function findRushJsonFolder(): string {
6868 } else {
6969 basePath = tempPath ;
7070 }
71- } while ( basePath !== ( tempPath = path . resolve ( basePath , '..' ) ) ) ; // Exit the loop when we hit the disk root
71+ } while ( basePath !== ( tempPath = path . dirname ( basePath ) ) ) ; // Exit the loop when we hit the disk root
7272
7373 if ( ! _rushJsonFolder ) {
7474 throw new Error ( 'Unable to find rush.json.' ) ;
@@ -88,7 +88,7 @@ function ensureAndResolveFolder(baseFolder: string, ...pathSegments: string[]):
8888 let resolvedDirectory : string = baseFolder ;
8989 try {
9090 for ( let pathSegment of pathSegments ) {
91- pathSegment = pathSegment . replace ( / [ \\ \/ ] / g, '_ ' ) ;
91+ pathSegment = pathSegment . replace ( / [ \\ \/ ] / g, '+ ' ) ;
9292 resolvedDirectory = path . resolve ( resolvedDirectory , pathSegment ) ;
9393 if ( ! fs . existsSync ( resolvedDirectory ) ) {
9494 fs . mkdirSync ( resolvedDirectory ) ;
@@ -155,7 +155,10 @@ function isPackageAlreadyInstalled(packageInstallFolder: string): boolean {
155155}
156156
157157/**
158- * Removes the installed.flag file and the node_modules folder under the specified folder path.
158+ * Removes the following files and directories under the specified folder path:
159+ * - installed.flag
160+ * -
161+ * - node_modules
159162 */
160163function cleanInstallFolder ( rushCommonFolder : string , packageInstallFolder : string ) : void {
161164 try {
@@ -164,13 +167,18 @@ function cleanInstallFolder(rushCommonFolder: string, packageInstallFolder: stri
164167 fs . unlinkSync ( flagFile ) ;
165168 }
166169
170+ const packageLockFile : string = path . resolve ( packageInstallFolder , 'package-lock.json' ) ;
171+ if ( fs . existsSync ( packageLockFile ) ) {
172+ fs . unlinkSync ( packageLockFile ) ;
173+ }
174+
167175 const nodeModulesFolder : string = path . resolve ( packageInstallFolder , NODE_MODULES_FOLDER_NAME ) ;
168176 if ( fs . existsSync ( nodeModulesFolder ) ) {
169177 const rushRecyclerFolder : string = ensureAndResolveFolder (
170178 rushCommonFolder ,
171179 'temp' ,
172180 'rush-recycler' ,
173- Date . now ( ) . toString ( )
181+ `install-run- ${ Date . now ( ) . toString ( ) } `
174182 ) ;
175183 fs . renameSync ( nodeModulesFolder , rushRecyclerFolder ) ;
176184 }
@@ -206,39 +214,33 @@ function installPackage(packageInstallFolder: string, name: string, version: str
206214 try {
207215 console . log ( `Installing ${ name } ...` ) ;
208216 const npmPath : string = getNpmPath ( ) ;
209- childProcess . execSync ( `"${ npmPath } " install` , { cwd : packageInstallFolder } ) ;
217+ const result : childProcess . SpawnSyncReturns < Buffer > = childProcess . spawnSync (
218+ npmPath ,
219+ [ 'install' ] ,
220+ {
221+ stdio : 'inherit' ,
222+ cwd : packageInstallFolder ,
223+ env : process . env
224+ }
225+ ) ;
226+
227+ if ( result . status !== 0 ) {
228+ throw new Error ( '"npm install" encountered an error' ) ;
229+ }
230+
210231 console . log ( `Successfully installed ${ name } @${ version } ` ) ;
211232 } catch ( e ) {
212233 throw new Error ( `Unable to install package: ${ e } ` ) ;
213234 }
214235}
215236
216237/**
217- * Try to resolve the specified binary in an installed package.
238+ * Get the ".bin" path for the package.
218239 */
219- function findBinPath ( packageInstallFolder : string , name : string , binName : string ) : string {
220- try {
221- const packagePath : string = path . resolve ( packageInstallFolder , NODE_MODULES_FOLDER_NAME , name ) ;
222- const packageJsonPath : string = path . resolve ( packagePath , PACKAGE_JSON_FILENAME ) ;
223- const packageJson : IPackageJson = require ( packageJsonPath ) ;
224- if ( ! packageJson . bin ) {
225- throw new Error ( 'No binaries are specified for package.' ) ;
226- } else {
227- const binValue : string = packageJson . bin [ binName ] ;
228- if ( ! binValue ) {
229- throw new Error ( `Binary ${ binName } is not specified in the package's package.json` ) ;
230- } else {
231- const resolvedBinPath : string = path . resolve ( packagePath , binValue ) ;
232- if ( ! fs . existsSync ( resolvedBinPath ) ) {
233- throw new Error ( 'The specified binary points to a path that does not exist' ) ;
234- } else {
235- return resolvedBinPath ;
236- }
237- }
238- }
239- } catch ( e ) {
240- throw new Error ( `Unable to find specified binary "${ binName } ": ${ e } ` ) ;
241- }
240+ function getBinPath ( packageInstallFolder : string , binName : string ) : string {
241+ const binFolderPath : string = path . resolve ( packageInstallFolder , NODE_MODULES_FOLDER_NAME , '.bin' ) ;
242+ const resolvedBinName : string = ( os . platform ( ) === 'win32' ) ? `${ binName } .cmd` : binName ;
243+ return path . resolve ( binFolderPath , resolvedBinName ) ;
242244}
243245
244246/**
@@ -249,17 +251,16 @@ function writeFlagFile(packageInstallFolder: string): void {
249251 const flagFilePath : string = path . join ( packageInstallFolder , INSTALLED_FLAG_FILENAME ) ;
250252 fs . writeFileSync ( flagFilePath , process . version ) ;
251253 } catch ( e ) {
252- // Ignore
254+ throw new Error ( `Unable to create installed.flag file in ${ packageInstallFolder } ` ) ;
253255 }
254256}
255257
256258export function installAndRun (
257- nodePath : string ,
258259 packageName : string ,
259260 packageVersion : string ,
260261 packageBinName : string ,
261262 packageBinArgs : string [ ]
262- ) : void {
263+ ) : number {
263264 const rushJsonFolder : string = findRushJsonFolder ( ) ;
264265 const rushCommonFolder : string = path . join ( rushJsonFolder , 'common' ) ;
265266 const packageInstallFolder : string = ensureAndResolveFolder (
@@ -278,21 +279,30 @@ export function installAndRun(
278279 writeFlagFile ( packageInstallFolder ) ;
279280 }
280281
281- const binPath : string = findBinPath ( packageInstallFolder , packageName , packageBinName ) ;
282- childProcess . spawnSync (
283- nodePath ,
284- [ binPath , ...packageBinArgs ] ,
282+ const statusMessage : string = `Invoking "${ packageBinName } ${ packageBinArgs . join ( ' ' ) } "` ;
283+ const statusMessageLine : string = new Array ( statusMessage . length ) . join ( '-' ) ;
284+ console . log ( os . EOL + statusMessage + os . EOL + statusMessageLine + os . EOL ) ;
285+
286+ const binPath : string = getBinPath ( packageInstallFolder , packageBinName ) ;
287+ const result : childProcess . SpawnSyncReturns < Buffer > = childProcess . spawnSync (
288+ binPath ,
289+ packageBinArgs ,
285290 {
286291 stdio : 'inherit' ,
287292 cwd : process . cwd ( ) ,
288293 env : process . env
289294 }
290295 ) ;
296+
297+ return result . status ;
291298}
292299
293- export function runWithErrorPrinting ( fn : ( ) => void ) : void {
300+ export function runWithErrorAndStatusCode ( fn : ( ) => number ) : void {
301+ process . exitCode = 1 ;
302+
294303 try {
295- fn ( ) ;
304+ const exitCode : number = fn ( ) ;
305+ process . exitCode = exitCode ;
296306 } catch ( e ) {
297307 console . error ( os . EOL + os . EOL + e . toString ( ) + os . EOL + os . EOL ) ;
298308 }
0 commit comments