1 | "use strict";
|
---|
2 | /**
|
---|
3 | * @license
|
---|
4 | * Copyright Google LLC 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 | */
|
---|
9 | Object.defineProperty(exports, "__esModule", { value: true });
|
---|
10 | exports.runTempPackageBin = exports.installTempPackage = exports.installPackage = exports.installAllPackages = void 0;
|
---|
11 | const child_process_1 = require("child_process");
|
---|
12 | const fs_1 = require("fs");
|
---|
13 | const os_1 = require("os");
|
---|
14 | const path_1 = require("path");
|
---|
15 | const workspace_schema_1 = require("../lib/config/workspace-schema");
|
---|
16 | const spinner_1 = require("./spinner");
|
---|
17 | async function installAllPackages(packageManager = workspace_schema_1.PackageManager.Npm, extraArgs = [], cwd = process.cwd()) {
|
---|
18 | const packageManagerArgs = getPackageManagerArguments(packageManager);
|
---|
19 | const installArgs = [];
|
---|
20 | if (packageManagerArgs.installAll) {
|
---|
21 | installArgs.push(packageManagerArgs.installAll);
|
---|
22 | }
|
---|
23 | installArgs.push(packageManagerArgs.silent);
|
---|
24 | const spinner = new spinner_1.Spinner();
|
---|
25 | spinner.start('Installing packages...');
|
---|
26 | const bufferedOutput = [];
|
---|
27 | return new Promise((resolve, reject) => {
|
---|
28 | var _a, _b;
|
---|
29 | const childProcess = child_process_1.spawn(packageManager, [...installArgs, ...extraArgs], {
|
---|
30 | stdio: 'pipe',
|
---|
31 | shell: true,
|
---|
32 | cwd,
|
---|
33 | }).on('close', (code) => {
|
---|
34 | if (code === 0) {
|
---|
35 | spinner.succeed('Packages successfully installed.');
|
---|
36 | resolve(0);
|
---|
37 | }
|
---|
38 | else {
|
---|
39 | spinner.stop();
|
---|
40 | bufferedOutput.forEach(({ stream, data }) => stream.write(data));
|
---|
41 | spinner.fail('Package install failed, see above.');
|
---|
42 | reject(1);
|
---|
43 | }
|
---|
44 | });
|
---|
45 | (_a = childProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => bufferedOutput.push({ stream: process.stdout, data: data }));
|
---|
46 | (_b = childProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => bufferedOutput.push({ stream: process.stderr, data: data }));
|
---|
47 | });
|
---|
48 | }
|
---|
49 | exports.installAllPackages = installAllPackages;
|
---|
50 | async function installPackage(packageName, packageManager = workspace_schema_1.PackageManager.Npm, save = true, extraArgs = [], cwd = process.cwd()) {
|
---|
51 | const packageManagerArgs = getPackageManagerArguments(packageManager);
|
---|
52 | const installArgs = [
|
---|
53 | packageManagerArgs.install,
|
---|
54 | packageName,
|
---|
55 | packageManagerArgs.silent,
|
---|
56 | ];
|
---|
57 | const spinner = new spinner_1.Spinner();
|
---|
58 | spinner.start('Installing package...');
|
---|
59 | if (save === 'devDependencies') {
|
---|
60 | installArgs.push(packageManagerArgs.saveDev);
|
---|
61 | }
|
---|
62 | const bufferedOutput = [];
|
---|
63 | return new Promise((resolve, reject) => {
|
---|
64 | var _a, _b;
|
---|
65 | const childProcess = child_process_1.spawn(packageManager, [...installArgs, ...extraArgs], {
|
---|
66 | stdio: 'pipe',
|
---|
67 | shell: true,
|
---|
68 | cwd,
|
---|
69 | }).on('close', (code) => {
|
---|
70 | if (code === 0) {
|
---|
71 | spinner.succeed('Package successfully installed.');
|
---|
72 | resolve(0);
|
---|
73 | }
|
---|
74 | else {
|
---|
75 | spinner.stop();
|
---|
76 | bufferedOutput.forEach(({ stream, data }) => stream.write(data));
|
---|
77 | spinner.fail('Package install failed, see above.');
|
---|
78 | reject(1);
|
---|
79 | }
|
---|
80 | });
|
---|
81 | (_a = childProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => bufferedOutput.push({ stream: process.stdout, data: data }));
|
---|
82 | (_b = childProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => bufferedOutput.push({ stream: process.stderr, data: data }));
|
---|
83 | });
|
---|
84 | }
|
---|
85 | exports.installPackage = installPackage;
|
---|
86 | async function installTempPackage(packageName, packageManager = workspace_schema_1.PackageManager.Npm, extraArgs) {
|
---|
87 | const tempPath = fs_1.mkdtempSync(path_1.join(fs_1.realpathSync(os_1.tmpdir()), 'angular-cli-packages-'));
|
---|
88 | // clean up temp directory on process exit
|
---|
89 | process.on('exit', () => {
|
---|
90 | try {
|
---|
91 | fs_1.rmdirSync(tempPath, { recursive: true, maxRetries: 3 });
|
---|
92 | }
|
---|
93 | catch { }
|
---|
94 | });
|
---|
95 | // NPM will warn when a `package.json` is not found in the install directory
|
---|
96 | // Example:
|
---|
97 | // npm WARN enoent ENOENT: no such file or directory, open '/tmp/.ng-temp-packages-84Qi7y/package.json'
|
---|
98 | // npm WARN .ng-temp-packages-84Qi7y No description
|
---|
99 | // npm WARN .ng-temp-packages-84Qi7y No repository field.
|
---|
100 | // npm WARN .ng-temp-packages-84Qi7y No license field.
|
---|
101 | // While we can use `npm init -y` we will end up needing to update the 'package.json' anyways
|
---|
102 | // because of missing fields.
|
---|
103 | fs_1.writeFileSync(path_1.join(tempPath, 'package.json'), JSON.stringify({
|
---|
104 | name: 'temp-cli-install',
|
---|
105 | description: 'temp-cli-install',
|
---|
106 | repository: 'temp-cli-install',
|
---|
107 | license: 'MIT',
|
---|
108 | }));
|
---|
109 | // setup prefix/global modules path
|
---|
110 | const packageManagerArgs = getPackageManagerArguments(packageManager);
|
---|
111 | const tempNodeModules = path_1.join(tempPath, 'node_modules');
|
---|
112 | // Yarn will not append 'node_modules' to the path
|
---|
113 | const prefixPath = packageManager === workspace_schema_1.PackageManager.Yarn ? tempNodeModules : tempPath;
|
---|
114 | const installArgs = [
|
---|
115 | ...(extraArgs || []),
|
---|
116 | `${packageManagerArgs.prefix}="${prefixPath}"`,
|
---|
117 | packageManagerArgs.noLockfile,
|
---|
118 | ];
|
---|
119 | return {
|
---|
120 | status: await installPackage(packageName, packageManager, true, installArgs, tempPath),
|
---|
121 | tempNodeModules,
|
---|
122 | };
|
---|
123 | }
|
---|
124 | exports.installTempPackage = installTempPackage;
|
---|
125 | async function runTempPackageBin(packageName, packageManager = workspace_schema_1.PackageManager.Npm, args = []) {
|
---|
126 | const { status: code, tempNodeModules } = await installTempPackage(packageName, packageManager);
|
---|
127 | if (code !== 0) {
|
---|
128 | return code;
|
---|
129 | }
|
---|
130 | // Remove version/tag etc... from package name
|
---|
131 | // Ex: @angular/cli@latest -> @angular/cli
|
---|
132 | const packageNameNoVersion = packageName.substring(0, packageName.lastIndexOf('@'));
|
---|
133 | const pkgLocation = path_1.join(tempNodeModules, packageNameNoVersion);
|
---|
134 | const packageJsonPath = path_1.join(pkgLocation, 'package.json');
|
---|
135 | // Get a binary location for this package
|
---|
136 | let binPath;
|
---|
137 | if (fs_1.existsSync(packageJsonPath)) {
|
---|
138 | const content = fs_1.readFileSync(packageJsonPath, 'utf-8');
|
---|
139 | if (content) {
|
---|
140 | const { bin = {} } = JSON.parse(content);
|
---|
141 | const binKeys = Object.keys(bin);
|
---|
142 | if (binKeys.length) {
|
---|
143 | binPath = path_1.resolve(pkgLocation, bin[binKeys[0]]);
|
---|
144 | }
|
---|
145 | }
|
---|
146 | }
|
---|
147 | if (!binPath) {
|
---|
148 | throw new Error(`Cannot locate bin for temporary package: ${packageNameNoVersion}.`);
|
---|
149 | }
|
---|
150 | const { status, error } = child_process_1.spawnSync(process.execPath, [binPath, ...args], {
|
---|
151 | stdio: 'inherit',
|
---|
152 | env: {
|
---|
153 | ...process.env,
|
---|
154 | NG_DISABLE_VERSION_CHECK: 'true',
|
---|
155 | NG_CLI_ANALYTICS: 'false',
|
---|
156 | },
|
---|
157 | });
|
---|
158 | if (status === null && error) {
|
---|
159 | throw error;
|
---|
160 | }
|
---|
161 | return status || 0;
|
---|
162 | }
|
---|
163 | exports.runTempPackageBin = runTempPackageBin;
|
---|
164 | function getPackageManagerArguments(packageManager) {
|
---|
165 | switch (packageManager) {
|
---|
166 | case workspace_schema_1.PackageManager.Yarn:
|
---|
167 | return {
|
---|
168 | silent: '--silent',
|
---|
169 | saveDev: '--dev',
|
---|
170 | install: 'add',
|
---|
171 | prefix: '--modules-folder',
|
---|
172 | noLockfile: '--no-lockfile',
|
---|
173 | };
|
---|
174 | case workspace_schema_1.PackageManager.Pnpm:
|
---|
175 | return {
|
---|
176 | silent: '--silent',
|
---|
177 | saveDev: '--save-dev',
|
---|
178 | install: 'add',
|
---|
179 | installAll: 'install',
|
---|
180 | prefix: '--prefix',
|
---|
181 | noLockfile: '--no-lockfile',
|
---|
182 | };
|
---|
183 | default:
|
---|
184 | return {
|
---|
185 | silent: '--quiet',
|
---|
186 | saveDev: '--save-dev',
|
---|
187 | install: 'install',
|
---|
188 | installAll: 'install',
|
---|
189 | prefix: '--prefix',
|
---|
190 | noLockfile: '--no-package-lock',
|
---|
191 | };
|
---|
192 | }
|
---|
193 | }
|
---|