diff --git a/integration/bazel-schematics/angular.json.original b/integration/bazel-schematics/angular.json.original
deleted file mode 100644
index fdb73942f0..0000000000
--- a/integration/bazel-schematics/angular.json.original
+++ /dev/null
@@ -1,141 +0,0 @@
-{
- "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
- "version": 1,
- "newProjectRoot": "projects",
- "projects": {
- "demo": {
- "root": "",
- "sourceRoot": "src",
- "projectType": "application",
- "prefix": "app",
- "schematics": {},
- "architect": {
- "build": {
- "builder": "@angular-devkit/build-angular:browser",
- "options": {
- "outputPath": "dist/demo",
- "index": "src/index.html",
- "main": "src/main.ts",
- "polyfills": "src/polyfills.ts",
- "tsConfig": "src/tsconfig.app.json",
- "assets": [
- "src/favicon.ico",
- "src/assets"
- ],
- "styles": [
- "src/styles.scss"
- ],
- "scripts": []
- },
- "configurations": {
- "production": {
- "fileReplacements": [
- {
- "replace": "src/environments/environment.ts",
- "with": "src/environments/environment.prod.ts"
- }
- ],
- "optimization": true,
- "outputHashing": "all",
- "sourceMap": false,
- "extractCss": true,
- "namedChunks": false,
- "aot": true,
- "extractLicenses": true,
- "vendorChunk": false,
- "buildOptimizer": true,
- "budgets": [
- {
- "type": "initial",
- "maximumWarning": "2mb",
- "maximumError": "5mb"
- }
- ]
- }
- }
- },
- "serve": {
- "builder": "@angular-devkit/build-angular:dev-server",
- "options": {
- "browserTarget": "demo:build"
- },
- "configurations": {
- "production": {
- "browserTarget": "demo:build:production"
- },
- "ci": {
- "progress": false
- }
- }
- },
- "extract-i18n": {
- "builder": "@angular-devkit/build-angular:extract-i18n",
- "options": {
- "browserTarget": "demo:build"
- }
- },
- "test": {
- "builder": "@angular-devkit/build-angular:karma",
- "options": {
- "main": "src/test.ts",
- "polyfills": "src/polyfills.ts",
- "tsConfig": "src/tsconfig.spec.json",
- "karmaConfig": "src/karma.conf.js",
- "styles": [
- "src/styles.scss"
- ],
- "scripts": [],
- "assets": [
- "src/favicon.ico",
- "src/assets"
- ]
- }
- },
- "lint": {
- "builder": "@angular-devkit/build-angular:tslint",
- "options": {
- "tsConfig": [
- "src/tsconfig.app.json",
- "src/tsconfig.spec.json"
- ],
- "exclude": [
- "**/node_modules/**"
- ]
- }
- }
- }
- },
- "demo-e2e": {
- "root": "e2e/",
- "projectType": "application",
- "prefix": "",
- "architect": {
- "e2e": {
- "builder": "@angular-devkit/build-angular:protractor",
- "options": {
- "protractorConfig": "e2e/protractor.conf.js",
- "devServerTarget": "demo:serve"
- },
- "configurations": {
- "production": {
- "devServerTarget": "demo:serve:production"
- },
- "ci": {
- "devServerTarget": "demo:serve:ci"
- }
- }
- },
- "lint": {
- "builder": "@angular-devkit/build-angular:tslint",
- "options": {
- "tsConfig": "e2e/tsconfig.e2e.json",
- "exclude": [
- "**/node_modules/**"
- ]
- }
- }
- }
- }
- },
- "defaultProject": "demo"
-}
diff --git a/integration/bazel-schematics/test.sh b/integration/bazel-schematics/test.sh
index de1ebbefdb..e781e81dd8 100755
--- a/integration/bazel-schematics/test.sh
+++ b/integration/bazel-schematics/test.sh
@@ -5,6 +5,7 @@ set -eux -o pipefail
function testBazel() {
# Set up
bazel version
+ ng version
rm -rf demo
# Create project
ng new demo --collection=@angular/bazel --defaults --skip-git --style=scss
@@ -21,11 +22,11 @@ function testBazel() {
function testNonBazel() {
# Replace angular.json that uses Bazel builder with the default generated by CLI
- cp ../angular.json.original ./angular.json
+ mv ./angular.json.bak ./angular.json
rm -rf dist src/main.dev.ts src/main.prod.ts
ng build --progress=false
ng test --progress=false --watch=false
- ng e2e --configuration=ci --webdriver-update=false
+ ng e2e --configuration=production --webdriver-update=false
}
testBazel
diff --git a/integration/bazel-schematics/yarn.lock b/integration/bazel-schematics/yarn.lock
index daf440e6eb..051182105d 100644
--- a/integration/bazel-schematics/yarn.lock
+++ b/integration/bazel-schematics/yarn.lock
@@ -29,12 +29,12 @@
rxjs "6.3.3"
source-map "0.7.3"
-"@angular-devkit/core@7.1.3", "@angular-devkit/core@^7.0.4":
- version "7.1.3"
- resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.1.3.tgz#3d82a7e99aeb6259ff941d82b65759cb1c397042"
- integrity sha512-pGBInxmuR5DAhZ1RSfIlkv7cdgh3EDNXXea9ZObEuI9MuFsIWUKODT5oKbRrsOWM6IqwNmx68VEW+xQm2DXyJw==
+"@angular-devkit/core@7.2.3", "@angular-devkit/core@^7.0.4":
+ version "7.2.3"
+ resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.2.3.tgz#03fad4edcbfbf5b2f0d35a121eca45b1273b238a"
+ integrity sha512-NnN8O+97nJAxqD2zVTDlU8dSzrGCZmqYMDqDoRJJChYxAgmGwP4lhb+Jyi5D34tPxgKRTnjTOwC+G7D+WrXSDQ==
dependencies:
- ajv "6.5.3"
+ ajv "6.6.2"
chokidar "2.0.4"
fast-json-stable-stringify "2.0.0"
rxjs "6.3.3"
@@ -51,12 +51,12 @@
rxjs "6.3.3"
source-map "0.7.3"
-"@angular-devkit/schematics@7.1.3":
- version "7.1.3"
- resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-7.1.3.tgz#30d03fde5bb27d6606d9a6e055188382408670d6"
- integrity sha512-Snmfog/n5k1PWdDaI+Top1F978vlXZFTvxHRPzlMCGhGsY+LMOpeRLVHADI+WP1q1LZ+2BjLELZVA2GP35AH8A==
+"@angular-devkit/schematics@7.2.3":
+ version "7.2.3"
+ resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-7.2.3.tgz#e85269fc44d87fd79314875084ecdecdc42020b5"
+ integrity sha512-zhnI1zxEcjx4OZ0yIzAAOujS8fzXE6nxjyC1viqliQbbjbikA6WIL7UT0jQXZKDsRBl8VXOyutBOaeOXuqktTQ==
dependencies:
- "@angular-devkit/core" "7.1.3"
+ "@angular-devkit/core" "7.2.3"
rxjs "6.3.3"
"@angular-devkit/schematics@7.3.0-rc.0", "@angular-devkit/schematics@^7.3.0-rc.0":
@@ -139,13 +139,13 @@
typescript "3.2.2"
"@schematics/angular@^7.0.4":
- version "7.1.3"
- resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-7.1.3.tgz#2cdbc6471358cf429fbea7ab192edc7246c87bd5"
- integrity sha512-6Wq6vNjGTc0zmudPogTjiegtTUc0pORTCxI39iinUM+5iemMrCLYKJmYLi5mPFU4OG/Q2fnT06A3dYUorhtLkA==
+ version "7.2.3"
+ resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-7.2.3.tgz#e08baf642fad4ff7b27a2724379c4583a5a381b5"
+ integrity sha512-hKp+qaM8YU55+JukteXOVY2N5IQBDIIIXkyPcikbC2GBXUeNOMiPqw9au9sjHrgtFp+SVGoaFzzz9+MOCc1gig==
dependencies:
- "@angular-devkit/core" "7.1.3"
- "@angular-devkit/schematics" "7.1.3"
- typescript "3.1.6"
+ "@angular-devkit/core" "7.2.3"
+ "@angular-devkit/schematics" "7.2.3"
+ typescript "3.2.2"
"@schematics/update@0.13.0-rc.0":
version "0.13.0-rc.0"
@@ -208,6 +208,16 @@ ajv@6.5.3:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
+ajv@6.6.2:
+ version "6.6.2"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.2.tgz#caceccf474bf3fc3ce3b147443711a24063cc30d"
+ integrity sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==
+ dependencies:
+ fast-deep-equal "^2.0.1"
+ fast-json-stable-stringify "^2.0.0"
+ json-schema-traverse "^0.4.1"
+ uri-js "^4.2.2"
+
ajv@6.7.0:
version "6.7.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.7.0.tgz#e3ce7bb372d6577bb1839f1dfdfcbf5ad2948d96"
@@ -219,9 +229,9 @@ ajv@6.7.0:
uri-js "^4.2.2"
ansi-escapes@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30"
- integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b"
+ integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==
ansi-regex@^2.0.0:
version "2.1.1"
@@ -383,27 +393,7 @@ bytebuffer@~5:
dependencies:
long "~3"
-cacache@^11.0.1:
- version "11.3.1"
- resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.1.tgz#d09d25f6c4aca7a6d305d141ae332613aa1d515f"
- integrity sha512-2PEw4cRRDu+iQvBTTuttQifacYjLPhET+SYO/gEFMy8uhi+jlJREDAjSF5FWSdV/Aw5h18caHA7vMTw2c+wDzA==
- dependencies:
- bluebird "^3.5.1"
- chownr "^1.0.1"
- figgy-pudding "^3.1.0"
- glob "^7.1.2"
- graceful-fs "^4.1.11"
- lru-cache "^4.1.3"
- mississippi "^3.0.0"
- mkdirp "^0.5.1"
- move-concurrently "^1.0.1"
- promise-inflight "^1.0.1"
- rimraf "^2.6.2"
- ssri "^6.0.0"
- unique-filename "^1.1.0"
- y18n "^4.0.0"
-
-cacache@^11.3.2:
+cacache@^11.0.1, cacache@^11.3.2:
version "11.3.2"
resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.2.tgz#2d81e308e3d258ca38125b676b98b2ac9ce69bfa"
integrity sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==
@@ -444,9 +434,9 @@ camelcase@^2.0.1:
integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=
chalk@^2.0.0:
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
- integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==
+ version "2.4.2"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
+ integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
dependencies:
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
@@ -477,7 +467,7 @@ chokidar@2.0.4:
optionalDependencies:
fsevents "^1.2.2"
-chownr@^1.0.1, chownr@^1.1.1:
+chownr@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494"
integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==
@@ -770,7 +760,7 @@ fast-json-stable-stringify@2.0.0, fast-json-stable-stringify@^2.0.0:
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
-figgy-pudding@^3.1.0, figgy-pudding@^3.4.1, figgy-pudding@^3.5.1:
+figgy-pudding@^3.4.1, figgy-pudding@^3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==
@@ -843,9 +833,9 @@ fs.realpath@^1.0.0:
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
fsevents@^1.2.2:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426"
- integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.7.tgz#4851b664a3783e52003b3c66eb0eee1074933aa4"
+ integrity sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==
dependencies:
nan "^2.9.2"
node-pre-gyp "^0.10.0"
@@ -889,7 +879,7 @@ glob-parent@^3.1.0:
is-glob "^3.1.0"
path-dirname "^1.0.0"
-glob@^7.0.0, glob@^7.0.5, glob@^7.1.2, glob@^7.1.3:
+glob@^7.0.0, glob@^7.0.5, glob@^7.1.3:
version "7.1.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==
@@ -1042,9 +1032,9 @@ inquirer@6.2.1:
through "^2.3.6"
interpret@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
- integrity sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296"
+ integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==
invert-kv@^1.0.0:
version "1.0.0"
@@ -1435,9 +1425,9 @@ mute-stream@0.0.7:
integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=
nan@^2.9.2:
- version "2.11.1"
- resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766"
- integrity sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==
+ version "2.12.1"
+ resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552"
+ integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==
nanomatch@^1.2.9:
version "1.2.13"
@@ -1531,9 +1521,9 @@ npm-package-arg@6.1.0, npm-package-arg@^6.0.0, npm-package-arg@^6.1.0:
validate-npm-package-name "^3.0.0"
npm-packlist@^1.1.12, npm-packlist@^1.1.6:
- version "1.1.12"
- resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a"
- integrity sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g==
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.2.0.tgz#55a60e793e272f00862c7089274439a4cc31fc7f"
+ integrity sha512-7Mni4Z8Xkx0/oegoqlcao/JpPCPEMtUvsmB0q7mgvlMinykJLSRTYuFqoQLYgGY8biuxIeiHO+QNJKbCfljewQ==
dependencies:
ignore-walk "^3.0.1"
npm-bundled "^1.0.1"
@@ -1548,9 +1538,9 @@ npm-pick-manifest@^2.2.3:
semver "^5.4.1"
npm-registry-fetch@^3.8.0:
- version "3.8.0"
- resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-3.8.0.tgz#aa7d9a7c92aff94f48dba0984bdef4bd131c88cc"
- integrity sha512-hrw8UMD+Nob3Kl3h8Z/YjmKamb1gf7D1ZZch2otrIXM3uFLB5vjEY6DhMlq80z/zZet6eETLbOXcuQudCB3Zpw==
+ version "3.9.0"
+ resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-3.9.0.tgz#44d841780e2833f06accb34488f8c7450d1a6856"
+ integrity sha512-srwmt8YhNajAoSAaDWndmZgx89lJwIZ1GWxOuckH4Coek4uHv5S+o/l9FLQe/awA+JwTnj4FJHldxhlXdZEBmw==
dependencies:
JSONStream "^1.3.4"
bluebird "^3.5.1"
@@ -1710,7 +1700,7 @@ path-is-absolute@^1.0.0:
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
-path-parse@^1.0.5:
+path-parse@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
@@ -1858,11 +1848,11 @@ resolve-url@^0.2.1:
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
resolve@^1.1.6:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26"
- integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba"
+ integrity sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==
dependencies:
- path-parse "^1.0.5"
+ path-parse "^1.0.6"
restore-cursor@^2.0.0:
version "2.0.0"
@@ -1883,11 +1873,11 @@ retry@^0.10.0:
integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=
rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2:
- version "2.6.2"
- resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
- integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==
+ version "2.6.3"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
+ integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
dependencies:
- glob "^7.0.5"
+ glob "^7.1.3"
run-async@^2.2.0:
version "2.3.0"
@@ -1983,10 +1973,10 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
-smart-buffer@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.1.tgz#07ea1ca8d4db24eb4cac86537d7d18995221ace3"
- integrity sha512-RFqinRVJVcCAL9Uh1oVqE6FZkqsyLiVOYEZ20TqIOjuX7iFVJ+zsbs4RIghnw/pTs7mZvt8ZHhvm1ZUrR4fykg==
+smart-buffer@4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.2.tgz#5207858c3815cc69110703c6b94e46c15634395d"
+ integrity sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw==
snapdragon-node@^2.0.1:
version "2.1.1"
@@ -2027,12 +2017,12 @@ socks-proxy-agent@^4.0.0:
socks "~2.2.0"
socks@~2.2.0:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/socks/-/socks-2.2.2.tgz#f061219fc2d4d332afb4af93e865c84d3fa26e2b"
- integrity sha512-g6wjBnnMOZpE0ym6e0uHSddz9p3a+WsBaaYQaBaSCJYvrC4IXykQR9MNGjLQf38e9iIIhp3b1/Zk8YZI3KGJ0Q==
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/socks/-/socks-2.2.3.tgz#7399ce11e19b2a997153c983a9ccb6306721f2dc"
+ integrity sha512-+2r83WaRT3PXYoO/1z+RDEBE7Z2f9YcdQnJ0K/ncXXbV5gJ6wYfNAebYFYiiUjM6E4JyXnPY8cimwyvFYHVUUA==
dependencies:
ip "^1.1.5"
- smart-buffer "^4.0.1"
+ smart-buffer "4.0.2"
source-map-resolve@^0.5.0:
version "0.5.2"
@@ -2095,9 +2085,9 @@ spdx-expression-parse@^3.0.0:
spdx-license-ids "^3.0.0"
spdx-license-ids@^3.0.0:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz#a59efc09784c2a5bada13cfeaf5c75dd214044d2"
- integrity sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg==
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz#81c0ce8f21474756148bbb5f3bfc0f36bf15d76e"
+ integrity sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==
split-string@^3.0.1, split-string@^3.0.2:
version "3.1.0"
@@ -2280,11 +2270,6 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
-typescript@3.1.6:
- version "3.1.6"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.6.tgz#b6543a83cfc8c2befb3f4c8fba6896f5b0c9be68"
- integrity sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==
-
typescript@3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.2.tgz#fe8101c46aa123f8353523ebdcf5730c2ae493e5"
@@ -2300,7 +2285,7 @@ union-value@^1.0.0:
is-extendable "^0.1.1"
set-value "^0.4.3"
-unique-filename@^1.1.0, unique-filename@^1.1.1:
+unique-filename@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230"
integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==
diff --git a/packages/bazel/BUILD.bazel b/packages/bazel/BUILD.bazel
index 03f97b9fe0..31c10a2cde 100644
--- a/packages/bazel/BUILD.bazel
+++ b/packages/bazel/BUILD.bazel
@@ -23,6 +23,7 @@ npm_package(
"//packages/bazel/src/ngc-wrapped:ngc_lib",
"//packages/bazel/src/protractor/utils",
"//packages/bazel/src/schematics/bazel-workspace",
+ "//packages/bazel/src/schematics/ng-add",
"//packages/bazel/src/schematics/ng-new",
],
)
diff --git a/packages/bazel/src/schematics/BUILD.bazel b/packages/bazel/src/schematics/BUILD.bazel
index 5770199cc3..bc65567b2d 100644
--- a/packages/bazel/src/schematics/BUILD.bazel
+++ b/packages/bazel/src/schematics/BUILD.bazel
@@ -15,6 +15,7 @@ jasmine_node_test(
bootstrap = ["angular/tools/testing/init_node_spec.js"],
deps = [
"//packages/bazel/src/schematics/bazel-workspace:test",
+ "//packages/bazel/src/schematics/ng-add:test",
"//packages/bazel/src/schematics/ng-new:test",
"//tools/testing:node",
],
diff --git a/packages/bazel/src/schematics/bazel-workspace/files/yarn.lock b/packages/bazel/src/schematics/bazel-workspace/files/yarn.lock
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/packages/bazel/src/schematics/bazel-workspace/index.ts b/packages/bazel/src/schematics/bazel-workspace/index.ts
index c2cd5f65df..f5f73bae3a 100644
--- a/packages/bazel/src/schematics/bazel-workspace/index.ts
+++ b/packages/bazel/src/schematics/bazel-workspace/index.ts
@@ -86,6 +86,10 @@ export default function(options: BazelWorkspaceOptions): Rule {
}
});
+ if (!host.exists('yarn.lock')) {
+ host.create('yarn.lock', '');
+ }
+
const workspaceVersions = {
'RULES_NODEJS_VERSION': '0.16.5',
'RULES_TYPESCRIPT_VERSION': '0.22.1',
diff --git a/packages/bazel/src/schematics/bazel-workspace/index_spec.ts b/packages/bazel/src/schematics/bazel-workspace/index_spec.ts
index 77b9fc6062..056f1c6ed5 100644
--- a/packages/bazel/src/schematics/bazel-workspace/index_spec.ts
+++ b/packages/bazel/src/schematics/bazel-workspace/index_spec.ts
@@ -29,17 +29,19 @@ describe('Bazel-workspace Schematic', () => {
expect(files).toContain('/yarn.lock');
});
- it('should find existing Angular version', () => {
- let host = new UnitTestTree(new HostTree);
- host.create('/node_modules/@angular/core/package.json', JSON.stringify({
- name: '@angular/core',
- version: '6.6.6',
- }));
- const options = {...defaultOptions};
- host = schematicRunner.runSchematic('bazel-workspace', options, host);
- expect(host.files).toContain('/WORKSPACE');
- const workspace = host.readContent('/WORKSPACE');
- expect(workspace).toMatch('ANGULAR_VERSION = "6.6.6"');
+ it('should generate empty yarn.lock file', () => {
+ const host = schematicRunner.runSchematic('bazel-workspace', defaultOptions);
+ expect(host.files).toContain('/yarn.lock');
+ expect(host.readContent('/yarn.lock')).toBe('');
+ });
+
+ it('should not replace yarn.lock if it exists', () => {
+ let host = new UnitTestTree(new HostTree());
+ host.create('yarn.lock', 'some content');
+ expect(host.files).toContain('/yarn.lock');
+ host = schematicRunner.runSchematic('bazel-workspace', defaultOptions, host);
+ expect(host.files).toContain('/yarn.lock');
+ expect(host.readContent('/yarn.lock')).toBe('some content');
});
it('should have the correct entry_module for devserver', () => {
diff --git a/packages/bazel/src/schematics/collection.json b/packages/bazel/src/schematics/collection.json
index 5e5d5eff46..534f02cd62 100644
--- a/packages/bazel/src/schematics/collection.json
+++ b/packages/bazel/src/schematics/collection.json
@@ -1,17 +1,22 @@
{
- "name": "@angular/bazel",
- "version": "0.1",
- "schematics": {
- "ng-new": {
- "factory": "./ng-new",
- "schema": "./ng-new/schema.json",
- "description": "Create an Angular project that builds with Bazel."
- },
- "bazel-workspace": {
- "factory": "./bazel-workspace",
- "schema": "./bazel-workspace/schema.json",
- "description": "Setup Bazel workspace",
- "hidden": true
- }
+ "name": "@angular/bazel",
+ "version": "0.1",
+ "schematics": {
+ "ng-add": {
+ "factory": "./ng-add",
+ "schema": "ng-add/schema.json",
+ "description": "Add Bazel build files and configurations to a project"
+ },
+ "ng-new": {
+ "factory": "./ng-new",
+ "schema": "./ng-new/schema.json",
+ "description": "Create an Angular project that builds with Bazel."
+ },
+ "bazel-workspace": {
+ "factory": "./bazel-workspace",
+ "schema": "./bazel-workspace/schema.json",
+ "description": "Setup Bazel workspace",
+ "hidden": true
}
}
+}
diff --git a/packages/bazel/src/schematics/ng-add/BUILD.bazel b/packages/bazel/src/schematics/ng-add/BUILD.bazel
new file mode 100644
index 0000000000..a9fe9e35fe
--- /dev/null
+++ b/packages/bazel/src/schematics/ng-add/BUILD.bazel
@@ -0,0 +1,36 @@
+package(default_visibility = ["//visibility:public"])
+
+load("//tools:defaults.bzl", "ts_library")
+
+ts_library(
+ name = "ng-add",
+ srcs = [
+ "index.ts",
+ "schema.d.ts",
+ ],
+ data = glob(["files/**/*"]) + [
+ "schema.json",
+ ],
+ deps = [
+ "//packages/bazel/src/schematics/bazel-workspace",
+ "@ngdeps//@angular-devkit/core",
+ "@ngdeps//@angular-devkit/schematics",
+ "@ngdeps//@schematics/angular",
+ "@ngdeps//typescript",
+ ],
+)
+
+ts_library(
+ name = "test",
+ testonly = True,
+ srcs = [
+ "index_spec.ts",
+ ],
+ data = [
+ "//packages/bazel/src/schematics:package_assets",
+ ],
+ deps = [
+ ":ng-add",
+ "@ngdeps//@angular-devkit/schematics",
+ ],
+)
diff --git a/packages/bazel/src/schematics/ng-new/files/main.dev.ts.template b/packages/bazel/src/schematics/ng-add/files/main.dev.ts.template
similarity index 100%
rename from packages/bazel/src/schematics/ng-new/files/main.dev.ts.template
rename to packages/bazel/src/schematics/ng-add/files/main.dev.ts.template
diff --git a/packages/bazel/src/schematics/ng-new/files/main.prod.ts.template b/packages/bazel/src/schematics/ng-add/files/main.prod.ts.template
similarity index 100%
rename from packages/bazel/src/schematics/ng-new/files/main.prod.ts.template
rename to packages/bazel/src/schematics/ng-add/files/main.prod.ts.template
diff --git a/packages/bazel/src/schematics/ng-add/index.ts b/packages/bazel/src/schematics/ng-add/index.ts
new file mode 100755
index 0000000000..8ae2acba3c
--- /dev/null
+++ b/packages/bazel/src/schematics/ng-add/index.ts
@@ -0,0 +1,232 @@
+/**
+ * @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 Schematics for ng-new project that builds with Bazel.
+ */
+
+import {SchematicContext, apply, applyTemplates, chain, mergeWith, move, Rule, schematic, Tree, url, SchematicsException, UpdateRecorder,} from '@angular-devkit/schematics';
+import {parseJsonAst, JsonAstObject, strings, JsonValue} from '@angular-devkit/core';
+import {findPropertyInAstObject, insertPropertyInAstObjectInOrder} from '@schematics/angular/utility/json-utils';
+import {validateProjectName} from '@schematics/angular/utility/validation';
+import {getWorkspacePath} from '@schematics/angular/utility/config';
+import {Schema} from './schema';
+
+/**
+ * Packages that build under Bazel require additional dev dependencies. This
+ * function adds those dependencies to "devDependencies" section in
+ * package.json.
+ */
+function addDevDependenciesToPackageJson(options: Schema) {
+ return (host: Tree) => {
+ const packageJson = 'package.json';
+ if (!host.exists(packageJson)) {
+ throw new Error(`Could not find ${packageJson}`);
+ }
+ const packageJsonContent = host.read(packageJson);
+ if (!packageJsonContent) {
+ throw new Error('Failed to read package.json content');
+ }
+ const jsonAst = parseJsonAst(packageJsonContent.toString()) as JsonAstObject;
+ const deps = findPropertyInAstObject(jsonAst, 'dependencies') as JsonAstObject;
+ const devDeps = findPropertyInAstObject(jsonAst, 'devDependencies') as JsonAstObject;
+
+ const angularCoreNode = findPropertyInAstObject(deps, '@angular/core');
+ if (!angularCoreNode) {
+ throw new Error('@angular/core dependency not found in package.json');
+ }
+ const angularCoreVersion = angularCoreNode.value as string;
+
+ const devDependencies: {[k: string]: string} = {
+ '@angular/bazel': angularCoreVersion,
+ // TODO(kyliau): Consider moving this to latest-versions.ts
+ '@bazel/bazel': '^0.22.1',
+ '@bazel/ibazel': '^0.9.0',
+ '@bazel/karma': '^0.22.1',
+ '@bazel/typescript': '^0.22.1',
+ };
+
+ const recorder = host.beginUpdate(packageJson);
+ for (const packageName of Object.keys(devDependencies)) {
+ const version = devDependencies[packageName];
+ const indent = 4;
+ insertPropertyInAstObjectInOrder(recorder, devDeps, packageName, version, indent);
+ }
+ host.commitUpdate(recorder);
+ return host;
+ };
+}
+
+/**
+ * Append main.dev.ts and main.prod.ts to src directory. These files are needed
+ * by Bazel for devserver and prodserver, respectively. They are different from
+ * main.ts generated by CLI because they use platformBrowser (AOT) instead of
+ * platformBrowserDynamic (JIT).
+ */
+function addDevAndProdMainForAot(options: Schema) {
+ return (host: Tree) => {
+ return mergeWith(apply(url('./files'), [
+ applyTemplates({
+ utils: strings,
+ ...options,
+ 'dot': '.',
+ }),
+ move('/src'),
+ ]));
+ };
+}
+
+/**
+ * Append '/bazel-out' to the gitignore file.
+ */
+function updateGitignore() {
+ return (host: Tree) => {
+ const gitignore = '/.gitignore';
+ if (!host.exists(gitignore)) {
+ return host;
+ }
+ const gitIgnoreContent = host.read(gitignore).toString();
+ if (gitIgnoreContent.includes('\n/bazel-out\n')) {
+ return host;
+ }
+ const compiledOutput = '# compiled output\n';
+ const index = gitIgnoreContent.indexOf(compiledOutput);
+ const insertionIndex = index >= 0 ? index + compiledOutput.length : gitIgnoreContent.length;
+ const recorder = host.beginUpdate(gitignore);
+ recorder.insertRight(insertionIndex, '/bazel-out\n');
+ host.commitUpdate(recorder);
+ return host;
+ };
+}
+
+function replacePropertyInAstObject(
+ recorder: UpdateRecorder, node: JsonAstObject, propertyName: string, value: JsonValue,
+ indent: number) {
+ const property = findPropertyInAstObject(node, propertyName);
+ if (property === null) {
+ throw new Error(`Property ${propertyName} does not exist in JSON object`);
+ }
+ const {start, text} = property;
+ recorder.remove(start.offset, text.length);
+ const indentStr = '\n' +
+ ' '.repeat(indent);
+ const content = JSON.stringify(value, null, ' ').replace(/\n/g, indentStr);
+ recorder.insertLeft(start.offset, content);
+}
+
+function updateAngularJsonToUseBazelBuilder(options: Schema): Rule {
+ return (host: Tree, context: SchematicContext) => {
+ const {name} = options;
+ const workspacePath = getWorkspacePath(host);
+ if (!workspacePath) {
+ throw new Error('Could not find angular.json');
+ }
+ const workspaceContent = host.read(workspacePath).toString();
+ const workspaceJsonAst = parseJsonAst(workspaceContent) as JsonAstObject;
+ const projects = findPropertyInAstObject(workspaceJsonAst, 'projects');
+ if (!projects) {
+ throw new SchematicsException('Expect projects in angular.json to be an Object');
+ }
+ const project = findPropertyInAstObject(projects as JsonAstObject, name);
+ if (!project) {
+ throw new SchematicsException(`Expected projects to contain ${name}`);
+ }
+ const recorder = host.beginUpdate(workspacePath);
+ const indent = 8;
+ const architect =
+ findPropertyInAstObject(project as JsonAstObject, 'architect') as JsonAstObject;
+ replacePropertyInAstObject(
+ recorder, architect, 'build', {
+ builder: '@angular/bazel:build',
+ options: {
+ targetLabel: '//src:bundle.js',
+ bazelCommand: 'build',
+ },
+ configurations: {
+ production: {
+ targetLabel: '//src:bundle',
+ },
+ },
+ },
+ indent);
+ replacePropertyInAstObject(
+ recorder, architect, 'serve', {
+ builder: '@angular/bazel:build',
+ options: {
+ targetLabel: '//src:devserver',
+ bazelCommand: 'run',
+ },
+ configurations: {
+ production: {
+ targetLabel: '//src:prodserver',
+ },
+ },
+ },
+ indent);
+ replacePropertyInAstObject(
+ recorder, architect, 'test', {
+ builder: '@angular/bazel:build',
+ options: {'bazelCommand': 'test', 'targetLabel': '//src/...'},
+ },
+ indent);
+
+ const e2e = `${options.name}-e2e`;
+ const e2eNode = findPropertyInAstObject(projects as JsonAstObject, e2e);
+ if (e2eNode) {
+ const architect =
+ findPropertyInAstObject(e2eNode as JsonAstObject, 'architect') as JsonAstObject;
+ replacePropertyInAstObject(
+ recorder, architect, 'e2e', {
+ builder: '@angular/bazel:build',
+ options: {
+ bazelCommand: 'test',
+ targetLabel: '//e2e:devserver_test',
+ },
+ configurations: {
+ production: {
+ targetLabel: '//e2e:prodserver_test',
+ },
+ }
+ },
+ indent);
+ }
+
+ host.commitUpdate(recorder);
+ return host;
+ };
+}
+
+/**
+ * Create a backup for the original angular.json file in case user wants to
+ * eject Bazel and revert to the original workflow.
+ */
+function backupAngularJson(): Rule {
+ return (host: Tree, context: SchematicContext) => {
+ const workspacePath = getWorkspacePath(host);
+ if (!workspacePath) {
+ return;
+ }
+ host.create(
+ `${workspacePath}.bak`, '// This is a backup file of the original angular.json. ' +
+ 'This file is needed in case you want to revert to the workflow without Bazel.\n\n' +
+ host.read(workspacePath));
+ };
+}
+
+export default function(options: Schema): Rule {
+ return (host: Tree) => {
+ validateProjectName(options.name);
+
+ return chain([
+ schematic('bazel-workspace', options),
+ addDevAndProdMainForAot(options),
+ addDevDependenciesToPackageJson(options),
+ backupAngularJson(),
+ updateAngularJsonToUseBazelBuilder(options),
+ updateGitignore(),
+ ]);
+ };
+}
diff --git a/packages/bazel/src/schematics/ng-add/index_spec.ts b/packages/bazel/src/schematics/ng-add/index_spec.ts
new file mode 100644
index 0000000000..2120153c9a
--- /dev/null
+++ b/packages/bazel/src/schematics/ng-add/index_spec.ts
@@ -0,0 +1,171 @@
+/**
+ * @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 {HostTree} from '@angular-devkit/schematics';
+import {SchematicTestRunner, UnitTestTree} from '@angular-devkit/schematics/testing';
+
+describe('ng-add schematic', () => {
+
+ const defaultOptions = {name: 'demo'};
+ let host: UnitTestTree;
+ let schematicRunner: SchematicTestRunner;
+
+ beforeEach(() => {
+ host = new UnitTestTree(new HostTree());
+ host.create('package.json', JSON.stringify({
+ name: 'demo',
+ dependencies: {
+ '@angular/core': '1.2.3',
+ },
+ devDependencies: {
+ 'typescript': '3.2.2',
+ },
+ }));
+ host.create('angular.json', JSON.stringify({
+ projects: {
+ 'demo': {
+ architect: {
+ build: {},
+ serve: {},
+ test: {},
+ 'extract-i18n': {
+ builder: '@angular-devkit/build-angular:extract-i18n',
+ },
+ },
+ },
+ 'demo-e2e': {
+ architect: {
+ e2e: {},
+ lint: {
+ builder: '@angular-devkit/build-angular:tslint',
+ },
+ },
+ },
+ },
+ }));
+ schematicRunner =
+ new SchematicTestRunner('@angular/bazel', require.resolve('../collection.json'));
+ });
+
+ it('throws if package.json is not found', () => {
+ expect(host.files).toContain('/package.json');
+ host.delete('/package.json');
+ expect(() => schematicRunner.runSchematic('ng-add', defaultOptions))
+ .toThrowError('Could not find package.json');
+ });
+
+ it('throws if angular.json is not found', () => {
+ expect(host.files).toContain('/angular.json');
+ host.delete('/angular.json');
+ expect(() => schematicRunner.runSchematic('ng-add', defaultOptions, host))
+ .toThrowError('Could not find angular.json');
+ });
+
+ it('should add @angular/bazel to package.json dependencies', () => {
+ host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
+ const {files} = host;
+ expect(files).toContain('/package.json');
+ const content = host.readContent('/package.json');
+ expect(() => JSON.parse(content)).not.toThrow();
+ const json = JSON.parse(content);
+ const core = '@angular/core';
+ const bazel = '@angular/bazel';
+ expect(Object.keys(json)).toContain('dependencies');
+ expect(Object.keys(json)).toContain('devDependencies');
+ expect(Object.keys(json.dependencies)).toContain(core);
+ expect(Object.keys(json.devDependencies)).toContain(bazel);
+ expect(json.dependencies[core]).toBe(json.devDependencies[bazel]);
+ });
+
+ it('should add @bazel/* dev dependencies', () => {
+ host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
+ const content = host.readContent('/package.json');
+ const json = JSON.parse(content);
+ const devDeps = Object.keys(json.devDependencies);
+ expect(devDeps).toContain('@bazel/bazel');
+ expect(devDeps).toContain('@bazel/ibazel');
+ expect(devDeps).toContain('@bazel/karma');
+ expect(devDeps).toContain('@bazel/typescript');
+ });
+
+ it('should create Bazel workspace file', () => {
+ host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
+ const {files} = host;
+ expect(files).toContain('/WORKSPACE');
+ expect(files).toContain('/BUILD.bazel');
+ });
+
+ it('should produce main.dev.ts and main.prod.ts for AOT', () => {
+ host.create('/src/main.ts', 'generated by CLI');
+ host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
+ const {files} = host;
+ // main.dev.ts and main.prod.ts are used by Bazel for AOT
+ expect(files).toContain('/src/main.dev.ts');
+ expect(files).toContain('/src/main.prod.ts');
+ // main.ts is produced by original ng-add schematics
+ // This file should be present for backwards compatibility.
+ expect(files).toContain('/src/main.ts');
+ });
+
+ it('should not overwrite index.html with script tags', () => {
+ host.create('/src/index.html', 'Hello World');
+ host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
+ const {files} = host;
+ expect(files).toContain('/src/index.html');
+ const content = host.readContent('/src/index.html');
+ expect(content).not.toMatch('');
+ expect(content).not.toMatch('');
+ });
+
+ it('should generate main.dev.ts and main.prod.ts', () => {
+ host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
+ const {files} = host;
+ expect(files).toContain('/src/main.dev.ts');
+ expect(files).toContain('/src/main.prod.ts');
+ });
+
+ it('should overwrite .gitignore for bazel-out directory', () => {
+ host.create('.gitignore', '\n# compiled output\n');
+ host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
+ const {files} = host;
+ expect(files).toContain('/.gitignore');
+ const content = host.readContent('/.gitignore');
+ expect(content).toMatch('\n# compiled output\n/bazel-out\n');
+ });
+
+ it('should create a backup for original angular.json', () => {
+ expect(host.files).toContain('/angular.json');
+ const original = host.readContent('/angular.json');
+ host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
+ expect(host.files).toContain('/angular.json.bak');
+ const content = host.readContent('/angular.json.bak');
+ expect(content.startsWith('// This is a backup file')).toBe(true);
+ expect(content).toMatch(original);
+ });
+
+ it('should update angular.json to use Bazel builder', () => {
+ host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
+ const {files} = host;
+ expect(files).toContain('/angular.json');
+ const content = host.readContent('/angular.json');
+ expect(() => JSON.parse(content)).not.toThrow();
+ const json = JSON.parse(content);
+ const demo = json.projects.demo;
+ const demo_e2e = json.projects['demo-e2e'];
+ const {build, serve, test} = demo.architect;
+ expect(build.builder).toBe('@angular/bazel:build');
+ expect(serve.builder).toBe('@angular/bazel:build');
+ expect(test.builder).toBe('@angular/bazel:build');
+ const {e2e, lint} = demo_e2e.architect;
+ expect(e2e.builder).toBe('@angular/bazel:build');
+ // it should leave non-Bazel commands unmodified
+ expect(demo.architect['extract-i18n'].builder)
+ .toBe('@angular-devkit/build-angular:extract-i18n');
+ expect(lint.builder).toBe('@angular-devkit/build-angular:tslint');
+ });
+});
diff --git a/packages/bazel/src/schematics/ng-add/schema.d.ts b/packages/bazel/src/schematics/ng-add/schema.d.ts
new file mode 100644
index 0000000000..4e0ad890ab
--- /dev/null
+++ b/packages/bazel/src/schematics/ng-add/schema.d.ts
@@ -0,0 +1,13 @@
+
+// THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE
+// THE CORRESPONDING JSON SCHEMA FILE. See README.md.
+
+// tslint:disable:no-global-tslint-disable
+// tslint:disable
+
+export interface Schema {
+ /**
+ * The name of the project.
+ */
+ name: string;
+}
diff --git a/packages/bazel/src/schematics/ng-add/schema.json b/packages/bazel/src/schematics/ng-add/schema.json
new file mode 100755
index 0000000000..dbfb4ab203
--- /dev/null
+++ b/packages/bazel/src/schematics/ng-add/schema.json
@@ -0,0 +1,20 @@
+{
+ "$schema": "http://json-schema.org/schema",
+ "id": "SchematicsAngularBazelNgAdd",
+ "title": "Angular Bazel Ng Add Schema",
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "The name of the project.",
+ "type": "string",
+ "format": "html-selector",
+ "$default": {
+ "$source": "argv",
+ "index": 0
+ }
+ }
+ },
+ "required": [
+ "name"
+ ]
+}
diff --git a/packages/bazel/src/schematics/ng-new/BUILD.bazel b/packages/bazel/src/schematics/ng-new/BUILD.bazel
index d70cab250f..6227329322 100644
--- a/packages/bazel/src/schematics/ng-new/BUILD.bazel
+++ b/packages/bazel/src/schematics/ng-new/BUILD.bazel
@@ -12,11 +12,9 @@ ts_library(
"schema.json",
],
deps = [
- "//packages/bazel/src/schematics/bazel-workspace",
- "@ngdeps//@angular-devkit/core",
+ "//packages/bazel/src/schematics/ng-add",
"@ngdeps//@angular-devkit/schematics",
"@ngdeps//@schematics/angular",
- "@ngdeps//typescript",
],
)
diff --git a/packages/bazel/src/schematics/ng-new/index.ts b/packages/bazel/src/schematics/ng-new/index.ts
old mode 100755
new mode 100644
index fe3e4adc10..e132ffec6f
--- a/packages/bazel/src/schematics/ng-new/index.ts
+++ b/packages/bazel/src/schematics/ng-new/index.ts
@@ -8,211 +8,19 @@
* @fileoverview Schematics for ng-new project that builds with Bazel.
*/
-import {SchematicContext, apply, applyTemplates, chain, externalSchematic, MergeStrategy, mergeWith, move, Rule, schematic, Tree, url, SchematicsException, UpdateRecorder,} from '@angular-devkit/schematics';
-import {parseJsonAst, JsonAstObject, strings, JsonValue} from '@angular-devkit/core';
-import {findPropertyInAstObject, insertPropertyInAstObjectInOrder} from '@schematics/angular/utility/json-utils';
+import {Rule, Tree, chain, externalSchematic, schematic} from '@angular-devkit/schematics';
import {validateProjectName} from '@schematics/angular/utility/validation';
-import {getWorkspace} from '@schematics/angular/utility/config';
import {Schema} from './schema';
-/**
- * Packages that build under Bazel require additional dev dependencies. This
- * function adds those dependencies to "devDependencies" section in
- * package.json.
- */
-function addDevDependenciesToPackageJson(options: Schema) {
- return (host: Tree) => {
- const packageJson = `${options.name}/package.json`;
-
- if (!host.exists(packageJson)) {
- throw new Error(`Could not find ${packageJson}`);
- }
- const packageJsonContent = host.read(packageJson);
- if (!packageJsonContent) {
- throw new Error('Failed to read package.json content');
- }
- const jsonAst = parseJsonAst(packageJsonContent.toString()) as JsonAstObject;
- const deps = findPropertyInAstObject(jsonAst, 'dependencies') as JsonAstObject;
- const devDeps = findPropertyInAstObject(jsonAst, 'devDependencies') as JsonAstObject;
-
- const angularCoreNode = findPropertyInAstObject(deps, '@angular/core');
- const angularCoreVersion = angularCoreNode !.value as string;
-
- const devDependencies: {[k: string]: string} = {
- '@angular/bazel': angularCoreVersion,
- // TODO(kyliau): Consider moving this to latest-versions.ts
- '@bazel/bazel': '^0.22.1',
- '@bazel/ibazel': '^0.9.0',
- '@bazel/karma': '^0.22.1',
- '@bazel/typescript': '^0.22.1',
- };
-
- const recorder = host.beginUpdate(packageJson);
- for (const packageName of Object.keys(devDependencies)) {
- const version = devDependencies[packageName];
- const indent = 4;
- insertPropertyInAstObjectInOrder(recorder, devDeps, packageName, version, indent);
- }
- host.commitUpdate(recorder);
- return host;
- };
-}
-
-/**
- * Append main.dev.ts and main.prod.ts to src directory. These files are needed
- * by Bazel for devserver and prodserver, respectively. They are different from
- * main.ts generated by CLI because they use platformBrowser (AOT) instead of
- * platformBrowserDynamic (JIT).
- */
-function addDevAndProdMainForAot(options: Schema) {
- return (host: Tree) => {
- let newProjectRoot = '';
- try {
- const workspace = getWorkspace(host);
- newProjectRoot = workspace.newProjectRoot || '';
- } catch {
- }
- const srcDir = `${newProjectRoot}/${options.name}/src`;
-
- return mergeWith(apply(url('./files'), [
- applyTemplates({
- utils: strings,
- ...options,
- 'dot': '.',
- }),
- move(srcDir),
- ]));
- };
-}
-
-function overwriteGitignore(options: Schema) {
- return (host: Tree) => {
- const gitignore = `${options.name}/.gitignore`;
- if (!host.exists(gitignore)) {
- return host;
- }
- const gitIgnoreContent = host.read(gitignore);
- if (!gitIgnoreContent) {
- throw new Error('Failed to read .gitignore content');
- }
-
- if (gitIgnoreContent.includes('/bazel-out\n')) {
- return host;
- }
- const lines = gitIgnoreContent.toString().split(/\n/g);
- const recorder = host.beginUpdate(gitignore);
- const compileOutput = lines.findIndex((line: string) => line === '# compiled output');
- recorder.insertRight(compileOutput, '\n/bazel-out');
- host.commitUpdate(recorder);
-
- return host;
- };
-}
-
-function replacePropertyInAstObject(
- recorder: UpdateRecorder, node: JsonAstObject, propertyName: string, value: JsonValue,
- indent: number) {
- const property = findPropertyInAstObject(node, propertyName);
- if (property === null) {
- throw new Error(`Property ${propertyName} does not exist in JSON object`);
- }
- const {start, text} = property;
- recorder.remove(start.offset, text.length);
- const indentStr = '\n' +
- ' '.repeat(indent);
- const content = JSON.stringify(value, null, ' ').replace(/\n/g, indentStr);
- recorder.insertLeft(start.offset, content);
-}
-
-function updateWorkspaceFileToUseBazelBuilder(options: Schema): Rule {
- return (host: Tree, context: SchematicContext) => {
- const {name} = options;
- const workspacePath = `${name}/angular.json`;
- if (!host.exists(workspacePath)) {
- throw new SchematicsException(`Workspace file ${workspacePath} not found.`);
- }
- const workspaceBuffer = host.read(workspacePath) !;
- const workspaceJsonAst = parseJsonAst(workspaceBuffer.toString()) as JsonAstObject;
- const projects = findPropertyInAstObject(workspaceJsonAst, 'projects');
- if (!projects) {
- throw new SchematicsException('Expect projects in angular.json to be an Object');
- }
- const project = findPropertyInAstObject(projects as JsonAstObject, name);
- if (!project) {
- throw new SchematicsException(`Expected projects to contain ${name}`);
- }
- const recorder = host.beginUpdate(workspacePath);
- const indent = 6;
- replacePropertyInAstObject(
- recorder, project as JsonAstObject, 'architect', {
- 'build': {
- 'builder': '@angular/bazel:build',
- 'options': {'targetLabel': '//src:bundle.js', 'bazelCommand': 'build'},
- 'configurations': {'production': {'targetLabel': '//src:bundle'}}
- },
- 'serve': {
- 'builder': '@angular/bazel:build',
- 'options': {'targetLabel': '//src:devserver', 'bazelCommand': 'run'},
- 'configurations': {'production': {'targetLabel': '//src:prodserver'}}
- },
- 'extract-i18n': {
- 'builder': '@angular-devkit/build-angular:extract-i18n',
- 'options': {'browserTarget': `${name}:build`}
- },
- 'test': {
- 'builder': '@angular/bazel:build',
- 'options': {'bazelCommand': 'test', 'targetLabel': '//src/...'}
- },
- 'lint': {
- 'builder': '@angular-devkit/build-angular:tslint',
- 'options': {
- 'tsConfig': ['src/tsconfig.app.json', 'src/tsconfig.spec.json'],
- 'exclude': ['**/node_modules/**']
- }
- }
- },
- indent);
-
- const e2e = `${options.name}-e2e`;
- const e2eNode = findPropertyInAstObject(projects as JsonAstObject, e2e);
- if (e2eNode) {
- replacePropertyInAstObject(
- recorder, e2eNode as JsonAstObject, 'architect', {
- 'e2e': {
- 'builder': '@angular/bazel:build',
- 'options': {'bazelCommand': 'test', 'targetLabel': '//e2e:devserver_test'},
- 'configurations': {'production': {'targetLabel': '//e2e:prodserver_test'}}
- },
- 'lint': {
- 'builder': '@angular-devkit/build-angular:tslint',
- 'options': {'tsConfig': 'e2e/tsconfig.e2e.json', 'exclude': ['**/node_modules/**']}
- }
- },
- indent);
- }
-
- host.commitUpdate(recorder);
- return host;
- };
-}
-
export default function(options: Schema): Rule {
return (host: Tree) => {
validateProjectName(options.name);
return chain([
- externalSchematic(
- '@schematics/angular', 'ng-new',
- {
- ...options,
- }),
- addDevDependenciesToPackageJson(options),
- addDevAndProdMainForAot(options),
- schematic('bazel-workspace', options, {
+ externalSchematic('@schematics/angular', 'ng-new', options),
+ schematic('ng-add', options, {
scope: options.name,
}),
- overwriteGitignore(options),
- updateWorkspaceFileToUseBazelBuilder(options),
]);
};
}
diff --git a/packages/bazel/src/schematics/ng-new/index_spec.ts b/packages/bazel/src/schematics/ng-new/index_spec.ts
index 946e162eaa..66177ea67c 100644
--- a/packages/bazel/src/schematics/ng-new/index_spec.ts
+++ b/packages/bazel/src/schematics/ng-new/index_spec.ts
@@ -8,7 +8,7 @@
import {SchematicTestRunner} from '@angular-devkit/schematics/testing';
-describe('Ng-new Schematic', () => {
+describe('ng-new schematic', () => {
const schematicRunner =
new SchematicTestRunner('@angular/bazel', require.resolve('../collection.json'), );
const defaultOptions = {
@@ -22,94 +22,15 @@ describe('Ng-new Schematic', () => {
const {files} = host;
// External schematic should produce workspace file angular.json
expect(files).toContain('/demo/angular.json');
- });
-
- it('should add @angular/bazel to package.json dependencies', () => {
- const options = {...defaultOptions};
- const host = schematicRunner.runSchematic('ng-new', options);
- const {files} = host;
expect(files).toContain('/demo/package.json');
- const content = host.readContent('/demo/package.json');
- expect(() => JSON.parse(content)).not.toThrow();
- const json = JSON.parse(content);
- const core = '@angular/core';
- const bazel = '@angular/bazel';
- expect(Object.keys(json)).toContain('dependencies');
- expect(Object.keys(json)).toContain('devDependencies');
- expect(Object.keys(json.dependencies)).toContain(core);
- expect(Object.keys(json.devDependencies)).toContain(bazel);
- expect(json.dependencies[core]).toBe(json.devDependencies[bazel]);
});
- it('should add @bazel/* dev dependencies', () => {
- const options = {...defaultOptions};
- const host = schematicRunner.runSchematic('ng-new', options);
- const content = host.readContent('/demo/package.json');
- const json = JSON.parse(content);
- const devDeps = Object.keys(json.devDependencies);
- expect(devDeps).toContain('@bazel/karma');
- expect(devDeps).toContain('@bazel/typescript');
- });
-
- it('should create Bazel workspace file', () => {
+ it('should call ng-add to generate Bazel files', () => {
const options = {...defaultOptions};
const host = schematicRunner.runSchematic('ng-new', options);
const {files} = host;
expect(files).toContain('/demo/WORKSPACE');
expect(files).toContain('/demo/BUILD.bazel');
- });
-
- it('should produce main.prod.ts for AOT', () => {
- const options = {...defaultOptions};
- const host = schematicRunner.runSchematic('ng-new', options);
- const {files} = host;
- // main.prod.ts is used by Bazel for AOT
- expect(files).toContain('/demo/src/main.prod.ts');
- // main.ts is produced by original ng-new schematics
- // This file should be present for backwards compatibility.
- expect(files).toContain('/demo/src/main.ts');
- });
-
- it('should not overwrite index.html with script tags', () => {
- const options = {...defaultOptions};
- const host = schematicRunner.runSchematic('ng-new', options);
- const {files} = host;
- expect(files).toContain('/demo/src/index.html');
- const content = host.readContent('/demo/src/index.html');
- expect(content).not.toMatch('');
- expect(content).not.toMatch('');
- });
-
- it('should generate main.dev.ts and main.prod.ts', () => {
- const options = {...defaultOptions};
- const host = schematicRunner.runSchematic('ng-new', options);
- const {files} = host;
- expect(files).toContain('/demo/src/main.dev.ts');
- expect(files).toContain('/demo/src/main.prod.ts');
- });
-
- it('should overwrite .gitignore for bazel-out directory', () => {
- const options = {...defaultOptions};
- const host = schematicRunner.runSchematic('ng-new', options);
- const {files} = host;
- expect(files).toContain('/demo/.gitignore');
- const content = host.readContent('/demo/.gitignore');
- expect(content).toMatch('/bazel-out');
- });
-
- it('should update angular.json to use Bazel builder', () => {
- const options = {...defaultOptions};
- const host = schematicRunner.runSchematic('ng-new', options);
- const {files} = host;
- expect(files).toContain('/demo/angular.json');
- const content = host.readContent('/demo/angular.json');
- expect(() => JSON.parse(content)).not.toThrow();
- const json = JSON.parse(content);
- let {architect} = json.projects.demo;
- expect(architect.build.builder).toBe('@angular/bazel:build');
- expect(architect.serve.builder).toBe('@angular/bazel:build');
- expect(architect.test.builder).toBe('@angular/bazel:build');
- architect = json.projects['demo-e2e'].architect;
- expect(architect.e2e.builder).toBe('@angular/bazel:build');
+ expect(files).toContain('/demo/src/BUILD.bazel');
});
});
diff --git a/packages/bazel/src/schematics/ng-new/schema.json b/packages/bazel/src/schematics/ng-new/schema.json
old mode 100755
new mode 100644
index e80bc82bc3..ba82f2c628
--- a/packages/bazel/src/schematics/ng-new/schema.json
+++ b/packages/bazel/src/schematics/ng-new/schema.json
@@ -43,7 +43,9 @@
"commit": {
"description": "Initial repository commit information.",
"oneOf": [
- { "type": "boolean" },
+ {
+ "type": "boolean"
+ },
{
"type": "object",
"properties": {
@@ -85,7 +87,12 @@
},
"viewEncapsulation": {
"description": "Specifies the view encapsulation strategy.",
- "enum": ["Emulated", "Native", "None", "ShadowDom"],
+ "enum": [
+ "Emulated",
+ "Native",
+ "None",
+ "ShadowDom"
+ ],
"type": "string"
},
"version": {
@@ -118,11 +125,22 @@
"message": "Which stylesheet format would you like to use?",
"type": "list",
"items": [
- { "value": "css", "label": "CSS" },
- { "value": "scss", "label": "SCSS [ http://sass-lang.com ]" },
- { "value": "sass", "label": "SASS [ http://sass-lang.com ]" },
- { "value": "less", "label": "LESS [ http://lesscss.org ]" },
- { "value": "styl", "label": "Stylus [ http://stylus-lang.com ]" }
+ {
+ "value": "css",
+ "label": "CSS"
+ },
+ {
+ "value": "sass",
+ "label": "Sass [ http://sass-lang.com ]"
+ },
+ {
+ "value": "less",
+ "label": "Less [ http://lesscss.org ]"
+ },
+ {
+ "value": "styl",
+ "label": "Stylus [ http://stylus-lang.com ]"
+ }
]
}
},