UNPKG

6.01 kBJavaScriptView Raw
1"use strict";
2/**
3 * @license
4 * Copyright Google Inc. All Rights Reserved.
5 *
6 * Use of this source code is governed by an MIT-style license that can be
7 * found in the LICENSE file at https://angular.io/license
8 */
9Object.defineProperty(exports, "__esModule", { value: true });
10exports.runTempPackageBin = exports.installTempPackage = exports.installPackage = void 0;
11const child_process_1 = require("child_process");
12const fs_1 = require("fs");
13const os_1 = require("os");
14const path_1 = require("path");
15const rimraf = require("rimraf");
16const schema_1 = require("../lib/config/schema");
17const color_1 = require("../utilities/color");
18function installPackage(packageName, logger, packageManager = schema_1.PackageManager.Npm, save = true, extraArgs = [], cwd = process.cwd()) {
19 const packageManagerArgs = getPackageManagerArguments(packageManager);
20 const installArgs = [
21 packageManagerArgs.install,
22 packageName,
23 packageManagerArgs.silent,
24 ];
25 logger.info(color_1.colors.green(`Installing packages for tooling via ${packageManager}.`));
26 if (save === 'devDependencies') {
27 installArgs.push(packageManagerArgs.saveDev);
28 }
29 const { status, stderr, stdout, error } = child_process_1.spawnSync(packageManager, [...installArgs, ...extraArgs], {
30 stdio: 'pipe',
31 shell: true,
32 encoding: 'utf8',
33 cwd,
34 });
35 if (status !== 0) {
36 let errorMessage = ((error && error.message) || stderr || stdout || '').trim();
37 if (errorMessage) {
38 errorMessage += '\n';
39 }
40 throw new Error(errorMessage + `Package install failed${errorMessage ? ', see above' : ''}.`);
41 }
42 logger.info(color_1.colors.green(`Installed packages for tooling via ${packageManager}.`));
43}
44exports.installPackage = installPackage;
45function installTempPackage(packageName, logger, packageManager = schema_1.PackageManager.Npm, extraArgs) {
46 const tempPath = fs_1.mkdtempSync(path_1.join(fs_1.realpathSync(os_1.tmpdir()), 'angular-cli-packages-'));
47 // clean up temp directory on process exit
48 process.on('exit', () => {
49 try {
50 rimraf.sync(tempPath);
51 }
52 catch (_a) { }
53 });
54 // NPM will warn when a `package.json` is not found in the install directory
55 // Example:
56 // npm WARN enoent ENOENT: no such file or directory, open '/tmp/.ng-temp-packages-84Qi7y/package.json'
57 // npm WARN .ng-temp-packages-84Qi7y No description
58 // npm WARN .ng-temp-packages-84Qi7y No repository field.
59 // npm WARN .ng-temp-packages-84Qi7y No license field.
60 // While we can use `npm init -y` we will end up needing to update the 'package.json' anyways
61 // because of missing fields.
62 fs_1.writeFileSync(path_1.join(tempPath, 'package.json'), JSON.stringify({
63 name: 'temp-cli-install',
64 description: 'temp-cli-install',
65 repository: 'temp-cli-install',
66 license: 'MIT',
67 }));
68 // setup prefix/global modules path
69 const packageManagerArgs = getPackageManagerArguments(packageManager);
70 const tempNodeModules = path_1.join(tempPath, 'node_modules');
71 // Yarn will not append 'node_modules' to the path
72 const prefixPath = packageManager === schema_1.PackageManager.Yarn ? tempNodeModules : tempPath;
73 const installArgs = [
74 ...(extraArgs || []),
75 `${packageManagerArgs.prefix}="${prefixPath}"`,
76 packageManagerArgs.noLockfile,
77 ];
78 installPackage(packageName, logger, packageManager, true, installArgs, tempPath);
79 return tempNodeModules;
80}
81exports.installTempPackage = installTempPackage;
82function runTempPackageBin(packageName, logger, packageManager = schema_1.PackageManager.Npm, args = []) {
83 const tempNodeModulesPath = installTempPackage(packageName, logger, packageManager);
84 // Remove version/tag etc... from package name
85 // Ex: @angular/cli@latest -> @angular/cli
86 const packageNameNoVersion = packageName.substring(0, packageName.lastIndexOf('@'));
87 const pkgLocation = path_1.join(tempNodeModulesPath, packageNameNoVersion);
88 const packageJsonPath = path_1.join(pkgLocation, 'package.json');
89 // Get a binary location for this package
90 let binPath;
91 if (fs_1.existsSync(packageJsonPath)) {
92 const content = fs_1.readFileSync(packageJsonPath, 'utf-8');
93 if (content) {
94 const { bin = {} } = JSON.parse(content);
95 const binKeys = Object.keys(bin);
96 if (binKeys.length) {
97 binPath = path_1.resolve(pkgLocation, bin[binKeys[0]]);
98 }
99 }
100 }
101 if (!binPath) {
102 throw new Error(`Cannot locate bin for temporary package: ${packageNameNoVersion}.`);
103 }
104 const argv = [binPath, ...args];
105 const { status, error } = child_process_1.spawnSync('node', argv, {
106 stdio: 'inherit',
107 shell: true,
108 env: {
109 ...process.env,
110 NG_DISABLE_VERSION_CHECK: 'true',
111 NG_CLI_ANALYTICS: 'false',
112 },
113 });
114 if (status === null && error) {
115 throw error;
116 }
117 return status || 0;
118}
119exports.runTempPackageBin = runTempPackageBin;
120function getPackageManagerArguments(packageManager) {
121 switch (packageManager) {
122 case schema_1.PackageManager.Yarn:
123 return {
124 silent: '--silent',
125 saveDev: '--dev',
126 install: 'add',
127 prefix: '--modules-folder',
128 noLockfile: '--no-lockfile',
129 };
130 case schema_1.PackageManager.Pnpm:
131 return {
132 silent: '--silent',
133 saveDev: '--save-dev',
134 install: 'add',
135 prefix: '--prefix',
136 noLockfile: '--no-lockfile',
137 };
138 default:
139 return {
140 silent: '--quiet',
141 saveDev: '--save-dev',
142 install: 'install',
143 prefix: '--prefix',
144 noLockfile: '--no-package-lock',
145 };
146 }
147}