@angular/cli 14.0.0-next.6 → 14.0.0-next.7
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/lib/cli/index.d.ts +0 -1
- package/lib/cli/index.js +3 -30
- package/lib/config/schema.json +22 -3
- package/lib/config/workspace-schema.d.ts +5 -0
- package/lib/init.js +2 -5
- package/package.json +15 -18
- package/src/analytics/analytics-collector.js +2 -0
- package/src/analytics/analytics.js +17 -16
- package/src/command-builder/architect-command-module.js +3 -3
- package/src/command-builder/command-module.d.ts +3 -2
- package/src/command-builder/command-runner.d.ts +1 -2
- package/src/command-builder/command-runner.js +50 -33
- package/src/command-builder/schematics-command-module.d.ts +4 -2
- package/src/command-builder/schematics-command-module.js +81 -41
- package/src/commands/add/cli.js +14 -14
- package/src/commands/add/long-description.md +1 -4
- package/src/commands/analytics/cli.d.ts +1 -1
- package/src/commands/analytics/info/cli.d.ts +1 -1
- package/src/commands/analytics/settings/cli.d.ts +1 -1
- package/src/commands/cache/clean/cli.d.ts +17 -0
- package/src/commands/cache/clean/cli.js +32 -0
- package/src/commands/cache/cli.d.ts +17 -0
- package/src/commands/cache/cli.js +38 -0
- package/src/commands/cache/info/cli.d.ts +20 -0
- package/src/commands/cache/info/cli.js +82 -0
- package/src/commands/cache/long-description.md +53 -0
- package/src/commands/cache/settings/cli.d.ts +27 -0
- package/src/commands/cache/settings/cli.js +42 -0
- package/src/commands/cache/utilities.d.ts +11 -0
- package/src/commands/cache/utilities.js +50 -0
- package/src/commands/config/cli.d.ts +1 -1
- package/src/commands/config/cli.js +2 -2
- package/src/commands/doc/cli.d.ts +1 -1
- package/src/commands/e2e/cli.d.ts +1 -1
- package/src/commands/e2e/cli.js +3 -3
- package/src/commands/generate/cli.d.ts +11 -1
- package/src/commands/generate/cli.js +54 -23
- package/src/commands/new/cli.d.ts +2 -0
- package/src/commands/new/cli.js +15 -4
- package/src/commands/update/cli.d.ts +1 -0
- package/src/commands/update/cli.js +50 -21
- package/src/commands/update/schematic/index.js +27 -18
- package/src/commands/version/cli.d.ts +0 -1
- package/src/commands/version/cli.js +4 -23
- package/src/typings-bazel.d.ts +14 -0
- package/src/typings.d.ts +0 -13
- package/src/utilities/config.d.ts +1 -2
- package/src/utilities/config.js +18 -41
- package/src/{analytics/analytics-environment-options.d.ts → utilities/environment-options.d.ts} +3 -0
- package/src/utilities/environment-options.js +24 -0
- package/src/utilities/package-manager.d.ts +33 -5
- package/src/utilities/package-manager.js +241 -71
- package/src/utilities/package-metadata.d.ts +15 -37
- package/src/utilities/package-metadata.js +10 -26
- package/src/utilities/package-tree.d.ts +2 -2
- package/src/utilities/prompt.js +2 -2
- package/bin/postinstall/analytics-prompt.js +0 -27
- package/bin/postinstall/script.js +0 -16
- package/src/analytics/analytics-environment-options.js +0 -20
- package/src/utilities/install-package.d.ts +0 -16
- package/src/utilities/install-package.js +0 -193
- package/src/utilities/package-json.d.ts +0 -249
- package/src/utilities/package-json.js +0 -9
|
@@ -11,7 +11,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.VersionCommandModule = void 0;
|
|
14
|
-
const child_process_1 = require("child_process");
|
|
15
14
|
const module_1 = __importDefault(require("module"));
|
|
16
15
|
const path_1 = require("path");
|
|
17
16
|
const command_module_1 = require("../../command-builder/command-module");
|
|
@@ -43,10 +42,11 @@ class VersionCommandModule extends command_module_1.CommandModule {
|
|
|
43
42
|
return localYargs;
|
|
44
43
|
}
|
|
45
44
|
async run() {
|
|
46
|
-
|
|
45
|
+
var _a;
|
|
46
|
+
const { packageManager, logger, root } = this.context;
|
|
47
47
|
const localRequire = module_1.default.createRequire((0, path_1.resolve)(__filename, '../../../'));
|
|
48
48
|
// Trailing slash is used to allow the path to be treated as a directory
|
|
49
|
-
const workspaceRequire = module_1.default.createRequire(
|
|
49
|
+
const workspaceRequire = module_1.default.createRequire(root + '/');
|
|
50
50
|
const cliPackage = localRequire('./package.json');
|
|
51
51
|
let workspacePackage;
|
|
52
52
|
try {
|
|
@@ -100,7 +100,7 @@ class VersionCommandModule extends command_module_1.CommandModule {
|
|
|
100
100
|
logger.info(`
|
|
101
101
|
Angular CLI: ${ngCliVersion}
|
|
102
102
|
Node: ${process.versions.node}${unsupportedNodeVersion ? ' (Unsupported)' : ''}
|
|
103
|
-
Package Manager: ${
|
|
103
|
+
Package Manager: ${packageManager.name} ${(_a = packageManager.version) !== null && _a !== void 0 ? _a : '<error>'}
|
|
104
104
|
OS: ${process.platform} ${process.arch}
|
|
105
105
|
|
|
106
106
|
Angular: ${angularCoreVersion}
|
|
@@ -157,24 +157,5 @@ class VersionCommandModule extends command_module_1.CommandModule {
|
|
|
157
157
|
}
|
|
158
158
|
return '<error>';
|
|
159
159
|
}
|
|
160
|
-
getPackageManagerVersion() {
|
|
161
|
-
try {
|
|
162
|
-
const manager = this.context.packageManager;
|
|
163
|
-
const version = (0, child_process_1.execSync)(`${manager} --version`, {
|
|
164
|
-
encoding: 'utf8',
|
|
165
|
-
stdio: ['ignore', 'pipe', 'ignore'],
|
|
166
|
-
env: {
|
|
167
|
-
...process.env,
|
|
168
|
-
// NPM updater notifier will prevents the child process from closing until it timeout after 3 minutes.
|
|
169
|
-
NO_UPDATE_NOTIFIER: '1',
|
|
170
|
-
NPM_CONFIG_UPDATE_NOTIFIER: 'false',
|
|
171
|
-
},
|
|
172
|
-
}).trim();
|
|
173
|
-
return `${manager} ${version}`;
|
|
174
|
-
}
|
|
175
|
-
catch {
|
|
176
|
-
return '<error>';
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
160
|
}
|
|
180
161
|
exports.VersionCommandModule = VersionCommandModule;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/* eslint-disable import/no-extraneous-dependencies */
|
|
10
|
+
// Workaround for https://github.com/bazelbuild/rules_nodejs/issues/1033
|
|
11
|
+
// Alternative approach instead of https://github.com/angular/angular/pull/33226
|
|
12
|
+
declare module '@yarnpkg/lockfile' {
|
|
13
|
+
export * from '@types/yarnpkg__lockfile';
|
|
14
|
+
}
|
package/src/typings.d.ts
CHANGED
|
@@ -5,20 +5,7 @@
|
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
|
-
declare module '@yarnpkg/lockfile' {
|
|
9
|
-
function parse(data: string): Record<string, any>;
|
|
10
|
-
}
|
|
11
|
-
declare module 'ini' {
|
|
12
|
-
function parse(data: string): Record<string, any>;
|
|
13
|
-
}
|
|
14
8
|
declare module 'npm-pick-manifest' {
|
|
15
9
|
function pickManifest(metadata: import('./utilities/package-metadata').PackageMetadata, selector: string): import('./utilities/package-metadata').PackageManifest;
|
|
16
10
|
export = pickManifest;
|
|
17
11
|
}
|
|
18
|
-
declare module 'pacote' {
|
|
19
|
-
function manifest(specifier: string, options: Record<string, unknown>): Promise<{
|
|
20
|
-
name: string;
|
|
21
|
-
version: string;
|
|
22
|
-
}>;
|
|
23
|
-
function packument(specifier: string, options: Record<string, unknown>): Promise<import('./utilities/package-metadata').NpmRepositoryPackageJson>;
|
|
24
|
-
}
|
|
@@ -20,7 +20,7 @@ export declare class AngularWorkspace {
|
|
|
20
20
|
getProjectCli(projectName: string): Record<string, any>;
|
|
21
21
|
static load(workspaceFilePath: string): Promise<AngularWorkspace>;
|
|
22
22
|
}
|
|
23
|
-
export declare function getWorkspace(level?: 'local' | 'global'): Promise<AngularWorkspace |
|
|
23
|
+
export declare function getWorkspace(level?: 'local' | 'global'): Promise<AngularWorkspace | undefined>;
|
|
24
24
|
export declare function createGlobalSettings(): string;
|
|
25
25
|
export declare function getWorkspaceRaw(level?: 'local' | 'global'): [JSONFile | null, string | null];
|
|
26
26
|
export declare function validateWorkspace(data: json.JsonObject): Promise<void>;
|
|
@@ -28,4 +28,3 @@ export declare function getProjectByCwd(workspace: AngularWorkspace): string | n
|
|
|
28
28
|
export declare function getConfiguredPackageManager(): Promise<PackageManager | null>;
|
|
29
29
|
export declare function getSchematicDefaults(collection: string, schematic: string, project?: string | null): Promise<{}>;
|
|
30
30
|
export declare function isWarningEnabled(warning: string): Promise<boolean>;
|
|
31
|
-
export declare function getProjectsByPath(workspace: workspaces.WorkspaceDefinition, cwd: string, root: string): string[];
|
package/src/utilities/config.js
CHANGED
|
@@ -30,7 +30,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
30
30
|
return result;
|
|
31
31
|
};
|
|
32
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
-
exports.
|
|
33
|
+
exports.isWarningEnabled = exports.getSchematicDefaults = exports.getConfiguredPackageManager = exports.getProjectByCwd = exports.validateWorkspace = exports.getWorkspaceRaw = exports.createGlobalSettings = exports.getWorkspace = exports.AngularWorkspace = exports.workspaceSchemaPath = void 0;
|
|
34
34
|
const core_1 = require("@angular-devkit/core");
|
|
35
35
|
const fs_1 = require("fs");
|
|
36
36
|
const os = __importStar(require("os"));
|
|
@@ -42,15 +42,16 @@ function isJsonObject(value) {
|
|
|
42
42
|
}
|
|
43
43
|
function createWorkspaceHost() {
|
|
44
44
|
return {
|
|
45
|
-
|
|
46
|
-
return
|
|
45
|
+
readFile(path) {
|
|
46
|
+
return fs_1.promises.readFile(path, 'utf-8');
|
|
47
47
|
},
|
|
48
48
|
async writeFile(path, data) {
|
|
49
|
-
|
|
49
|
+
await fs_1.promises.writeFile(path, data);
|
|
50
50
|
},
|
|
51
51
|
async isDirectory(path) {
|
|
52
52
|
try {
|
|
53
|
-
|
|
53
|
+
const stats = await fs_1.promises.stat(path);
|
|
54
|
+
return stats.isDirectory();
|
|
54
55
|
}
|
|
55
56
|
catch {
|
|
56
57
|
return false;
|
|
@@ -58,7 +59,8 @@ function createWorkspaceHost() {
|
|
|
58
59
|
},
|
|
59
60
|
async isFile(path) {
|
|
60
61
|
try {
|
|
61
|
-
|
|
62
|
+
const stats = await fs_1.promises.stat(path);
|
|
63
|
+
return stats.isFile();
|
|
62
64
|
}
|
|
63
65
|
catch {
|
|
64
66
|
return false;
|
|
@@ -147,14 +149,13 @@ class AngularWorkspace {
|
|
|
147
149
|
exports.AngularWorkspace = AngularWorkspace;
|
|
148
150
|
const cachedWorkspaces = new Map();
|
|
149
151
|
async function getWorkspace(level = 'local') {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
return cached;
|
|
152
|
+
if (cachedWorkspaces.has(level)) {
|
|
153
|
+
return cachedWorkspaces.get(level);
|
|
153
154
|
}
|
|
154
155
|
const configPath = level === 'local' ? projectFilePath() : globalFilePath();
|
|
155
156
|
if (!configPath) {
|
|
156
|
-
cachedWorkspaces.set(level,
|
|
157
|
-
return
|
|
157
|
+
cachedWorkspaces.set(level, undefined);
|
|
158
|
+
return undefined;
|
|
158
159
|
}
|
|
159
160
|
try {
|
|
160
161
|
const workspace = await AngularWorkspace.load(configPath);
|
|
@@ -237,6 +238,7 @@ function findProjectByPath(workspace, location) {
|
|
|
237
238
|
}
|
|
238
239
|
return projects[0][1];
|
|
239
240
|
}
|
|
241
|
+
let defaultProjectDeprecationWarningShown = false;
|
|
240
242
|
function getProjectByCwd(workspace) {
|
|
241
243
|
if (workspace.projects.size === 1) {
|
|
242
244
|
// If there is only one project, return that one.
|
|
@@ -249,6 +251,11 @@ function getProjectByCwd(workspace) {
|
|
|
249
251
|
const defaultProject = workspace.extensions['defaultProject'];
|
|
250
252
|
if (defaultProject && typeof defaultProject === 'string') {
|
|
251
253
|
// If there is a default project name, return it.
|
|
254
|
+
if (!defaultProjectDeprecationWarningShown) {
|
|
255
|
+
console.warn(`DEPRECATED: The 'defaultProject' workspace option has been deprecated. ` +
|
|
256
|
+
`The project to use will be determined from the current working directory.`);
|
|
257
|
+
defaultProjectDeprecationWarningShown = true;
|
|
258
|
+
}
|
|
252
259
|
return defaultProject;
|
|
253
260
|
}
|
|
254
261
|
return null;
|
|
@@ -341,33 +348,3 @@ async function isWarningEnabled(warning) {
|
|
|
341
348
|
return result !== null && result !== void 0 ? result : true;
|
|
342
349
|
}
|
|
343
350
|
exports.isWarningEnabled = isWarningEnabled;
|
|
344
|
-
function getProjectsByPath(workspace, cwd, root) {
|
|
345
|
-
if (workspace.projects.size === 1) {
|
|
346
|
-
return Array.from(workspace.projects.keys());
|
|
347
|
-
}
|
|
348
|
-
const isInside = (base, potential) => {
|
|
349
|
-
const absoluteBase = path.resolve(root, base);
|
|
350
|
-
const absolutePotential = path.resolve(root, potential);
|
|
351
|
-
const relativePotential = path.relative(absoluteBase, absolutePotential);
|
|
352
|
-
if (!relativePotential.startsWith('..') && !path.isAbsolute(relativePotential)) {
|
|
353
|
-
return true;
|
|
354
|
-
}
|
|
355
|
-
return false;
|
|
356
|
-
};
|
|
357
|
-
const projects = Array.from(workspace.projects.entries())
|
|
358
|
-
.map(([name, project]) => [path.resolve(root, project.root), name])
|
|
359
|
-
.filter((tuple) => isInside(tuple[0], cwd))
|
|
360
|
-
// Sort tuples by depth, with the deeper ones first. Since the first member is a path and
|
|
361
|
-
// we filtered all invalid paths, the longest will be the deepest (and in case of equality
|
|
362
|
-
// the sort is stable and the first declared project will win).
|
|
363
|
-
.sort((a, b) => b[0].length - a[0].length);
|
|
364
|
-
if (projects.length === 1) {
|
|
365
|
-
return [projects[0][1]];
|
|
366
|
-
}
|
|
367
|
-
else if (projects.length > 1) {
|
|
368
|
-
const firstPath = projects[0][0];
|
|
369
|
-
return projects.filter((v) => v[0] === firstPath).map((v) => v[1]);
|
|
370
|
-
}
|
|
371
|
-
return [];
|
|
372
|
-
}
|
|
373
|
-
exports.getProjectsByPath = getProjectsByPath;
|
|
@@ -0,0 +1,24 @@
|
|
|
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.ngDebug = exports.disableVersionCheck = exports.isCI = exports.analyticsShareDisabled = exports.analyticsDisabled = void 0;
|
|
11
|
+
function isPresent(variable) {
|
|
12
|
+
return typeof variable === 'string' && variable !== '';
|
|
13
|
+
}
|
|
14
|
+
function isDisabled(variable) {
|
|
15
|
+
return isPresent(variable) && (variable === '0' || variable.toLowerCase() === 'false');
|
|
16
|
+
}
|
|
17
|
+
function isEnabled(variable) {
|
|
18
|
+
return isPresent(variable) && (variable === '1' || variable.toLowerCase() === 'true');
|
|
19
|
+
}
|
|
20
|
+
exports.analyticsDisabled = isDisabled(process.env['NG_CLI_ANALYTICS']);
|
|
21
|
+
exports.analyticsShareDisabled = isDisabled(process.env['NG_CLI_ANALYTICS_SHARE']);
|
|
22
|
+
exports.isCI = isEnabled(process.env['CI']);
|
|
23
|
+
exports.disableVersionCheck = isEnabled(process.env['NG_DISABLE_VERSION_CHECK']);
|
|
24
|
+
exports.ngDebug = isEnabled(process.env['NG_DEBUG']);
|
|
@@ -6,8 +6,36 @@
|
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
8
|
import { PackageManager } from '../../lib/config/workspace-schema';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
import { AngularWorkspace } from './config';
|
|
10
|
+
export interface PackageManagerUtilsContext {
|
|
11
|
+
globalConfiguration?: AngularWorkspace;
|
|
12
|
+
workspace?: AngularWorkspace;
|
|
13
|
+
root: string;
|
|
14
|
+
}
|
|
15
|
+
export declare class PackageManagerUtils {
|
|
16
|
+
private readonly context;
|
|
17
|
+
constructor(context: PackageManagerUtilsContext);
|
|
18
|
+
/** Get the package manager name. */
|
|
19
|
+
get name(): PackageManager;
|
|
20
|
+
/** Get the package manager version. */
|
|
21
|
+
get version(): string | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Checks if the package manager is supported. If not, display a warning.
|
|
24
|
+
*/
|
|
25
|
+
ensureCompatibility(): void;
|
|
26
|
+
/** Install a single package. */
|
|
27
|
+
install(packageName: string, save?: 'dependencies' | 'devDependencies' | true, extraArgs?: string[], cwd?: string): Promise<boolean>;
|
|
28
|
+
/** Install all packages. */
|
|
29
|
+
installAll(extraArgs?: string[], cwd?: string): Promise<boolean>;
|
|
30
|
+
/** Install a single package temporary. */
|
|
31
|
+
installTemp(packageName: string, extraArgs?: string[]): Promise<{
|
|
32
|
+
success: boolean;
|
|
33
|
+
tempNodeModules: string;
|
|
34
|
+
}>;
|
|
35
|
+
private getArguments;
|
|
36
|
+
private run;
|
|
37
|
+
private getVersion;
|
|
38
|
+
private getName;
|
|
39
|
+
private hasLockfile;
|
|
40
|
+
private getConfiguredPackageManager;
|
|
41
|
+
}
|
|
@@ -7,26 +7,231 @@
|
|
|
7
7
|
* found in the LICENSE file at https://angular.io/license
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.
|
|
10
|
+
exports.PackageManagerUtils = void 0;
|
|
11
|
+
const core_1 = require("@angular-devkit/core");
|
|
11
12
|
const child_process_1 = require("child_process");
|
|
12
13
|
const fs_1 = require("fs");
|
|
14
|
+
const os_1 = require("os");
|
|
13
15
|
const path_1 = require("path");
|
|
14
16
|
const semver_1 = require("semver");
|
|
15
|
-
const util_1 = require("util");
|
|
16
17
|
const workspace_schema_1 = require("../../lib/config/workspace-schema");
|
|
17
18
|
const config_1 = require("./config");
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return true;
|
|
19
|
+
const spinner_1 = require("./spinner");
|
|
20
|
+
class PackageManagerUtils {
|
|
21
|
+
constructor(context) {
|
|
22
|
+
this.context = context;
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
/** Get the package manager name. */
|
|
25
|
+
get name() {
|
|
26
|
+
return this.getName();
|
|
26
27
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
/** Get the package manager version. */
|
|
29
|
+
get version() {
|
|
30
|
+
return this.getVersion(this.name);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Checks if the package manager is supported. If not, display a warning.
|
|
34
|
+
*/
|
|
35
|
+
ensureCompatibility() {
|
|
36
|
+
if (this.name !== workspace_schema_1.PackageManager.Npm) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
const version = (0, semver_1.valid)(this.version);
|
|
41
|
+
if (!version) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if ((0, semver_1.satisfies)(version, '>=7 <7.5.6')) {
|
|
45
|
+
// eslint-disable-next-line no-console
|
|
46
|
+
console.warn(`npm version ${version} detected.` +
|
|
47
|
+
' When using npm 7 with the Angular CLI, npm version 7.5.6 or higher is recommended.');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// npm is not installed.
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** Install a single package. */
|
|
55
|
+
async install(packageName, save = true, extraArgs = [], cwd) {
|
|
56
|
+
const packageManagerArgs = this.getArguments();
|
|
57
|
+
const installArgs = [
|
|
58
|
+
packageManagerArgs.install,
|
|
59
|
+
packageName,
|
|
60
|
+
packageManagerArgs.silent,
|
|
61
|
+
];
|
|
62
|
+
if (save === 'devDependencies') {
|
|
63
|
+
installArgs.push(packageManagerArgs.saveDev);
|
|
64
|
+
}
|
|
65
|
+
return this.run([...installArgs, ...extraArgs], cwd);
|
|
66
|
+
}
|
|
67
|
+
/** Install all packages. */
|
|
68
|
+
async installAll(extraArgs = [], cwd) {
|
|
69
|
+
const packageManagerArgs = this.getArguments();
|
|
70
|
+
const installArgs = [packageManagerArgs.silent];
|
|
71
|
+
if (packageManagerArgs.installAll) {
|
|
72
|
+
installArgs.push(packageManagerArgs.installAll);
|
|
73
|
+
}
|
|
74
|
+
return this.run([...installArgs, ...extraArgs], cwd);
|
|
75
|
+
}
|
|
76
|
+
/** Install a single package temporary. */
|
|
77
|
+
async installTemp(packageName, extraArgs) {
|
|
78
|
+
const tempPath = await fs_1.promises.mkdtemp((0, path_1.join)((0, fs_1.realpathSync)((0, os_1.tmpdir)()), 'angular-cli-packages-'));
|
|
79
|
+
// clean up temp directory on process exit
|
|
80
|
+
process.on('exit', () => {
|
|
81
|
+
try {
|
|
82
|
+
(0, fs_1.rmdirSync)(tempPath, { recursive: true, maxRetries: 3 });
|
|
83
|
+
}
|
|
84
|
+
catch { }
|
|
85
|
+
});
|
|
86
|
+
// NPM will warn when a `package.json` is not found in the install directory
|
|
87
|
+
// Example:
|
|
88
|
+
// npm WARN enoent ENOENT: no such file or directory, open '/tmp/.ng-temp-packages-84Qi7y/package.json'
|
|
89
|
+
// npm WARN .ng-temp-packages-84Qi7y No description
|
|
90
|
+
// npm WARN .ng-temp-packages-84Qi7y No repository field.
|
|
91
|
+
// npm WARN .ng-temp-packages-84Qi7y No license field.
|
|
92
|
+
// While we can use `npm init -y` we will end up needing to update the 'package.json' anyways
|
|
93
|
+
// because of missing fields.
|
|
94
|
+
await fs_1.promises.writeFile((0, path_1.join)(tempPath, 'package.json'), JSON.stringify({
|
|
95
|
+
name: 'temp-cli-install',
|
|
96
|
+
description: 'temp-cli-install',
|
|
97
|
+
repository: 'temp-cli-install',
|
|
98
|
+
license: 'MIT',
|
|
99
|
+
}));
|
|
100
|
+
// setup prefix/global modules path
|
|
101
|
+
const packageManagerArgs = this.getArguments();
|
|
102
|
+
const tempNodeModules = (0, path_1.join)(tempPath, 'node_modules');
|
|
103
|
+
// Yarn will not append 'node_modules' to the path
|
|
104
|
+
const prefixPath = this.name === workspace_schema_1.PackageManager.Yarn ? tempNodeModules : tempPath;
|
|
105
|
+
const installArgs = [
|
|
106
|
+
...(extraArgs !== null && extraArgs !== void 0 ? extraArgs : []),
|
|
107
|
+
`${packageManagerArgs.prefix}="${prefixPath}"`,
|
|
108
|
+
packageManagerArgs.noLockfile,
|
|
109
|
+
];
|
|
110
|
+
return {
|
|
111
|
+
success: await this.install(packageName, true, installArgs, tempPath),
|
|
112
|
+
tempNodeModules,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
getArguments() {
|
|
116
|
+
switch (this.name) {
|
|
117
|
+
case workspace_schema_1.PackageManager.Yarn:
|
|
118
|
+
return {
|
|
119
|
+
silent: '--silent',
|
|
120
|
+
saveDev: '--dev',
|
|
121
|
+
install: 'add',
|
|
122
|
+
prefix: '--modules-folder',
|
|
123
|
+
noLockfile: '--no-lockfile',
|
|
124
|
+
};
|
|
125
|
+
case workspace_schema_1.PackageManager.Pnpm:
|
|
126
|
+
return {
|
|
127
|
+
silent: '--silent',
|
|
128
|
+
saveDev: '--save-dev',
|
|
129
|
+
install: 'add',
|
|
130
|
+
installAll: 'install',
|
|
131
|
+
prefix: '--prefix',
|
|
132
|
+
noLockfile: '--no-lockfile',
|
|
133
|
+
};
|
|
134
|
+
default:
|
|
135
|
+
return {
|
|
136
|
+
silent: '--quiet',
|
|
137
|
+
saveDev: '--save-dev',
|
|
138
|
+
install: 'install',
|
|
139
|
+
installAll: 'install',
|
|
140
|
+
prefix: '--prefix',
|
|
141
|
+
noLockfile: '--no-package-lock',
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
async run(args, cwd = process.cwd()) {
|
|
146
|
+
const spinner = new spinner_1.Spinner();
|
|
147
|
+
spinner.start('Installing packages...');
|
|
148
|
+
return new Promise((resolve) => {
|
|
149
|
+
var _a, _b;
|
|
150
|
+
const bufferedOutput = [];
|
|
151
|
+
const childProcess = (0, child_process_1.spawn)(this.name, args, {
|
|
152
|
+
stdio: 'pipe',
|
|
153
|
+
shell: true,
|
|
154
|
+
cwd,
|
|
155
|
+
}).on('close', (code) => {
|
|
156
|
+
if (code === 0) {
|
|
157
|
+
spinner.succeed('Packages successfully installed.');
|
|
158
|
+
resolve(true);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
spinner.stop();
|
|
162
|
+
bufferedOutput.forEach(({ stream, data }) => stream.write(data));
|
|
163
|
+
spinner.fail('Packages installation failed, see above.');
|
|
164
|
+
resolve(false);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
(_a = childProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => bufferedOutput.push({ stream: process.stdout, data: data }));
|
|
168
|
+
(_b = childProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => bufferedOutput.push({ stream: process.stderr, data: data }));
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
// TODO(alan-agius4): use the memoize decorator when it's merged.
|
|
172
|
+
getVersion(name) {
|
|
173
|
+
try {
|
|
174
|
+
return (0, child_process_1.execSync)(`${name} --version`, {
|
|
175
|
+
encoding: 'utf8',
|
|
176
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
177
|
+
env: {
|
|
178
|
+
...process.env,
|
|
179
|
+
// NPM updater notifier will prevents the child process from closing until it timeout after 3 minutes.
|
|
180
|
+
NO_UPDATE_NOTIFIER: '1',
|
|
181
|
+
NPM_CONFIG_UPDATE_NOTIFIER: 'false',
|
|
182
|
+
},
|
|
183
|
+
}).trim();
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// TODO(alan-agius4): use the memoize decorator when it's merged.
|
|
190
|
+
getName() {
|
|
191
|
+
const packageManager = this.getConfiguredPackageManager();
|
|
192
|
+
if (packageManager) {
|
|
193
|
+
return packageManager;
|
|
194
|
+
}
|
|
195
|
+
const hasNpmLock = this.hasLockfile(workspace_schema_1.PackageManager.Npm);
|
|
196
|
+
const hasYarnLock = this.hasLockfile(workspace_schema_1.PackageManager.Yarn);
|
|
197
|
+
const hasPnpmLock = this.hasLockfile(workspace_schema_1.PackageManager.Pnpm);
|
|
198
|
+
// PERF NOTE: `this.getVersion` spawns the package a the child_process which can take around ~300ms at times.
|
|
199
|
+
// Therefore, we should only call this method when needed. IE: don't call `this.getVersion(PackageManager.Pnpm)` unless truly needed.
|
|
200
|
+
// The result of this method is not stored in a variable because it's memoized.
|
|
201
|
+
if (hasNpmLock) {
|
|
202
|
+
// Has NPM lock file.
|
|
203
|
+
if (!hasYarnLock && !hasPnpmLock && this.getVersion(workspace_schema_1.PackageManager.Npm)) {
|
|
204
|
+
// Only NPM lock file and NPM binary is available.
|
|
205
|
+
return workspace_schema_1.PackageManager.Npm;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
// No NPM lock file.
|
|
210
|
+
if (hasYarnLock && this.getVersion(workspace_schema_1.PackageManager.Yarn)) {
|
|
211
|
+
// Yarn lock file and Yarn binary is available.
|
|
212
|
+
return workspace_schema_1.PackageManager.Yarn;
|
|
213
|
+
}
|
|
214
|
+
else if (hasPnpmLock && this.getVersion(workspace_schema_1.PackageManager.Pnpm)) {
|
|
215
|
+
// PNPM lock file and PNPM binary is available.
|
|
216
|
+
return workspace_schema_1.PackageManager.Pnpm;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (!this.getVersion(workspace_schema_1.PackageManager.Npm)) {
|
|
220
|
+
// Doesn't have NPM installed.
|
|
221
|
+
const hasYarn = !!this.getVersion(workspace_schema_1.PackageManager.Yarn);
|
|
222
|
+
const hasPnpm = !!this.getVersion(workspace_schema_1.PackageManager.Pnpm);
|
|
223
|
+
if (hasYarn && !hasPnpm) {
|
|
224
|
+
return workspace_schema_1.PackageManager.Yarn;
|
|
225
|
+
}
|
|
226
|
+
else if (!hasYarn && hasPnpm) {
|
|
227
|
+
return workspace_schema_1.PackageManager.Pnpm;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
// TODO: This should eventually inform the user of ambiguous package manager usage.
|
|
231
|
+
// Potentially with a prompt to choose and optionally set as the default.
|
|
232
|
+
return workspace_schema_1.PackageManager.Npm;
|
|
233
|
+
}
|
|
234
|
+
hasLockfile(packageManager) {
|
|
30
235
|
let lockfileName;
|
|
31
236
|
switch (packageManager) {
|
|
32
237
|
case workspace_schema_1.PackageManager.Yarn:
|
|
@@ -40,67 +245,32 @@ async function hasLockfile(root, packageManager) {
|
|
|
40
245
|
lockfileName = 'package-lock.json';
|
|
41
246
|
break;
|
|
42
247
|
}
|
|
43
|
-
|
|
44
|
-
return true;
|
|
45
|
-
}
|
|
46
|
-
catch {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
async function getPackageManager(root) {
|
|
51
|
-
const packageManager = await (0, config_1.getConfiguredPackageManager)();
|
|
52
|
-
if (packageManager) {
|
|
53
|
-
return packageManager;
|
|
54
|
-
}
|
|
55
|
-
const [hasYarnLock, hasNpmLock, hasPnpmLock] = await Promise.all([
|
|
56
|
-
hasLockfile(root, workspace_schema_1.PackageManager.Yarn),
|
|
57
|
-
hasLockfile(root, workspace_schema_1.PackageManager.Npm),
|
|
58
|
-
hasLockfile(root, workspace_schema_1.PackageManager.Pnpm),
|
|
59
|
-
]);
|
|
60
|
-
const hasYarn = await supports(workspace_schema_1.PackageManager.Yarn);
|
|
61
|
-
if (hasYarn && hasYarnLock && !hasNpmLock) {
|
|
62
|
-
return workspace_schema_1.PackageManager.Yarn;
|
|
63
|
-
}
|
|
64
|
-
const hasPnpm = await supports(workspace_schema_1.PackageManager.Pnpm);
|
|
65
|
-
if (hasPnpm && hasPnpmLock && !hasNpmLock) {
|
|
66
|
-
return workspace_schema_1.PackageManager.Pnpm;
|
|
248
|
+
return (0, fs_1.existsSync)((0, path_1.join)(this.context.root, lockfileName));
|
|
67
249
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if ((await getPackageManager(root)) !== workspace_schema_1.PackageManager.Npm) {
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
try {
|
|
91
|
-
const versionText = (0, child_process_1.execSync)('npm --version', { encoding: 'utf8', stdio: 'pipe' }).trim();
|
|
92
|
-
const version = (0, semver_1.valid)(versionText);
|
|
93
|
-
if (!version) {
|
|
94
|
-
return;
|
|
250
|
+
getConfiguredPackageManager() {
|
|
251
|
+
var _a;
|
|
252
|
+
const getPackageManager = (source) => {
|
|
253
|
+
if (source && (0, core_1.isJsonObject)(source)) {
|
|
254
|
+
const value = source['packageManager'];
|
|
255
|
+
if (typeof value === 'string') {
|
|
256
|
+
return value;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return undefined;
|
|
260
|
+
};
|
|
261
|
+
let result;
|
|
262
|
+
const { workspace: localWorkspace, globalConfiguration: globalWorkspace } = this.context;
|
|
263
|
+
if (localWorkspace) {
|
|
264
|
+
const project = (0, config_1.getProjectByCwd)(localWorkspace);
|
|
265
|
+
if (project) {
|
|
266
|
+
result = getPackageManager((_a = localWorkspace.projects.get(project)) === null || _a === void 0 ? void 0 : _a.extensions['cli']);
|
|
267
|
+
}
|
|
268
|
+
result !== null && result !== void 0 ? result : (result = getPackageManager(localWorkspace.extensions['cli']));
|
|
95
269
|
}
|
|
96
|
-
if (
|
|
97
|
-
|
|
98
|
-
console.warn(`npm version ${version} detected.` +
|
|
99
|
-
' When using npm 7 with the Angular CLI, npm version 7.5.6 or higher is recommended.');
|
|
270
|
+
if (!result) {
|
|
271
|
+
result = getPackageManager(globalWorkspace === null || globalWorkspace === void 0 ? void 0 : globalWorkspace.extensions['cli']);
|
|
100
272
|
}
|
|
101
|
-
|
|
102
|
-
catch {
|
|
103
|
-
// npm is not installed
|
|
273
|
+
return result;
|
|
104
274
|
}
|
|
105
275
|
}
|
|
106
|
-
exports.
|
|
276
|
+
exports.PackageManagerUtils = PackageManagerUtils;
|