microsoft/typespec

Public

mirrored from https://github.com/microsoft/typespecAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
c749b1148f33fc87efa6edda1e97335f29078dc8

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

common/scripts/install-run.js

716lines · modecode

1// THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED.
2//
3// This script is intended for usage in an automated build environment where a Node tool may not have
4// been preinstalled, or may have an unpredictable version. This script will automatically install the specified
5// version of the specified tool (if not already installed), and then pass a command-line to it.
6// An example usage would be:
7//
8// node common/scripts/install-run.js qrcode@1.2.2 qrcode https://rushjs.io
9//
10// For more information, see: https://rushjs.io/pages/maintainer/setup_new_repo/
11
12/******/ (() => { // webpackBootstrap
13/******/ "use strict";
14/******/ var __webpack_modules__ = ({
15
16/***/ 679877:
17/*!************************************************!*\
18 !*** ./lib-esnext/utilities/npmrcUtilities.js ***!
19 \************************************************/
20/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
21
22__webpack_require__.r(__webpack_exports__);
23/* harmony export */ __webpack_require__.d(__webpack_exports__, {
24/* harmony export */ "isVariableSetInNpmrcFile": () => (/* binding */ isVariableSetInNpmrcFile),
25/* harmony export */ "syncNpmrc": () => (/* binding */ syncNpmrc)
26/* harmony export */ });
27/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! fs */ 657147);
28/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__);
29/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! path */ 371017);
30/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__);
31// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
32// See LICENSE in the project root for license information.
33// IMPORTANT - do not use any non-built-in libraries in this file
34
35
36/**
37 * This function reads the content for given .npmrc file path, and also trims
38 * unusable lines from the .npmrc file.
39 *
40 * @returns
41 * The text of the the .npmrc.
42 */
43// create a global _combinedNpmrc for cache purpose
44const _combinedNpmrcMap = new Map();
45function _trimNpmrcFile(sourceNpmrcPath) {
46 const combinedNpmrcFromCache = _combinedNpmrcMap.get(sourceNpmrcPath);
47 if (combinedNpmrcFromCache !== undefined) {
48 return combinedNpmrcFromCache;
49 }
50 let npmrcFileLines = fs__WEBPACK_IMPORTED_MODULE_0__.readFileSync(sourceNpmrcPath).toString().split('\n');
51 npmrcFileLines = npmrcFileLines.map((line) => (line || '').trim());
52 const resultLines = [];
53 // This finds environment variable tokens that look like "${VAR_NAME}"
54 const expansionRegExp = /\$\{([^\}]+)\}/g;
55 // Comment lines start with "#" or ";"
56 const commentRegExp = /^\s*[#;]/;
57 // Trim out lines that reference environment variables that aren't defined
58 for (let line of npmrcFileLines) {
59 let lineShouldBeTrimmed = false;
60 //remove spaces before or after key and value
61 line = line
62 .split('=')
63 .map((lineToTrim) => lineToTrim.trim())
64 .join('=');
65 // Ignore comment lines
66 if (!commentRegExp.test(line)) {
67 const environmentVariables = line.match(expansionRegExp);
68 if (environmentVariables) {
69 for (const token of environmentVariables) {
70 // Remove the leading "${" and the trailing "}" from the token
71 const environmentVariableName = token.substring(2, token.length - 1);
72 // Is the environment variable defined?
73 if (!process.env[environmentVariableName]) {
74 // No, so trim this line
75 lineShouldBeTrimmed = true;
76 break;
77 }
78 }
79 }
80 }
81 if (lineShouldBeTrimmed) {
82 // Example output:
83 // "; MISSING ENVIRONMENT VARIABLE: //my-registry.com/npm/:_authToken=${MY_AUTH_TOKEN}"
84 resultLines.push('; MISSING ENVIRONMENT VARIABLE: ' + line);
85 }
86 else {
87 resultLines.push(line);
88 }
89 }
90 const combinedNpmrc = resultLines.join('\n');
91 //save the cache
92 _combinedNpmrcMap.set(sourceNpmrcPath, combinedNpmrc);
93 return combinedNpmrc;
94}
95/**
96 * As a workaround, copyAndTrimNpmrcFile() copies the .npmrc file to the target folder, and also trims
97 * unusable lines from the .npmrc file.
98 *
99 * Why are we trimming the .npmrc lines? NPM allows environment variables to be specified in
100 * the .npmrc file to provide different authentication tokens for different registry.
101 * However, if the environment variable is undefined, it expands to an empty string, which
102 * produces a valid-looking mapping with an invalid URL that causes an error. Instead,
103 * we'd prefer to skip that line and continue looking in other places such as the user's
104 * home directory.
105 *
106 * @returns
107 * The text of the the .npmrc with lines containing undefined variables commented out.
108 */
109function _copyAndTrimNpmrcFile(logger, sourceNpmrcPath, targetNpmrcPath) {
110 logger.info(`Transforming ${sourceNpmrcPath}`); // Verbose
111 logger.info(` --> "${targetNpmrcPath}"`);
112 const combinedNpmrc = _trimNpmrcFile(sourceNpmrcPath);
113 fs__WEBPACK_IMPORTED_MODULE_0__.writeFileSync(targetNpmrcPath, combinedNpmrc);
114 return combinedNpmrc;
115}
116/**
117 * syncNpmrc() copies the .npmrc file to the target folder, and also trims unusable lines from the .npmrc file.
118 * If the source .npmrc file not exist, then syncNpmrc() will delete an .npmrc that is found in the target folder.
119 *
120 * IMPORTANT: THIS CODE SHOULD BE KEPT UP TO DATE WITH Utilities._syncNpmrc()
121 *
122 * @returns
123 * The text of the the synced .npmrc, if one exists. If one does not exist, then undefined is returned.
124 */
125function syncNpmrc(sourceNpmrcFolder, targetNpmrcFolder, useNpmrcPublish, logger = {
126 // eslint-disable-next-line no-console
127 info: console.log,
128 // eslint-disable-next-line no-console
129 error: console.error
130}) {
131 const sourceNpmrcPath = path__WEBPACK_IMPORTED_MODULE_1__.join(sourceNpmrcFolder, !useNpmrcPublish ? '.npmrc' : '.npmrc-publish');
132 const targetNpmrcPath = path__WEBPACK_IMPORTED_MODULE_1__.join(targetNpmrcFolder, '.npmrc');
133 try {
134 if (fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(sourceNpmrcPath)) {
135 return _copyAndTrimNpmrcFile(logger, sourceNpmrcPath, targetNpmrcPath);
136 }
137 else if (fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(targetNpmrcPath)) {
138 // If the source .npmrc doesn't exist and there is one in the target, delete the one in the target
139 logger.info(`Deleting ${targetNpmrcPath}`); // Verbose
140 fs__WEBPACK_IMPORTED_MODULE_0__.unlinkSync(targetNpmrcPath);
141 }
142 }
143 catch (e) {
144 throw new Error(`Error syncing .npmrc file: ${e}`);
145 }
146}
147function isVariableSetInNpmrcFile(sourceNpmrcFolder, variableKey) {
148 const sourceNpmrcPath = `${sourceNpmrcFolder}/.npmrc`;
149 //if .npmrc file does not exist, return false directly
150 if (!fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(sourceNpmrcPath)) {
151 return false;
152 }
153 const trimmedNpmrcFile = _trimNpmrcFile(sourceNpmrcPath);
154 const variableKeyRegExp = new RegExp(`^${variableKey}=`, 'm');
155 return trimmedNpmrcFile.match(variableKeyRegExp) !== null;
156}
157//# sourceMappingURL=npmrcUtilities.js.map
158
159/***/ }),
160
161/***/ 532081:
162/*!********************************!*\
163 !*** external "child_process" ***!
164 \********************************/
165/***/ ((module) => {
166
167module.exports = require("child_process");
168
169/***/ }),
170
171/***/ 657147:
172/*!*********************!*\
173 !*** external "fs" ***!
174 \*********************/
175/***/ ((module) => {
176
177module.exports = require("fs");
178
179/***/ }),
180
181/***/ 822037:
182/*!*********************!*\
183 !*** external "os" ***!
184 \*********************/
185/***/ ((module) => {
186
187module.exports = require("os");
188
189/***/ }),
190
191/***/ 371017:
192/*!***********************!*\
193 !*** external "path" ***!
194 \***********************/
195/***/ ((module) => {
196
197module.exports = require("path");
198
199/***/ })
200
201/******/ });
202/************************************************************************/
203/******/ // The module cache
204/******/ var __webpack_module_cache__ = {};
205/******/
206/******/ // The require function
207/******/ function __webpack_require__(moduleId) {
208/******/ // Check if module is in cache
209/******/ var cachedModule = __webpack_module_cache__[moduleId];
210/******/ if (cachedModule !== undefined) {
211/******/ return cachedModule.exports;
212/******/ }
213/******/ // Create a new module (and put it into the cache)
214/******/ var module = __webpack_module_cache__[moduleId] = {
215/******/ // no module.id needed
216/******/ // no module.loaded needed
217/******/ exports: {}
218/******/ };
219/******/
220/******/ // Execute the module function
221/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
222/******/
223/******/ // Return the exports of the module
224/******/ return module.exports;
225/******/ }
226/******/
227/************************************************************************/
228/******/ /* webpack/runtime/compat get default export */
229/******/ (() => {
230/******/ // getDefaultExport function for compatibility with non-harmony modules
231/******/ __webpack_require__.n = (module) => {
232/******/ var getter = module && module.__esModule ?
233/******/ () => (module['default']) :
234/******/ () => (module);
235/******/ __webpack_require__.d(getter, { a: getter });
236/******/ return getter;
237/******/ };
238/******/ })();
239/******/
240/******/ /* webpack/runtime/define property getters */
241/******/ (() => {
242/******/ // define getter functions for harmony exports
243/******/ __webpack_require__.d = (exports, definition) => {
244/******/ for(var key in definition) {
245/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
246/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
247/******/ }
248/******/ }
249/******/ };
250/******/ })();
251/******/
252/******/ /* webpack/runtime/hasOwnProperty shorthand */
253/******/ (() => {
254/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
255/******/ })();
256/******/
257/******/ /* webpack/runtime/make namespace object */
258/******/ (() => {
259/******/ // define __esModule on exports
260/******/ __webpack_require__.r = (exports) => {
261/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
262/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
263/******/ }
264/******/ Object.defineProperty(exports, '__esModule', { value: true });
265/******/ };
266/******/ })();
267/******/
268/************************************************************************/
269var __webpack_exports__ = {};
270// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
271(() => {
272/*!*******************************************!*\
273 !*** ./lib-esnext/scripts/install-run.js ***!
274 \*******************************************/
275__webpack_require__.r(__webpack_exports__);
276/* harmony export */ __webpack_require__.d(__webpack_exports__, {
277/* harmony export */ "RUSH_JSON_FILENAME": () => (/* binding */ RUSH_JSON_FILENAME),
278/* harmony export */ "findRushJsonFolder": () => (/* binding */ findRushJsonFolder),
279/* harmony export */ "getNpmPath": () => (/* binding */ getNpmPath),
280/* harmony export */ "installAndRun": () => (/* binding */ installAndRun),
281/* harmony export */ "runWithErrorAndStatusCode": () => (/* binding */ runWithErrorAndStatusCode)
282/* harmony export */ });
283/* harmony import */ var child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! child_process */ 532081);
284/* harmony import */ var child_process__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(child_process__WEBPACK_IMPORTED_MODULE_0__);
285/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! fs */ 657147);
286/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__);
287/* harmony import */ var os__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! os */ 822037);
288/* harmony import */ var os__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(os__WEBPACK_IMPORTED_MODULE_2__);
289/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! path */ 371017);
290/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_3__);
291/* harmony import */ var _utilities_npmrcUtilities__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utilities/npmrcUtilities */ 679877);
292// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
293// See LICENSE in the project root for license information.
294/* eslint-disable no-console */
295
296
297
298
299
300const RUSH_JSON_FILENAME = 'rush.json';
301const RUSH_TEMP_FOLDER_ENV_VARIABLE_NAME = 'RUSH_TEMP_FOLDER';
302const INSTALL_RUN_LOCKFILE_PATH_VARIABLE = 'INSTALL_RUN_LOCKFILE_PATH';
303const INSTALLED_FLAG_FILENAME = 'installed.flag';
304const NODE_MODULES_FOLDER_NAME = 'node_modules';
305const PACKAGE_JSON_FILENAME = 'package.json';
306/**
307 * Parse a package specifier (in the form of name\@version) into name and version parts.
308 */
309function _parsePackageSpecifier(rawPackageSpecifier) {
310 rawPackageSpecifier = (rawPackageSpecifier || '').trim();
311 const separatorIndex = rawPackageSpecifier.lastIndexOf('@');
312 let name;
313 let version = undefined;
314 if (separatorIndex === 0) {
315 // The specifier starts with a scope and doesn't have a version specified
316 name = rawPackageSpecifier;
317 }
318 else if (separatorIndex === -1) {
319 // The specifier doesn't have a version
320 name = rawPackageSpecifier;
321 }
322 else {
323 name = rawPackageSpecifier.substring(0, separatorIndex);
324 version = rawPackageSpecifier.substring(separatorIndex + 1);
325 }
326 if (!name) {
327 throw new Error(`Invalid package specifier: ${rawPackageSpecifier}`);
328 }
329 return { name, version };
330}
331let _npmPath = undefined;
332/**
333 * Get the absolute path to the npm executable
334 */
335function getNpmPath() {
336 if (!_npmPath) {
337 try {
338 if (os__WEBPACK_IMPORTED_MODULE_2__.platform() === 'win32') {
339 // We're on Windows
340 const whereOutput = child_process__WEBPACK_IMPORTED_MODULE_0__.execSync('where npm', { stdio: [] }).toString();
341 const lines = whereOutput.split(os__WEBPACK_IMPORTED_MODULE_2__.EOL).filter((line) => !!line);
342 // take the last result, we are looking for a .cmd command
343 // see https://github.com/microsoft/rushstack/issues/759
344 _npmPath = lines[lines.length - 1];
345 }
346 else {
347 // We aren't on Windows - assume we're on *NIX or Darwin
348 _npmPath = child_process__WEBPACK_IMPORTED_MODULE_0__.execSync('command -v npm', { stdio: [] }).toString();
349 }
350 }
351 catch (e) {
352 throw new Error(`Unable to determine the path to the NPM tool: ${e}`);
353 }
354 _npmPath = _npmPath.trim();
355 if (!fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(_npmPath)) {
356 throw new Error('The NPM executable does not exist');
357 }
358 }
359 return _npmPath;
360}
361function _ensureFolder(folderPath) {
362 if (!fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(folderPath)) {
363 const parentDir = path__WEBPACK_IMPORTED_MODULE_3__.dirname(folderPath);
364 _ensureFolder(parentDir);
365 fs__WEBPACK_IMPORTED_MODULE_1__.mkdirSync(folderPath);
366 }
367}
368/**
369 * Create missing directories under the specified base directory, and return the resolved directory.
370 *
371 * Does not support "." or ".." path segments.
372 * Assumes the baseFolder exists.
373 */
374function _ensureAndJoinPath(baseFolder, ...pathSegments) {
375 let joinedPath = baseFolder;
376 try {
377 for (let pathSegment of pathSegments) {
378 pathSegment = pathSegment.replace(/[\\\/]/g, '+');
379 joinedPath = path__WEBPACK_IMPORTED_MODULE_3__.join(joinedPath, pathSegment);
380 if (!fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(joinedPath)) {
381 fs__WEBPACK_IMPORTED_MODULE_1__.mkdirSync(joinedPath);
382 }
383 }
384 }
385 catch (e) {
386 throw new Error(`Error building local installation folder (${path__WEBPACK_IMPORTED_MODULE_3__.join(baseFolder, ...pathSegments)}): ${e}`);
387 }
388 return joinedPath;
389}
390function _getRushTempFolder(rushCommonFolder) {
391 const rushTempFolder = process.env[RUSH_TEMP_FOLDER_ENV_VARIABLE_NAME];
392 if (rushTempFolder !== undefined) {
393 _ensureFolder(rushTempFolder);
394 return rushTempFolder;
395 }
396 else {
397 return _ensureAndJoinPath(rushCommonFolder, 'temp');
398 }
399}
400/**
401 * Compare version strings according to semantic versioning.
402 * Returns a positive integer if "a" is a later version than "b",
403 * a negative integer if "b" is later than "a",
404 * and 0 otherwise.
405 */
406function _compareVersionStrings(a, b) {
407 const aParts = a.split(/[.-]/);
408 const bParts = b.split(/[.-]/);
409 const numberOfParts = Math.max(aParts.length, bParts.length);
410 for (let i = 0; i < numberOfParts; i++) {
411 if (aParts[i] !== bParts[i]) {
412 return (Number(aParts[i]) || 0) - (Number(bParts[i]) || 0);
413 }
414 }
415 return 0;
416}
417/**
418 * Resolve a package specifier to a static version
419 */
420function _resolvePackageVersion(logger, rushCommonFolder, { name, version }) {
421 if (!version) {
422 version = '*'; // If no version is specified, use the latest version
423 }
424 if (version.match(/^[a-zA-Z0-9\-\+\.]+$/)) {
425 // If the version contains only characters that we recognize to be used in static version specifiers,
426 // pass the version through
427 return version;
428 }
429 else {
430 // version resolves to
431 try {
432 const rushTempFolder = _getRushTempFolder(rushCommonFolder);
433 const sourceNpmrcFolder = path__WEBPACK_IMPORTED_MODULE_3__.join(rushCommonFolder, 'config', 'rush');
434 (0,_utilities_npmrcUtilities__WEBPACK_IMPORTED_MODULE_4__.syncNpmrc)(sourceNpmrcFolder, rushTempFolder, undefined, logger);
435 const npmPath = getNpmPath();
436 // This returns something that looks like:
437 // ```
438 // [
439 // "3.0.0",
440 // "3.0.1",
441 // ...
442 // "3.0.20"
443 // ]
444 // ```
445 //
446 // if multiple versions match the selector, or
447 //
448 // ```
449 // "3.0.0"
450 // ```
451 //
452 // if only a single version matches.
453 const npmVersionSpawnResult = child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync(npmPath, ['view', `${name}@${version}`, 'version', '--no-update-notifier', '--json'], {
454 cwd: rushTempFolder,
455 stdio: []
456 });
457 if (npmVersionSpawnResult.status !== 0) {
458 throw new Error(`"npm view" returned error code ${npmVersionSpawnResult.status}`);
459 }
460 const npmViewVersionOutput = npmVersionSpawnResult.stdout.toString();
461 const parsedVersionOutput = JSON.parse(npmViewVersionOutput);
462 const versions = Array.isArray(parsedVersionOutput)
463 ? parsedVersionOutput
464 : [parsedVersionOutput];
465 let latestVersion = versions[0];
466 for (let i = 1; i < versions.length; i++) {
467 const latestVersionCandidate = versions[i];
468 if (_compareVersionStrings(latestVersionCandidate, latestVersion) > 0) {
469 latestVersion = latestVersionCandidate;
470 }
471 }
472 if (!latestVersion) {
473 throw new Error('No versions found for the specified version range.');
474 }
475 return latestVersion;
476 }
477 catch (e) {
478 throw new Error(`Unable to resolve version ${version} of package ${name}: ${e}`);
479 }
480 }
481}
482let _rushJsonFolder;
483/**
484 * Find the absolute path to the folder containing rush.json
485 */
486function findRushJsonFolder() {
487 if (!_rushJsonFolder) {
488 let basePath = __dirname;
489 let tempPath = __dirname;
490 do {
491 const testRushJsonPath = path__WEBPACK_IMPORTED_MODULE_3__.join(basePath, RUSH_JSON_FILENAME);
492 if (fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(testRushJsonPath)) {
493 _rushJsonFolder = basePath;
494 break;
495 }
496 else {
497 basePath = tempPath;
498 }
499 } while (basePath !== (tempPath = path__WEBPACK_IMPORTED_MODULE_3__.dirname(basePath))); // Exit the loop when we hit the disk root
500 if (!_rushJsonFolder) {
501 throw new Error('Unable to find rush.json.');
502 }
503 }
504 return _rushJsonFolder;
505}
506/**
507 * Detects if the package in the specified directory is installed
508 */
509function _isPackageAlreadyInstalled(packageInstallFolder) {
510 try {
511 const flagFilePath = path__WEBPACK_IMPORTED_MODULE_3__.join(packageInstallFolder, INSTALLED_FLAG_FILENAME);
512 if (!fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(flagFilePath)) {
513 return false;
514 }
515 const fileContents = fs__WEBPACK_IMPORTED_MODULE_1__.readFileSync(flagFilePath).toString();
516 return fileContents.trim() === process.version;
517 }
518 catch (e) {
519 return false;
520 }
521}
522/**
523 * Delete a file. Fail silently if it does not exist.
524 */
525function _deleteFile(file) {
526 try {
527 fs__WEBPACK_IMPORTED_MODULE_1__.unlinkSync(file);
528 }
529 catch (err) {
530 if (err.code !== 'ENOENT' && err.code !== 'ENOTDIR') {
531 throw err;
532 }
533 }
534}
535/**
536 * Removes the following files and directories under the specified folder path:
537 * - installed.flag
538 * -
539 * - node_modules
540 */
541function _cleanInstallFolder(rushTempFolder, packageInstallFolder, lockFilePath) {
542 try {
543 const flagFile = path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, INSTALLED_FLAG_FILENAME);
544 _deleteFile(flagFile);
545 const packageLockFile = path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, 'package-lock.json');
546 if (lockFilePath) {
547 fs__WEBPACK_IMPORTED_MODULE_1__.copyFileSync(lockFilePath, packageLockFile);
548 }
549 else {
550 // Not running `npm ci`, so need to cleanup
551 _deleteFile(packageLockFile);
552 const nodeModulesFolder = path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME);
553 if (fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(nodeModulesFolder)) {
554 const rushRecyclerFolder = _ensureAndJoinPath(rushTempFolder, 'rush-recycler');
555 fs__WEBPACK_IMPORTED_MODULE_1__.renameSync(nodeModulesFolder, path__WEBPACK_IMPORTED_MODULE_3__.join(rushRecyclerFolder, `install-run-${Date.now().toString()}`));
556 }
557 }
558 }
559 catch (e) {
560 throw new Error(`Error cleaning the package install folder (${packageInstallFolder}): ${e}`);
561 }
562}
563function _createPackageJson(packageInstallFolder, name, version) {
564 try {
565 const packageJsonContents = {
566 name: 'ci-rush',
567 version: '0.0.0',
568 dependencies: {
569 [name]: version
570 },
571 description: "DON'T WARN",
572 repository: "DON'T WARN",
573 license: 'MIT'
574 };
575 const packageJsonPath = path__WEBPACK_IMPORTED_MODULE_3__.join(packageInstallFolder, PACKAGE_JSON_FILENAME);
576 fs__WEBPACK_IMPORTED_MODULE_1__.writeFileSync(packageJsonPath, JSON.stringify(packageJsonContents, undefined, 2));
577 }
578 catch (e) {
579 throw new Error(`Unable to create package.json: ${e}`);
580 }
581}
582/**
583 * Run "npm install" in the package install folder.
584 */
585function _installPackage(logger, packageInstallFolder, name, version, command) {
586 try {
587 logger.info(`Installing ${name}...`);
588 const npmPath = getNpmPath();
589 const result = child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync(npmPath, [command], {
590 stdio: 'inherit',
591 cwd: packageInstallFolder,
592 env: process.env
593 });
594 if (result.status !== 0) {
595 throw new Error(`"npm ${command}" encountered an error`);
596 }
597 logger.info(`Successfully installed ${name}@${version}`);
598 }
599 catch (e) {
600 throw new Error(`Unable to install package: ${e}`);
601 }
602}
603/**
604 * Get the ".bin" path for the package.
605 */
606function _getBinPath(packageInstallFolder, binName) {
607 const binFolderPath = path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME, '.bin');
608 const resolvedBinName = os__WEBPACK_IMPORTED_MODULE_2__.platform() === 'win32' ? `${binName}.cmd` : binName;
609 return path__WEBPACK_IMPORTED_MODULE_3__.resolve(binFolderPath, resolvedBinName);
610}
611/**
612 * Write a flag file to the package's install directory, signifying that the install was successful.
613 */
614function _writeFlagFile(packageInstallFolder) {
615 try {
616 const flagFilePath = path__WEBPACK_IMPORTED_MODULE_3__.join(packageInstallFolder, INSTALLED_FLAG_FILENAME);
617 fs__WEBPACK_IMPORTED_MODULE_1__.writeFileSync(flagFilePath, process.version);
618 }
619 catch (e) {
620 throw new Error(`Unable to create installed.flag file in ${packageInstallFolder}`);
621 }
622}
623function installAndRun(logger, packageName, packageVersion, packageBinName, packageBinArgs, lockFilePath = process.env[INSTALL_RUN_LOCKFILE_PATH_VARIABLE]) {
624 const rushJsonFolder = findRushJsonFolder();
625 const rushCommonFolder = path__WEBPACK_IMPORTED_MODULE_3__.join(rushJsonFolder, 'common');
626 const rushTempFolder = _getRushTempFolder(rushCommonFolder);
627 const packageInstallFolder = _ensureAndJoinPath(rushTempFolder, 'install-run', `${packageName}@${packageVersion}`);
628 if (!_isPackageAlreadyInstalled(packageInstallFolder)) {
629 // The package isn't already installed
630 _cleanInstallFolder(rushTempFolder, packageInstallFolder, lockFilePath);
631 const sourceNpmrcFolder = path__WEBPACK_IMPORTED_MODULE_3__.join(rushCommonFolder, 'config', 'rush');
632 (0,_utilities_npmrcUtilities__WEBPACK_IMPORTED_MODULE_4__.syncNpmrc)(sourceNpmrcFolder, packageInstallFolder, undefined, logger);
633 _createPackageJson(packageInstallFolder, packageName, packageVersion);
634 const command = lockFilePath ? 'ci' : 'install';
635 _installPackage(logger, packageInstallFolder, packageName, packageVersion, command);
636 _writeFlagFile(packageInstallFolder);
637 }
638 const statusMessage = `Invoking "${packageBinName} ${packageBinArgs.join(' ')}"`;
639 const statusMessageLine = new Array(statusMessage.length + 1).join('-');
640 logger.info('\n' + statusMessage + '\n' + statusMessageLine + '\n');
641 const binPath = _getBinPath(packageInstallFolder, packageBinName);
642 const binFolderPath = path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME, '.bin');
643 // Windows environment variables are case-insensitive. Instead of using SpawnSyncOptions.env, we need to
644 // assign via the process.env proxy to ensure that we append to the right PATH key.
645 const originalEnvPath = process.env.PATH || '';
646 let result;
647 try {
648 // Node.js on Windows can not spawn a file when the path has a space on it
649 // unless the path gets wrapped in a cmd friendly way and shell mode is used
650 const shouldUseShell = binPath.includes(' ') && os__WEBPACK_IMPORTED_MODULE_2__.platform() === 'win32';
651 const platformBinPath = shouldUseShell ? `"${binPath}"` : binPath;
652 process.env.PATH = [binFolderPath, originalEnvPath].join(path__WEBPACK_IMPORTED_MODULE_3__.delimiter);
653 result = child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync(platformBinPath, packageBinArgs, {
654 stdio: 'inherit',
655 windowsVerbatimArguments: false,
656 shell: shouldUseShell,
657 cwd: process.cwd(),
658 env: process.env
659 });
660 }
661 finally {
662 process.env.PATH = originalEnvPath;
663 }
664 if (result.status !== null) {
665 return result.status;
666 }
667 else {
668 throw result.error || new Error('An unknown error occurred.');
669 }
670}
671function runWithErrorAndStatusCode(logger, fn) {
672 process.exitCode = 1;
673 try {
674 const exitCode = fn();
675 process.exitCode = exitCode;
676 }
677 catch (e) {
678 logger.error('\n\n' + e.toString() + '\n\n');
679 }
680}
681function _run() {
682 const [nodePath /* Ex: /bin/node */, scriptPath /* /repo/common/scripts/install-run-rush.js */, rawPackageSpecifier /* qrcode@^1.2.0 */, packageBinName /* qrcode */, ...packageBinArgs /* [-f, myproject/lib] */] = process.argv;
683 if (!nodePath) {
684 throw new Error('Unexpected exception: could not detect node path');
685 }
686 if (path__WEBPACK_IMPORTED_MODULE_3__.basename(scriptPath).toLowerCase() !== 'install-run.js') {
687 // If install-run.js wasn't directly invoked, don't execute the rest of this function. Return control
688 // to the script that (presumably) imported this file
689 return;
690 }
691 if (process.argv.length < 4) {
692 console.log('Usage: install-run.js <package>@<version> <command> [args...]');
693 console.log('Example: install-run.js qrcode@1.2.2 qrcode https://rushjs.io');
694 process.exit(1);
695 }
696 const logger = { info: console.log, error: console.error };
697 runWithErrorAndStatusCode(logger, () => {
698 const rushJsonFolder = findRushJsonFolder();
699 const rushCommonFolder = _ensureAndJoinPath(rushJsonFolder, 'common');
700 const packageSpecifier = _parsePackageSpecifier(rawPackageSpecifier);
701 const name = packageSpecifier.name;
702 const version = _resolvePackageVersion(logger, rushCommonFolder, packageSpecifier);
703 if (packageSpecifier.version !== version) {
704 console.log(`Resolved to ${name}@${version}`);
705 }
706 return installAndRun(logger, name, version, packageBinName, packageBinArgs);
707 });
708}
709_run();
710//# sourceMappingURL=install-run.js.map
711})();
712
713module.exports = __webpack_exports__;
714/******/ })()
715;
716//# sourceMappingURL=install-run.js.map