diff --git a/package.json b/package.json
index 135a2a4fe9..6c837f4929 100644
--- a/package.json
+++ b/package.json
@@ -33,6 +33,7 @@
},
"// 1": "dependencies are used locally and by bazel",
"dependencies": {
+ "@angular-devkit/architect": "^0.10.6",
"@angular-devkit/core": "^7.0.4",
"@angular-devkit/schematics": "^7.0.4",
"@bazel/typescript": "0.21.0",
diff --git a/packages/bazel/BUILD.bazel b/packages/bazel/BUILD.bazel
index b1e12f19ec..e8260eaa38 100644
--- a/packages/bazel/BUILD.bazel
+++ b/packages/bazel/BUILD.bazel
@@ -14,6 +14,7 @@ npm_package(
],
tags = ["release-with-framework"],
deps = [
+ "//packages/bazel/src/builders",
"//packages/bazel/src/ng_package:lib",
"//packages/bazel/src/ngc-wrapped:ngc_lib",
"//packages/bazel/src/protractor/utils",
diff --git a/packages/bazel/package.json b/packages/bazel/package.json
index 2d126fc971..674abc01d9 100644
--- a/packages/bazel/package.json
+++ b/packages/bazel/package.json
@@ -12,6 +12,7 @@
},
"typings": "./src/ngc-wrapped/index.d.ts",
"dependencies": {
+ "@angular-devkit/architect": "^0.10.6",
"@angular-devkit/core": "^7.0.4",
"@angular-devkit/schematics": "^7.0.4",
"@bazel/typescript": "^0.21.0",
@@ -28,6 +29,7 @@
"type": "git",
"url": "https://github.com/angular/angular.git"
},
+ "builders": "./src/builders/builders.json",
"schematics": "./src/schematics/collection.json",
"ng-update": {
"packageGroup": "NG_UPDATE_PACKAGE_GROUP"
diff --git a/packages/bazel/src/builders/BUILD.bazel b/packages/bazel/src/builders/BUILD.bazel
new file mode 100644
index 0000000000..0a4c2299d0
--- /dev/null
+++ b/packages/bazel/src/builders/BUILD.bazel
@@ -0,0 +1,30 @@
+package(default_visibility = ["//visibility:public"])
+
+filegroup(
+ name = "package_assets",
+ srcs = [
+ "builders.json",
+ ],
+ visibility = ["//packages/bazel:__subpackages__"],
+)
+
+load("//tools:defaults.bzl", "ts_library")
+
+ts_library(
+ name = "builders",
+ srcs = [
+ "bazel.ts",
+ "index.ts",
+ "schema.d.ts",
+ ],
+ data = [
+ "schema.json",
+ ],
+ deps = [
+ "@ngdeps//@angular-devkit/architect",
+ "@ngdeps//@angular-devkit/core",
+ "@ngdeps//@types/node",
+ "@rxjs",
+ "@rxjs//operators",
+ ],
+)
diff --git a/packages/bazel/src/builders/bazel.ts b/packages/bazel/src/builders/bazel.ts
new file mode 100644
index 0000000000..24c5369a8d
--- /dev/null
+++ b/packages/bazel/src/builders/bazel.ts
@@ -0,0 +1,43 @@
+/**
+ * @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 {spawn, spawnSync} from 'child_process';
+import {Observable, Subject} from 'rxjs';
+
+export type Executable = 'bazel' | 'ibazel';
+export type Command = 'build' | 'test' | 'run' | 'coverage' | 'query';
+
+export function runBazel(
+ projectDir: string, executable: Executable, command: Command, workspaceTarget: string,
+ flags: string[]): Observable {
+ const doneSubject = new Subject();
+ const buildProcess = spawn(executable, [command, workspaceTarget, ...flags], {
+ cwd: projectDir,
+ stdio: 'inherit',
+ shell: false,
+ });
+
+ buildProcess.once('close', (code: number) => {
+ if (code === 0) {
+ doneSubject.next();
+ } else {
+ doneSubject.error(`${executable} failed with code ${code}.`);
+ }
+ });
+
+ return doneSubject.asObservable();
+}
+
+export function checkInstallation(executable: Executable, projectDir: string) {
+ const child = spawnSync(executable, ['version'], {
+ cwd: projectDir,
+ shell: false,
+ });
+ return child.status === 0;
+}
diff --git a/packages/bazel/src/builders/builders.json b/packages/bazel/src/builders/builders.json
new file mode 100644
index 0000000000..3999f35086
--- /dev/null
+++ b/packages/bazel/src/builders/builders.json
@@ -0,0 +1,9 @@
+{
+ "builders": {
+ "build": {
+ "class": "./index#Builder",
+ "schema": "./schema.json",
+ "description": "Executes Bazel on a target."
+ }
+ }
+}
diff --git a/packages/bazel/src/builders/index.ts b/packages/bazel/src/builders/index.ts
new file mode 100644
index 0000000000..b2d88fe225
--- /dev/null
+++ b/packages/bazel/src/builders/index.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
+ *
+ * @fileoverview Bazel bundle builder
+ */
+
+import {BuildEvent, Builder as BuilderInterface, BuilderConfiguration, BuilderContext} from '@angular-devkit/architect';
+import {getSystemPath, resolve} from '@angular-devkit/core';
+import {Observable, of } from 'rxjs';
+import {catchError, map, tap} from 'rxjs/operators';
+
+import {checkInstallation, runBazel} from './bazel';
+import {Schema} from './schema';
+
+export class Builder implements BuilderInterface {
+ constructor(private context: BuilderContext) {}
+
+ run(builderConfig: BuilderConfiguration>): Observable {
+ const projectRoot = getSystemPath(resolve(this.context.workspace.root, builderConfig.root));
+ const targetLabel = builderConfig.options.targetLabel;
+
+ const executable = builderConfig.options.watch ? 'ibazel' : 'bazel';
+
+ if (!checkInstallation(executable, projectRoot)) {
+ throw new Error(
+ `Could not run ${executable}. Please make sure that the ` +
+ `"${executable}" command is available in the $PATH.`);
+ }
+
+ // TODO: Support passing flags.
+ return runBazel(
+ projectRoot, executable, builderConfig.options.bazelCommand !, targetLabel !,
+ [] /* flags */)
+ .pipe(map(() => ({success: true})), catchError(() => of ({success: false})), );
+ }
+}
diff --git a/packages/bazel/src/builders/schema.d.ts b/packages/bazel/src/builders/schema.d.ts
new file mode 100644
index 0000000000..79426a2eed
--- /dev/null
+++ b/packages/bazel/src/builders/schema.d.ts
@@ -0,0 +1,24 @@
+
+// THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE THE
+// CORRESPONDING JSON SCHEMA FILE, THEN RUN devkit-admin build (or bazel build ...).
+
+// tslint:disable:no-global-tslint-disable
+// tslint:disable
+
+/**
+ * Options for Bazel Builder
+ */
+export interface Schema {
+ bazelCommand: BazelCommand;
+ /**
+ * Target to be executed under Bazel.
+ */
+ targetLabel: string;
+ watch?: boolean;
+}
+
+export enum BazelCommand {
+ Build = 'build',
+ Run = 'run',
+ Test = 'test',
+}
diff --git a/packages/bazel/src/builders/schema.json b/packages/bazel/src/builders/schema.json
new file mode 100644
index 0000000000..22bdfa55a9
--- /dev/null
+++ b/packages/bazel/src/builders/schema.json
@@ -0,0 +1,29 @@
+{
+ "$schema": "http://json-schema.org/schema",
+ "title": "Bazel builder schema",
+ "description": "Options for Bazel Builder",
+ "type": "object",
+ "properties": {
+ "targetLabel": {
+ "type": "string",
+ "description": "Target to be executed under Bazel."
+ },
+ "bazelCommand": {
+ "type": "string",
+ "enum": [
+ "run",
+ "build",
+ "test"
+ ]
+ },
+ "watch": {
+ "type": "boolean",
+ "default": false
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "targetLabel",
+ "bazelCommand"
+ ]
+}
diff --git a/tools/npm/yarn.lock b/tools/npm/yarn.lock
index 47b51e66a6..b977557f4d 100644
--- a/tools/npm/yarn.lock
+++ b/tools/npm/yarn.lock
@@ -1693,7 +1693,7 @@ karma-sourcemap-loader@0.3.7:
dependencies:
graceful-fs "^4.1.2"
-"karma@github:alexeagle/karma#fa1a84ac881485b5657cb669e9b4e5da77b79f0a":
+karma@alexeagle/karma#fa1a84ac881485b5657cb669e9b4e5da77b79f0a:
version "1.7.1"
resolved "https://codeload.github.com/alexeagle/karma/tar.gz/fa1a84ac881485b5657cb669e9b4e5da77b79f0a"
dependencies:
diff --git a/yarn.lock b/yarn.lock
index 4ede5d8d10..89ffa63f02 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,6 +2,14 @@
# yarn lockfile v1
+"@angular-devkit/architect@^0.10.6":
+ version "0.10.6"
+ resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.10.6.tgz#7007e7591be21eeb478951106c84c83802ca21a4"
+ integrity sha512-IygpkXNn946vVUFFWKWEDxRqRy888vOAUWcmkZzqPEBYkuwWt7WnLfe8Sjw4fH/+HLWEMS8RXbdSTHiiaP9qOg==
+ dependencies:
+ "@angular-devkit/core" "7.0.6"
+ rxjs "6.3.3"
+
"@angular-devkit/core@7.0.5", "@angular-devkit/core@^7.0.4":
version "7.0.5"
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.0.5.tgz#60866c0a2367cea44b436a359ac9be99a138e180"
@@ -13,6 +21,17 @@
rxjs "6.3.3"
source-map "0.7.3"
+"@angular-devkit/core@7.0.6":
+ version "7.0.6"
+ resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.0.6.tgz#26c4cd4d271e8cd03f6e50b4ec30cbc606f3346e"
+ integrity sha512-RPSXUtLrpYDTqAEL0rCyDKxES76EomsPBvUUZTD6UkE2pihoh9ZIxkzhzlE+HU/xdqm28+smQYFhvvEAXFWwSQ==
+ dependencies:
+ ajv "6.5.3"
+ chokidar "2.0.4"
+ fast-json-stable-stringify "2.0.0"
+ rxjs "6.3.3"
+ source-map "0.7.3"
+
"@angular-devkit/schematics@7.0.5", "@angular-devkit/schematics@^7.0.4":
version "7.0.5"
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-7.0.5.tgz#527bf0af5352172e92c5473a33bc07af44c77796"