Skip to content

Commit 7dbc56e

Browse files
committed
fix(@angular/cli): use default project for single target commands
Fix angular#10352
1 parent 0d663ad commit 7dbc56e

File tree

6 files changed

+33
-12
lines changed

6 files changed

+33
-12
lines changed

packages/@angular/cli/commands/e2e.ts

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export default class E2eCommand extends ArchitectCommand {
1313
public readonly description = 'Run e2e tests in existing project.';
1414
public static aliases: string[] = ['e'];
1515
public readonly scope = CommandScope.inProject;
16+
public readonly multiTarget: true;
1617
public readonly options: Option[] = [
1718
this.prodOption,
1819
this.configurationOption

packages/@angular/cli/commands/lint.ts

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export default class LintCommand extends ArchitectCommand {
1212
public readonly description = 'Lints code in existing project.';
1313
public static aliases = ['l'];
1414
public readonly scope = CommandScope.inProject;
15+
public readonly multiTarget: true;
1516
public readonly options: Option[] = [
1617
this.configurationOption
1718
];

packages/@angular/cli/commands/test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export default class TestCommand extends ArchitectCommand {
1313
public readonly description = 'Run unit tests in existing project.';
1414
public static aliases = ['t'];
1515
public readonly scope = CommandScope.inProject;
16+
public readonly multiTarget: true;
1617
public readonly options: Option[] = [
1718
this.prodOption,
1819
this.configurationOption

packages/@angular/cli/commands/xi18n.ts

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export default class Xi18nCommand extends ArchitectCommand {
1111
public readonly target = 'extract-i18n';
1212
public readonly description = 'Extracts i18n messages from source code.';
1313
public readonly scope = CommandScope.inProject;
14+
public readonly multiTarget: true;
1415
public readonly options: Option[] = [
1516
this.configurationOption
1617
];

packages/@angular/cli/models/architect-command.ts

+26-11
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,13 @@ import { concatMap, map, tap, toArray } from 'rxjs/operators';
1111
import { WorkspaceLoader } from '../models/workspace-loader';
1212

1313

14-
export interface GenericTargetTargetSpecifier {
15-
target: string;
16-
configuration?: string;
17-
}
18-
1914
export abstract class ArchitectCommand<T = any> extends Command<T> {
2015
private _host = new NodeJsSyncHost();
2116
private _architect: Architect;
2217
private _workspace: experimental.workspace.Workspace;
2318
private _logger = createConsoleLogger();
19+
// If this command supports running multiple targets.
20+
protected multiTarget = false;
2421

2522
readonly Options: Option[] = [{
2623
name: 'configuration',
@@ -46,7 +43,7 @@ export abstract class ArchitectCommand<T = any> extends Command<T> {
4643
const [project, target] = options.target.split(':');
4744
targetSpec = { project, target };
4845
} else if (this.target) {
49-
const projects = this.getAllProjectsForTargetName(this.target);
46+
const projects = this.getProjectNamesByTarget(this.target);
5047

5148
if (projects.length === 1) {
5249
// If there is a single target, use it to parse overrides.
@@ -70,12 +67,12 @@ export abstract class ArchitectCommand<T = any> extends Command<T> {
7067
);
7168
})
7269
).toPromise()
73-
.then(() => {});
70+
.then(() => { });
7471
}
7572

7673
public validate(options: any) {
7774
if (!options.project && this.target) {
78-
const projectNames = this.getAllProjectsForTargetName(this.target);
75+
const projectNames = this.getProjectNamesByTarget(this.target);
7976
const overrides = { ...options };
8077
delete overrides.project;
8178
delete overrides.configuration;
@@ -164,7 +161,7 @@ export abstract class ArchitectCommand<T = any> extends Command<T> {
164161
if (!targetSpec.project && this.target) {
165162
// This runs each target sequentially.
166163
// Running them in parallel would jumble the log messages.
167-
return await from(this.getAllProjectsForTargetName(this.target)).pipe(
164+
return await from(this.getProjectNamesByTarget(this.target)).pipe(
168165
concatMap(project => runSingleTarget({ ...targetSpec, project })),
169166
toArray(),
170167
).toPromise().then(results => results.every(res => res === 0) ? 0 : 1);
@@ -197,10 +194,28 @@ export abstract class ArchitectCommand<T = any> extends Command<T> {
197194
}
198195
}
199196

200-
private getAllProjectsForTargetName(targetName: string) {
201-
return this._workspace.listProjectNames().map(projectName =>
197+
private getProjectNamesByTarget(targetName: string): string[] {
198+
const allProjectsForTargetName = this._workspace.listProjectNames().map(projectName =>
202199
this._architect.listProjectTargets(projectName).includes(targetName) ? projectName : null
203200
).filter(x => !!x);
201+
202+
if (this.multiTarget) {
203+
// For multi target commands, we always list all projects that have the target.
204+
return allProjectsForTargetName;
205+
} else {
206+
// For single target commands, we try try the default project project first,
207+
// then the full list if it has a single project, then error out.
208+
const maybeDefaultProject = this._workspace.getDefaultProjectName();
209+
if (maybeDefaultProject && allProjectsForTargetName.includes(maybeDefaultProject)) {
210+
return [maybeDefaultProject];
211+
}
212+
213+
if (allProjectsForTargetName.length === 1) {
214+
return allProjectsForTargetName;
215+
}
216+
217+
throw new Error(`Could not determine a single project for the '${targetName} target.`);
218+
}
204219
}
205220

206221
private _loadWorkspaceAndArchitect() {

tests/e2e/tests/generate/library/library-consumption.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ export default function () {
4141
}
4242
}
4343
`))
44+
// Check that the build succeeds both with named project, unnammed (should build app), and prod.
4445
.then(() => ng('build', 'test-project'))
45-
.then(() => ng('build', 'test-project', '--prod'));
46+
.then(() => ng('build'))
47+
.then(() => ng('build', '--prod'));
4648
}

0 commit comments

Comments
 (0)