forked from microsoft/rushstack
-
Notifications
You must be signed in to change notification settings - Fork 0
/
RushVersionSelector.ts
97 lines (81 loc) · 4.11 KB
/
RushVersionSelector.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
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: number = 3;
export class RushVersionSelector {
private _rushGlobalFolder: _RushGlobalFolder;
private _currentPackageVersion: string;
public constructor(currentPackageVersion: string) {
this._rushGlobalFolder = new _RushGlobalFolder();
this._currentPackageVersion = currentPackageVersion;
}
public async ensureRushVersionInstalledAsync(
version: string,
configuration: MinimalRushConfiguration | undefined,
executeOptions: ILaunchOptions
): Promise<void> {
const isLegacyRushVersion: boolean = semver.lt(version, '4.0.0');
const expectedRushPath: string = path.join(this._rushGlobalFolder.nodeSpecificPath, `rush-${version}`);
const installMarker: _LastInstallFlag = new _LastInstallFlag(expectedRushPath, {
node: process.versions.node
});
if (!installMarker.isValid()) {
// Need to install Rush
console.log(`Rush version ${version} is not currently installed. Installing...`);
const resourceName: string = `rush-${version}`;
console.log(`Trying to acquire lock for ${resourceName}`);
const lock: LockFile = 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,
// This is using a local configuration to install a package in a shared global location.
// Generally that's a bad practice, but in this case if we can successfully install
// the package at all, we can reasonably assume it's good for all the repositories.
// In particular, we'll assume that two different NPM registries cannot have two
// different implementations of the same version of the same package.
// This was needed for: https://github.com/microsoft/rushstack/issues/691
commonRushConfigFolder: configuration ? configuration.commonRushConfigFolder : undefined,
suppressOutput: true
});
console.log(`Successfully installed Rush version ${version} in ${expectedRushPath}.`);
// If we've made it here without exception, write the flag file
installMarker.create();
lock.release();
}
}
if (semver.lt(version, '3.0.20')) {
// In old versions, requiring the entry point invoked the command-line parser immediately,
// so fail if "rushx" or "rush-pnpm" was used
RushCommandSelector.failIfNotInvokedAsRush(version);
require(path.join(expectedRushPath, 'node_modules', '@microsoft', 'rush', 'lib', 'rush'));
} else if (semver.lt(version, '4.0.0')) {
// In old versions, requiring the entry point invoked the command-line parser immediately,
// so fail if "rushx" or "rush-pnpm" was used
RushCommandSelector.failIfNotInvokedAsRush(version);
require(path.join(expectedRushPath, 'node_modules', '@microsoft', 'rush', 'lib', 'start'));
} else {
// For newer rush-lib, RushCommandSelector can test whether "rushx" is supported or not
const rushCliEntrypoint: {} = require(path.join(
expectedRushPath,
'node_modules',
'@microsoft',
'rush-lib',
'lib',
'index'
));
RushCommandSelector.execute(this._currentPackageVersion, rushCliEntrypoint, executeOptions);
}
}
}