Skip to content

Commit 56f802b

Browse files
clydinalan-agius4
authored andcommittedNov 22, 2021
feat(@angular/cli): ask to install angular-eslint when running ng lint in new projects
To improve the developer experience for the `ng lint` command in new projects, the lint command will now ask the developer if they wish to install `@angular-eslint/schematics` when no lint target has been configured for the specified project. `@angular-eslint/schematics` is currently the only option listed in the warning shown prior to the introduction of the prompt in this change. If additional example packages are added to the warning text in the future, the confirmation prompt should be changed to a list prompt which would allow the user to pick one of the potential future listed example packages. Closes: #21387
1 parent 4f8674a commit 56f802b

File tree

2 files changed

+47
-14
lines changed

2 files changed

+47
-14
lines changed
 

Diff for: ‎packages/angular/cli/commands/lint-impl.ts

+26-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
import { spawnSync } from 'child_process';
10+
import * as path from 'path';
911
import { ArchitectCommand } from '../models/architect-command';
1012
import { Arguments } from '../models/interface';
13+
import { askConfirmation } from '../utilities/prompt';
1114
import { Schema as LintCommandSchema } from './lint';
1215

1316
const MissingBuilder = `
@@ -22,11 +25,33 @@ For example:
2225
export class LintCommand extends ArchitectCommand<LintCommandSchema> {
2326
override readonly target = 'lint';
2427
override readonly multiTarget = true;
25-
override readonly missingTargetError = MissingBuilder;
2628

2729
override async initialize(options: LintCommandSchema & Arguments): Promise<number | void> {
2830
if (!options.help) {
2931
return super.initialize(options);
3032
}
3133
}
34+
35+
override async onMissingTarget(): Promise<void | number> {
36+
this.logger.warn(MissingBuilder);
37+
38+
const shouldAdd = await askConfirmation('Would you like to add ESLint now?', true, false);
39+
if (shouldAdd) {
40+
// Run `ng add @angular-eslint/schematics`
41+
const binPath = path.resolve(__dirname, '../bin/ng.js');
42+
const { status, error } = spawnSync(
43+
process.execPath,
44+
[binPath, 'add', '@angular-eslint/schematics'],
45+
{
46+
stdio: 'inherit',
47+
},
48+
);
49+
50+
if (error) {
51+
throw error;
52+
}
53+
54+
return status ?? 0;
55+
}
56+
}
3257
}

Diff for: ‎packages/angular/cli/models/architect-command.ts

+21-13
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,23 @@ export abstract class ArchitectCommand<
3939
target: string | undefined;
4040
missingTargetError: string | undefined;
4141

42+
protected async onMissingTarget(projectName?: string): Promise<void | number> {
43+
if (this.missingTargetError) {
44+
this.logger.fatal(this.missingTargetError);
45+
46+
return 1;
47+
}
48+
49+
if (projectName) {
50+
this.logger.fatal(`Project '${projectName}' does not support the '${this.target}' target.`);
51+
} else {
52+
this.logger.fatal(`No projects support the '${this.target}' target.`);
53+
}
54+
55+
return 1;
56+
}
57+
58+
// eslint-disable-next-line max-lines-per-function
4259
public override async initialize(options: T & Arguments): Promise<number | void> {
4360
this._registry = new json.schema.CoreSchemaRegistry();
4461
this._registry.addPostTransform(json.schema.transforms.addUndefinedDefaults);
@@ -87,21 +104,12 @@ export abstract class ArchitectCommand<
87104
}
88105
}
89106

90-
if (targetProjectNames.length === 0) {
91-
this.logger.fatal(
92-
this.missingTargetError || `No projects support the '${this.target}' target.`,
93-
);
94-
95-
return 1;
96-
}
97-
98107
if (projectName && !targetProjectNames.includes(projectName)) {
99-
this.logger.fatal(
100-
this.missingTargetError ||
101-
`Project '${projectName}' does not support the '${this.target}' target.`,
102-
);
108+
return await this.onMissingTarget(projectName);
109+
}
103110

104-
return 1;
111+
if (targetProjectNames.length === 0) {
112+
return await this.onMissingTarget();
105113
}
106114

107115
if (!projectName && commandLeftovers && commandLeftovers.length > 0) {

0 commit comments

Comments
 (0)
Please sign in to comment.