@angular/cli 14.0.0-next.9 → 14.0.0-rc.0
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/config/schema.json +18 -0
- package/lib/config/workspace-schema.d.ts +12 -0
- package/package.json +14 -14
- package/src/command-builder/architect-base-command-module.d.ts +1 -1
- package/src/command-builder/command-module.js +7 -0
- package/src/command-builder/command-runner.js +2 -7
- package/src/command-builder/schematics-command-module.js +1 -3
- package/src/command-builder/utilities/command.d.ts +1 -1
- package/src/command-builder/utilities/schematic-engine-host.js +3 -1
- package/src/commands/completion/cli.d.ts +1 -1
- package/src/commands/completion/cli.js +32 -2
- package/src/commands/completion/long-description.md +5 -1
- package/src/commands/config/cli.js +1 -0
- package/src/utilities/completion.d.ts +22 -0
- package/src/utilities/completion.js +219 -0
- package/src/utilities/environment-options.d.ts +1 -0
- package/src/utilities/environment-options.js +8 -1
- package/src/utilities/json-file.js +1 -0
package/lib/config/schema.json
CHANGED
|
@@ -812,6 +812,12 @@
|
|
|
812
812
|
"alias": "t",
|
|
813
813
|
"x-user-analytics": 10
|
|
814
814
|
},
|
|
815
|
+
"standalone": {
|
|
816
|
+
"description": "Whether the generated component is standalone.",
|
|
817
|
+
"type": "boolean",
|
|
818
|
+
"default": false,
|
|
819
|
+
"x-user-analytics": 15
|
|
820
|
+
},
|
|
815
821
|
"viewEncapsulation": {
|
|
816
822
|
"description": "The view encapsulation strategy to use in the new component.",
|
|
817
823
|
"enum": [
|
|
@@ -964,6 +970,12 @@
|
|
|
964
970
|
"format": "html-selector",
|
|
965
971
|
"description": "The HTML selector to use for this directive."
|
|
966
972
|
},
|
|
973
|
+
"standalone": {
|
|
974
|
+
"description": "Whether the generated directive is standalone.",
|
|
975
|
+
"type": "boolean",
|
|
976
|
+
"default": false,
|
|
977
|
+
"x-user-analytics": 15
|
|
978
|
+
},
|
|
967
979
|
"flat": {
|
|
968
980
|
"type": "boolean",
|
|
969
981
|
"description": "When true (the default), creates the new files at the top level of the current project.",
|
|
@@ -1251,6 +1263,12 @@
|
|
|
1251
1263
|
"description": "Do not import this pipe into the owning NgModule.",
|
|
1252
1264
|
"x-user-analytics": 18
|
|
1253
1265
|
},
|
|
1266
|
+
"standalone": {
|
|
1267
|
+
"description": "Whether the generated pipe is standalone.",
|
|
1268
|
+
"type": "boolean",
|
|
1269
|
+
"default": false,
|
|
1270
|
+
"x-user-analytics": 15
|
|
1271
|
+
},
|
|
1254
1272
|
"module": {
|
|
1255
1273
|
"type": "string",
|
|
1256
1274
|
"description": "The declaring NgModule.",
|
|
@@ -292,6 +292,10 @@ export interface AngularComponentOptionsSchema {
|
|
|
292
292
|
* Do not create "spec.ts" test files for the new component.
|
|
293
293
|
*/
|
|
294
294
|
skipTests?: boolean;
|
|
295
|
+
/**
|
|
296
|
+
* Whether the generated component is standalone.
|
|
297
|
+
*/
|
|
298
|
+
standalone?: boolean;
|
|
295
299
|
/**
|
|
296
300
|
* The file extension or preprocessor to use for style files, or 'none' to skip generating
|
|
297
301
|
* the style file.
|
|
@@ -369,6 +373,10 @@ export interface AngularDirectiveOptionsSchema {
|
|
|
369
373
|
* Do not create "spec.ts" test files for the new class.
|
|
370
374
|
*/
|
|
371
375
|
skipTests?: boolean;
|
|
376
|
+
/**
|
|
377
|
+
* Whether the generated directive is standalone.
|
|
378
|
+
*/
|
|
379
|
+
standalone?: boolean;
|
|
372
380
|
}
|
|
373
381
|
/**
|
|
374
382
|
* Generates a new, generic enum definition for the given or default project.
|
|
@@ -640,6 +648,10 @@ export interface AngularPipeOptionsSchema {
|
|
|
640
648
|
* Do not create "spec.ts" test files for the new pipe.
|
|
641
649
|
*/
|
|
642
650
|
skipTests?: boolean;
|
|
651
|
+
/**
|
|
652
|
+
* Whether the generated pipe is standalone.
|
|
653
|
+
*/
|
|
654
|
+
standalone?: boolean;
|
|
643
655
|
}
|
|
644
656
|
/**
|
|
645
657
|
* Generates a new, generic resolver definition in the given or default project.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular/cli",
|
|
3
|
-
"version": "14.0.0-
|
|
3
|
+
"version": "14.0.0-rc.0",
|
|
4
4
|
"description": "CLI tool for Angular",
|
|
5
5
|
"main": "lib/cli/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -25,23 +25,23 @@
|
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://github.com/angular/angular-cli",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@angular-devkit/architect": "0.1400.0-
|
|
29
|
-
"@angular-devkit/core": "14.0.0-
|
|
30
|
-
"@angular-devkit/schematics": "14.0.0-
|
|
31
|
-
"@schematics/angular": "14.0.0-
|
|
28
|
+
"@angular-devkit/architect": "0.1400.0-rc.0",
|
|
29
|
+
"@angular-devkit/core": "14.0.0-rc.0",
|
|
30
|
+
"@angular-devkit/schematics": "14.0.0-rc.0",
|
|
31
|
+
"@schematics/angular": "14.0.0-rc.0",
|
|
32
32
|
"@yarnpkg/lockfile": "1.1.0",
|
|
33
33
|
"ansi-colors": "4.1.1",
|
|
34
34
|
"debug": "4.3.4",
|
|
35
35
|
"ini": "3.0.0",
|
|
36
|
-
"inquirer": "8.2.
|
|
36
|
+
"inquirer": "8.2.4",
|
|
37
37
|
"jsonc-parser": "3.0.0",
|
|
38
38
|
"npm-package-arg": "9.0.2",
|
|
39
39
|
"npm-pick-manifest": "7.0.1",
|
|
40
40
|
"open": "8.4.0",
|
|
41
41
|
"ora": "5.4.1",
|
|
42
|
-
"pacote": "13.
|
|
42
|
+
"pacote": "13.3.0",
|
|
43
43
|
"resolve": "1.22.0",
|
|
44
|
-
"semver": "7.3.
|
|
44
|
+
"semver": "7.3.7",
|
|
45
45
|
"symbol-observable": "4.0.0",
|
|
46
46
|
"uuid": "8.3.2",
|
|
47
47
|
"yargs": "17.4.1"
|
|
@@ -49,12 +49,12 @@
|
|
|
49
49
|
"ng-update": {
|
|
50
50
|
"migrations": "@schematics/angular/migrations/migration-collection.json",
|
|
51
51
|
"packageGroup": {
|
|
52
|
-
"@angular/cli": "14.0.0-
|
|
53
|
-
"@angular-devkit/architect": "0.1400.0-
|
|
54
|
-
"@angular-devkit/build-angular": "14.0.0-
|
|
55
|
-
"@angular-devkit/build-webpack": "0.1400.0-
|
|
56
|
-
"@angular-devkit/core": "14.0.0-
|
|
57
|
-
"@angular-devkit/schematics": "14.0.0-
|
|
52
|
+
"@angular/cli": "14.0.0-rc.0",
|
|
53
|
+
"@angular-devkit/architect": "0.1400.0-rc.0",
|
|
54
|
+
"@angular-devkit/build-angular": "14.0.0-rc.0",
|
|
55
|
+
"@angular-devkit/build-webpack": "0.1400.0-rc.0",
|
|
56
|
+
"@angular-devkit/core": "14.0.0-rc.0",
|
|
57
|
+
"@angular-devkit/schematics": "14.0.0-rc.0"
|
|
58
58
|
}
|
|
59
59
|
},
|
|
60
60
|
"engines": {
|
|
@@ -13,7 +13,7 @@ export interface MissingTargetChoice {
|
|
|
13
13
|
name: string;
|
|
14
14
|
value: string;
|
|
15
15
|
}
|
|
16
|
-
export declare abstract class ArchitectBaseCommandModule<T> extends CommandModule<T> implements CommandModuleImplementation<T> {
|
|
16
|
+
export declare abstract class ArchitectBaseCommandModule<T extends object> extends CommandModule<T> implements CommandModuleImplementation<T> {
|
|
17
17
|
static scope: CommandScope;
|
|
18
18
|
protected shouldReportAnalytics: boolean;
|
|
19
19
|
protected readonly missingTargetChoices: MissingTargetChoice[] | undefined;
|
|
@@ -42,6 +42,7 @@ const fs_1 = require("fs");
|
|
|
42
42
|
const path = __importStar(require("path"));
|
|
43
43
|
const helpers_1 = require("yargs/helpers");
|
|
44
44
|
const analytics_1 = require("../analytics/analytics");
|
|
45
|
+
const completion_1 = require("../utilities/completion");
|
|
45
46
|
const memoize_1 = require("../utilities/memoize");
|
|
46
47
|
var CommandScope;
|
|
47
48
|
(function (CommandScope) {
|
|
@@ -89,6 +90,12 @@ class CommandModule {
|
|
|
89
90
|
for (const [key, value] of Object.entries(options)) {
|
|
90
91
|
camelCasedOptions[helpers_1.Parser.camelCase(key)] = value;
|
|
91
92
|
}
|
|
93
|
+
// Set up autocompletion if appropriate.
|
|
94
|
+
const autocompletionExitCode = await (0, completion_1.considerSettingUpAutocompletion)(this.commandName, this.context.logger);
|
|
95
|
+
if (autocompletionExitCode !== undefined) {
|
|
96
|
+
process.exitCode = autocompletionExitCode;
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
92
99
|
// Gather and report analytics.
|
|
93
100
|
const analytics = await this.getAnalytics();
|
|
94
101
|
if (this.shouldReportAnalytics) {
|
|
@@ -110,16 +110,11 @@ async function runCommand(args, logger) {
|
|
|
110
110
|
}
|
|
111
111
|
localYargs = (0, command_1.addCommandModuleToYargs)(localYargs, CommandModule, context);
|
|
112
112
|
}
|
|
113
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
114
|
-
const usageInstance = localYargs.getInternalMethods().getUsageInstance();
|
|
115
113
|
if (jsonHelp) {
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
115
|
+
const usageInstance = localYargs.getInternalMethods().getUsageInstance();
|
|
116
116
|
usageInstance.help = () => (0, json_help_1.jsonHelpUsage)();
|
|
117
117
|
}
|
|
118
|
-
if (getYargsCompletions) {
|
|
119
|
-
// When in auto completion mode avoid printing description as it causes a slugish
|
|
120
|
-
// experience when there are a large set of options.
|
|
121
|
-
usageInstance.getDescriptions = () => ({});
|
|
122
|
-
}
|
|
123
118
|
await localYargs
|
|
124
119
|
.scriptName('ng')
|
|
125
120
|
// https://github.com/yargs/yargs/blob/main/docs/advanced.md#customizing-yargs-parser
|
|
@@ -109,9 +109,7 @@ class SchematicsCommandModule extends command_module_1.CommandModule {
|
|
|
109
109
|
optionTransforms: [
|
|
110
110
|
// Add configuration file defaults
|
|
111
111
|
async (schematic, current) => {
|
|
112
|
-
const projectName = typeof current.project === 'string'
|
|
113
|
-
? current.project
|
|
114
|
-
: this.getProjectName();
|
|
112
|
+
const projectName = typeof (current === null || current === void 0 ? void 0 : current.project) === 'string' ? current.project : this.getProjectName();
|
|
115
113
|
return {
|
|
116
114
|
...(await (0, config_1.getSchematicDefaults)(schematic.collection.name, schematic.name, projectName)),
|
|
117
115
|
...current,
|
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
import { Argv } from 'yargs';
|
|
9
9
|
import { CommandContext, CommandModule, CommandModuleImplementation } from '../command-module';
|
|
10
10
|
export declare const demandCommandFailureMessage = "You need to specify a command before moving on. Use '--help' to view the available commands.";
|
|
11
|
-
export declare function addCommandModuleToYargs<T, U extends Partial<CommandModuleImplementation> & {
|
|
11
|
+
export declare function addCommandModuleToYargs<T extends object, U extends Partial<CommandModuleImplementation> & {
|
|
12
12
|
new (context: CommandContext): Partial<CommandModuleImplementation> & CommandModule;
|
|
13
13
|
}>(localYargs: Argv<T>, commandModule: U, context: CommandContext): Argv<T>;
|
|
@@ -161,7 +161,9 @@ function wrap(schematicFile, schematicDirectory, moduleCache, exportName) {
|
|
|
161
161
|
const schematicCode = (0, fs_1.readFileSync)(schematicFile, 'utf8');
|
|
162
162
|
// `module` is required due to @angular/localize ng-add being in UMD format
|
|
163
163
|
const headerCode = '(function() {\nvar exports = {};\nvar module = { exports };\n';
|
|
164
|
-
const footerCode = exportName
|
|
164
|
+
const footerCode = exportName
|
|
165
|
+
? `\nreturn module.exports['${exportName}'];});`
|
|
166
|
+
: '\nreturn module.exports;});';
|
|
165
167
|
const script = new vm_1.Script(headerCode + schematicCode + footerCode, {
|
|
166
168
|
filename: schematicFile,
|
|
167
169
|
lineOffset: 3,
|
|
@@ -14,13 +14,44 @@ exports.CompletionCommandModule = void 0;
|
|
|
14
14
|
const path_1 = require("path");
|
|
15
15
|
const yargs_1 = __importDefault(require("yargs"));
|
|
16
16
|
const command_module_1 = require("../../command-builder/command-module");
|
|
17
|
+
const command_1 = require("../../command-builder/utilities/command");
|
|
18
|
+
const color_1 = require("../../utilities/color");
|
|
19
|
+
const completion_1 = require("../../utilities/completion");
|
|
17
20
|
class CompletionCommandModule extends command_module_1.CommandModule {
|
|
18
21
|
constructor() {
|
|
19
22
|
super(...arguments);
|
|
20
23
|
this.command = 'completion';
|
|
21
|
-
this.describe = '
|
|
24
|
+
this.describe = 'Set up Angular CLI autocompletion for your terminal.';
|
|
22
25
|
this.longDescriptionPath = (0, path_1.join)(__dirname, 'long-description.md');
|
|
23
26
|
}
|
|
27
|
+
builder(localYargs) {
|
|
28
|
+
return (0, command_1.addCommandModuleToYargs)(localYargs, CompletionScriptCommandModule, this.context);
|
|
29
|
+
}
|
|
30
|
+
async run() {
|
|
31
|
+
let rcFile;
|
|
32
|
+
try {
|
|
33
|
+
rcFile = await (0, completion_1.initializeAutocomplete)();
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
this.context.logger.error(err.message);
|
|
37
|
+
return 1;
|
|
38
|
+
}
|
|
39
|
+
this.context.logger.info(`
|
|
40
|
+
Appended \`source <(ng completion script)\` to \`${rcFile}\`. Restart your terminal or run the following to autocomplete \`ng\` commands:
|
|
41
|
+
|
|
42
|
+
${color_1.colors.yellow('source <(ng completion script)')}
|
|
43
|
+
`.trim());
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.CompletionCommandModule = CompletionCommandModule;
|
|
48
|
+
class CompletionScriptCommandModule extends command_module_1.CommandModule {
|
|
49
|
+
constructor() {
|
|
50
|
+
super(...arguments);
|
|
51
|
+
this.command = 'script';
|
|
52
|
+
this.describe = 'Generate a bash and zsh real-time type-ahead autocompletion script.';
|
|
53
|
+
this.longDescriptionPath = undefined;
|
|
54
|
+
}
|
|
24
55
|
builder(localYargs) {
|
|
25
56
|
return localYargs;
|
|
26
57
|
}
|
|
@@ -28,4 +59,3 @@ class CompletionCommandModule extends command_module_1.CommandModule {
|
|
|
28
59
|
yargs_1.default.showCompletionScript();
|
|
29
60
|
}
|
|
30
61
|
}
|
|
31
|
-
exports.CompletionCommandModule = CompletionCommandModule;
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
To enable
|
|
1
|
+
To enable Bash and Zsh real-time type-ahead autocompletion, run
|
|
2
|
+
`ng completion` and restart your terminal.
|
|
3
|
+
|
|
4
|
+
Alternatively, append `source <(ng completion script)` to the appropriate `.bashrc`,
|
|
5
|
+
`.bash_profile`, `.zshrc`, `.zsh_profile`, or `.profile` file.
|
|
@@ -83,6 +83,7 @@ class ConfigCommandModule extends command_module_1.CommandModule {
|
|
|
83
83
|
'cli.analytics',
|
|
84
84
|
'cli.analyticsSharing.tracking',
|
|
85
85
|
'cli.analyticsSharing.uuid',
|
|
86
|
+
'cli.completion.prompted',
|
|
86
87
|
]);
|
|
87
88
|
if (options.global &&
|
|
88
89
|
!options.jsonPath.startsWith('schematics.') &&
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
import { logging } from '@angular-devkit/core';
|
|
9
|
+
/**
|
|
10
|
+
* Checks if it is appropriate to prompt the user to setup autocompletion. If not, does nothing. If
|
|
11
|
+
* so prompts and sets up autocompletion for the user. Returns an exit code if the program should
|
|
12
|
+
* terminate, otherwise returns `undefined`.
|
|
13
|
+
* @returns an exit code if the program should terminate, undefined otherwise.
|
|
14
|
+
*/
|
|
15
|
+
export declare function considerSettingUpAutocompletion(command: string, logger: logging.Logger): Promise<number | undefined>;
|
|
16
|
+
/**
|
|
17
|
+
* Sets up autocompletion for the user's terminal. This attempts to find the configuration file for
|
|
18
|
+
* the current shell (`.bashrc`, `.zshrc`, etc.) and append a command which enables autocompletion
|
|
19
|
+
* for the Angular CLI. Supports only Bash and Zsh. Returns whether or not it was successful.
|
|
20
|
+
* @return The full path of the configuration file modified.
|
|
21
|
+
*/
|
|
22
|
+
export declare function initializeAutocomplete(): Promise<string>;
|
|
@@ -0,0 +1,219 @@
|
|
|
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
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
26
|
+
if (mod && mod.__esModule) return mod;
|
|
27
|
+
var result = {};
|
|
28
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
29
|
+
__setModuleDefault(result, mod);
|
|
30
|
+
return result;
|
|
31
|
+
};
|
|
32
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
+
exports.initializeAutocomplete = exports.considerSettingUpAutocompletion = void 0;
|
|
34
|
+
const core_1 = require("@angular-devkit/core");
|
|
35
|
+
const fs_1 = require("fs");
|
|
36
|
+
const path = __importStar(require("path"));
|
|
37
|
+
const process_1 = require("process");
|
|
38
|
+
const color_1 = require("../utilities/color");
|
|
39
|
+
const config_1 = require("../utilities/config");
|
|
40
|
+
const environment_options_1 = require("../utilities/environment-options");
|
|
41
|
+
const tty_1 = require("../utilities/tty");
|
|
42
|
+
/**
|
|
43
|
+
* Checks if it is appropriate to prompt the user to setup autocompletion. If not, does nothing. If
|
|
44
|
+
* so prompts and sets up autocompletion for the user. Returns an exit code if the program should
|
|
45
|
+
* terminate, otherwise returns `undefined`.
|
|
46
|
+
* @returns an exit code if the program should terminate, undefined otherwise.
|
|
47
|
+
*/
|
|
48
|
+
async function considerSettingUpAutocompletion(command, logger) {
|
|
49
|
+
// Check if we should prompt the user to setup autocompletion.
|
|
50
|
+
const completionConfig = await getCompletionConfig();
|
|
51
|
+
if (!(await shouldPromptForAutocompletionSetup(command, completionConfig))) {
|
|
52
|
+
return undefined; // Already set up or prompted previously, nothing to do.
|
|
53
|
+
}
|
|
54
|
+
// Prompt the user and record their response.
|
|
55
|
+
const shouldSetupAutocompletion = await promptForAutocompletion();
|
|
56
|
+
if (!shouldSetupAutocompletion) {
|
|
57
|
+
// User rejected the prompt and doesn't want autocompletion.
|
|
58
|
+
logger.info(`
|
|
59
|
+
Ok, you won't be prompted again. Should you change your mind, the following command will set up autocompletion for you:
|
|
60
|
+
|
|
61
|
+
${color_1.colors.yellow(`ng completion`)}
|
|
62
|
+
`.trim());
|
|
63
|
+
// Save configuration to remember that the user was prompted and avoid prompting again.
|
|
64
|
+
await setCompletionConfig({ ...completionConfig, prompted: true });
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
// User accepted the prompt, set up autocompletion.
|
|
68
|
+
let rcFile;
|
|
69
|
+
try {
|
|
70
|
+
rcFile = await initializeAutocomplete();
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
// Failed to set up autocompeletion, log the error and abort.
|
|
74
|
+
logger.error(err.message);
|
|
75
|
+
return 1;
|
|
76
|
+
}
|
|
77
|
+
// Notify the user autocompletion was set up successfully.
|
|
78
|
+
logger.info(`
|
|
79
|
+
Appended \`source <(ng completion script)\` to \`${rcFile}\`. Restart your terminal or run the following to autocomplete \`ng\` commands:
|
|
80
|
+
|
|
81
|
+
${color_1.colors.yellow(`source <(ng completion script)`)}
|
|
82
|
+
`.trim());
|
|
83
|
+
// Save configuration to remember that the user was prompted.
|
|
84
|
+
await setCompletionConfig({ ...completionConfig, prompted: true });
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
exports.considerSettingUpAutocompletion = considerSettingUpAutocompletion;
|
|
88
|
+
async function getCompletionConfig() {
|
|
89
|
+
var _a;
|
|
90
|
+
const wksp = await (0, config_1.getWorkspace)('global');
|
|
91
|
+
return (_a = wksp === null || wksp === void 0 ? void 0 : wksp.getCli()) === null || _a === void 0 ? void 0 : _a['completion'];
|
|
92
|
+
}
|
|
93
|
+
async function setCompletionConfig(config) {
|
|
94
|
+
var _a;
|
|
95
|
+
var _b;
|
|
96
|
+
const wksp = await (0, config_1.getWorkspace)('global');
|
|
97
|
+
if (!wksp) {
|
|
98
|
+
throw new Error(`Could not find global workspace`);
|
|
99
|
+
}
|
|
100
|
+
(_a = (_b = wksp.extensions)['cli']) !== null && _a !== void 0 ? _a : (_b['cli'] = {});
|
|
101
|
+
const cli = wksp.extensions['cli'];
|
|
102
|
+
if (!core_1.json.isJsonObject(cli)) {
|
|
103
|
+
throw new Error(`Invalid config found at ${wksp.filePath}. \`extensions.cli\` should be an object.`);
|
|
104
|
+
}
|
|
105
|
+
cli.completion = config;
|
|
106
|
+
await wksp.save();
|
|
107
|
+
}
|
|
108
|
+
async function shouldPromptForAutocompletionSetup(command, config) {
|
|
109
|
+
// Force whether or not to prompt for autocomplete to give an easy path for e2e testing to skip.
|
|
110
|
+
if (environment_options_1.forceAutocomplete !== undefined) {
|
|
111
|
+
return environment_options_1.forceAutocomplete;
|
|
112
|
+
}
|
|
113
|
+
// Don't prompt on `ng update` or `ng completion`.
|
|
114
|
+
if (command === 'update' || command === 'completion') {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
// Non-interactive and continuous integration systems don't care about autocompletion.
|
|
118
|
+
if (!(0, tty_1.isTTY)()) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
// Skip prompt if the user has already been prompted.
|
|
122
|
+
if (config === null || config === void 0 ? void 0 : config.prompted) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
// `$HOME` variable is necessary to find RC files to modify.
|
|
126
|
+
const home = process_1.env['HOME'];
|
|
127
|
+
if (!home) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
// Get possible RC files for the current shell.
|
|
131
|
+
const shell = process_1.env['SHELL'];
|
|
132
|
+
if (!shell) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
const rcFiles = getShellRunCommandCandidates(shell, home);
|
|
136
|
+
if (!rcFiles) {
|
|
137
|
+
return false; // Unknown shell.
|
|
138
|
+
}
|
|
139
|
+
// Check each RC file if they already use `ng completion script` in any capacity and don't prompt.
|
|
140
|
+
for (const rcFile of rcFiles) {
|
|
141
|
+
const contents = await fs_1.promises.readFile(rcFile, 'utf-8').catch(() => undefined);
|
|
142
|
+
if (contents === null || contents === void 0 ? void 0 : contents.includes('ng completion script')) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
async function promptForAutocompletion() {
|
|
149
|
+
// Dynamically load `inquirer` so users don't have to pay the cost of parsing and executing it for
|
|
150
|
+
// the 99% of builds that *don't* prompt for autocompletion.
|
|
151
|
+
const { prompt } = await Promise.resolve().then(() => __importStar(require('inquirer')));
|
|
152
|
+
const { autocomplete } = await prompt([
|
|
153
|
+
{
|
|
154
|
+
name: 'autocomplete',
|
|
155
|
+
type: 'confirm',
|
|
156
|
+
message: `
|
|
157
|
+
Would you like to enable autocompletion? This will set up your terminal so pressing TAB while typing
|
|
158
|
+
Angular CLI commands will show possible options and autocomplete arguments. (Enabling autocompletion
|
|
159
|
+
will modify configuration files in your home directory.)
|
|
160
|
+
`
|
|
161
|
+
.split('\n')
|
|
162
|
+
.join(' ')
|
|
163
|
+
.trim(),
|
|
164
|
+
default: true,
|
|
165
|
+
},
|
|
166
|
+
]);
|
|
167
|
+
return autocomplete;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Sets up autocompletion for the user's terminal. This attempts to find the configuration file for
|
|
171
|
+
* the current shell (`.bashrc`, `.zshrc`, etc.) and append a command which enables autocompletion
|
|
172
|
+
* for the Angular CLI. Supports only Bash and Zsh. Returns whether or not it was successful.
|
|
173
|
+
* @return The full path of the configuration file modified.
|
|
174
|
+
*/
|
|
175
|
+
async function initializeAutocomplete() {
|
|
176
|
+
var _a, _b;
|
|
177
|
+
// Get the currently active `$SHELL` and `$HOME` environment variables.
|
|
178
|
+
const shell = process_1.env['SHELL'];
|
|
179
|
+
if (!shell) {
|
|
180
|
+
throw new Error('`$SHELL` environment variable not set. Angular CLI autocompletion only supports Bash or' +
|
|
181
|
+
" Zsh. If you're on Windows, Cmd and Powershell don't support command autocompletion," +
|
|
182
|
+
' but Git Bash or Windows Subsystem for Linux should work, so please try again in one of' +
|
|
183
|
+
' those environments.');
|
|
184
|
+
}
|
|
185
|
+
const home = process_1.env['HOME'];
|
|
186
|
+
if (!home) {
|
|
187
|
+
throw new Error('`$HOME` environment variable not set. Setting up autocompletion modifies configuration files' +
|
|
188
|
+
' in the home directory and must be set.');
|
|
189
|
+
}
|
|
190
|
+
// Get all the files we can add `ng completion` to which apply to the user's `$SHELL`.
|
|
191
|
+
const runCommandCandidates = getShellRunCommandCandidates(shell, home);
|
|
192
|
+
if (!runCommandCandidates) {
|
|
193
|
+
throw new Error(`Unknown \`$SHELL\` environment variable value (${shell}). Angular CLI autocompletion only supports Bash or Zsh.`);
|
|
194
|
+
}
|
|
195
|
+
// Get the first file that already exists or fallback to a new file of the first candidate.
|
|
196
|
+
const candidates = await Promise.allSettled(runCommandCandidates.map((rcFile) => fs_1.promises.access(rcFile).then(() => rcFile)));
|
|
197
|
+
const rcFile = (_b = (_a = candidates.find((result) => result.status === 'fulfilled')) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : runCommandCandidates[0];
|
|
198
|
+
// Append Angular autocompletion setup to RC file.
|
|
199
|
+
try {
|
|
200
|
+
await fs_1.promises.appendFile(rcFile, '\n\n# Load Angular CLI autocompletion.\nsource <(ng completion script)\n');
|
|
201
|
+
}
|
|
202
|
+
catch (err) {
|
|
203
|
+
throw new Error(`Failed to append autocompletion setup to \`${rcFile}\`:\n${err.message}`);
|
|
204
|
+
}
|
|
205
|
+
return rcFile;
|
|
206
|
+
}
|
|
207
|
+
exports.initializeAutocomplete = initializeAutocomplete;
|
|
208
|
+
/** Returns an ordered list of possible candidates of RC files used by the given shell. */
|
|
209
|
+
function getShellRunCommandCandidates(shell, home) {
|
|
210
|
+
if (shell.toLowerCase().includes('bash')) {
|
|
211
|
+
return ['.bashrc', '.bash_profile', '.profile'].map((file) => path.join(home, file));
|
|
212
|
+
}
|
|
213
|
+
else if (shell.toLowerCase().includes('zsh')) {
|
|
214
|
+
return ['.zshrc', '.zsh_profile', '.profile'].map((file) => path.join(home, file));
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
return undefined;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* found in the LICENSE file at https://angular.io/license
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.ngDebug = exports.disableVersionCheck = exports.isCI = exports.analyticsShareDisabled = exports.analyticsDisabled = void 0;
|
|
10
|
+
exports.forceAutocomplete = exports.ngDebug = exports.disableVersionCheck = exports.isCI = exports.analyticsShareDisabled = exports.analyticsDisabled = void 0;
|
|
11
11
|
function isPresent(variable) {
|
|
12
12
|
return typeof variable === 'string' && variable !== '';
|
|
13
13
|
}
|
|
@@ -17,8 +17,15 @@ function isDisabled(variable) {
|
|
|
17
17
|
function isEnabled(variable) {
|
|
18
18
|
return isPresent(variable) && (variable === '1' || variable.toLowerCase() === 'true');
|
|
19
19
|
}
|
|
20
|
+
function optional(variable) {
|
|
21
|
+
if (!isPresent(variable)) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
return isEnabled(variable);
|
|
25
|
+
}
|
|
20
26
|
exports.analyticsDisabled = isDisabled(process.env['NG_CLI_ANALYTICS']);
|
|
21
27
|
exports.analyticsShareDisabled = isDisabled(process.env['NG_CLI_ANALYTICS_SHARE']);
|
|
22
28
|
exports.isCI = isEnabled(process.env['CI']);
|
|
23
29
|
exports.disableVersionCheck = isEnabled(process.env['NG_DISABLE_VERSION_CHECK']);
|
|
24
30
|
exports.ngDebug = isEnabled(process.env['NG_DEBUG']);
|
|
31
|
+
exports.forceAutocomplete = optional(process.env['NG_FORCE_AUTOCOMPLETE']);
|