From 8ef690c3421be61a11ccd954625b53dc676c6fbf Mon Sep 17 00:00:00 2001 From: Keen Yee Liau Date: Thu, 14 Mar 2019 15:15:26 -0700 Subject: [PATCH] fix(bazel): Support new e2e project layout (#29318) https://github.com/angular/angular-cli/pull/13780 changes the project layout for the e2e application. It is no longer a separate project and the e2e directory is now located alongside the existing project. This commit updates Bazel scheamtics to support both old and new project layout. PR Close #29318 --- .../builders/files/e2e/BUILD.bazel.template | 2 +- packages/bazel/src/schematics/ng-add/index.ts | 20 +++++---- .../bazel/src/schematics/utility/BUILD.bazel | 2 + .../src/schematics/utility/workspace-utils.ts | 40 ++++++++++++++++++ .../utility/workspace-utils_spec.ts | 42 +++++++++++++++++++ 5 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 packages/bazel/src/schematics/utility/workspace-utils.ts create mode 100644 packages/bazel/src/schematics/utility/workspace-utils_spec.ts diff --git a/packages/bazel/src/builders/files/e2e/BUILD.bazel.template b/packages/bazel/src/builders/files/e2e/BUILD.bazel.template index b38c34575f8f2..9bf7e4360f409 100644 --- a/packages/bazel/src/builders/files/e2e/BUILD.bazel.template +++ b/packages/bazel/src/builders/files/e2e/BUILD.bazel.template @@ -5,7 +5,7 @@ ts_library( name = "e2e_lib", testonly = 1, srcs = glob(["src/**/*.ts"]), - tsconfig = ":tsconfig.e2e.json", + tsconfig = ":tsconfig.e2e.json" if len(glob(["tsconfig.e2e.json"])) else ":tsconfig.json", deps = [ "@npm//@types/jasmine", "@npm//@types/jasminewd2", diff --git a/packages/bazel/src/schematics/ng-add/index.ts b/packages/bazel/src/schematics/ng-add/index.ts index 8a1fe694facea..7e38393170b4f 100755 --- a/packages/bazel/src/schematics/ng-add/index.ts +++ b/packages/bazel/src/schematics/ng-add/index.ts @@ -8,14 +8,18 @@ * @fileoverview Schematics for ng-new project that builds with Bazel. */ -import {JsonAstObject, parseJsonAst, strings} from '@angular-devkit/core'; -import {Rule, SchematicContext, SchematicsException, Tree, apply, applyTemplates, chain, mergeWith, move, schematic, url} from '@angular-devkit/schematics'; +import {JsonAstObject, parseJsonAst} from '@angular-devkit/core'; +import {Rule, SchematicContext, SchematicsException, Tree, apply, applyTemplates, chain, mergeWith, url} from '@angular-devkit/schematics'; import {getWorkspacePath} from '@schematics/angular/utility/config'; import {findPropertyInAstObject, insertPropertyInAstObjectInOrder} from '@schematics/angular/utility/json-utils'; import {validateProjectName} from '@schematics/angular/utility/validation'; + import {isJsonAstObject, removeKeyValueInAstObject, replacePropertyInAstObject} from '../utility/json-utils'; +import {findE2eArchitect} from '../utility/workspace-utils'; + import {Schema} from './schema'; + /** * Packages that build under Bazel require additional dev dependencies. This * function adds those dependencies to "devDependencies" section in @@ -98,6 +102,9 @@ function updateGitignore() { }; } +/** + * Change the architect in angular.json to use Bazel builder. + */ function updateAngularJsonToUseBazelBuilder(options: Schema): Rule { return (host: Tree, context: SchematicContext) => { const {name} = options; @@ -153,13 +160,10 @@ function updateAngularJsonToUseBazelBuilder(options: Schema): Rule { }, indent); - const e2e = `${options.name}-e2e`; - const e2eNode = findPropertyInAstObject(projects as JsonAstObject, e2e); - if (e2eNode) { - const architect = - findPropertyInAstObject(e2eNode as JsonAstObject, 'architect') as JsonAstObject; + const e2eArchitect = findE2eArchitect(workspaceJsonAst, name); + if (e2eArchitect) { replacePropertyInAstObject( - recorder, architect, 'e2e', { + recorder, e2eArchitect, 'e2e', { builder: '@angular/bazel:build', options: { bazelCommand: 'test', diff --git a/packages/bazel/src/schematics/utility/BUILD.bazel b/packages/bazel/src/schematics/utility/BUILD.bazel index 9420f1a17a6b2..7425aa574ffe0 100644 --- a/packages/bazel/src/schematics/utility/BUILD.bazel +++ b/packages/bazel/src/schematics/utility/BUILD.bazel @@ -6,6 +6,7 @@ ts_library( name = "utility", srcs = [ "json-utils.ts", + "workspace-utils.ts", ], module_name = "@angular/bazel/src/schematics/utility", deps = [ @@ -21,6 +22,7 @@ ts_library( testonly = True, srcs = [ "json-utils_spec.ts", + "workspace-utils_spec.ts", ], deps = [ ":utility", diff --git a/packages/bazel/src/schematics/utility/workspace-utils.ts b/packages/bazel/src/schematics/utility/workspace-utils.ts new file mode 100644 index 0000000000000..0fdb599abccb4 --- /dev/null +++ b/packages/bazel/src/schematics/utility/workspace-utils.ts @@ -0,0 +1,40 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import {JsonAstNode, JsonAstObject} from '@angular-devkit/core'; +import {findPropertyInAstObject} from '@schematics/angular/utility/json-utils'; +import {isJsonAstObject} from './json-utils'; + +/** + * Find the e2e architect node in the JSON ast. + * The e2e application is relocated alongside the existing application. + * This function supports looking up the e2e architect in both the new and old + * layout. + * See https://github.com/angular/angular-cli/pull/13780 + */ +export function findE2eArchitect(ast: JsonAstObject, name: string): JsonAstObject|null { + const projects = findPropertyInAstObject(ast, 'projects'); + if (!isJsonAstObject(projects)) { + return null; + } + let architect: JsonAstNode|null; + const e2e = findPropertyInAstObject(projects, `${name}-e2e`); + if (isJsonAstObject(e2e)) { + architect = findPropertyInAstObject(e2e, 'architect'); + } else { + const project = findPropertyInAstObject(projects, name); + if (!isJsonAstObject(project)) { + return null; + } + architect = findPropertyInAstObject(project, 'architect'); + } + if (!isJsonAstObject(architect)) { + return null; + } + return architect; +} diff --git a/packages/bazel/src/schematics/utility/workspace-utils_spec.ts b/packages/bazel/src/schematics/utility/workspace-utils_spec.ts new file mode 100644 index 0000000000000..fa5a0024ba58d --- /dev/null +++ b/packages/bazel/src/schematics/utility/workspace-utils_spec.ts @@ -0,0 +1,42 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import {JsonAstObject, parseJsonAst} from '@angular-devkit/core'; +import {isJsonAstObject} from './json-utils'; +import {findE2eArchitect} from './workspace-utils'; + +describe('Workspace utils', () => { + describe('findE2eArchitect', () => { + it('should find e2e architect in old project layout', () => { + const workspace = { + projects: { + demo: {}, + 'demo-e2e': { + architect: {}, + }, + }, + }; + const ast = parseJsonAst(JSON.stringify(workspace)); + const architect = findE2eArchitect(ast as JsonAstObject, 'demo'); + expect(isJsonAstObject(architect)).toBe(true); + }); + + it('should find e2e architect in new project layout', () => { + const workspace = { + projects: { + demo: { + architect: {}, + }, + }, + }; + const ast = parseJsonAst(JSON.stringify(workspace)); + const architect = findE2eArchitect(ast as JsonAstObject, 'demo'); + expect(isJsonAstObject(architect)).toBe(true); + }); + }); +});