import * as path from 'path' ; import * as semver from 'semver' ; import { LockFile } from '@rushstack/node-core-library' ; import { Utilities } from '@microsoft/rush-lib/lib/utilities/Utilities' ; import { _LastInstallFlag , _RushGlobalFolder , ILaunchOptions } from '@microsoft/rush-lib' ; import { RushCommandSelector } from './RushCommandSelector' ; import { MinimalRushConfiguration } from './MinimalRushConfiguration' ; const MAX_INSTALL_ATTEMPTS = 3 ; export class RushVersionSelector { private _rushGlobalFolder : _RushGlobalFolder ; private _currentPackageVersion : string ; public constructor ( currentPackageVersion ) { this . _rushGlobalFolder = new _RushGlobalFolder ( ) ; this . _currentPackageVersion = currentPackageVersion ; } public async ensureRushVersionInstalledAsync ( version , configuration , executeOptions ) { const isLegacyRushVersion = semver . lt ( version , '4.0.0' ) ; const expectedRushPath = path . join ( this . _rushGlobalFolder . nodeSpecificPath , `rush-${ version }` ) ; const installMarker = new _LastInstallFlag ( expectedRushPath , { node : process . versions . node } ) ; if ( ! installMarker . isValid ( ) ) { console . log ( `Rush version ${ version } is not currently installed. Installing...` ) ; const resourceName = `rush-${ version }` ; console . log ( `Trying to acquire lock for ${ resourceName }` ) ; const lock = await LockFile . acquire ( expectedRushPath , resourceName ) ; if ( installMarker . isValid ( ) ) { console . log ( 'Another process performed the installation.' ) ; } else { Utilities . installPackageInDirectory ( { directory : expectedRushPath , packageName : isLegacyRushVersion ? '@microsoft/rush' : '@microsoft/rush-lib' , version : version , tempPackageTitle : 'rush-local-install' , maxInstallAttempts : MAX_INSTALL_ATTEMPTS , commonRushConfigFolder : configuration ? configuration . commonRushConfigFolder : undefined , suppressOutput : true } ) ; console . log ( `Successfully installed Rush version ${ version } in ${ expectedRushPath }.` ) ; installMarker . create ( ) ; lock . release ( ) ; } } if ( semver . lt ( version , '3.0.20' ) ) { RushCommandSelector . failIfNotInvokedAsRush ( version ) ; require ( path . join ( expectedRushPath , 'node_modules' , '@microsoft' , 'rush' , 'lib' , 'rush' ) ) ; } else if ( semver . lt ( version , '4.0.0' ) ) { RushCommandSelector . failIfNotInvokedAsRush ( version ) ; require ( path . join ( expectedRushPath , 'node_modules' , '@microsoft' , 'rush' , 'lib' , 'start' ) ) ; } else { const rushCliEntrypoint = require ( path . join ( expectedRushPath , 'node_modules' , '@microsoft' , 'rush-lib' , 'lib' , 'index' ) ) ; RushCommandSelector . execute ( this . _currentPackageVersion , rushCliEntrypoint , executeOptions ) ; } } }