feat(bazel): Bazel workspace schematics (#26971)
This commit creates a schematics for Bazel workspace. PR Close #26971
This commit is contained in:
parent
4f965ad2a1
commit
b07bd30b70
|
@ -1,7 +1,7 @@
|
||||||
.DS_STORE
|
.DS_STORE
|
||||||
|
|
||||||
/dist/
|
/dist/
|
||||||
bazel-*
|
/bazel-*
|
||||||
e2e_test.*
|
e2e_test.*
|
||||||
node_modules
|
node_modules
|
||||||
bower_components
|
bower_components
|
||||||
|
|
|
@ -33,9 +33,10 @@
|
||||||
},
|
},
|
||||||
"// 1": "dependencies are used locally and by bazel",
|
"// 1": "dependencies are used locally and by bazel",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular-devkit/schematics": "^0.5.5",
|
"@angular-devkit/core": "^7.0.4",
|
||||||
|
"@angular-devkit/schematics": "^7.0.4",
|
||||||
"@bazel/typescript": "0.20.3",
|
"@bazel/typescript": "0.20.3",
|
||||||
"@schematics/angular": "^0.5.4",
|
"@schematics/angular": "^7.0.4",
|
||||||
"@types/chokidar": "1.7.3",
|
"@types/chokidar": "1.7.3",
|
||||||
"@types/convert-source-map": "^1.5.1",
|
"@types/convert-source-map": "^1.5.1",
|
||||||
"@types/diff": "^3.2.2",
|
"@types/diff": "^3.2.2",
|
||||||
|
@ -143,4 +144,4 @@
|
||||||
"vrsource-tslint-rules": "5.1.1",
|
"vrsource-tslint-rules": "5.1.1",
|
||||||
"webpack": "1.12.9"
|
"webpack": "1.12.9"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ npm_package(
|
||||||
"package.json",
|
"package.json",
|
||||||
"protractor-utils.js",
|
"protractor-utils.js",
|
||||||
"//packages/bazel/src:package_assets",
|
"//packages/bazel/src:package_assets",
|
||||||
|
"//packages/bazel/src/schematics:package_assets",
|
||||||
],
|
],
|
||||||
packages = [
|
packages = [
|
||||||
"//packages/bazel/docs",
|
"//packages/bazel/docs",
|
||||||
|
@ -16,5 +17,6 @@ npm_package(
|
||||||
"//packages/bazel/src/ng_package:lib",
|
"//packages/bazel/src/ng_package:lib",
|
||||||
"//packages/bazel/src/ngc-wrapped:ngc_lib",
|
"//packages/bazel/src/ngc-wrapped:ngc_lib",
|
||||||
"//packages/bazel/src/protractor/utils",
|
"//packages/bazel/src/protractor/utils",
|
||||||
|
"//packages/bazel/src/schematics/bazel-workspace",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,7 +12,10 @@
|
||||||
},
|
},
|
||||||
"typings": "./src/ngc-wrapped/index.d.ts",
|
"typings": "./src/ngc-wrapped/index.d.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@angular-devkit/core": "^7.0.4",
|
||||||
|
"@angular-devkit/schematics": "^7.0.4",
|
||||||
"@bazel/typescript": "^0.20.3",
|
"@bazel/typescript": "^0.20.3",
|
||||||
|
"@schematics/angular": "^7.0.4",
|
||||||
"@types/node": "6.0.84",
|
"@types/node": "6.0.84",
|
||||||
"shelljs": "0.8.2",
|
"shelljs": "0.8.2",
|
||||||
"tsickle": "0.32.1"
|
"tsickle": "0.32.1"
|
||||||
|
@ -25,6 +28,7 @@
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/angular/angular.git"
|
"url": "https://github.com/angular/angular.git"
|
||||||
},
|
},
|
||||||
|
"schematics": "./src/schematics/collection.json",
|
||||||
"ng-update": {
|
"ng-update": {
|
||||||
"packageGroup": "NG_UPDATE_PACKAGE_GROUP"
|
"packageGroup": "NG_UPDATE_PACKAGE_GROUP"
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "package_assets",
|
||||||
|
srcs = [
|
||||||
|
"collection.json",
|
||||||
|
],
|
||||||
|
visibility = ["//packages/bazel:__subpackages__"],
|
||||||
|
)
|
||||||
|
|
||||||
|
load("//tools:defaults.bzl", "jasmine_node_test", "ts_library")
|
||||||
|
|
||||||
|
jasmine_node_test(
|
||||||
|
name = "test",
|
||||||
|
bootstrap = ["angular/tools/testing/init_node_spec.js"],
|
||||||
|
deps = [
|
||||||
|
"//packages/bazel/src/schematics/bazel-workspace:test",
|
||||||
|
"//tools/testing:node",
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Schematics for Bazel
|
||||||
|
|
||||||
|
## Development notes
|
||||||
|
|
||||||
|
To test any local changes, run
|
||||||
|
|
||||||
|
```shell
|
||||||
|
bazel build //packages/bazel:npm_package
|
||||||
|
```
|
||||||
|
|
||||||
|
then `cd` to the npm package in the `dist` folder and run `yarn link`.
|
||||||
|
Next run `yarn link` again in the directory where the `ng` command is invoked.
|
||||||
|
Make sure the `ng` command is local, and not the global installation.
|
||||||
|
|
||||||
|
## Generate .d.ts file from JSON schema
|
||||||
|
|
||||||
|
The script to generate `.d.ts` file is located in the
|
||||||
|
[Angular CLI](https://github.com/angular/angular-cli) repo. Make sure
|
||||||
|
the CLI repository is checked out on your local machine.
|
||||||
|
|
||||||
|
Then, in the CLI repository, run the following command
|
||||||
|
|
||||||
|
```shell
|
||||||
|
bazel run //tools:quicktype_runner -- \
|
||||||
|
~/Documents/GitHub/angular/packages/bazel/src/schematics/ng-new/schema.json \
|
||||||
|
~/Documents/GitHub/angular/packages/bazel/src/schematics/ng-new/schema.d.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
## TODOs
|
||||||
|
|
||||||
|
1. Make the `ts_json_schema` rule re-usable and portable.
|
||||||
|
2. Add comments in BUILD files. See discussion [here](https://github.com/angular/angular/pull/26971#discussion_r231325683).
|
|
@ -0,0 +1,34 @@
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
load("//tools:defaults.bzl", "ts_library")
|
||||||
|
|
||||||
|
ts_library(
|
||||||
|
name = "bazel-workspace",
|
||||||
|
srcs = [
|
||||||
|
"index.ts",
|
||||||
|
"schema.d.ts",
|
||||||
|
],
|
||||||
|
data = glob(["files/**/*"]) + [
|
||||||
|
"schema.json",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
"@ngdeps//@angular-devkit/core",
|
||||||
|
"@ngdeps//@angular-devkit/schematics",
|
||||||
|
"@ngdeps//@schematics/angular",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
ts_library(
|
||||||
|
name = "test",
|
||||||
|
testonly = True,
|
||||||
|
srcs = [
|
||||||
|
"index_spec.ts",
|
||||||
|
],
|
||||||
|
data = [
|
||||||
|
"//packages/bazel/src/schematics:package_assets",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
":bazel-workspace",
|
||||||
|
"@ngdeps//@angular-devkit/schematics",
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,7 @@
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
# This export allows targets in other packages to reference files that live
|
||||||
|
# in this package.
|
||||||
|
exports_files([
|
||||||
|
"tsconfig.json",
|
||||||
|
])
|
|
@ -0,0 +1,76 @@
|
||||||
|
# WARNING: This file is generated and it's not meant to be edited.
|
||||||
|
# Before making any changes, please read Bazel documentation.
|
||||||
|
# https://docs.bazel.build/versions/master/be/workspace.html
|
||||||
|
# The WORKSPACE file tells Bazel that this directory is a "workspace", which is like a project root.
|
||||||
|
# The content of this file specifies all the external dependencies Bazel needs to perform a build.
|
||||||
|
|
||||||
|
####################################
|
||||||
|
# ESModule imports (and TypeScript imports) can be absolute starting with the workspace name.
|
||||||
|
# The name of the workspace should match the npm package where we publish, so that these
|
||||||
|
# imports also make sense when referencing the published package.
|
||||||
|
workspace(name = "<%= utils.underscore(name) %>")
|
||||||
|
|
||||||
|
# The @angular repo contains rule for building Angular applications
|
||||||
|
# Provides "build_bazel_rules_typescript"
|
||||||
|
ANGULAR_VERSION = "<%= ANGULAR_VERSION %>"
|
||||||
|
http_archive(
|
||||||
|
name = "angular",
|
||||||
|
url = "https://github.com/angular/angular/archive/%s.zip" % ANGULAR_VERSION,
|
||||||
|
strip_prefix = "angular-%s" % ANGULAR_VERSION,
|
||||||
|
)
|
||||||
|
|
||||||
|
# RxJS
|
||||||
|
RXJS_VERSION = "<%= RXJS_VERSION %>"
|
||||||
|
http_archive(
|
||||||
|
name = "rxjs",
|
||||||
|
url = "https://registry.yarnpkg.com/rxjs/-/rxjs-%s.tgz" % RXJS_VERSION,
|
||||||
|
strip_prefix = "package/src",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Rules for compiling sass
|
||||||
|
RULES_SASS_VERSION = "<%= RULES_SASS_VERSION %>"
|
||||||
|
http_archive(
|
||||||
|
name = "io_bazel_rules_sass",
|
||||||
|
url = "https://github.com/bazelbuild/rules_sass/archive/%s.zip" % RULES_SASS_VERSION,
|
||||||
|
strip_prefix = "rules_sass-%s" % RULES_SASS_VERSION,
|
||||||
|
)
|
||||||
|
|
||||||
|
####################################
|
||||||
|
# Load and install our dependencies downloaded above.
|
||||||
|
|
||||||
|
load("@angular//packages/bazel:package.bzl", "rules_angular_dependencies")
|
||||||
|
rules_angular_dependencies()
|
||||||
|
|
||||||
|
load("@build_bazel_rules_typescript//:package.bzl", "rules_typescript_dependencies")
|
||||||
|
rules_typescript_dependencies()
|
||||||
|
# build_bazel_rules_nodejs is loaded transitively through rules_typescript_dependencies.
|
||||||
|
|
||||||
|
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
|
||||||
|
# 0.18.0 is needed for .bazelignore
|
||||||
|
check_bazel_version("0.18.0")
|
||||||
|
node_repositories()
|
||||||
|
yarn_install(
|
||||||
|
name = "npm",
|
||||||
|
package_json = "//:package.json",
|
||||||
|
yarn_lock = "//:yarn.lock",
|
||||||
|
)
|
||||||
|
|
||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
|
||||||
|
go_rules_dependencies()
|
||||||
|
go_register_toolchains()
|
||||||
|
|
||||||
|
load("@io_bazel_rules_webtesting//web:repositories.bzl", "browser_repositories", "web_test_repositories")
|
||||||
|
web_test_repositories()
|
||||||
|
browser_repositories(
|
||||||
|
chromium = True,
|
||||||
|
firefox = True,
|
||||||
|
)
|
||||||
|
|
||||||
|
load("@build_bazel_rules_typescript//:defs.bzl", "ts_setup_workspace", "check_rules_typescript_version")
|
||||||
|
ts_setup_workspace()
|
||||||
|
|
||||||
|
load("@io_bazel_rules_sass//sass:sass_repositories.bzl", "sass_repositories")
|
||||||
|
sass_repositories()
|
||||||
|
|
||||||
|
load("@angular//:index.bzl", "ng_setup_workspace")
|
||||||
|
ng_setup_workspace()
|
|
@ -0,0 +1,2 @@
|
||||||
|
dist
|
||||||
|
node_modules
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Make TypeScript and Angular compilation fast, by keeping a few copies of the
|
||||||
|
# compiler running as daemons, and cache SourceFile AST's to reduce parse time.
|
||||||
|
build --strategy=TypeScriptCompile=worker
|
||||||
|
build --strategy=AngularTemplateCompile=worker
|
||||||
|
|
||||||
|
# Don't create bazel-* symlinks in the WORKSPACE directory, except `bazel-out`,
|
||||||
|
# which is mandatory.
|
||||||
|
# These require .gitignore and may scare users.
|
||||||
|
# Also, it's a workaround for https://github.com/bazelbuild/rules_typescript/issues/12
|
||||||
|
# which affects the common case of having `tsconfig.json` in the WORKSPACE directory.
|
||||||
|
#
|
||||||
|
# Instead, the output will appear in `dist/bin`. You'll need to ignore the
|
||||||
|
# `bazel-out` directory that is created in the workspace root.
|
||||||
|
build --symlink_prefix=dist/
|
||||||
|
|
||||||
|
test --test_output=errors
|
||||||
|
|
||||||
|
# Use the Angular 6 compiler
|
||||||
|
build --define=compile=legacy
|
|
@ -0,0 +1,46 @@
|
||||||
|
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library")
|
||||||
|
load("@angular//:index.bzl", "protractor_web_test_suite")
|
||||||
|
|
||||||
|
ts_library(
|
||||||
|
name = "e2e_lib",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = glob(["src/**/*.ts"]),
|
||||||
|
tsconfig = ":tsconfig.e2e.json",
|
||||||
|
deps = [
|
||||||
|
"@npm//@types/jasmine",
|
||||||
|
"@npm//@types/jasminewd2",
|
||||||
|
"@npm//@types/node",
|
||||||
|
"@npm//jasmine",
|
||||||
|
"@npm//protractor",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
protractor_web_test_suite(
|
||||||
|
name = "prodserver_test",
|
||||||
|
data = [
|
||||||
|
"@angular//packages/bazel/src/protractor/utils",
|
||||||
|
"@npm//protractor",
|
||||||
|
],
|
||||||
|
on_prepare = ":protractor.on-prepare.js",
|
||||||
|
server = "//src:prodserver",
|
||||||
|
deps = [":e2e_lib"],
|
||||||
|
)
|
||||||
|
|
||||||
|
protractor_web_test_suite(
|
||||||
|
name = "devserver_test",
|
||||||
|
data = [
|
||||||
|
"@angular//packages/bazel/src/protractor/utils",
|
||||||
|
"@npm//protractor",
|
||||||
|
],
|
||||||
|
on_prepare = ":protractor.on-prepare.js",
|
||||||
|
server = "//src:devserver",
|
||||||
|
deps = [":e2e_lib"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Default target in this package is to run the e2e tests on the devserver.
|
||||||
|
# This is a faster round-trip but doesn't exercise production optimizations like
|
||||||
|
# code-splitting and lazy loading.
|
||||||
|
alias(
|
||||||
|
name = "e2e",
|
||||||
|
actual = "devserver_test",
|
||||||
|
)
|
|
@ -0,0 +1,23 @@
|
||||||
|
// The function exported from this file is used by the protractor_web_test_suite.
|
||||||
|
// It is passed to the `onPrepare` configuration setting in protractor and executed
|
||||||
|
// before running tests.
|
||||||
|
//
|
||||||
|
// If the function returns a promise, as it does here, protractor will wait
|
||||||
|
// for the promise to resolve before running tests.
|
||||||
|
|
||||||
|
const protractorUtils = require('@angular/bazel/protractor-utils');
|
||||||
|
const protractor = require('protractor');
|
||||||
|
|
||||||
|
module.exports = function(config) {
|
||||||
|
// In this example, `@angular/bazel/protractor-utils` is used to run
|
||||||
|
// the server. protractorUtils.runServer() runs the server on a randomly
|
||||||
|
// selected port (given a port flag to pass to the server as an argument).
|
||||||
|
// The port used is returned in serverSpec and the protractor serverUrl
|
||||||
|
// is the configured.
|
||||||
|
const portFlag = config.server.endsWith('prodserver') ? '-p' : '-port';
|
||||||
|
return protractorUtils.runServer(config.workspace, config.server, portFlag, [])
|
||||||
|
.then(serverSpec => {
|
||||||
|
const serverUrl = `http://localhost:${serverSpec.port}`;
|
||||||
|
protractor.browser.baseUrl = serverUrl;
|
||||||
|
});
|
||||||
|
};
|
|
@ -0,0 +1,90 @@
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
load("@angular//:index.bzl", "ng_module")
|
||||||
|
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library", "ts_web_test_suite")
|
||||||
|
load("@build_bazel_rules_nodejs//:defs.bzl", "rollup_bundle", "history_server")
|
||||||
|
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
|
||||||
|
|
||||||
|
ng_module(
|
||||||
|
name = "src",
|
||||||
|
srcs = glob(["**/*.ts"], exclude = ["**/*.spec.ts", "test.ts"]),
|
||||||
|
assets = glob([
|
||||||
|
"**/*.css",
|
||||||
|
"**/*.html",
|
||||||
|
]),
|
||||||
|
deps = [
|
||||||
|
"@angular//packages/core",
|
||||||
|
"@angular//packages/platform-browser",
|
||||||
|
"@npm//@types",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
rollup_bundle(
|
||||||
|
name = "bundle",
|
||||||
|
entry_point = "src/main",
|
||||||
|
deps = ["//src"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Needed because the prodserver only loads static files that appear under this
|
||||||
|
# package.
|
||||||
|
genrule(
|
||||||
|
name = "zonejs",
|
||||||
|
srcs = ["@npm//node_modules/zone.js:dist/zone.min.js"],
|
||||||
|
outs = ["zone.min.js"],
|
||||||
|
cmd = "cp $< $@",
|
||||||
|
)
|
||||||
|
|
||||||
|
history_server(
|
||||||
|
name = "prodserver",
|
||||||
|
data = [
|
||||||
|
"index.html",
|
||||||
|
":bundle",
|
||||||
|
":zonejs",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
ts_devserver(
|
||||||
|
name = "devserver",
|
||||||
|
port = 4200,
|
||||||
|
additional_root_paths = [
|
||||||
|
"npm/node_modules/zone.js/dist",
|
||||||
|
"npm/node_modules/tslib",
|
||||||
|
],
|
||||||
|
entry_module = "<%= name %>/src/main",
|
||||||
|
serving_path = "/bundle.min.js",
|
||||||
|
static_files = [
|
||||||
|
"@npm//node_modules/zone.js:dist/zone.min.js",
|
||||||
|
"@npm//node_modules/tslib:tslib.js",
|
||||||
|
"index.html",
|
||||||
|
],
|
||||||
|
deps = [":src"],
|
||||||
|
)
|
||||||
|
|
||||||
|
ts_library(
|
||||||
|
name = "test_lib",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = glob(["**/*.spec.ts"]),
|
||||||
|
deps = [
|
||||||
|
":src",
|
||||||
|
"@angular//packages/core/testing",
|
||||||
|
"@angular//packages/platform-browser-dynamic/testing",
|
||||||
|
"@npm//@types",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
ts_web_test_suite(
|
||||||
|
name = "test",
|
||||||
|
srcs = ["@npm//node_modules/tslib:tslib.js"],
|
||||||
|
# do not sort
|
||||||
|
bootstrap = [
|
||||||
|
"@npm//node_modules/zone.js:dist/zone-testing-bundle.js",
|
||||||
|
"@npm//node_modules/reflect-metadata:Reflect.js",
|
||||||
|
],
|
||||||
|
browsers = [
|
||||||
|
"@io_bazel_rules_webtesting//browsers:chromium-local",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
":test_lib",
|
||||||
|
"@npm//karma-jasmine",
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
* @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 bazel-workspace
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {strings} from '@angular-devkit/core';
|
||||||
|
import {Rule, SchematicContext, SchematicsException, Tree, apply, applyTemplates, mergeWith, move, url} from '@angular-devkit/schematics';
|
||||||
|
import {getWorkspace} from '@schematics/angular/utility/config';
|
||||||
|
import {validateProjectName} from '@schematics/angular/utility/validation';
|
||||||
|
|
||||||
|
import {Schema as BazelWorkspaceOptions} from './schema';
|
||||||
|
|
||||||
|
export default function(options: BazelWorkspaceOptions): Rule {
|
||||||
|
return (host: Tree, context: SchematicContext) => {
|
||||||
|
if (!options.name) {
|
||||||
|
throw new SchematicsException(`Invalid options, "name" is required.`);
|
||||||
|
}
|
||||||
|
validateProjectName(options.name);
|
||||||
|
let newProjectRoot = '';
|
||||||
|
try {
|
||||||
|
const workspace = getWorkspace(host);
|
||||||
|
newProjectRoot = workspace.newProjectRoot || '';
|
||||||
|
} catch {
|
||||||
|
}
|
||||||
|
const appDir = `${newProjectRoot}/${options.name}`;
|
||||||
|
|
||||||
|
const workspaceVersions = {
|
||||||
|
'ANGULAR_VERSION': '7.0.2',
|
||||||
|
'RULES_SASS_VERSION': '1.14.1',
|
||||||
|
'RXJS_VERSION': '6.3.3',
|
||||||
|
};
|
||||||
|
|
||||||
|
return mergeWith(apply(url('./files'), [
|
||||||
|
applyTemplates({
|
||||||
|
utils: strings,
|
||||||
|
...options,
|
||||||
|
'dot': '.', ...workspaceVersions,
|
||||||
|
}),
|
||||||
|
move(appDir),
|
||||||
|
]));
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
* @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 {SchematicTestRunner} from '@angular-devkit/schematics/testing';
|
||||||
|
|
||||||
|
describe('Bazel-workspace Schematic', () => {
|
||||||
|
const schematicRunner =
|
||||||
|
new SchematicTestRunner('@angular/bazel', require.resolve('../collection.json'), );
|
||||||
|
const defaultOptions = {
|
||||||
|
name: 'demo',
|
||||||
|
};
|
||||||
|
|
||||||
|
it('should generate Bazel workspace files', () => {
|
||||||
|
const options = {...defaultOptions};
|
||||||
|
const host = schematicRunner.runSchematic('bazel-workspace', options);
|
||||||
|
const files = host.files;
|
||||||
|
expect(files).toContain('/demo/.bazelignore');
|
||||||
|
expect(files).toContain('/demo/.bazelrc');
|
||||||
|
expect(files).toContain('/demo/BUILD.bazel');
|
||||||
|
expect(files).toContain('/demo/src/BUILD.bazel');
|
||||||
|
expect(files).toContain('/demo/WORKSPACE');
|
||||||
|
expect(files).toContain('/demo/yarn.lock');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('WORKSPACE', () => {
|
||||||
|
it('should contain project name', () => {
|
||||||
|
const options = {...defaultOptions};
|
||||||
|
const host = schematicRunner.runSchematic('bazel-workspace', options);
|
||||||
|
expect(host.files).toContain('/demo/WORKSPACE');
|
||||||
|
const content = host.readContent('/demo/WORKSPACE');
|
||||||
|
expect(content).toContain('workspace(name = "demo")');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should convert dashes in name to underscore', () => {
|
||||||
|
const options = {...defaultOptions, name: 'demo-project'};
|
||||||
|
const host = schematicRunner.runSchematic('bazel-workspace', options);
|
||||||
|
expect(host.files).toContain('/demo-project/WORKSPACE');
|
||||||
|
const content = host.readContent('/demo-project/WORKSPACE');
|
||||||
|
expect(content).toContain('workspace(name = "demo_project"');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -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;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/schema",
|
||||||
|
"id": "SchematicsAngularBazelWorkspace",
|
||||||
|
"title": "Angular Bazel Workspace Schema",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"description": "The name of the project.",
|
||||||
|
"type": "string",
|
||||||
|
"format": "html-selector",
|
||||||
|
"$default": {
|
||||||
|
"$source": "argv",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"name": "@angular/bazel",
|
||||||
|
"version": "0.1",
|
||||||
|
"schematics": {
|
||||||
|
"bazel-workspace": {
|
||||||
|
"factory": "./bazel-workspace",
|
||||||
|
"schema": "./bazel-workspace/schema.json",
|
||||||
|
"description": "Setup Bazel workspace",
|
||||||
|
"hidden": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
104
yarn.lock
104
yarn.lock
|
@ -2,23 +2,24 @@
|
||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
"@angular-devkit/core@0.5.13":
|
"@angular-devkit/core@7.0.5", "@angular-devkit/core@^7.0.4":
|
||||||
version "0.5.13"
|
version "7.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-0.5.13.tgz#c48c83c1bf38917e6af3f399d221d29466be9677"
|
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.0.5.tgz#60866c0a2367cea44b436a359ac9be99a138e180"
|
||||||
integrity sha512-v2OOSoYCHP6QrdQ8/df22+jzqWGAkaB5UxRMpbIyvhEc+UIQxDLugCIxYKTSEmiVmaOwcoH6lYd18RpMkkLgtQ==
|
integrity sha512-QaORf9NCnwlHEuMs45Vb/KBf5eO2m+hIdNdIK0MnTaK9SrvhQhg0AFjo2KCPtOjI9eCcvsDz/O7W28CHJrG1iA==
|
||||||
dependencies:
|
dependencies:
|
||||||
ajv "~6.4.0"
|
ajv "6.5.3"
|
||||||
chokidar "^2.0.3"
|
chokidar "2.0.4"
|
||||||
rxjs "^6.0.0"
|
fast-json-stable-stringify "2.0.0"
|
||||||
source-map "^0.5.6"
|
rxjs "6.3.3"
|
||||||
|
source-map "0.7.3"
|
||||||
|
|
||||||
"@angular-devkit/schematics@0.5.13", "@angular-devkit/schematics@^0.5.5":
|
"@angular-devkit/schematics@7.0.5", "@angular-devkit/schematics@^7.0.4":
|
||||||
version "0.5.13"
|
version "7.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-0.5.13.tgz#be90657c668cddae4054645a61d4cf852de51ede"
|
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-7.0.5.tgz#527bf0af5352172e92c5473a33bc07af44c77796"
|
||||||
integrity sha512-OUFpq8k+Z85JQPJBdMuPjXeh7kvojKvffmYZu2TxLyE0aNSYSPmJDM1LwoPcr/HsqcBJXUcrJJgMCvmyv6pnnQ==
|
integrity sha512-mWtPfBtObXXw5IWnMuOXBLn/Bv2lPxdmSqrCX9chTmxLXlFuv5e6HkzJfuF4BxjRUMaA+OW1qhnsHRJSI+p6sQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@angular-devkit/core" "0.5.13"
|
"@angular-devkit/core" "7.0.5"
|
||||||
rxjs "^6.0.0"
|
rxjs "6.3.3"
|
||||||
|
|
||||||
"@bazel/bazel-darwin_x64@0.18.0":
|
"@bazel/bazel-darwin_x64@0.18.0":
|
||||||
version "0.18.0"
|
version "0.18.0"
|
||||||
|
@ -75,14 +76,14 @@
|
||||||
tsickle "0.28.0"
|
tsickle "0.28.0"
|
||||||
tsutils "2.27.2"
|
tsutils "2.27.2"
|
||||||
|
|
||||||
"@schematics/angular@^0.5.4":
|
"@schematics/angular@^7.0.4":
|
||||||
version "0.5.13"
|
version "7.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-0.5.13.tgz#e93e249f3903c8465e476c0d0a87668f0d5354bd"
|
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-7.0.5.tgz#96a2fc65113e707548ff732583297e40ab96350d"
|
||||||
integrity sha512-R9beP3P26BlxqbmUcDjUPKwl04L5HqjRB5KhbQN6xfOH+2Vdbi2lZO3+4YxCW5qwNC0cvI6hizn3HUylxMAdWg==
|
integrity sha512-a8oWALnxs4+QwapeeBZfVBq1YEs5bdgmErBecCHioonhHidoBZX0GjJWQOH/TN8qA8HenNDf7b07WN7sRAVC1Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@angular-devkit/core" "0.5.13"
|
"@angular-devkit/core" "7.0.5"
|
||||||
"@angular-devkit/schematics" "0.5.13"
|
"@angular-devkit/schematics" "7.0.5"
|
||||||
typescript ">=2.6.2 <2.8"
|
typescript "3.1.6"
|
||||||
|
|
||||||
"@types/angular@^1.6.47":
|
"@types/angular@^1.6.47":
|
||||||
version "1.6.48"
|
version "1.6.48"
|
||||||
|
@ -315,6 +316,16 @@ agent-base@4, agent-base@^4.1.0, agent-base@^4.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
es6-promisify "^5.0.0"
|
es6-promisify "^5.0.0"
|
||||||
|
|
||||||
|
ajv@6.5.3:
|
||||||
|
version "6.5.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.3.tgz#71a569d189ecf4f4f321224fecb166f071dd90f9"
|
||||||
|
integrity sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==
|
||||||
|
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@^4.9.1:
|
ajv@^4.9.1:
|
||||||
version "4.11.8"
|
version "4.11.8"
|
||||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
|
resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
|
||||||
|
@ -333,16 +344,6 @@ ajv@^5.1.0:
|
||||||
fast-json-stable-stringify "^2.0.0"
|
fast-json-stable-stringify "^2.0.0"
|
||||||
json-schema-traverse "^0.3.0"
|
json-schema-traverse "^0.3.0"
|
||||||
|
|
||||||
ajv@~6.4.0:
|
|
||||||
version "6.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.4.0.tgz#d3aff78e9277549771daf0164cff48482b754fc6"
|
|
||||||
integrity sha1-06/3jpJ3VJdx2vAWTP9ISCt1T8Y=
|
|
||||||
dependencies:
|
|
||||||
fast-deep-equal "^1.0.0"
|
|
||||||
fast-json-stable-stringify "^2.0.0"
|
|
||||||
json-schema-traverse "^0.3.0"
|
|
||||||
uri-js "^3.0.2"
|
|
||||||
|
|
||||||
align-text@^0.1.1, align-text@^0.1.3:
|
align-text@^0.1.1, align-text@^0.1.3:
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
|
resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
|
||||||
|
@ -1338,7 +1339,7 @@ chokidar@1.7.0, chokidar@^1.0.0, chokidar@^1.4.1:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents "^1.0.0"
|
fsevents "^1.0.0"
|
||||||
|
|
||||||
chokidar@^2.0.3:
|
chokidar@2.0.4, chokidar@^2.0.3:
|
||||||
version "2.0.4"
|
version "2.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26"
|
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26"
|
||||||
integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==
|
integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==
|
||||||
|
@ -2814,7 +2815,12 @@ fast-deep-equal@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
|
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
|
||||||
integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=
|
integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=
|
||||||
|
|
||||||
fast-json-stable-stringify@^2.0.0:
|
fast-deep-equal@^2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
|
||||||
|
integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=
|
||||||
|
|
||||||
|
fast-json-stable-stringify@2.0.0, fast-json-stable-stringify@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
|
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
|
||||||
integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
|
integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
|
||||||
|
@ -4521,6 +4527,11 @@ json-schema-traverse@^0.3.0:
|
||||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
|
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
|
||||||
integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=
|
integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=
|
||||||
|
|
||||||
|
json-schema-traverse@^0.4.1:
|
||||||
|
version "0.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||||
|
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
||||||
|
|
||||||
json-schema@0.2.3:
|
json-schema@0.2.3:
|
||||||
version "0.2.3"
|
version "0.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
||||||
|
@ -7223,14 +7234,7 @@ rollup@0.47.4:
|
||||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.47.4.tgz#e3a55de83a78221d232ce29619a8d68189ae845e"
|
resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.47.4.tgz#e3a55de83a78221d232ce29619a8d68189ae845e"
|
||||||
integrity sha512-inBVqr6CRcR+DaWQZncoUK6FGCpjf3ZymXLFW7rbwVM3+kJQ2tFY2nUdnkhbBczDY+Z06pFa7Vxwk5mKPc7IvQ==
|
integrity sha512-inBVqr6CRcR+DaWQZncoUK6FGCpjf3ZymXLFW7rbwVM3+kJQ2tFY2nUdnkhbBczDY+Z06pFa7Vxwk5mKPc7IvQ==
|
||||||
|
|
||||||
rxjs@^6.0.0:
|
rxjs@6.3.3, rxjs@^6.3.0:
|
||||||
version "6.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.0.0.tgz#d647e029b5854617f994c82fe57a4c6747b352da"
|
|
||||||
integrity sha512-2MgLQr1zvks8+Kip4T6hcJdiBhV+SIvxguoWjhwtSpNPTp/5e09HJbgclCwR/nW0yWzhubM+6Q0prl8G5RuoBA==
|
|
||||||
dependencies:
|
|
||||||
tslib "^1.9.0"
|
|
||||||
|
|
||||||
rxjs@^6.3.0:
|
|
||||||
version "6.3.3"
|
version "6.3.3"
|
||||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55"
|
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55"
|
||||||
integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==
|
integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==
|
||||||
|
@ -7701,7 +7705,7 @@ source-map-url@^0.4.0:
|
||||||
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
|
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
|
||||||
integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=
|
integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=
|
||||||
|
|
||||||
source-map@*:
|
source-map@*, source-map@0.7.3:
|
||||||
version "0.7.3"
|
version "0.7.3"
|
||||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
|
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
|
||||||
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
|
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
|
||||||
|
@ -8429,10 +8433,10 @@ typedarray@^0.0.6:
|
||||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||||
|
|
||||||
"typescript@>=2.6.2 <2.8":
|
typescript@3.1.6:
|
||||||
version "2.7.2"
|
version "3.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.2.tgz#2d615a1ef4aee4f574425cdff7026edf81919836"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.6.tgz#b6543a83cfc8c2befb3f4c8fba6896f5b0c9be68"
|
||||||
integrity sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw==
|
integrity sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==
|
||||||
|
|
||||||
typescript@~3.1.1:
|
typescript@~3.1.1:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
|
@ -8604,10 +8608,10 @@ upath@^1.0.5:
|
||||||
resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd"
|
resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd"
|
||||||
integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==
|
integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==
|
||||||
|
|
||||||
uri-js@^3.0.2:
|
uri-js@^4.2.2:
|
||||||
version "3.0.2"
|
version "4.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-3.0.2.tgz#f90b858507f81dea4dcfbb3c4c3dbfa2b557faaa"
|
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
|
||||||
integrity sha1-+QuFhQf4HepNz7s8TD2/orVX+qo=
|
integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
punycode "^2.1.0"
|
punycode "^2.1.0"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue