UNPKG

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