@angular/cli 14.0.0-next.8 → 14.0.0-rc.1
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.js +1 -1
- package/lib/config/schema.json +18 -0
- package/lib/config/workspace-schema.d.ts +12 -0
- package/lib/init.js +1 -1
- package/package.json +16 -16
- package/src/analytics/analytics.d.ts +1 -1
- package/src/analytics/analytics.js +22 -20
- package/src/command-builder/architect-base-command-module.d.ts +1 -1
- package/src/command-builder/architect-base-command-module.js +7 -1
- package/src/command-builder/architect-command-module.d.ts +4 -0
- package/src/command-builder/architect-command-module.js +26 -6
- package/src/command-builder/command-module.d.ts +1 -0
- package/src/command-builder/command-module.js +7 -0
- package/src/command-builder/command-runner.js +41 -30
- package/src/command-builder/schematics-command-module.js +10 -7
- package/src/command-builder/utilities/command.d.ts +1 -1
- package/src/command-builder/utilities/normalize-options-middleware.d.ts +18 -0
- package/src/command-builder/utilities/normalize-options-middleware.js +59 -0
- package/src/command-builder/utilities/schematic-engine-host.d.ts +2 -2
- package/src/command-builder/utilities/schematic-engine-host.js +33 -18
- package/src/commands/analytics/settings/cli.js +2 -2
- package/src/commands/cache/settings/cli.d.ts +2 -2
- package/src/commands/cache/settings/cli.js +2 -2
- package/src/commands/cache/utilities.d.ts +1 -1
- package/src/commands/cache/utilities.js +7 -8
- package/src/commands/completion/cli.d.ts +16 -0
- package/src/commands/completion/cli.js +68 -0
- package/src/commands/completion/long-description.md +73 -0
- package/src/commands/config/cli.js +15 -14
- package/src/commands/doc/cli.js +2 -2
- package/src/commands/run/cli.d.ts +2 -0
- package/src/commands/run/cli.js +24 -0
- package/src/commands/update/cli.js +3 -2
- package/src/utilities/completion.d.ts +30 -0
- package/src/utilities/completion.js +282 -0
- package/src/utilities/config.d.ts +4 -3
- package/src/utilities/config.js +11 -5
- 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
|
@@ -0,0 +1,59 @@
|
|
|
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.normalizeOptionsMiddleware = void 0;
|
|
34
|
+
const yargs = __importStar(require("yargs"));
|
|
35
|
+
/**
|
|
36
|
+
* A Yargs middleware that normalizes non Array options when the argument has been provided multiple times.
|
|
37
|
+
*
|
|
38
|
+
* By default, when an option is non array and it is provided multiple times in the command line, yargs
|
|
39
|
+
* will not override it's value but instead it will be changed to an array unless `duplicate-arguments-array` is disabled.
|
|
40
|
+
* But this option also have an effect on real array options which isn't desired.
|
|
41
|
+
*
|
|
42
|
+
* See: https://github.com/yargs/yargs-parser/pull/163#issuecomment-516566614
|
|
43
|
+
*/
|
|
44
|
+
function normalizeOptionsMiddleware(args) {
|
|
45
|
+
// `getOptions` is not included in the types even though it's public API.
|
|
46
|
+
// https://github.com/yargs/yargs/issues/2098
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
48
|
+
const { array } = yargs.getOptions();
|
|
49
|
+
const arrayOptions = new Set(array);
|
|
50
|
+
for (const [key, value] of Object.entries(args)) {
|
|
51
|
+
if (key !== '_' && Array.isArray(value) && !arrayOptions.has(key)) {
|
|
52
|
+
const newValue = value.pop();
|
|
53
|
+
// eslint-disable-next-line no-console
|
|
54
|
+
console.warn(`Option '${key}' has been specified multiple times. The value '${newValue}' will be used.`);
|
|
55
|
+
args[key] = newValue;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.normalizeOptionsMiddleware = normalizeOptionsMiddleware;
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
8
|
import { RuleFactory } from '@angular-devkit/schematics';
|
|
9
|
-
import { NodeModulesEngineHost } from '@angular-devkit/schematics/tools';
|
|
9
|
+
import { FileSystemCollectionDesc, NodeModulesEngineHost } from '@angular-devkit/schematics/tools';
|
|
10
10
|
export declare class SchematicEngineHost extends NodeModulesEngineHost {
|
|
11
|
-
protected _resolveReferenceString(refString: string, parentPath: string): {
|
|
11
|
+
protected _resolveReferenceString(refString: string, parentPath: string, collectionDescription?: FileSystemCollectionDesc): {
|
|
12
12
|
ref: RuleFactory<{}>;
|
|
13
13
|
path: string;
|
|
14
14
|
} | null;
|
|
@@ -21,21 +21,18 @@ const path_1 = require("path");
|
|
|
21
21
|
const vm_1 = require("vm");
|
|
22
22
|
/**
|
|
23
23
|
* Environment variable to control schematic package redirection
|
|
24
|
-
* Default: Angular schematics only
|
|
25
24
|
*/
|
|
26
25
|
const schematicRedirectVariable = (_a = process.env['NG_SCHEMATIC_REDIRECT']) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
27
|
-
function shouldWrapSchematic(schematicFile) {
|
|
26
|
+
function shouldWrapSchematic(schematicFile, schematicEncapsulation) {
|
|
28
27
|
// Check environment variable if present
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
28
|
+
switch (schematicRedirectVariable) {
|
|
29
|
+
case '0':
|
|
30
|
+
case 'false':
|
|
31
|
+
case 'off':
|
|
32
|
+
case 'none':
|
|
33
|
+
return false;
|
|
34
|
+
case 'all':
|
|
35
|
+
return true;
|
|
39
36
|
}
|
|
40
37
|
const normalizedSchematicFile = schematicFile.replace(/\\/g, '/');
|
|
41
38
|
// Never wrap the internal update schematic when executed directly
|
|
@@ -45,17 +42,21 @@ function shouldWrapSchematic(schematicFile) {
|
|
|
45
42
|
!normalizedSchematicFile.includes('node_modules/@angular/cli/node_modules/')) {
|
|
46
43
|
return false;
|
|
47
44
|
}
|
|
48
|
-
//
|
|
45
|
+
// Check for first-party Angular schematic packages
|
|
49
46
|
// Angular schematics are safe to use in the wrapped VM context
|
|
50
|
-
|
|
47
|
+
if (/\/node_modules\/@(?:angular|schematics|nguniversal)\//.test(normalizedSchematicFile)) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
// Otherwise use the value of the schematic collection's encapsulation option (current default of false)
|
|
51
|
+
return schematicEncapsulation;
|
|
51
52
|
}
|
|
52
53
|
class SchematicEngineHost extends tools_1.NodeModulesEngineHost {
|
|
53
|
-
_resolveReferenceString(refString, parentPath) {
|
|
54
|
+
_resolveReferenceString(refString, parentPath, collectionDescription) {
|
|
54
55
|
const [path, name] = refString.split('#', 2);
|
|
55
56
|
// Mimic behavior of ExportStringRef class used in default behavior
|
|
56
57
|
const fullPath = path[0] === '.' ? (0, path_1.resolve)(parentPath !== null && parentPath !== void 0 ? parentPath : process.cwd(), path) : path;
|
|
57
58
|
const schematicFile = require.resolve(fullPath, { paths: [parentPath] });
|
|
58
|
-
if (shouldWrapSchematic(schematicFile)) {
|
|
59
|
+
if (shouldWrapSchematic(schematicFile, !!(collectionDescription === null || collectionDescription === void 0 ? void 0 : collectionDescription.encapsulation))) {
|
|
59
60
|
const schematicPath = (0, path_1.dirname)(schematicFile);
|
|
60
61
|
const moduleCache = new Map();
|
|
61
62
|
const factoryInitializer = wrap(schematicFile, schematicPath, moduleCache, name || 'default');
|
|
@@ -66,7 +67,7 @@ class SchematicEngineHost extends tools_1.NodeModulesEngineHost {
|
|
|
66
67
|
return { ref: factory, path: schematicPath };
|
|
67
68
|
}
|
|
68
69
|
// All other schematics use default behavior
|
|
69
|
-
return super._resolveReferenceString(refString, parentPath);
|
|
70
|
+
return super._resolveReferenceString(refString, parentPath, collectionDescription);
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
exports.SchematicEngineHost = SchematicEngineHost;
|
|
@@ -108,6 +109,15 @@ function wrap(schematicFile, schematicDirectory, moduleCache, exportName) {
|
|
|
108
109
|
// Provide compatibility modules for older versions of @angular/cdk
|
|
109
110
|
return legacyModules[id];
|
|
110
111
|
}
|
|
112
|
+
else if (id.startsWith('schematics:')) {
|
|
113
|
+
// Schematics built-in modules use the `schematics` scheme (similar to the Node.js `node` scheme)
|
|
114
|
+
const builtinId = id.slice(11);
|
|
115
|
+
const builtinModule = loadBuiltinModule(builtinId);
|
|
116
|
+
if (!builtinModule) {
|
|
117
|
+
throw new Error(`Unknown schematics built-in module '${id}' requested from schematic '${schematicFile}'`);
|
|
118
|
+
}
|
|
119
|
+
return builtinModule;
|
|
120
|
+
}
|
|
111
121
|
else if (id.startsWith('@angular-devkit/') || id.startsWith('@schematics/')) {
|
|
112
122
|
// Files should not redirect `@angular/core` and instead use the direct
|
|
113
123
|
// dependency if available. This allows old major version migrations to continue to function
|
|
@@ -151,7 +161,9 @@ function wrap(schematicFile, schematicDirectory, moduleCache, exportName) {
|
|
|
151
161
|
const schematicCode = (0, fs_1.readFileSync)(schematicFile, 'utf8');
|
|
152
162
|
// `module` is required due to @angular/localize ng-add being in UMD format
|
|
153
163
|
const headerCode = '(function() {\nvar exports = {};\nvar module = { exports };\n';
|
|
154
|
-
const footerCode = exportName
|
|
164
|
+
const footerCode = exportName
|
|
165
|
+
? `\nreturn module.exports['${exportName}'];});`
|
|
166
|
+
: '\nreturn module.exports;});';
|
|
155
167
|
const script = new vm_1.Script(headerCode + schematicCode + footerCode, {
|
|
156
168
|
filename: schematicFile,
|
|
157
169
|
lineOffset: 3,
|
|
@@ -170,3 +182,6 @@ function wrap(schematicFile, schematicDirectory, moduleCache, exportName) {
|
|
|
170
182
|
const exportsFactory = script.runInNewContext(context);
|
|
171
183
|
return exportsFactory;
|
|
172
184
|
}
|
|
185
|
+
function loadBuiltinModule(id) {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
@@ -30,7 +30,7 @@ class AnalyticsDisableModule extends AnalyticsSettingModule {
|
|
|
30
30
|
this.describe = 'Disables analytics gathering and reporting for the user.';
|
|
31
31
|
}
|
|
32
32
|
async run({ global }) {
|
|
33
|
-
(0, analytics_1.setAnalyticsConfig)(global, false);
|
|
33
|
+
await (0, analytics_1.setAnalyticsConfig)(global, false);
|
|
34
34
|
process.stderr.write(await (0, analytics_1.getAnalyticsInfoString)());
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -43,7 +43,7 @@ class AnalyticsEnableModule extends AnalyticsSettingModule {
|
|
|
43
43
|
this.describe = 'Enables analytics gathering and reporting for the user.';
|
|
44
44
|
}
|
|
45
45
|
async run({ global }) {
|
|
46
|
-
(0, analytics_1.setAnalyticsConfig)(global, true);
|
|
46
|
+
await (0, analytics_1.setAnalyticsConfig)(global, true);
|
|
47
47
|
process.stderr.write(await (0, analytics_1.getAnalyticsInfoString)());
|
|
48
48
|
}
|
|
49
49
|
}
|
|
@@ -14,7 +14,7 @@ export declare class CacheDisableModule extends CommandModule implements Command
|
|
|
14
14
|
longDescriptionPath: string | undefined;
|
|
15
15
|
static scope: CommandScope.In;
|
|
16
16
|
builder(localYargs: Argv): Argv;
|
|
17
|
-
run(): void
|
|
17
|
+
run(): Promise<void>;
|
|
18
18
|
}
|
|
19
19
|
export declare class CacheEnableModule extends CommandModule implements CommandModuleImplementation {
|
|
20
20
|
command: string;
|
|
@@ -23,5 +23,5 @@ export declare class CacheEnableModule extends CommandModule implements CommandM
|
|
|
23
23
|
longDescriptionPath: string | undefined;
|
|
24
24
|
static scope: CommandScope.In;
|
|
25
25
|
builder(localYargs: Argv): Argv;
|
|
26
|
-
run(): void
|
|
26
|
+
run(): Promise<void>;
|
|
27
27
|
}
|
|
@@ -21,7 +21,7 @@ class CacheDisableModule extends command_module_1.CommandModule {
|
|
|
21
21
|
return localYargs;
|
|
22
22
|
}
|
|
23
23
|
run() {
|
|
24
|
-
(0, utilities_1.updateCacheConfig)('enabled', false);
|
|
24
|
+
return (0, utilities_1.updateCacheConfig)(this.getWorkspaceOrThrow(), 'enabled', false);
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
exports.CacheDisableModule = CacheDisableModule;
|
|
@@ -36,7 +36,7 @@ class CacheEnableModule extends command_module_1.CommandModule {
|
|
|
36
36
|
return localYargs;
|
|
37
37
|
}
|
|
38
38
|
run() {
|
|
39
|
-
(0, utilities_1.updateCacheConfig)('enabled', true);
|
|
39
|
+
return (0, utilities_1.updateCacheConfig)(this.getWorkspaceOrThrow(), 'enabled', true);
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
exports.CacheEnableModule = CacheEnableModule;
|
|
@@ -7,5 +7,5 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { Cache } from '../../../lib/config/workspace-schema';
|
|
9
9
|
import { AngularWorkspace } from '../../utilities/config';
|
|
10
|
-
export declare function updateCacheConfig<K extends keyof Cache>(key: K, value: Cache[K]): void
|
|
10
|
+
export declare function updateCacheConfig<K extends keyof Cache>(workspace: AngularWorkspace, key: K, value: Cache[K]): Promise<void>;
|
|
11
11
|
export declare function getCacheConfig(workspace: AngularWorkspace | undefined): Required<Cache>;
|
|
@@ -11,14 +11,13 @@ exports.getCacheConfig = exports.updateCacheConfig = void 0;
|
|
|
11
11
|
const core_1 = require("@angular-devkit/core");
|
|
12
12
|
const path_1 = require("path");
|
|
13
13
|
const workspace_schema_1 = require("../../../lib/config/workspace-schema");
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
localWorkspace.save();
|
|
14
|
+
function updateCacheConfig(workspace, key, value) {
|
|
15
|
+
var _a, _b;
|
|
16
|
+
var _c;
|
|
17
|
+
const cli = ((_a = (_c = workspace.extensions)['cli']) !== null && _a !== void 0 ? _a : (_c['cli'] = {}));
|
|
18
|
+
const cache = ((_b = cli['cache']) !== null && _b !== void 0 ? _b : (cli['cache'] = {}));
|
|
19
|
+
cache[key] = value;
|
|
20
|
+
return workspace.save();
|
|
22
21
|
}
|
|
23
22
|
exports.updateCacheConfig = updateCacheConfig;
|
|
24
23
|
function getCacheConfig(workspace) {
|
|
@@ -0,0 +1,16 @@
|
|
|
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 { Argv } from 'yargs';
|
|
9
|
+
import { CommandModule, CommandModuleImplementation } from '../../command-builder/command-module';
|
|
10
|
+
export declare class CompletionCommandModule extends CommandModule implements CommandModuleImplementation {
|
|
11
|
+
command: string;
|
|
12
|
+
describe: string;
|
|
13
|
+
longDescriptionPath: string;
|
|
14
|
+
builder(localYargs: Argv): Argv;
|
|
15
|
+
run(): Promise<number>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
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 __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.CompletionCommandModule = void 0;
|
|
14
|
+
const path_1 = require("path");
|
|
15
|
+
const yargs_1 = __importDefault(require("yargs"));
|
|
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");
|
|
20
|
+
class CompletionCommandModule extends command_module_1.CommandModule {
|
|
21
|
+
constructor() {
|
|
22
|
+
super(...arguments);
|
|
23
|
+
this.command = 'completion';
|
|
24
|
+
this.describe = 'Set up Angular CLI autocompletion for your terminal.';
|
|
25
|
+
this.longDescriptionPath = (0, path_1.join)(__dirname, 'long-description.md');
|
|
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
|
+
if ((await (0, completion_1.hasGlobalCliInstall)()) === false) {
|
|
45
|
+
this.context.logger.warn('Setup completed successfully, but there does not seem to be a global install of the' +
|
|
46
|
+
' Angular CLI. For autocompletion to work, the CLI will need to be on your `$PATH`, which' +
|
|
47
|
+
' is typically done with the `-g` flag in `npm install -g @angular/cli`.' +
|
|
48
|
+
'\n\n' +
|
|
49
|
+
'For more information, see https://angular.io/cli/completion#global-install');
|
|
50
|
+
}
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.CompletionCommandModule = CompletionCommandModule;
|
|
55
|
+
class CompletionScriptCommandModule extends command_module_1.CommandModule {
|
|
56
|
+
constructor() {
|
|
57
|
+
super(...arguments);
|
|
58
|
+
this.command = 'script';
|
|
59
|
+
this.describe = 'Generate a bash and zsh real-time type-ahead autocompletion script.';
|
|
60
|
+
this.longDescriptionPath = undefined;
|
|
61
|
+
}
|
|
62
|
+
builder(localYargs) {
|
|
63
|
+
return localYargs;
|
|
64
|
+
}
|
|
65
|
+
run() {
|
|
66
|
+
yargs_1.default.showCompletionScript();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
Setting up autocompletion configures your terminal, so pressing the `<TAB>` key while in the middle
|
|
2
|
+
of typing will display various commands and options available to you. This makes it very easy to
|
|
3
|
+
discover and use CLI commands without lots of memorization.
|
|
4
|
+
|
|
5
|
+

|
|
8
|
+
|
|
9
|
+
## Automated setup
|
|
10
|
+
|
|
11
|
+
The CLI should prompt and ask to set up autocompletion for you the first time you use it (v14+).
|
|
12
|
+
Simply answer "Yes" and the CLI will take care of the rest.
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
$ ng serve
|
|
16
|
+
? Would you like to enable autocompletion? This will set up your terminal so pressing TAB while
|
|
17
|
+
typing Angular CLI commands will show possible options and autocomplete arguments. (Enabling
|
|
18
|
+
autocompletion will modify configuration files in your home directory.) Yes
|
|
19
|
+
Appended `source <(ng completion script)` to `/home/my-username/.bashrc`. Restart your terminal or
|
|
20
|
+
run:
|
|
21
|
+
|
|
22
|
+
source <(ng completion script)
|
|
23
|
+
|
|
24
|
+
to autocomplete `ng` commands.
|
|
25
|
+
|
|
26
|
+
# Serve output...
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
If you already refused the prompt, it won't ask again. But you can run `ng completion` to
|
|
30
|
+
do the same thing automatically.
|
|
31
|
+
|
|
32
|
+
This modifies your terminal environment to load Angular CLI autocompletion, but can't update your
|
|
33
|
+
current terminal session. Either restart it or run `source <(ng completion script)` directly to
|
|
34
|
+
enable autocompletion in your current session.
|
|
35
|
+
|
|
36
|
+
Test it out by typing `ng ser<TAB>` and it should autocomplete to `ng serve`. Ambiguous arguments
|
|
37
|
+
will show all possible options and their documentation, such as `ng generate <TAB>`.
|
|
38
|
+
|
|
39
|
+
## Manual setup
|
|
40
|
+
|
|
41
|
+
Some users may have highly customized terminal setups, possibly with configuration files checked
|
|
42
|
+
into source control with an opinionated structure. `ng completion` only ever appends Angular's setup
|
|
43
|
+
to an existing configuration file for your current shell, or creates one if none exists. If you want
|
|
44
|
+
more control over exactly where this configuration lives, you can manually set it up by having your
|
|
45
|
+
shell run at startup:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
source <(ng completion script)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
This is equivalent to what `ng completion` will automatically set up, and gives power users more
|
|
52
|
+
flexibility in their environments when desired.
|
|
53
|
+
|
|
54
|
+
## Platform support
|
|
55
|
+
|
|
56
|
+
Angular CLI supports autocompletion for the Bash and Zsh shells on MacOS and Linux operating
|
|
57
|
+
systems.
|
|
58
|
+
|
|
59
|
+
Windows does not support autocompletion in native shells, such as Cmd and Powershell. However,
|
|
60
|
+
the Angular CLI supports Git Bash and
|
|
61
|
+
[Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/) using Bash or Zsh.
|
|
62
|
+
|
|
63
|
+
## Global install
|
|
64
|
+
|
|
65
|
+
Autocompletion works by configuring your terminal to invoke the Angular CLI on startup to load the
|
|
66
|
+
setup script. This means the terminal must be able to find and execute the Angular CLI, typically
|
|
67
|
+
through a global install that places the binary on the user's `$PATH`. If you get
|
|
68
|
+
`command not found: ng`, make sure the CLI is installed globally which you can do with the `-g`
|
|
69
|
+
flag:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npm install -g @angular/cli
|
|
73
|
+
```
|
|
@@ -71,25 +71,23 @@ class ConfigCommandModule extends command_module_1.CommandModule {
|
|
|
71
71
|
return 0;
|
|
72
72
|
}
|
|
73
73
|
async set(options) {
|
|
74
|
-
var _a
|
|
74
|
+
var _a;
|
|
75
75
|
if (!((_a = options.jsonPath) === null || _a === void 0 ? void 0 : _a.trim())) {
|
|
76
76
|
throw new command_module_1.CommandModuleError('Invalid Path.');
|
|
77
77
|
}
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
['cli.cache.environment', undefined],
|
|
88
|
-
['cli.cache.path', undefined],
|
|
78
|
+
const validGlobalCliPaths = new Set([
|
|
79
|
+
'cli.warnings.versionMismatch',
|
|
80
|
+
'cli.defaultCollection',
|
|
81
|
+
'cli.schematicCollections',
|
|
82
|
+
'cli.packageManager',
|
|
83
|
+
'cli.analytics',
|
|
84
|
+
'cli.analyticsSharing.tracking',
|
|
85
|
+
'cli.analyticsSharing.uuid',
|
|
86
|
+
'cli.completion.prompted',
|
|
89
87
|
]);
|
|
90
88
|
if (options.global &&
|
|
91
89
|
!options.jsonPath.startsWith('schematics.') &&
|
|
92
|
-
!
|
|
90
|
+
!validGlobalCliPaths.has(options.jsonPath)) {
|
|
93
91
|
throw new command_module_1.CommandModuleError('Invalid Path.');
|
|
94
92
|
}
|
|
95
93
|
const [config, configPath] = (0, config_1.getWorkspaceRaw)(options.global ? 'global' : 'local');
|
|
@@ -97,7 +95,10 @@ class ConfigCommandModule extends command_module_1.CommandModule {
|
|
|
97
95
|
if (!config || !configPath) {
|
|
98
96
|
throw new command_module_1.CommandModuleError('Confguration file cannot be found.');
|
|
99
97
|
}
|
|
100
|
-
const
|
|
98
|
+
const normalizeUUIDValue = (v) => (v === '' ? (0, uuid_1.v4)() : `${v}`);
|
|
99
|
+
const value = options.jsonPath === 'cli.analyticsSharing.uuid'
|
|
100
|
+
? normalizeUUIDValue(options.value)
|
|
101
|
+
: options.value;
|
|
101
102
|
const modified = config.modify(parseJsonPath(options.jsonPath), normalizeValue(value));
|
|
102
103
|
if (!modified) {
|
|
103
104
|
logger.error('Value cannot be found.');
|
package/src/commands/doc/cli.js
CHANGED
|
@@ -93,8 +93,8 @@ class DocCommandModule extends command_module_1.CommandModule {
|
|
|
93
93
|
catch { }
|
|
94
94
|
}
|
|
95
95
|
await (0, open_1.default)(options.search
|
|
96
|
-
? `https://${domain}/
|
|
97
|
-
: `https://${domain}/
|
|
96
|
+
? `https://${domain}/docs?search=${options.keyword}`
|
|
97
|
+
: `https://${domain}/api?query=${options.keyword}`);
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
exports.DocCommandModule = DocCommandModule;
|
|
@@ -20,4 +20,6 @@ export declare class RunCommandModule extends ArchitectBaseCommandModule<RunComm
|
|
|
20
20
|
builder(argv: Argv): Promise<Argv<RunCommandArgs>>;
|
|
21
21
|
run(options: Options<RunCommandArgs> & OtherOptions): Promise<number>;
|
|
22
22
|
protected makeTargetSpecifier(options?: Options<RunCommandArgs>): Target | undefined;
|
|
23
|
+
/** @returns a sorted list of target specifiers to be used for auto completion. */
|
|
24
|
+
private getTargetChoices;
|
|
23
25
|
}
|
package/src/commands/run/cli.js
CHANGED
|
@@ -19,11 +19,15 @@ class RunCommandModule extends architect_base_command_module_1.ArchitectBaseComm
|
|
|
19
19
|
this.longDescriptionPath = (0, path_1.join)(__dirname, 'long-description.md');
|
|
20
20
|
}
|
|
21
21
|
async builder(argv) {
|
|
22
|
+
const { jsonHelp, getYargsCompletions, help } = this.context.args.options;
|
|
22
23
|
const localYargs = argv
|
|
23
24
|
.positional('target', {
|
|
24
25
|
describe: 'The Architect target to run.',
|
|
25
26
|
type: 'string',
|
|
26
27
|
demandOption: true,
|
|
28
|
+
// Show only in when using --help and auto completion because otherwise comma seperated configuration values will be invalid.
|
|
29
|
+
// Also, hide choices from JSON help so that we don't display them in AIO.
|
|
30
|
+
choices: (getYargsCompletions || help) && !jsonHelp ? this.getTargetChoices() : undefined,
|
|
27
31
|
})
|
|
28
32
|
.strict();
|
|
29
33
|
const target = this.makeTargetSpecifier();
|
|
@@ -54,6 +58,26 @@ class RunCommandModule extends architect_base_command_module_1.ArchitectBaseComm
|
|
|
54
58
|
configuration,
|
|
55
59
|
};
|
|
56
60
|
}
|
|
61
|
+
/** @returns a sorted list of target specifiers to be used for auto completion. */
|
|
62
|
+
getTargetChoices() {
|
|
63
|
+
if (!this.context.workspace) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const targets = [];
|
|
67
|
+
for (const [projectName, project] of this.context.workspace.projects) {
|
|
68
|
+
for (const [targetName, target] of project.targets) {
|
|
69
|
+
const currentTarget = `${projectName}:${targetName}`;
|
|
70
|
+
targets.push(currentTarget);
|
|
71
|
+
if (!target.configurations) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
for (const configName of Object.keys(target.configurations)) {
|
|
75
|
+
targets.push(`${currentTarget}:${configName}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return targets.sort();
|
|
80
|
+
}
|
|
57
81
|
}
|
|
58
82
|
exports.RunCommandModule = RunCommandModule;
|
|
59
83
|
RunCommandModule.scope = command_module_1.CommandScope.In;
|
|
@@ -584,8 +584,9 @@ class UpdateCommandModule extends command_module_1.CommandModule {
|
|
|
584
584
|
}
|
|
585
585
|
}
|
|
586
586
|
const result = await this.executeMigrations(workflow, migration.package, migrations, migration.from, migration.to, options.createCommits);
|
|
587
|
-
|
|
588
|
-
|
|
587
|
+
// A non-zero value is a failure for the package's migrations
|
|
588
|
+
if (result !== 0) {
|
|
589
|
+
return result;
|
|
589
590
|
}
|
|
590
591
|
}
|
|
591
592
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
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>;
|
|
23
|
+
/**
|
|
24
|
+
* Returns whether the user has a global CLI install or `undefined` if this can't be determined.
|
|
25
|
+
* Execution from `npx` is *not* considered a global CLI install.
|
|
26
|
+
*
|
|
27
|
+
* This does *not* mean the current execution is from a global CLI install, only that a global
|
|
28
|
+
* install exists on the system.
|
|
29
|
+
*/
|
|
30
|
+
export declare function hasGlobalCliInstall(): Promise<boolean | undefined>;
|