@rushstack/rush-sdk 5.161.0 → 5.163.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/rush-lib.d.ts +13 -39
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/api/RushProjectConfiguration.d.ts +7 -0
- package/lib/cli/RushCommandLineParser.d.ts +4 -0
- package/lib/cli/actions/ListAction.d.ts +4 -0
- package/lib/cli/parsing/SelectionParameterSet.d.ts +5 -0
- package/lib/cli/parsing/associateParametersByPhase.d.ts +12 -0
- package/lib/cli/parsing/associateParametersByPhase.js +1 -0
- package/lib/cli/parsing/defineCustomParameters.d.ts +12 -0
- package/lib/cli/parsing/defineCustomParameters.js +1 -0
- package/lib/index.d.ts +1 -1
- package/lib/logic/InteractiveUpgrader.d.ts +0 -1
- package/lib/logic/PackageJsonUpdater.d.ts +2 -3
- package/lib/logic/operations/IPCOperationRunner.d.ts +2 -0
- package/lib/logic/operations/ShellOperationRunner.d.ts +2 -0
- package/lib/logic/operations/ShellOperationRunnerPlugin.d.ts +21 -0
- package/lib/logic/selectors/PathProjectSelectorParser.d.ts +11 -0
- package/lib/logic/selectors/PathProjectSelectorParser.js +1 -0
- package/lib/utilities/InteractiveUpgradeUI.d.ts +4 -5
- package/lib/utilities/objectUtilities.d.ts +0 -4
- package/lib-shim/index.js +4 -1021
- package/lib-shim/index.js.map +1 -1
- package/package.json +12 -11
- package/lib/logic/CredentialCache.d.ts +0 -40
- package/lib/logic/CredentialCache.js +0 -1
package/lib-shim/index.js
CHANGED
|
@@ -108,7 +108,7 @@ async function iterateAsync(basePath, filePath, segments) {
|
|
|
108
108
|
|
|
109
109
|
/***/ "../rush-lib/lib-esnext/api/RushGlobalFolder.js":
|
|
110
110
|
/*!******************************************************************!*\
|
|
111
|
-
!*** ../rush-lib/lib-esnext/api/RushGlobalFolder.js +
|
|
111
|
+
!*** ../rush-lib/lib-esnext/api/RushGlobalFolder.js + 2 modules ***!
|
|
112
112
|
\******************************************************************/
|
|
113
113
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
114
114
|
|
|
@@ -122,181 +122,10 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
122
122
|
|
|
123
123
|
// EXTERNAL MODULE: external "node:path"
|
|
124
124
|
var external_node_path_ = __webpack_require__("node:path");
|
|
125
|
-
;// external "node:child_process"
|
|
126
|
-
const external_node_child_process_namespaceObject = require("node:child_process");
|
|
127
|
-
;// external "node:os"
|
|
128
|
-
const external_node_os_namespaceObject = require("node:os");
|
|
129
|
-
;// external "node:perf_hooks"
|
|
130
|
-
const external_node_perf_hooks_namespaceObject = require("node:perf_hooks");
|
|
131
|
-
;// external "node:stream"
|
|
132
|
-
const external_node_stream_namespaceObject = require("node:stream");
|
|
133
125
|
// EXTERNAL MODULE: external "@rushstack/node-core-library"
|
|
134
126
|
var node_core_library_ = __webpack_require__("@rushstack/node-core-library");
|
|
135
|
-
;// external "node:
|
|
136
|
-
const
|
|
137
|
-
;// ../rush-lib/lib-esnext/utilities/npmrcUtilities.js
|
|
138
|
-
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
139
|
-
// See LICENSE in the project root for license information.
|
|
140
|
-
// IMPORTANT - do not use any non-built-in libraries in this file
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* This function reads the content for given .npmrc file path, and also trims
|
|
145
|
-
* unusable lines from the .npmrc file.
|
|
146
|
-
*
|
|
147
|
-
* @returns
|
|
148
|
-
* The text of the the .npmrc.
|
|
149
|
-
*/
|
|
150
|
-
// create a global _combinedNpmrc for cache purpose
|
|
151
|
-
const _combinedNpmrcMap = new Map();
|
|
152
|
-
function _trimNpmrcFile(options) {
|
|
153
|
-
const { sourceNpmrcPath, linesToPrepend, linesToAppend, supportEnvVarFallbackSyntax } = options;
|
|
154
|
-
const combinedNpmrcFromCache = _combinedNpmrcMap.get(sourceNpmrcPath);
|
|
155
|
-
if (combinedNpmrcFromCache !== undefined) {
|
|
156
|
-
return combinedNpmrcFromCache;
|
|
157
|
-
}
|
|
158
|
-
let npmrcFileLines = [];
|
|
159
|
-
if (linesToPrepend) {
|
|
160
|
-
npmrcFileLines.push(...linesToPrepend);
|
|
161
|
-
}
|
|
162
|
-
if (external_node_fs_namespaceObject.existsSync(sourceNpmrcPath)) {
|
|
163
|
-
npmrcFileLines.push(...external_node_fs_namespaceObject.readFileSync(sourceNpmrcPath).toString().split('\n'));
|
|
164
|
-
}
|
|
165
|
-
if (linesToAppend) {
|
|
166
|
-
npmrcFileLines.push(...linesToAppend);
|
|
167
|
-
}
|
|
168
|
-
npmrcFileLines = npmrcFileLines.map((line) => (line || '').trim());
|
|
169
|
-
const resultLines = trimNpmrcFileLines(npmrcFileLines, process.env, supportEnvVarFallbackSyntax);
|
|
170
|
-
const combinedNpmrc = resultLines.join('\n');
|
|
171
|
-
//save the cache
|
|
172
|
-
_combinedNpmrcMap.set(sourceNpmrcPath, combinedNpmrc);
|
|
173
|
-
return combinedNpmrc;
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
*
|
|
177
|
-
* @param npmrcFileLines The npmrc file's lines
|
|
178
|
-
* @param env The environment variables object
|
|
179
|
-
* @param supportEnvVarFallbackSyntax Whether to support fallback values in the form of `${VAR_NAME:-fallback}`
|
|
180
|
-
* @returns
|
|
181
|
-
*/
|
|
182
|
-
function trimNpmrcFileLines(npmrcFileLines, env, supportEnvVarFallbackSyntax) {
|
|
183
|
-
var _a;
|
|
184
|
-
const resultLines = [];
|
|
185
|
-
// This finds environment variable tokens that look like "${VAR_NAME}"
|
|
186
|
-
const expansionRegExp = /\$\{([^\}]+)\}/g;
|
|
187
|
-
// Comment lines start with "#" or ";"
|
|
188
|
-
const commentRegExp = /^\s*[#;]/;
|
|
189
|
-
// Trim out lines that reference environment variables that aren't defined
|
|
190
|
-
for (let line of npmrcFileLines) {
|
|
191
|
-
let lineShouldBeTrimmed = false;
|
|
192
|
-
//remove spaces before or after key and value
|
|
193
|
-
line = line
|
|
194
|
-
.split('=')
|
|
195
|
-
.map((lineToTrim) => lineToTrim.trim())
|
|
196
|
-
.join('=');
|
|
197
|
-
// Ignore comment lines
|
|
198
|
-
if (!commentRegExp.test(line)) {
|
|
199
|
-
const environmentVariables = line.match(expansionRegExp);
|
|
200
|
-
if (environmentVariables) {
|
|
201
|
-
for (const token of environmentVariables) {
|
|
202
|
-
/**
|
|
203
|
-
* Remove the leading "${" and the trailing "}" from the token
|
|
204
|
-
*
|
|
205
|
-
* ${nameString} -> nameString
|
|
206
|
-
* ${nameString-fallbackString} -> name-fallbackString
|
|
207
|
-
* ${nameString:-fallbackString} -> name:-fallbackString
|
|
208
|
-
*/
|
|
209
|
-
const nameWithFallback = token.substring(2, token.length - 1);
|
|
210
|
-
let environmentVariableName;
|
|
211
|
-
let fallback;
|
|
212
|
-
if (supportEnvVarFallbackSyntax) {
|
|
213
|
-
/**
|
|
214
|
-
* Get the environment variable name and fallback value.
|
|
215
|
-
*
|
|
216
|
-
* name fallback
|
|
217
|
-
* nameString -> nameString undefined
|
|
218
|
-
* nameString-fallbackString -> nameString fallbackString
|
|
219
|
-
* nameString:-fallbackString -> nameString fallbackString
|
|
220
|
-
*/
|
|
221
|
-
const matched = nameWithFallback.match(/^([^:-]+)(?:\:?-(.+))?$/);
|
|
222
|
-
// matched: [originStr, variableName, fallback]
|
|
223
|
-
environmentVariableName = (_a = matched === null || matched === void 0 ? void 0 : matched[1]) !== null && _a !== void 0 ? _a : nameWithFallback;
|
|
224
|
-
fallback = matched === null || matched === void 0 ? void 0 : matched[2];
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
environmentVariableName = nameWithFallback;
|
|
228
|
-
}
|
|
229
|
-
// Is the environment variable and fallback value defined.
|
|
230
|
-
if (!env[environmentVariableName] && !fallback) {
|
|
231
|
-
// No, so trim this line
|
|
232
|
-
lineShouldBeTrimmed = true;
|
|
233
|
-
break;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
if (lineShouldBeTrimmed) {
|
|
239
|
-
// Example output:
|
|
240
|
-
// "; MISSING ENVIRONMENT VARIABLE: //my-registry.com/npm/:_authToken=${MY_AUTH_TOKEN}"
|
|
241
|
-
resultLines.push('; MISSING ENVIRONMENT VARIABLE: ' + line);
|
|
242
|
-
}
|
|
243
|
-
else {
|
|
244
|
-
resultLines.push(line);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
return resultLines;
|
|
248
|
-
}
|
|
249
|
-
function _copyAndTrimNpmrcFile(options) {
|
|
250
|
-
const { logger, sourceNpmrcPath, targetNpmrcPath } = options;
|
|
251
|
-
logger.info(`Transforming ${sourceNpmrcPath}`); // Verbose
|
|
252
|
-
logger.info(` --> "${targetNpmrcPath}"`);
|
|
253
|
-
const combinedNpmrc = _trimNpmrcFile(options);
|
|
254
|
-
external_node_fs_namespaceObject.writeFileSync(targetNpmrcPath, combinedNpmrc);
|
|
255
|
-
return combinedNpmrc;
|
|
256
|
-
}
|
|
257
|
-
function syncNpmrc(options) {
|
|
258
|
-
const { sourceNpmrcFolder, targetNpmrcFolder, useNpmrcPublish, logger = {
|
|
259
|
-
// eslint-disable-next-line no-console
|
|
260
|
-
info: console.log,
|
|
261
|
-
// eslint-disable-next-line no-console
|
|
262
|
-
error: console.error
|
|
263
|
-
}, createIfMissing = false } = options;
|
|
264
|
-
const sourceNpmrcPath = external_node_path_.join(sourceNpmrcFolder, !useNpmrcPublish ? '.npmrc' : '.npmrc-publish');
|
|
265
|
-
const targetNpmrcPath = external_node_path_.join(targetNpmrcFolder, '.npmrc');
|
|
266
|
-
try {
|
|
267
|
-
if (external_node_fs_namespaceObject.existsSync(sourceNpmrcPath) || createIfMissing) {
|
|
268
|
-
// Ensure the target folder exists
|
|
269
|
-
if (!external_node_fs_namespaceObject.existsSync(targetNpmrcFolder)) {
|
|
270
|
-
external_node_fs_namespaceObject.mkdirSync(targetNpmrcFolder, { recursive: true });
|
|
271
|
-
}
|
|
272
|
-
return _copyAndTrimNpmrcFile({
|
|
273
|
-
sourceNpmrcPath,
|
|
274
|
-
targetNpmrcPath,
|
|
275
|
-
logger,
|
|
276
|
-
...options
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
else if (external_node_fs_namespaceObject.existsSync(targetNpmrcPath)) {
|
|
280
|
-
// If the source .npmrc doesn't exist and there is one in the target, delete the one in the target
|
|
281
|
-
logger.info(`Deleting ${targetNpmrcPath}`); // Verbose
|
|
282
|
-
external_node_fs_namespaceObject.unlinkSync(targetNpmrcPath);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
catch (e) {
|
|
286
|
-
throw new Error(`Error syncing .npmrc file: ${e}`);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
function isVariableSetInNpmrcFile(sourceNpmrcFolder, variableKey, supportEnvVarFallbackSyntax) {
|
|
290
|
-
const sourceNpmrcPath = `${sourceNpmrcFolder}/.npmrc`;
|
|
291
|
-
//if .npmrc file does not exist, return false directly
|
|
292
|
-
if (!fs.existsSync(sourceNpmrcPath)) {
|
|
293
|
-
return false;
|
|
294
|
-
}
|
|
295
|
-
const trimmedNpmrcFile = _trimNpmrcFile({ sourceNpmrcPath, supportEnvVarFallbackSyntax });
|
|
296
|
-
const variableKeyRegExp = new RegExp(`^${variableKey}=`, 'm');
|
|
297
|
-
return trimmedNpmrcFile.match(variableKeyRegExp) !== null;
|
|
298
|
-
}
|
|
299
|
-
//# sourceMappingURL=npmrcUtilities.js.map
|
|
127
|
+
;// external "node:os"
|
|
128
|
+
const external_node_os_namespaceObject = require("node:os");
|
|
300
129
|
// EXTERNAL MODULE: ../../common/temp/default/node_modules/.pnpm/true-case-path@2.2.1/node_modules/true-case-path/index.js
|
|
301
130
|
var true_case_path = __webpack_require__("../../common/temp/default/node_modules/.pnpm/true-case-path@2.2.1/node_modules/true-case-path/index.js");
|
|
302
131
|
;// ../rush-lib/lib-esnext/api/EnvironmentConfiguration.js
|
|
@@ -891,852 +720,6 @@ EnvironmentConfiguration._absoluteSymlinks = false;
|
|
|
891
720
|
EnvironmentConfiguration._allowUnsupportedNodeVersion = false;
|
|
892
721
|
EnvironmentConfiguration._allowWarningsInSuccessfulBuild = false;
|
|
893
722
|
//# sourceMappingURL=EnvironmentConfiguration.js.map
|
|
894
|
-
;// ../rush-lib/lib-esnext/logic/RushConstants.js
|
|
895
|
-
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
896
|
-
// See LICENSE in the project root for license information.
|
|
897
|
-
/**
|
|
898
|
-
* Constants used by the Rush tool.
|
|
899
|
-
* @beta
|
|
900
|
-
*
|
|
901
|
-
* @remarks
|
|
902
|
-
*
|
|
903
|
-
* These are NOT part of the public API surface for rush-lib.
|
|
904
|
-
* The rationale is that we don't want people implementing custom parsers for
|
|
905
|
-
* the Rush config files; instead, they should rely on the official APIs from rush-lib.
|
|
906
|
-
*/
|
|
907
|
-
class RushConstants {
|
|
908
|
-
}
|
|
909
|
-
/**
|
|
910
|
-
* The filename ("rush.json") for the root-level configuration file.
|
|
911
|
-
*/
|
|
912
|
-
RushConstants.rushJsonFilename = 'rush.json';
|
|
913
|
-
/**
|
|
914
|
-
* The filename ("browser-approved-packages.json") for an optional policy configuration file
|
|
915
|
-
* that stores a list of NPM packages that have been approved for usage by Rush projects.
|
|
916
|
-
* This is part of a pair of config files, one for projects that run in a web browser
|
|
917
|
-
* (e.g. whose approval criteria mostly focuses on licensing and code size), and one for everywhere else
|
|
918
|
-
* (e.g. tooling projects whose approval criteria mostly focuses on avoiding node_modules sprawl).
|
|
919
|
-
*/
|
|
920
|
-
RushConstants.browserApprovedPackagesFilename = 'browser-approved-packages.json';
|
|
921
|
-
/**
|
|
922
|
-
* The folder name ("changes") where change files will be stored.
|
|
923
|
-
*/
|
|
924
|
-
RushConstants.changeFilesFolderName = 'changes';
|
|
925
|
-
/**
|
|
926
|
-
* The filename ("nonbrowser-approved-packages.json") for an optional policy configuration file
|
|
927
|
-
* that stores a list of NPM packages that have been approved for usage by Rush projects.
|
|
928
|
-
* This is part of a pair of config files, one for projects that run in a web browser
|
|
929
|
-
* (e.g. whose approval criteria mostly focuses on licensing and code size), and one for everywhere else
|
|
930
|
-
* (e.g. tooling projects whose approval criteria mostly focuses on avoiding node_modules sprawl).
|
|
931
|
-
*/
|
|
932
|
-
RushConstants.nonbrowserApprovedPackagesFilename = 'nonbrowser-approved-packages.json';
|
|
933
|
-
/**
|
|
934
|
-
* The folder name ("common") where Rush's common data will be stored.
|
|
935
|
-
*/
|
|
936
|
-
RushConstants.commonFolderName = 'common';
|
|
937
|
-
/**
|
|
938
|
-
* The NPM scope ("\@rush-temp") that is used for Rush's temporary projects.
|
|
939
|
-
*/
|
|
940
|
-
RushConstants.rushTempNpmScope = '@rush-temp';
|
|
941
|
-
/**
|
|
942
|
-
* The folder name ("variants") under which named variant configurations for
|
|
943
|
-
* alternate dependency sets may be found.
|
|
944
|
-
* Example: `C:\MyRepo\common\config\rush\variants`
|
|
945
|
-
*/
|
|
946
|
-
RushConstants.rushVariantsFolderName = 'variants';
|
|
947
|
-
/**
|
|
948
|
-
* The folder name ("temp") under the common folder, or under the .rush folder in each project's directory where
|
|
949
|
-
* temporary files will be stored.
|
|
950
|
-
* Example: `C:\MyRepo\common\temp`
|
|
951
|
-
*/
|
|
952
|
-
RushConstants.rushTempFolderName = 'temp';
|
|
953
|
-
/**
|
|
954
|
-
* The folder name ("projects") where temporary projects will be stored.
|
|
955
|
-
* Example: `C:\MyRepo\common\temp\projects`
|
|
956
|
-
*/
|
|
957
|
-
RushConstants.rushTempProjectsFolderName = 'projects';
|
|
958
|
-
/**
|
|
959
|
-
* The filename ("npm-shrinkwrap.json") used to store an installation plan for the NPM package manger.
|
|
960
|
-
*/
|
|
961
|
-
RushConstants.npmShrinkwrapFilename = 'npm-shrinkwrap.json';
|
|
962
|
-
/**
|
|
963
|
-
* Number of installation attempts
|
|
964
|
-
*/
|
|
965
|
-
RushConstants.defaultMaxInstallAttempts = 1;
|
|
966
|
-
/**
|
|
967
|
-
* The filename ("pnpm-lock.yaml") used to store an installation plan for the PNPM package manger
|
|
968
|
-
* (PNPM version 3.x and later).
|
|
969
|
-
*/
|
|
970
|
-
RushConstants.pnpmV3ShrinkwrapFilename = 'pnpm-lock.yaml';
|
|
971
|
-
/**
|
|
972
|
-
* The filename ("pnpmfile.js") used to add custom configuration to PNPM (PNPM version 1.x and later).
|
|
973
|
-
*/
|
|
974
|
-
RushConstants.pnpmfileV1Filename = 'pnpmfile.js';
|
|
975
|
-
/**
|
|
976
|
-
* The filename (".pnpmfile.cjs") used to add custom configuration to PNPM (PNPM version 6.x and later).
|
|
977
|
-
*/
|
|
978
|
-
RushConstants.pnpmfileV6Filename = '.pnpmfile.cjs';
|
|
979
|
-
/**
|
|
980
|
-
* The filename (".modules.yaml") used by pnpm to specify configurations in the node_modules directory
|
|
981
|
-
*/
|
|
982
|
-
RushConstants.pnpmModulesFilename = '.modules.yaml';
|
|
983
|
-
/**
|
|
984
|
-
* The folder name (".pnpm") used by pnpm to store the code of the dependencies for this subspace
|
|
985
|
-
*/
|
|
986
|
-
RushConstants.pnpmVirtualStoreFolderName = '.pnpm';
|
|
987
|
-
/**
|
|
988
|
-
* The filename ("global-pnpmfile.cjs") used to add custom configuration to subspaces
|
|
989
|
-
*/
|
|
990
|
-
RushConstants.pnpmfileGlobalFilename = 'global-pnpmfile.cjs';
|
|
991
|
-
/**
|
|
992
|
-
* The folder name used to store patch files for pnpm
|
|
993
|
-
* Example: `C:\MyRepo\common\config\pnpm-patches`
|
|
994
|
-
* Example: `C:\MyRepo\common\temp\patches`
|
|
995
|
-
*/
|
|
996
|
-
RushConstants.pnpmPatchesFolderName = 'patches';
|
|
997
|
-
/**
|
|
998
|
-
* The folder name under `/common/temp` used to store checked-in patches.
|
|
999
|
-
* Example: `C:\MyRepo\common\pnpm-patches`
|
|
1000
|
-
*/
|
|
1001
|
-
RushConstants.pnpmPatchesCommonFolderName = `pnpm-${RushConstants.pnpmPatchesFolderName}`;
|
|
1002
|
-
/**
|
|
1003
|
-
* The filename ("shrinkwrap.yaml") used to store state for pnpm
|
|
1004
|
-
*/
|
|
1005
|
-
RushConstants.yarnShrinkwrapFilename = 'yarn.lock';
|
|
1006
|
-
/**
|
|
1007
|
-
* The folder name ("node_modules") where NPM installs its packages.
|
|
1008
|
-
*/
|
|
1009
|
-
RushConstants.nodeModulesFolderName = 'node_modules';
|
|
1010
|
-
/**
|
|
1011
|
-
* The filename ("pinned-versions.json") for an old configuration file that
|
|
1012
|
-
* that is no longer supported.
|
|
1013
|
-
*
|
|
1014
|
-
* @deprecated This feature has been superseded by the "preferredVersions" setting
|
|
1015
|
-
* in common-versions.json
|
|
1016
|
-
*/
|
|
1017
|
-
// NOTE: Although this is marked as "deprecated", we will probably never retire it,
|
|
1018
|
-
// since we always want to report the warning when someone upgrades an old repo.
|
|
1019
|
-
RushConstants.pinnedVersionsFilename = 'pinned-versions.json';
|
|
1020
|
-
/**
|
|
1021
|
-
* The filename ("common-versions.json") for an optional configuration file
|
|
1022
|
-
* that stores dependency version information that affects all projects in the repo.
|
|
1023
|
-
* This configuration file should go in the "common/config/rush" folder.
|
|
1024
|
-
*/
|
|
1025
|
-
RushConstants.commonVersionsFilename = 'common-versions.json';
|
|
1026
|
-
/**
|
|
1027
|
-
* The filename ("repo-state.json") for a file used by Rush to
|
|
1028
|
-
* store the state of various features as they stand in the repo.
|
|
1029
|
-
*/
|
|
1030
|
-
RushConstants.repoStateFilename = 'repo-state.json';
|
|
1031
|
-
/**
|
|
1032
|
-
* The filename ("custom-tips.json") for the file used by Rush to
|
|
1033
|
-
* print user-customized messages.
|
|
1034
|
-
* This configuration file should go in the "common/config/rush" folder.
|
|
1035
|
-
*/
|
|
1036
|
-
RushConstants.customTipsFilename = 'custom-tips.json';
|
|
1037
|
-
/**
|
|
1038
|
-
* The name of the per-project folder where project-specific Rush files are stored. For example,
|
|
1039
|
-
* the package-deps files, which are used by commands to determine if a particular project needs to be rebuilt.
|
|
1040
|
-
*/
|
|
1041
|
-
RushConstants.projectRushFolderName = '.rush';
|
|
1042
|
-
/**
|
|
1043
|
-
* Custom command line configuration file, which is used by rush for implementing
|
|
1044
|
-
* custom command and options.
|
|
1045
|
-
*/
|
|
1046
|
-
RushConstants.commandLineFilename = 'command-line.json';
|
|
1047
|
-
RushConstants.versionPoliciesFilename = 'version-policies.json';
|
|
1048
|
-
/**
|
|
1049
|
-
* Experiments configuration file.
|
|
1050
|
-
*/
|
|
1051
|
-
RushConstants.experimentsFilename = 'experiments.json';
|
|
1052
|
-
/**
|
|
1053
|
-
* Pnpm configuration file
|
|
1054
|
-
*/
|
|
1055
|
-
RushConstants.pnpmConfigFilename = 'pnpm-config.json';
|
|
1056
|
-
/**
|
|
1057
|
-
* Rush plugins configuration file name.
|
|
1058
|
-
*/
|
|
1059
|
-
RushConstants.rushPluginsConfigFilename = 'rush-plugins.json';
|
|
1060
|
-
/**
|
|
1061
|
-
* Rush plugin manifest file name.
|
|
1062
|
-
*/
|
|
1063
|
-
RushConstants.rushPluginManifestFilename = 'rush-plugin-manifest.json';
|
|
1064
|
-
/**
|
|
1065
|
-
* The artifactory.json configuration file name.
|
|
1066
|
-
*/
|
|
1067
|
-
RushConstants.artifactoryFilename = 'artifactory.json';
|
|
1068
|
-
/**
|
|
1069
|
-
* The subspaces.json configuration file name
|
|
1070
|
-
*/
|
|
1071
|
-
RushConstants.subspacesConfigFilename = 'subspaces.json';
|
|
1072
|
-
/**
|
|
1073
|
-
* The name of the default subspace if one isn't specified but subspaces is enabled.
|
|
1074
|
-
*/
|
|
1075
|
-
RushConstants.defaultSubspaceName = 'default';
|
|
1076
|
-
/**
|
|
1077
|
-
* Build cache configuration file.
|
|
1078
|
-
*/
|
|
1079
|
-
RushConstants.buildCacheFilename = 'build-cache.json';
|
|
1080
|
-
/**
|
|
1081
|
-
* Build cache version number, incremented when the logic to create cache entries changes.
|
|
1082
|
-
* Changing this ensures that cache entries generated by an old version will no longer register as a cache hit.
|
|
1083
|
-
*/
|
|
1084
|
-
RushConstants.buildCacheVersion = 1;
|
|
1085
|
-
/**
|
|
1086
|
-
* Cobuild configuration file.
|
|
1087
|
-
*/
|
|
1088
|
-
RushConstants.cobuildFilename = 'cobuild.json';
|
|
1089
|
-
/**
|
|
1090
|
-
* Per-project configuration filename.
|
|
1091
|
-
*/
|
|
1092
|
-
RushConstants.rushProjectConfigFilename = 'rush-project.json';
|
|
1093
|
-
/**
|
|
1094
|
-
* The URL ("http://rushjs.io") for the Rush web site.
|
|
1095
|
-
*/
|
|
1096
|
-
RushConstants.rushWebSiteUrl = 'https://rushjs.io';
|
|
1097
|
-
/**
|
|
1098
|
-
* The name of the NPM package for the Rush tool ("\@microsoft/rush").
|
|
1099
|
-
*/
|
|
1100
|
-
RushConstants.rushPackageName = '@microsoft/rush';
|
|
1101
|
-
/**
|
|
1102
|
-
* The folder name ("rush-recycler") where Rush moves large folder trees
|
|
1103
|
-
* before asynchronously deleting them.
|
|
1104
|
-
*/
|
|
1105
|
-
RushConstants.rushRecyclerFolderName = 'rush-recycler';
|
|
1106
|
-
/**
|
|
1107
|
-
* The name of the file to drop in project-folder/.rush/temp/ containing a listing of the project's direct
|
|
1108
|
-
* and indirect dependencies. This is used to detect if a project's dependencies have changed since the last build.
|
|
1109
|
-
*/
|
|
1110
|
-
RushConstants.projectShrinkwrapFilename = 'shrinkwrap-deps.json';
|
|
1111
|
-
/**
|
|
1112
|
-
* The value of the "commandKind" property for a bulk command in command-line.json
|
|
1113
|
-
*/
|
|
1114
|
-
RushConstants.bulkCommandKind = 'bulk';
|
|
1115
|
-
/**
|
|
1116
|
-
* The value of the "commandKind" property for a global command in command-line.json
|
|
1117
|
-
*/
|
|
1118
|
-
RushConstants.globalCommandKind = 'global';
|
|
1119
|
-
/**
|
|
1120
|
-
* The value of the "commandKind" property for a phased command in command-line.json
|
|
1121
|
-
*/
|
|
1122
|
-
RushConstants.phasedCommandKind = 'phased';
|
|
1123
|
-
/**
|
|
1124
|
-
* The name of the incremental build command.
|
|
1125
|
-
*/
|
|
1126
|
-
RushConstants.buildCommandName = 'build';
|
|
1127
|
-
/**
|
|
1128
|
-
* The name of the non-incremental build command.
|
|
1129
|
-
*/
|
|
1130
|
-
RushConstants.rebuildCommandName = 'rebuild';
|
|
1131
|
-
RushConstants.updateCloudCredentialsCommandName = 'update-cloud-credentials';
|
|
1132
|
-
/**
|
|
1133
|
-
* When a hash generated that contains multiple input segments, this character may be used
|
|
1134
|
-
* to separate them to avoid issues like
|
|
1135
|
-
* crypto.createHash('sha1').update('a').update('bc').digest('hex') === crypto.createHash('sha1').update('ab').update('c').digest('hex')
|
|
1136
|
-
*/
|
|
1137
|
-
RushConstants.hashDelimiter = '|';
|
|
1138
|
-
/**
|
|
1139
|
-
* The name of the per-user Rush configuration data folder.
|
|
1140
|
-
*/
|
|
1141
|
-
RushConstants.rushUserConfigurationFolderName = '.rush-user';
|
|
1142
|
-
/**
|
|
1143
|
-
* The name of the project `rush-logs` folder.
|
|
1144
|
-
*/
|
|
1145
|
-
RushConstants.rushLogsFolderName = 'rush-logs';
|
|
1146
|
-
/**
|
|
1147
|
-
* The expected prefix for phase names in "common/config/rush/command-line.json"
|
|
1148
|
-
*/
|
|
1149
|
-
RushConstants.phaseNamePrefix = '_phase:';
|
|
1150
|
-
/**
|
|
1151
|
-
* The default debounce value for Rush multi-project watch mode. When watching, controls
|
|
1152
|
-
* how long to wait after the last encountered file system event before execution. If another
|
|
1153
|
-
* file system event occurs in this interval, the timeout will reset.
|
|
1154
|
-
*/
|
|
1155
|
-
RushConstants.defaultWatchDebounceMs = 1000;
|
|
1156
|
-
/**
|
|
1157
|
-
* The name of the parameter that can be used to bypass policies.
|
|
1158
|
-
*/
|
|
1159
|
-
RushConstants.bypassPolicyFlagLongName = '--bypass-policy';
|
|
1160
|
-
/**
|
|
1161
|
-
* Merge Queue ignore configuration file.
|
|
1162
|
-
*/
|
|
1163
|
-
RushConstants.mergeQueueIgnoreFileName = '.mergequeueignore';
|
|
1164
|
-
/**
|
|
1165
|
-
* The filename ("project-impact-graph.yaml") for the project impact graph file.
|
|
1166
|
-
*/
|
|
1167
|
-
RushConstants.projectImpactGraphFilename = 'project-impact-graph.yaml';
|
|
1168
|
-
/**
|
|
1169
|
-
* The filename for the last link flag
|
|
1170
|
-
*/
|
|
1171
|
-
RushConstants.lastLinkFlagFilename = 'last-link';
|
|
1172
|
-
/**
|
|
1173
|
-
* The filename for the Rush alerts config file.
|
|
1174
|
-
*/
|
|
1175
|
-
RushConstants.rushAlertsConfigFilename = 'rush-alerts.json';
|
|
1176
|
-
/**
|
|
1177
|
-
* The filename for the file that tracks which variant is currently installed.
|
|
1178
|
-
*/
|
|
1179
|
-
RushConstants.currentVariantsFilename = 'current-variants.json';
|
|
1180
|
-
/**
|
|
1181
|
-
* The filename ("rush-hotlink-state.json") used to store information about packages connected via
|
|
1182
|
-
* "rush link-package" and "rush bridge-package" commands.
|
|
1183
|
-
*/
|
|
1184
|
-
RushConstants.rushHotlinkStateFilename = 'rush-hotlink-state.json';
|
|
1185
|
-
/**
|
|
1186
|
-
* The filename ("pnpm-sync.json") used to store the state of the pnpm sync command.
|
|
1187
|
-
*/
|
|
1188
|
-
RushConstants.pnpmSyncFilename = '.pnpm-sync.json';
|
|
1189
|
-
//# sourceMappingURL=RushConstants.js.map
|
|
1190
|
-
;// ../rush-lib/lib-esnext/utilities/Utilities.js
|
|
1191
|
-
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
1192
|
-
// See LICENSE in the project root for license information.
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
1203
|
-
const UNINITIALIZED = 'UNINITIALIZED';
|
|
1204
|
-
class Utilities {
|
|
1205
|
-
/**
|
|
1206
|
-
* Get the user's home directory. On windows this looks something like "C:\users\username\" and on UNIX
|
|
1207
|
-
* this looks something like "/home/username/"
|
|
1208
|
-
*/
|
|
1209
|
-
static getHomeFolder() {
|
|
1210
|
-
let homeFolder = Utilities._homeFolder;
|
|
1211
|
-
if (!homeFolder) {
|
|
1212
|
-
const unresolvedUserFolder = process.env[process.platform === 'win32' ? 'USERPROFILE' : 'HOME'];
|
|
1213
|
-
const dirError = "Unable to determine the current user's home directory";
|
|
1214
|
-
if (unresolvedUserFolder === undefined) {
|
|
1215
|
-
throw new Error(dirError);
|
|
1216
|
-
}
|
|
1217
|
-
homeFolder = external_node_path_.resolve(unresolvedUserFolder);
|
|
1218
|
-
if (!node_core_library_.FileSystem.exists(homeFolder)) {
|
|
1219
|
-
throw new Error(dirError);
|
|
1220
|
-
}
|
|
1221
|
-
Utilities._homeFolder = homeFolder;
|
|
1222
|
-
}
|
|
1223
|
-
return homeFolder;
|
|
1224
|
-
}
|
|
1225
|
-
/**
|
|
1226
|
-
* Node.js equivalent of performance.now().
|
|
1227
|
-
*/
|
|
1228
|
-
static getTimeInMs() {
|
|
1229
|
-
return external_node_perf_hooks_namespaceObject.performance.now();
|
|
1230
|
-
}
|
|
1231
|
-
/**
|
|
1232
|
-
* Retries a function until a timeout is reached. The function is expected to throw if it failed and
|
|
1233
|
-
* should be retried.
|
|
1234
|
-
*/
|
|
1235
|
-
static retryUntilTimeout(fn, maxWaitTimeMs, getTimeoutError, fnName) {
|
|
1236
|
-
const startTime = Utilities.getTimeInMs();
|
|
1237
|
-
let looped = false;
|
|
1238
|
-
let result;
|
|
1239
|
-
for (;;) {
|
|
1240
|
-
try {
|
|
1241
|
-
result = fn();
|
|
1242
|
-
break;
|
|
1243
|
-
}
|
|
1244
|
-
catch (e) {
|
|
1245
|
-
looped = true;
|
|
1246
|
-
const currentTime = Utilities.getTimeInMs();
|
|
1247
|
-
if (currentTime - startTime > maxWaitTimeMs) {
|
|
1248
|
-
throw getTimeoutError(e);
|
|
1249
|
-
}
|
|
1250
|
-
}
|
|
1251
|
-
}
|
|
1252
|
-
if (looped) {
|
|
1253
|
-
const currentTime = Utilities.getTimeInMs();
|
|
1254
|
-
const totalSeconds = ((currentTime - startTime) / 1000.0).toFixed(2);
|
|
1255
|
-
// This logging statement isn't meaningful to the end-user. `fnName` should be updated
|
|
1256
|
-
// to something like `operationDescription`
|
|
1257
|
-
// eslint-disable-next-line no-console
|
|
1258
|
-
console.log(`${fnName}() stalled for ${totalSeconds} seconds`);
|
|
1259
|
-
}
|
|
1260
|
-
return result;
|
|
1261
|
-
}
|
|
1262
|
-
/**
|
|
1263
|
-
* Creates the specified folder by calling FileSystem.ensureFolder(), but using a
|
|
1264
|
-
* retry loop to recover from temporary locks that may be held by other processes.
|
|
1265
|
-
* If the folder already exists, no error occurs.
|
|
1266
|
-
*/
|
|
1267
|
-
static createFolderWithRetry(folderName) {
|
|
1268
|
-
// Note: If a file exists with the same name, then we fall through and report
|
|
1269
|
-
// an error.
|
|
1270
|
-
if (Utilities.directoryExists(folderName)) {
|
|
1271
|
-
return;
|
|
1272
|
-
}
|
|
1273
|
-
// We need to do a simple "FileSystem.ensureFolder(localModulesFolder)" here,
|
|
1274
|
-
// however if the folder we deleted above happened to contain any files,
|
|
1275
|
-
// then there seems to be some OS process (virus scanner?) that holds
|
|
1276
|
-
// a lock on the folder for a split second, which causes mkdirSync to
|
|
1277
|
-
// fail. To workaround that, retry for up to 7 seconds before giving up.
|
|
1278
|
-
const maxWaitTimeMs = 7 * 1000;
|
|
1279
|
-
return Utilities.retryUntilTimeout(() => node_core_library_.FileSystem.ensureFolder(folderName), maxWaitTimeMs, (e) => new Error(`Error: ${e}\nOften this is caused by a file lock ` +
|
|
1280
|
-
'from a process such as your text editor, command prompt, ' +
|
|
1281
|
-
'or a filesystem watcher.'), 'createFolderWithRetry');
|
|
1282
|
-
}
|
|
1283
|
-
/**
|
|
1284
|
-
* Determines if a path points to a directory and that it exists.
|
|
1285
|
-
*/
|
|
1286
|
-
static directoryExists(directoryPath) {
|
|
1287
|
-
let exists = false;
|
|
1288
|
-
try {
|
|
1289
|
-
const lstat = node_core_library_.FileSystem.getLinkStatistics(directoryPath);
|
|
1290
|
-
exists = lstat.isDirectory();
|
|
1291
|
-
}
|
|
1292
|
-
catch (e) {
|
|
1293
|
-
/* no-op */
|
|
1294
|
-
}
|
|
1295
|
-
return exists;
|
|
1296
|
-
}
|
|
1297
|
-
/**
|
|
1298
|
-
* BE VERY CAREFUL CALLING THIS FUNCTION!
|
|
1299
|
-
* If you specify the wrong folderPath (e.g. "/"), it could potentially delete your entire
|
|
1300
|
-
* hard disk.
|
|
1301
|
-
*/
|
|
1302
|
-
static dangerouslyDeletePath(folderPath) {
|
|
1303
|
-
try {
|
|
1304
|
-
node_core_library_.FileSystem.deleteFolder(folderPath);
|
|
1305
|
-
}
|
|
1306
|
-
catch (e) {
|
|
1307
|
-
throw new Error(`${e.message}\nOften this is caused by a file lock from a process ` +
|
|
1308
|
-
'such as your text editor, command prompt, or a filesystem watcher');
|
|
1309
|
-
}
|
|
1310
|
-
}
|
|
1311
|
-
/*
|
|
1312
|
-
* Returns true if dateToCompare is more recent than all of the inputFilenames, which
|
|
1313
|
-
* would imply that we don't need to rebuild it. Returns false if any of the files
|
|
1314
|
-
* does not exist.
|
|
1315
|
-
* NOTE: The filenames can also be paths for directories, in which case the directory
|
|
1316
|
-
* timestamp is compared.
|
|
1317
|
-
*/
|
|
1318
|
-
static async isFileTimestampCurrentAsync(dateToCompare, inputFilePaths) {
|
|
1319
|
-
let anyAreOutOfDate = false;
|
|
1320
|
-
await node_core_library_.Async.forEachAsync(inputFilePaths, async (filePath) => {
|
|
1321
|
-
if (!anyAreOutOfDate) {
|
|
1322
|
-
let inputStats;
|
|
1323
|
-
try {
|
|
1324
|
-
inputStats = await node_core_library_.FileSystem.getStatisticsAsync(filePath);
|
|
1325
|
-
}
|
|
1326
|
-
catch (e) {
|
|
1327
|
-
if (node_core_library_.FileSystem.isNotExistError(e)) {
|
|
1328
|
-
// eslint-disable-next-line require-atomic-updates
|
|
1329
|
-
anyAreOutOfDate = true;
|
|
1330
|
-
}
|
|
1331
|
-
else {
|
|
1332
|
-
throw e;
|
|
1333
|
-
}
|
|
1334
|
-
}
|
|
1335
|
-
if (inputStats && dateToCompare < inputStats.mtime) {
|
|
1336
|
-
// eslint-disable-next-line require-atomic-updates
|
|
1337
|
-
anyAreOutOfDate = true;
|
|
1338
|
-
}
|
|
1339
|
-
}
|
|
1340
|
-
}, { concurrency: 10 });
|
|
1341
|
-
return !anyAreOutOfDate;
|
|
1342
|
-
}
|
|
1343
|
-
/**
|
|
1344
|
-
* Executes the command with the specified command-line parameters, and waits for it to complete.
|
|
1345
|
-
* The current directory will be set to the specified workingDirectory.
|
|
1346
|
-
*/
|
|
1347
|
-
static async executeCommandAsync({ command, args, workingDirectory, suppressOutput, onStdoutStreamChunk, environment, keepEnvironment, captureExitCodeAndSignal }) {
|
|
1348
|
-
const { exitCode, signal } = await Utilities._executeCommandInternalAsync({
|
|
1349
|
-
command,
|
|
1350
|
-
args,
|
|
1351
|
-
workingDirectory,
|
|
1352
|
-
stdio: onStdoutStreamChunk
|
|
1353
|
-
? // Inherit the stdin and stderr streams, but pipe the stdout stream, which will then be piped
|
|
1354
|
-
// to the process's stdout after being intercepted by the onStdoutStreamChunk callback.
|
|
1355
|
-
['inherit', 'pipe', 'inherit']
|
|
1356
|
-
: suppressOutput
|
|
1357
|
-
? // If the output is being suppressed, create pipes for all streams to prevent the child process
|
|
1358
|
-
// from printing to the parent process's (this process's) stdout/stderr, but allow the stdout and
|
|
1359
|
-
// stderr to be inspected if an error occurs.
|
|
1360
|
-
// TODO: Consider ignoring stdout and stdin and only piping stderr for inspection on error.
|
|
1361
|
-
['pipe', 'pipe', 'pipe']
|
|
1362
|
-
: // If the output is not being suppressed or intercepted, inherit all streams from the parent process.
|
|
1363
|
-
['inherit', 'inherit', 'inherit'],
|
|
1364
|
-
environment,
|
|
1365
|
-
keepEnvironment,
|
|
1366
|
-
onStdoutStreamChunk,
|
|
1367
|
-
captureOutput: false,
|
|
1368
|
-
captureExitCodeAndSignal
|
|
1369
|
-
});
|
|
1370
|
-
if (captureExitCodeAndSignal) {
|
|
1371
|
-
return { exitCode, signal };
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
/**
|
|
1375
|
-
* Executes the command with the specified command-line parameters, and waits for it to complete.
|
|
1376
|
-
* The current directory will be set to the specified workingDirectory.
|
|
1377
|
-
*/
|
|
1378
|
-
static async executeCommandAndCaptureOutputAsync(command, args, workingDirectory, environment, keepEnvironment = false) {
|
|
1379
|
-
const { stdout } = await Utilities._executeCommandInternalAsync({
|
|
1380
|
-
command,
|
|
1381
|
-
args,
|
|
1382
|
-
workingDirectory,
|
|
1383
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
1384
|
-
environment,
|
|
1385
|
-
keepEnvironment,
|
|
1386
|
-
captureOutput: true
|
|
1387
|
-
});
|
|
1388
|
-
return stdout;
|
|
1389
|
-
}
|
|
1390
|
-
/**
|
|
1391
|
-
* Attempts to run Utilities.executeCommand() up to maxAttempts times before giving up.
|
|
1392
|
-
*/
|
|
1393
|
-
static async executeCommandWithRetryAsync(options, maxAttempts, retryCallback) {
|
|
1394
|
-
if (maxAttempts < 1) {
|
|
1395
|
-
throw new Error('The maxAttempts parameter cannot be less than 1');
|
|
1396
|
-
}
|
|
1397
|
-
let attemptNumber = 1;
|
|
1398
|
-
for (;;) {
|
|
1399
|
-
try {
|
|
1400
|
-
await Utilities.executeCommandAsync(options);
|
|
1401
|
-
}
|
|
1402
|
-
catch (error) {
|
|
1403
|
-
// eslint-disable-next-line no-console
|
|
1404
|
-
console.log('\nThe command failed:');
|
|
1405
|
-
const { command, args } = options;
|
|
1406
|
-
// eslint-disable-next-line no-console
|
|
1407
|
-
console.log(` ${command} ` + args.join(' '));
|
|
1408
|
-
// eslint-disable-next-line no-console
|
|
1409
|
-
console.log(`ERROR: ${error.toString()}`);
|
|
1410
|
-
if (attemptNumber < maxAttempts) {
|
|
1411
|
-
++attemptNumber;
|
|
1412
|
-
// eslint-disable-next-line no-console
|
|
1413
|
-
console.log(`Trying again (attempt #${attemptNumber})...\n`);
|
|
1414
|
-
if (retryCallback) {
|
|
1415
|
-
retryCallback();
|
|
1416
|
-
}
|
|
1417
|
-
continue;
|
|
1418
|
-
}
|
|
1419
|
-
else {
|
|
1420
|
-
// eslint-disable-next-line no-console
|
|
1421
|
-
console.error(`Giving up after ${attemptNumber} attempts\n`);
|
|
1422
|
-
throw error;
|
|
1423
|
-
}
|
|
1424
|
-
}
|
|
1425
|
-
break;
|
|
1426
|
-
}
|
|
1427
|
-
}
|
|
1428
|
-
/**
|
|
1429
|
-
* Executes the command using cmd if running on windows, or using sh if running on a non-windows OS.
|
|
1430
|
-
* @param command - the command to run on shell
|
|
1431
|
-
* @param options - options for how the command should be run
|
|
1432
|
-
*/
|
|
1433
|
-
static executeLifecycleCommand(command, options) {
|
|
1434
|
-
const result = Utilities._executeLifecycleCommandInternal(command, external_node_child_process_namespaceObject.spawnSync, options);
|
|
1435
|
-
if (options.handleOutput) {
|
|
1436
|
-
Utilities._processResult({
|
|
1437
|
-
error: result.error,
|
|
1438
|
-
status: result.status,
|
|
1439
|
-
stderr: result.stderr.toString()
|
|
1440
|
-
});
|
|
1441
|
-
}
|
|
1442
|
-
if (result.status !== null) {
|
|
1443
|
-
return result.status;
|
|
1444
|
-
}
|
|
1445
|
-
else {
|
|
1446
|
-
throw result.error || new Error('An unknown error occurred.');
|
|
1447
|
-
}
|
|
1448
|
-
}
|
|
1449
|
-
/**
|
|
1450
|
-
* Executes the command using cmd if running on windows, or using sh if running on a non-windows OS.
|
|
1451
|
-
* @param command - the command to run on shell
|
|
1452
|
-
* @param options - options for how the command should be run
|
|
1453
|
-
*/
|
|
1454
|
-
static executeLifecycleCommandAsync(command, options) {
|
|
1455
|
-
const child = Utilities._executeLifecycleCommandInternal(command, external_node_child_process_namespaceObject.spawn, options);
|
|
1456
|
-
if (options.connectSubprocessTerminator) {
|
|
1457
|
-
node_core_library_.SubprocessTerminator.killProcessTreeOnExit(child, node_core_library_.SubprocessTerminator.RECOMMENDED_OPTIONS);
|
|
1458
|
-
}
|
|
1459
|
-
return child;
|
|
1460
|
-
}
|
|
1461
|
-
/**
|
|
1462
|
-
* For strings passed to a shell command, this adds appropriate escaping
|
|
1463
|
-
* to avoid misinterpretation of spaces or special characters.
|
|
1464
|
-
*
|
|
1465
|
-
* Example: 'hello there' --> '"hello there"'
|
|
1466
|
-
*/
|
|
1467
|
-
static escapeShellParameter(parameter) {
|
|
1468
|
-
// This approach is based on what NPM 7 now does:
|
|
1469
|
-
// https://github.com/npm/run-script/blob/47a4d539fb07220e7215cc0e482683b76407ef9b/lib/run-script-pkg.js#L34
|
|
1470
|
-
return JSON.stringify(parameter);
|
|
1471
|
-
}
|
|
1472
|
-
/**
|
|
1473
|
-
* Installs a package by name and version in the specified directory.
|
|
1474
|
-
*/
|
|
1475
|
-
static async installPackageInDirectoryAsync({ packageName, version, tempPackageTitle, commonRushConfigFolder, maxInstallAttempts, suppressOutput, directory }) {
|
|
1476
|
-
directory = external_node_path_.resolve(directory);
|
|
1477
|
-
const directoryExists = await node_core_library_.FileSystem.existsAsync(directory);
|
|
1478
|
-
if (directoryExists) {
|
|
1479
|
-
// eslint-disable-next-line no-console
|
|
1480
|
-
console.log('Deleting old files from ' + directory);
|
|
1481
|
-
}
|
|
1482
|
-
await node_core_library_.FileSystem.ensureEmptyFolderAsync(directory);
|
|
1483
|
-
const npmPackageJson = {
|
|
1484
|
-
dependencies: {
|
|
1485
|
-
[packageName]: version
|
|
1486
|
-
},
|
|
1487
|
-
description: 'Temporary file generated by the Rush tool',
|
|
1488
|
-
name: tempPackageTitle,
|
|
1489
|
-
private: true,
|
|
1490
|
-
version: '0.0.0'
|
|
1491
|
-
};
|
|
1492
|
-
await node_core_library_.JsonFile.saveAsync(npmPackageJson, external_node_path_.join(directory, node_core_library_.FileConstants.PackageJson));
|
|
1493
|
-
if (commonRushConfigFolder) {
|
|
1494
|
-
Utilities.syncNpmrc({
|
|
1495
|
-
sourceNpmrcFolder: commonRushConfigFolder,
|
|
1496
|
-
targetNpmrcFolder: directory,
|
|
1497
|
-
supportEnvVarFallbackSyntax: false
|
|
1498
|
-
});
|
|
1499
|
-
}
|
|
1500
|
-
// eslint-disable-next-line no-console
|
|
1501
|
-
console.log('\nRunning "npm install" in ' + directory);
|
|
1502
|
-
// NOTE: Here we use whatever version of NPM we happen to find in the PATH
|
|
1503
|
-
await Utilities.executeCommandWithRetryAsync({
|
|
1504
|
-
command: 'npm',
|
|
1505
|
-
args: ['install'],
|
|
1506
|
-
workingDirectory: directory,
|
|
1507
|
-
environment: Utilities._createEnvironmentForRushCommand({}),
|
|
1508
|
-
suppressOutput
|
|
1509
|
-
}, maxInstallAttempts);
|
|
1510
|
-
}
|
|
1511
|
-
/**
|
|
1512
|
-
* Copies the file "sourcePath" to "destinationPath", overwriting the target file location.
|
|
1513
|
-
* If the source file does not exist, then the target file is deleted.
|
|
1514
|
-
*/
|
|
1515
|
-
static syncFile(sourcePath, destinationPath) {
|
|
1516
|
-
if (node_core_library_.FileSystem.exists(sourcePath)) {
|
|
1517
|
-
// eslint-disable-next-line no-console
|
|
1518
|
-
console.log(`Copying "${sourcePath}"`);
|
|
1519
|
-
// eslint-disable-next-line no-console
|
|
1520
|
-
console.log(` --> "${destinationPath}"`);
|
|
1521
|
-
node_core_library_.FileSystem.copyFile({ sourcePath, destinationPath });
|
|
1522
|
-
}
|
|
1523
|
-
else {
|
|
1524
|
-
if (node_core_library_.FileSystem.exists(destinationPath)) {
|
|
1525
|
-
// If the source file doesn't exist and there is one in the target, delete the one in the target
|
|
1526
|
-
// eslint-disable-next-line no-console
|
|
1527
|
-
console.log(`Deleting ${destinationPath}`);
|
|
1528
|
-
node_core_library_.FileSystem.deleteFile(destinationPath);
|
|
1529
|
-
}
|
|
1530
|
-
}
|
|
1531
|
-
}
|
|
1532
|
-
static getRushConfigNotFoundError() {
|
|
1533
|
-
return new Error(`Unable to find ${RushConstants.rushJsonFilename} configuration file`);
|
|
1534
|
-
}
|
|
1535
|
-
static async usingAsync(getDisposableAsync, doActionAsync) {
|
|
1536
|
-
let disposable;
|
|
1537
|
-
try {
|
|
1538
|
-
disposable = (await getDisposableAsync());
|
|
1539
|
-
await doActionAsync(disposable);
|
|
1540
|
-
}
|
|
1541
|
-
finally {
|
|
1542
|
-
disposable === null || disposable === void 0 ? void 0 : disposable.dispose();
|
|
1543
|
-
}
|
|
1544
|
-
}
|
|
1545
|
-
static trimAfterLastSlash(filePath) {
|
|
1546
|
-
const indexOfLastSlash = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\'));
|
|
1547
|
-
if (indexOfLastSlash < 0) {
|
|
1548
|
-
return filePath;
|
|
1549
|
-
}
|
|
1550
|
-
return filePath.substring(0, indexOfLastSlash);
|
|
1551
|
-
}
|
|
1552
|
-
/**
|
|
1553
|
-
* If the path refers to a symlink, `FileSystem.exists()` would normally test whether the symlink
|
|
1554
|
-
* points to a target that exists. By contrast, `existsOrIsBrokenSymlink()` will return true even if
|
|
1555
|
-
* the symlink exists but its target does not. */
|
|
1556
|
-
static existsOrIsSymlink(linkPath) {
|
|
1557
|
-
try {
|
|
1558
|
-
node_core_library_.FileSystem.getLinkStatistics(linkPath);
|
|
1559
|
-
return true;
|
|
1560
|
-
}
|
|
1561
|
-
catch (err) {
|
|
1562
|
-
return false;
|
|
1563
|
-
}
|
|
1564
|
-
}
|
|
1565
|
-
static _executeLifecycleCommandInternal(command, spawnFunction, options) {
|
|
1566
|
-
var _a;
|
|
1567
|
-
let shellCommand = process.env.comspec || 'cmd';
|
|
1568
|
-
let commandFlags = '/d /s /c';
|
|
1569
|
-
let useShell = true;
|
|
1570
|
-
if (process.platform !== 'win32') {
|
|
1571
|
-
shellCommand = 'sh';
|
|
1572
|
-
commandFlags = '-c';
|
|
1573
|
-
useShell = false;
|
|
1574
|
-
}
|
|
1575
|
-
const environment = Utilities._createEnvironmentForRushCommand({
|
|
1576
|
-
initCwd: options.initCwd,
|
|
1577
|
-
initialEnvironment: options.initialEnvironment,
|
|
1578
|
-
pathOptions: {
|
|
1579
|
-
...options.environmentPathOptions,
|
|
1580
|
-
rushJsonFolder: (_a = options.rushConfiguration) === null || _a === void 0 ? void 0 : _a.rushJsonFolder,
|
|
1581
|
-
projectRoot: options.workingDirectory,
|
|
1582
|
-
commonTempFolder: options.rushConfiguration ? options.rushConfiguration.commonTempFolder : undefined
|
|
1583
|
-
}
|
|
1584
|
-
});
|
|
1585
|
-
const stdio = options.handleOutput ? ['pipe', 'pipe', 'pipe'] : [0, 1, 2];
|
|
1586
|
-
if (options.ipc) {
|
|
1587
|
-
stdio.push('ipc');
|
|
1588
|
-
}
|
|
1589
|
-
const spawnOptions = {
|
|
1590
|
-
cwd: options.workingDirectory,
|
|
1591
|
-
shell: useShell,
|
|
1592
|
-
env: environment,
|
|
1593
|
-
stdio
|
|
1594
|
-
};
|
|
1595
|
-
if (options.connectSubprocessTerminator) {
|
|
1596
|
-
Object.assign(spawnOptions, node_core_library_.SubprocessTerminator.RECOMMENDED_OPTIONS);
|
|
1597
|
-
}
|
|
1598
|
-
return spawnFunction(shellCommand, [commandFlags, command], spawnOptions);
|
|
1599
|
-
}
|
|
1600
|
-
/**
|
|
1601
|
-
* Returns a process.env environment suitable for executing lifecycle scripts.
|
|
1602
|
-
* @param initialEnvironment - an existing environment to copy instead of process.env
|
|
1603
|
-
*
|
|
1604
|
-
* @remarks
|
|
1605
|
-
* Rush._assignRushInvokedFolder() assigns the `RUSH_INVOKED_FOLDER` variable globally
|
|
1606
|
-
* via the parent process's environment.
|
|
1607
|
-
*/
|
|
1608
|
-
static _createEnvironmentForRushCommand(options) {
|
|
1609
|
-
var _a;
|
|
1610
|
-
if (options.initialEnvironment === undefined) {
|
|
1611
|
-
options.initialEnvironment = process.env;
|
|
1612
|
-
}
|
|
1613
|
-
// Set some defaults for the environment
|
|
1614
|
-
const environment = {};
|
|
1615
|
-
if ((_a = options.pathOptions) === null || _a === void 0 ? void 0 : _a.rushJsonFolder) {
|
|
1616
|
-
environment.RUSHSTACK_FILE_ERROR_BASE_FOLDER = options.pathOptions.rushJsonFolder;
|
|
1617
|
-
}
|
|
1618
|
-
for (const key of Object.getOwnPropertyNames(options.initialEnvironment)) {
|
|
1619
|
-
const normalizedKey = external_node_os_namespaceObject.platform() === 'win32' ? key.toUpperCase() : key;
|
|
1620
|
-
// If Rush itself was invoked inside a lifecycle script, this may be set and would interfere
|
|
1621
|
-
// with Rush's installations. If we actually want it, we will set it explicitly below.
|
|
1622
|
-
if (normalizedKey === 'INIT_CWD') {
|
|
1623
|
-
continue;
|
|
1624
|
-
}
|
|
1625
|
-
// When NPM invokes a lifecycle event, it copies its entire configuration into environment
|
|
1626
|
-
// variables. Rush is supposed to be a deterministic controlled environment, so don't bring
|
|
1627
|
-
// this along.
|
|
1628
|
-
//
|
|
1629
|
-
// NOTE: Longer term we should clean out the entire environment and use rush.json to bring
|
|
1630
|
-
// back specific environment variables that the repo maintainer has determined to be safe.
|
|
1631
|
-
if (normalizedKey.match(/^NPM_CONFIG_/)) {
|
|
1632
|
-
continue;
|
|
1633
|
-
}
|
|
1634
|
-
// Use the uppercased environment variable name on Windows because environment variable names
|
|
1635
|
-
// are case-insensitive on Windows
|
|
1636
|
-
environment[normalizedKey] = options.initialEnvironment[key];
|
|
1637
|
-
}
|
|
1638
|
-
// When NPM invokes a lifecycle script, it sets an environment variable INIT_CWD that remembers
|
|
1639
|
-
// the directory that NPM started in. This allows naive scripts to change their current working directory
|
|
1640
|
-
// and invoke NPM operations, while still be able to find a local .npmrc file. Although Rush recommends
|
|
1641
|
-
// for toolchain scripts to be professionally written (versus brittle stuff like
|
|
1642
|
-
// "cd ./lib && npm run tsc && cd .."), we support INIT_CWD for compatibility.
|
|
1643
|
-
//
|
|
1644
|
-
// More about this feature: https://github.com/npm/npm/pull/12356
|
|
1645
|
-
if (options.initCwd) {
|
|
1646
|
-
environment['INIT_CWD'] = options.initCwd; // eslint-disable-line dot-notation
|
|
1647
|
-
}
|
|
1648
|
-
if (options.pathOptions) {
|
|
1649
|
-
if (options.pathOptions.includeRepoBin && options.pathOptions.commonTempFolder) {
|
|
1650
|
-
environment.PATH = Utilities._prependNodeModulesBinToPath(environment.PATH, options.pathOptions.commonTempFolder);
|
|
1651
|
-
}
|
|
1652
|
-
if (options.pathOptions.includeProjectBin && options.pathOptions.projectRoot) {
|
|
1653
|
-
environment.PATH = Utilities._prependNodeModulesBinToPath(environment.PATH, options.pathOptions.projectRoot);
|
|
1654
|
-
}
|
|
1655
|
-
if (options.pathOptions.additionalPathFolders) {
|
|
1656
|
-
environment.PATH = [...options.pathOptions.additionalPathFolders, environment.PATH].join(external_node_path_.delimiter);
|
|
1657
|
-
}
|
|
1658
|
-
}
|
|
1659
|
-
// Communicate to downstream calls that they should not try to run hooks
|
|
1660
|
-
environment[EnvironmentVariableNames._RUSH_RECURSIVE_RUSHX_CALL] = '1';
|
|
1661
|
-
return environment;
|
|
1662
|
-
}
|
|
1663
|
-
/**
|
|
1664
|
-
* Prepend the node_modules/.bin folder under the specified folder to the specified PATH variable. For example,
|
|
1665
|
-
* if `rootDirectory` is "/foobar" and `existingPath` is "/bin", this function will return
|
|
1666
|
-
* "/foobar/node_modules/.bin:/bin"
|
|
1667
|
-
*/
|
|
1668
|
-
static _prependNodeModulesBinToPath(existingPath, rootDirectory) {
|
|
1669
|
-
const binPath = external_node_path_.resolve(rootDirectory, 'node_modules', '.bin');
|
|
1670
|
-
if (existingPath) {
|
|
1671
|
-
return `${binPath}${external_node_path_.delimiter}${existingPath}`;
|
|
1672
|
-
}
|
|
1673
|
-
else {
|
|
1674
|
-
return binPath;
|
|
1675
|
-
}
|
|
1676
|
-
}
|
|
1677
|
-
/**
|
|
1678
|
-
* Executes the command with the specified command-line parameters, and waits for it to complete.
|
|
1679
|
-
* The current directory will be set to the specified workingDirectory.
|
|
1680
|
-
*/
|
|
1681
|
-
static async _executeCommandInternalAsync({ command, args, workingDirectory, stdio, environment, keepEnvironment, onStdoutStreamChunk, captureOutput, captureExitCodeAndSignal }) {
|
|
1682
|
-
var _a;
|
|
1683
|
-
const options = {
|
|
1684
|
-
cwd: workingDirectory,
|
|
1685
|
-
shell: true,
|
|
1686
|
-
stdio: stdio,
|
|
1687
|
-
env: keepEnvironment
|
|
1688
|
-
? environment
|
|
1689
|
-
: Utilities._createEnvironmentForRushCommand({ initialEnvironment: environment }),
|
|
1690
|
-
maxBuffer: 10 * 1024 * 1024 // Set default max buffer size to 10MB
|
|
1691
|
-
};
|
|
1692
|
-
// This is needed since we specify shell=true below.
|
|
1693
|
-
// NOTE: On Windows if we escape "NPM", the spawnSync() function runs something like this:
|
|
1694
|
-
// [ 'C:\\Windows\\system32\\cmd.exe', '/s', '/c', '""NPM" "install""' ]
|
|
1695
|
-
//
|
|
1696
|
-
// Due to a bug with Windows cmd.exe, the npm.cmd batch file's "%~dp0" variable will
|
|
1697
|
-
// return the current working directory instead of the batch file's directory.
|
|
1698
|
-
// The workaround is to not escape, npm, i.e. do this instead:
|
|
1699
|
-
// [ 'C:\\Windows\\system32\\cmd.exe', '/s', '/c', '"npm "install""' ]
|
|
1700
|
-
//
|
|
1701
|
-
// We will come up with a better solution for this when we promote executeCommand()
|
|
1702
|
-
// into node-core-library, but for now this hack will unblock people:
|
|
1703
|
-
// Only escape the command if it actually contains spaces:
|
|
1704
|
-
const escapedCommand = command.indexOf(' ') < 0 ? command : Utilities.escapeShellParameter(command);
|
|
1705
|
-
const escapedArgs = args.map((x) => Utilities.escapeShellParameter(x));
|
|
1706
|
-
const childProcess = external_node_child_process_namespaceObject.spawn(escapedCommand, escapedArgs, options);
|
|
1707
|
-
if (onStdoutStreamChunk) {
|
|
1708
|
-
const inspectStream = new external_node_stream_namespaceObject.Transform({
|
|
1709
|
-
transform: onStdoutStreamChunk
|
|
1710
|
-
? (chunk, encoding, callback) => {
|
|
1711
|
-
const chunkString = chunk.toString();
|
|
1712
|
-
const updatedChunk = onStdoutStreamChunk(chunkString);
|
|
1713
|
-
callback(undefined, updatedChunk !== null && updatedChunk !== void 0 ? updatedChunk : chunk);
|
|
1714
|
-
}
|
|
1715
|
-
: undefined
|
|
1716
|
-
});
|
|
1717
|
-
(_a = childProcess.stdout) === null || _a === void 0 ? void 0 : _a.pipe(inspectStream).pipe(process.stdout);
|
|
1718
|
-
}
|
|
1719
|
-
return await node_core_library_.Executable.waitForExitAsync(childProcess, {
|
|
1720
|
-
encoding: captureOutput ? 'utf8' : undefined,
|
|
1721
|
-
throwOnNonZeroExitCode: !captureExitCodeAndSignal,
|
|
1722
|
-
throwOnSignal: !captureExitCodeAndSignal
|
|
1723
|
-
});
|
|
1724
|
-
}
|
|
1725
|
-
static _processResult({ error, stderr, status }) {
|
|
1726
|
-
if (error) {
|
|
1727
|
-
error.message += `\n${stderr}`;
|
|
1728
|
-
if (status) {
|
|
1729
|
-
error.message += `\nExited with status ${status}`;
|
|
1730
|
-
}
|
|
1731
|
-
throw error;
|
|
1732
|
-
}
|
|
1733
|
-
if (status) {
|
|
1734
|
-
throw new Error(`The command failed with exit code ${status}\n${stderr}`);
|
|
1735
|
-
}
|
|
1736
|
-
}
|
|
1737
|
-
}
|
|
1738
|
-
Utilities.syncNpmrc = syncNpmrc;
|
|
1739
|
-
//# sourceMappingURL=Utilities.js.map
|
|
1740
723
|
;// ../rush-lib/lib-esnext/api/RushGlobalFolder.js
|
|
1741
724
|
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
1742
725
|
// See LICENSE in the project root for license information.
|
|
@@ -1757,7 +740,7 @@ class RushGlobalFolder {
|
|
|
1757
740
|
this.path = rushGlobalFolderOverride;
|
|
1758
741
|
}
|
|
1759
742
|
else {
|
|
1760
|
-
this.path = external_node_path_.join(
|
|
743
|
+
this.path = external_node_path_.join(node_core_library_.User.getHomeFolder(), '.rush');
|
|
1761
744
|
}
|
|
1762
745
|
const normalizedNodeVersion = process.version.match(/^[a-z0-9\-\.]+$/i)
|
|
1763
746
|
? process.version
|