Skip to content

Commit 22a317d

Browse files
kormidejosephperrott
authored andcommitted
build(bazel): stamp targets to build, test, and serve aio against
first party deps Architect is not compatible with disabling the rules_nodejs linker so these targets must use npm_link to link first party deps
1 parent 7a134cf commit 22a317d

File tree

27 files changed

+168
-49
lines changed

27 files changed

+168
-49
lines changed

.bazelrc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ build:release --stamp
5656
build:snapshot-build --workspace_status_command="yarn -s ng-dev release build-env-stamp --mode=snapshot"
5757
build:snapshot-build --stamp
5858

59+
####################################
60+
# AIO first party dep substitution #
61+
# Turn on with #
62+
# --config=aio_local_deps #
63+
####################################
64+
65+
build:aio_local_deps --//aio:flag_aio_local_deps
66+
5967
###############################
6068
# Output #
6169
###############################

aio/BUILD.bazel

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ load("@aio_npm//@angular-devkit/architect-cli:index.bzl", "architect", "architec
22
load("@build_bazel_rules_nodejs//:index.bzl", "npm_package_bin")
33
load("//aio/tools:defaults.bzl", "nodejs_binary")
44
load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
5+
load(":local_packages_util.bzl", "link_local_packages", "substitute_local_packages")
6+
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
57

68
# The write_source_files macro is used to write bazel outputs to the source tree and test that they are up to date.
79
# See: https://docs.aspect.build/aspect-build/bazel-lib/v0.5.0/docs/docs/write_source_files-docgen.html
@@ -12,6 +14,19 @@ exports_files([
1214
"ngsw-config.template.json",
1315
])
1416

17+
# If set will use first party angular deps for aio targets instead of their npm equivalent
18+
bool_flag(
19+
name = "flag_aio_local_deps",
20+
build_setting_default = False,
21+
)
22+
23+
config_setting(
24+
name = "aio_local_deps",
25+
flag_values = {
26+
":flag_aio_local_deps": "true",
27+
},
28+
)
29+
1530
# Generate ngsw-config
1631
npm_package_bin(
1732
name = "ngsw-config",
@@ -153,6 +168,10 @@ E2E_DEPS = APPLICATION_DEPS + [
153168
"@aio_npm//ts-node",
154169
]
155170

171+
# Stamp npm_link targets for all dependencies that correspond to a
172+
# first-party equivalent pacakge in angular.
173+
link_local_packages(deps = APPLICATION_DEPS)
174+
156175
architect(
157176
name = "build",
158177
args = [
@@ -161,7 +180,10 @@ architect(
161180
],
162181
chdir = package_name(),
163182
configuration_env_vars = ["NG_BUILD_CACHE"],
164-
data = APPLICATION_FILES + APPLICATION_DEPS,
183+
data = APPLICATION_FILES + select({
184+
":aio_local_deps": substitute_local_packages(APPLICATION_DEPS),
185+
"//conditions:default": APPLICATION_DEPS,
186+
}),
165187
output_dir = True,
166188
)
167189

@@ -173,7 +195,10 @@ architect_test(
173195
],
174196
chdir = package_name(),
175197
configuration_env_vars = ["NG_BUILD_CACHE"],
176-
data = TEST_FILES + TEST_DEPS,
198+
data = TEST_FILES + select({
199+
":aio_local_deps": substitute_local_packages(TEST_DEPS),
200+
"//conditions:default": TEST_DEPS,
201+
}),
177202
env = {
178203
"CHROME_BIN": "../$(CHROMIUM)",
179204
},
@@ -187,10 +212,14 @@ architect_test(
187212
args = [
188213
"site:e2e",
189214
"--no-webdriver-update",
215+
"--port=0",
190216
],
191217
chdir = package_name(),
192218
configuration_env_vars = ["NG_BUILD_CACHE"],
193-
data = E2E_FILES + E2E_DEPS,
219+
data = E2E_FILES + select({
220+
":aio_local_deps": substitute_local_packages(E2E_DEPS),
221+
"//conditions:default": E2E_DEPS,
222+
}),
194223
env = {
195224
"CHROME_BIN": "../$(CHROMIUM)",
196225
"CHROMEDRIVER_BIN": "../$(CHROMEDRIVER)",
@@ -207,20 +236,28 @@ architect(
207236
"site:serve",
208237
],
209238
chdir = package_name(),
210-
data = APPLICATION_DEPS + APPLICATION_FILES,
239+
data = APPLICATION_FILES + select({
240+
":aio_local_deps": substitute_local_packages(APPLICATION_DEPS),
241+
"//conditions:default": APPLICATION_DEPS,
242+
}),
211243
tags = ["ibazel_notify_changes"],
212244
)
213245

214246
# Build and serve the app, watch for changes, and run a fast but low-fidelity
215247
# rebuild when docs change. Watching and serving is a part of the node script,
216248
# so there is no need to run with ibazel, which would be slow as it would redo
217249
# the full dgeni build on each change.
250+
218251
nodejs_binary(
219252
name = "fast-serve",
220253
chdir = package_name(),
221-
data = APPLICATION_DEPS + APPLICATION_FILES + [
254+
data = APPLICATION_FILES + [
222255
"//aio/scripts:fast-serve-and-watch",
223-
],
256+
] + select({
257+
":aio_local_deps": substitute_local_packages(APPLICATION_DEPS),
258+
"//conditions:default": APPLICATION_DEPS,
259+
}),
260+
enable_linker = True,
224261
entry_point = "//aio/scripts:fast-serve-and-watch.js",
225262
env = {
226263
# Tell dgeni packages where the project root is since we used chdir

aio/local_packages_util.bzl

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
load("//:packages.bzl", "ALL_PACKAGES", "to_package_label")
2+
load("@build_bazel_rules_nodejs//internal/linker:npm_link.bzl", "npm_link")
3+
4+
def link_local_packages(deps):
5+
"""Stamp npm_link targets for packages in deps that has a local package equivalent.
6+
7+
Args:
8+
deps: list of npm dependency labels
9+
"""
10+
for dep in deps:
11+
label = Label(dep)
12+
if label.package in ALL_PACKAGES:
13+
npm_link(
14+
name = _npm_link_name(dep),
15+
target = to_package_label(label.package),
16+
package_name = label.package,
17+
package_path = native.package_name(),
18+
tags = ["manual"],
19+
)
20+
21+
def substitute_local_packages(deps):
22+
"""Substitute npm dependencies for their local npm_link equivalent.
23+
24+
Assumes that link_local_packages() was already called on these dependencies.
25+
Dependencies that are not associated with a local package are left alone.
26+
27+
Args:
28+
deps: list of npm dependency labels
29+
30+
Returns:
31+
substituted list of dependencies
32+
"""
33+
substituted = []
34+
for dep in deps:
35+
label = Label(dep)
36+
if label.package in ALL_PACKAGES:
37+
substituted.append(_npm_link_name(dep))
38+
else:
39+
substituted.append(dep)
40+
return substituted
41+
42+
def _npm_link_name(dep):
43+
label = Label(dep)
44+
return "local_%s" % label.package.replace("@", "_").replace("/", "_")

aio/tools/defaults.bzl

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,68 @@
11
load("@build_bazel_rules_nodejs//:index.bzl", _nodejs_binary = "nodejs_binary", _nodejs_test = "nodejs_test")
22

3-
def nodejs_binary(data = [], env = {}, templated_args = [], **kwargs):
3+
def nodejs_binary(data = [], env = {}, templated_args = [], chdir = "", enable_linker = False, **kwargs):
44
data = data + [
55
"//aio/tools/esm-loader",
66
"//aio/tools/esm-loader:esm-loader.mjs",
77
]
88

99
env = dict(env, **{"NODE_MODULES_WORKSPACE_NAME": "aio_npm"})
1010

11+
if not enable_linker:
12+
templated_args = templated_args + [
13+
# Disable the linker and rely on patched resolution which works better on Windows
14+
# and is less prone to race conditions when targets build concurrently.
15+
"--nobazel_run_linker",
16+
]
17+
1118
templated_args = templated_args + [
12-
# Disable the linker and rely on patched resolution which works better on Windows
13-
# and is less prone to race conditions when targets build concurrently.
14-
"--nobazel_run_linker",
1519
# Provide a custom esm loader to resolve third-party depenencies. Unlike for cjs
1620
# modules, rules_nodejs doesn't patch imports when the linker is disabled.
17-
"--node_options=--loader=./$(rootpath //aio/tools/esm-loader:esm-loader.mjs)",
21+
"--node_options=--loader=%s" % _esm_loader_path(chdir),
1822
]
1923

2024
_nodejs_binary(
2125
data = data,
2226
env = env,
2327
templated_args = templated_args,
28+
chdir = chdir,
2429
**kwargs
2530
)
2631

27-
def nodejs_test(data = [], env = {}, templated_args = [], **kwargs):
32+
def nodejs_test(data = [], env = {}, templated_args = [], chdir = "", enable_linker = False, **kwargs):
2833
data = data + [
2934
"//aio/tools/esm-loader",
3035
"//aio/tools/esm-loader:esm-loader.mjs",
3136
]
3237

3338
env = dict(env, **{"NODE_MODULES_WORKSPACE_NAME": "aio_npm"})
3439

40+
if not enable_linker:
41+
templated_args = templated_args + [
42+
# Disable the linker and rely on patched resolution which works better on Windows
43+
# and is less prone to race conditions when targets build concurrently.
44+
"--nobazel_run_linker",
45+
]
46+
3547
templated_args = templated_args + [
36-
# Disable the linker and rely on patched resolution which works better on Windows
37-
# and is less prone to race conditions when targets build concurrently.
38-
"--nobazel_run_linker",
3948
# Provide a custom esm loader to resolve third-party depenencies. Unlike for cjs
4049
# modules, rules_nodejs doesn't patch imports when the linker is disabled.
41-
"--node_options=--loader=./$(rootpath //aio/tools/esm-loader:esm-loader.mjs)",
50+
"--node_options=--loader=%s" % _esm_loader_path(chdir),
4251
]
4352

4453
_nodejs_test(
4554
data = data,
4655
env = env,
4756
templated_args = templated_args,
57+
chdir = chdir,
4858
**kwargs
4959
)
60+
61+
def _esm_loader_path(chdir):
62+
"""Adjust the path provided for the esm loader node option which
63+
depends on the value of chdir."""
64+
esm_loader_path_prefix = "./"
65+
if chdir and len(chdir) > 0:
66+
esm_loader_path_prefix = "".join(["../" for segment in chdir.split("/")])
67+
68+
return "%s$(rootpath //aio/tools/esm-loader:esm-loader.mjs)" % esm_loader_path_prefix

packages/animations/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ ng_module(
1717

1818
ng_package(
1919
name = "npm_package",
20+
package_name = "@angular/animations",
2021
srcs = [
2122
"package.json",
2223
],
@@ -26,6 +27,7 @@ ng_package(
2627
# Do not add more to this list.
2728
# Dependencies on the full npm_package cause long re-builds.
2829
visibility = [
30+
"//aio:__pkg__",
2931
"//aio/tools/examples/shared:__pkg__",
3032
"//integration:__subpackages__",
3133
"//packages/compiler-cli/integrationtest:__pkg__",

packages/bazel/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ load("//tools:defaults.bzl", "pkg_npm")
33

44
pkg_npm(
55
name = "npm_package",
6+
package_name = "@angular/bazel",
67
srcs = glob(
78
["*"],
89
exclude = ["yarn.lock"],
@@ -30,6 +31,7 @@ pkg_npm(
3031
# Do not add more to this list.
3132
# Dependencies on the full npm_package cause long re-builds.
3233
visibility = [
34+
"//aio:__pkg__",
3335
"//aio/tools/examples/shared:__pkg__",
3436
"//integration:__subpackages__",
3537
],

packages/bazel/src/ng_package/ng_package.bzl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ specification of this format at https://goo.gl/jB3GVv
1414
"""
1515

1616
load("@rules_nodejs//nodejs:providers.bzl", "StampSettingInfo")
17-
load("@build_bazel_rules_nodejs//:providers.bzl", "DeclarationInfo", "JSEcmaScriptModuleInfo", "NpmPackageInfo", "node_modules_aspect")
17+
load("@build_bazel_rules_nodejs//:providers.bzl", "DeclarationInfo", "JSEcmaScriptModuleInfo", "LinkablePackageInfo", "NpmPackageInfo", "node_modules_aspect")
1818
load("@build_bazel_rules_nodejs//internal/linker:link_node_modules.bzl", "LinkerPackageMappingInfo")
1919
load(
2020
"@build_bazel_rules_nodejs//internal/pkg_npm:pkg_npm.bzl",
@@ -542,6 +542,7 @@ def _ng_package_impl(ctx):
542542
# More details: https://github.com/bazelbuild/rules_nodejs/issues/2941.
543543
# TODO(devversion): Consider supporting the `package_name` attribute.
544544
LinkerPackageMappingInfo(mappings = empty_depset, node_modules_roots = empty_depset),
545+
LinkablePackageInfo(path = package_dir.path, files = depset([package_dir])),
545546
]
546547

547548
_NG_PACKAGE_DEPS_ASPECTS = [ng_package_module_mappings_aspect, node_modules_aspect]

packages/benchpress/BUILD.bazel

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ ts_library(
2020

2121
ng_package(
2222
name = "npm_package",
23+
package_name = "@angular/benchpress",
2324
srcs = [
2425
"README.md",
2526
"package.json",
@@ -30,7 +31,10 @@ ng_package(
3031
],
3132
# Do not add more to this list.
3233
# Dependencies on the full npm_package cause long re-builds.
33-
visibility = ["//integration:__subpackages__"],
34+
visibility = [
35+
"//aio:__subpackages__",
36+
"//integration:__subpackages__",
37+
],
3438
deps = [
3539
":benchpress",
3640
],

packages/common/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ generated_file_test(
2121

2222
ng_module(
2323
name = "common",
24+
package_name = "@angular/common",
2425
srcs = glob(
2526
[
2627
"*.ts",
@@ -45,6 +46,7 @@ ng_package(
4546
# Do not add more to this list.
4647
# Dependencies on the full npm_package cause long re-builds.
4748
visibility = [
49+
"//aio:__pkg__",
4850
"//aio/tools/examples/shared:__pkg__",
4951
"//integration:__subpackages__",
5052
"//packages/bazel/test/ng_package:__pkg__",

packages/compiler-cli/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ extract_types(
121121

122122
pkg_npm(
123123
name = "npm_package",
124+
package_name = "@angular/compiler-cli",
124125
srcs = [
125126
"package.json",
126127
],
@@ -130,6 +131,7 @@ pkg_npm(
130131
# Do not add more to this list.
131132
# Dependencies on the full npm_package cause long re-builds.
132133
visibility = [
134+
"//aio:__pkg__",
133135
"//aio/tools/examples/shared:__pkg__",
134136
"//integration:__subpackages__",
135137
"//packages/compiler-cli/integrationtest:__pkg__",

0 commit comments

Comments
 (0)