Skip to content

Commit 2c49eba

Browse files
authored
Parse angular.json as fallback during builder validation. (#332)
Parse angular.json as fallback during builder validation.
1 parent 3d033a9 commit 2c49eba

File tree

2 files changed

+66
-31
lines changed

2 files changed

+66
-31
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ information on using pull requests.
2525
## Community Guidelines
2626

2727
This project follows [Google's Open Source Community
28-
Guidelines](https://opensource.google/conduct/).
28+
Guidelines](https://opensource.google/conduct/).

packages/@apphosting/adapter-angular/src/utils.ts

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -50,40 +50,75 @@ export async function checkBuildConditions(opts: BuildOptions): Promise<void> {
5050
return;
5151
}
5252

53+
let angularBuilder = "";
5354
// dynamically load Angular so this can be used in an NPX context
5455
const angularCorePath = require.resolve("@angular/core", { paths: [process.cwd()] });
55-
const { NodeJsAsyncHost }: typeof import("@angular-devkit/core/node") = await import(
56-
require.resolve("@angular-devkit/core/node", {
57-
paths: [process.cwd(), angularCorePath],
58-
})
59-
);
60-
const { workspaces }: typeof import("@angular-devkit/core") = await import(
61-
require.resolve("@angular-devkit/core", {
62-
paths: [process.cwd(), angularCorePath],
63-
})
64-
);
65-
const host = workspaces.createWorkspaceHost(new NodeJsAsyncHost());
66-
const { workspace } = await workspaces.readWorkspace(opts.projectDirectory, host);
67-
68-
const apps: string[] = [];
69-
workspace.projects.forEach((value, key) => {
70-
if (value.extensions.projectType === "application") apps.push(key);
71-
});
72-
const project = apps[0];
73-
if (apps.length > 1 || !project) throw new Error("Unable to determine the application to deploy");
74-
75-
const workspaceProject = workspace.projects.get(project);
76-
if (!workspaceProject) throw new Error(`No project ${project} found.`);
77-
78-
const target = "build";
79-
if (!workspaceProject.targets.has(target)) throw new Error("Could not find build target.");
80-
81-
const { builder } = workspaceProject.targets.get(target)!;
82-
if (!ALLOWED_BUILDERS.includes(builder)) {
83-
throw new Error(
84-
`Currently, only the following builders are supported: ${ALLOWED_BUILDERS.join(",")}.`,
56+
try {
57+
// Note: we assume that the user's app has @angular-devkit/core in their node_modules/
58+
// because we expect them to have @angular-devkit/build-angular as a dependency which
59+
// pulls in @angular-devkit/core as a dependency. However this assumption may not hold
60+
// due to tree shaking.
61+
const { NodeJsAsyncHost }: typeof import("@angular-devkit/core/node") = await import(
62+
require.resolve("@angular-devkit/core/node", {
63+
paths: [process.cwd(), angularCorePath],
64+
})
8565
);
66+
const { workspaces }: typeof import("@angular-devkit/core") = await import(
67+
require.resolve("@angular-devkit/core", {
68+
paths: [process.cwd(), angularCorePath],
69+
})
70+
);
71+
const host = workspaces.createWorkspaceHost(new NodeJsAsyncHost());
72+
const { workspace } = await workspaces.readWorkspace(opts.projectDirectory, host);
73+
74+
const apps: string[] = [];
75+
workspace.projects.forEach((value, key) => {
76+
if (value.extensions.projectType === "application") apps.push(key);
77+
});
78+
const project = apps[0];
79+
if (apps.length > 1 || !project) {
80+
throw new Error("Unable to determine the application to deploy");
81+
}
82+
83+
const workspaceProject = workspace.projects.get(project);
84+
if (!workspaceProject) {
85+
throw new Error(`No project ${project} found.`);
86+
}
87+
88+
const target = "build";
89+
if (!workspaceProject.targets.has(target)) throw new Error("Could not find build target.");
90+
91+
const { builder } = workspaceProject.targets.get(target)!;
92+
angularBuilder = builder;
93+
} catch (error) {
94+
logger.debug("failed to determine angular builder from the workspace api: ", error);
95+
try {
96+
const root = process.cwd();
97+
const angularJSON = JSON.parse(readFileSync(join(root, "angular.json")).toString());
98+
const apps: string[] = [];
99+
Object.keys(angularJSON.projects).forEach((projectName) => {
100+
const project = angularJSON.projects[projectName];
101+
if (project["projectType"] === "application") apps.push(projectName);
102+
});
103+
const project = apps[0];
104+
if (apps.length > 1 || !project)
105+
throw new Error("Unable to determine the application to deploy");
106+
angularBuilder = angularJSON.projects[project].architect.build.builder;
107+
} catch (error) {
108+
logger.debug("failed to determine angular builder from parsing angular.json: ", error);
109+
}
110+
}
111+
112+
if (angularBuilder !== "") {
113+
if (!ALLOWED_BUILDERS.includes(angularBuilder)) {
114+
throw new Error(
115+
`Currently, only the following builders are supported: ${ALLOWED_BUILDERS.join(",")}.`,
116+
);
117+
}
86118
}
119+
// This is just a validation step and our methods for validation are flakey. If we failed to extract
120+
// the angular builder for validation, the build will continue. It may fail further down the line
121+
// but the failure reason should be non-ambigious.
87122
}
88123

89124
// Populate file or directory paths we need for generating output directory

0 commit comments

Comments
 (0)