Skip to content

Commit

Permalink
build(bazel): stamp targets to build, test, and serve aio against
Browse files Browse the repository at this point in the history
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
  • Loading branch information
kormide authored and josephperrott committed Nov 22, 2022
1 parent 7a134cf commit 22a317d
Show file tree
Hide file tree
Showing 27 changed files with 168 additions and 49 deletions.
8 changes: 8 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ build:release --stamp
build:snapshot-build --workspace_status_command="yarn -s ng-dev release build-env-stamp --mode=snapshot"
build:snapshot-build --stamp

####################################
# AIO first party dep substitution #
# Turn on with #
# --config=aio_local_deps #
####################################

build:aio_local_deps --//aio:flag_aio_local_deps

###############################
# Output #
###############################
Expand Down
49 changes: 43 additions & 6 deletions aio/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ load("@aio_npm//@angular-devkit/architect-cli:index.bzl", "architect", "architec
load("@build_bazel_rules_nodejs//:index.bzl", "npm_package_bin")
load("//aio/tools:defaults.bzl", "nodejs_binary")
load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
load(":local_packages_util.bzl", "link_local_packages", "substitute_local_packages")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")

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

# If set will use first party angular deps for aio targets instead of their npm equivalent
bool_flag(
name = "flag_aio_local_deps",
build_setting_default = False,
)

config_setting(
name = "aio_local_deps",
flag_values = {
":flag_aio_local_deps": "true",
},
)

# Generate ngsw-config
npm_package_bin(
name = "ngsw-config",
Expand Down Expand Up @@ -153,6 +168,10 @@ E2E_DEPS = APPLICATION_DEPS + [
"@aio_npm//ts-node",
]

# Stamp npm_link targets for all dependencies that correspond to a
# first-party equivalent pacakge in angular.
link_local_packages(deps = APPLICATION_DEPS)

architect(
name = "build",
args = [
Expand All @@ -161,7 +180,10 @@ architect(
],
chdir = package_name(),
configuration_env_vars = ["NG_BUILD_CACHE"],
data = APPLICATION_FILES + APPLICATION_DEPS,
data = APPLICATION_FILES + select({
":aio_local_deps": substitute_local_packages(APPLICATION_DEPS),
"//conditions:default": APPLICATION_DEPS,
}),
output_dir = True,
)

Expand All @@ -173,7 +195,10 @@ architect_test(
],
chdir = package_name(),
configuration_env_vars = ["NG_BUILD_CACHE"],
data = TEST_FILES + TEST_DEPS,
data = TEST_FILES + select({
":aio_local_deps": substitute_local_packages(TEST_DEPS),
"//conditions:default": TEST_DEPS,
}),
env = {
"CHROME_BIN": "../$(CHROMIUM)",
},
Expand All @@ -187,10 +212,14 @@ architect_test(
args = [
"site:e2e",
"--no-webdriver-update",
"--port=0",
],
chdir = package_name(),
configuration_env_vars = ["NG_BUILD_CACHE"],
data = E2E_FILES + E2E_DEPS,
data = E2E_FILES + select({
":aio_local_deps": substitute_local_packages(E2E_DEPS),
"//conditions:default": E2E_DEPS,
}),
env = {
"CHROME_BIN": "../$(CHROMIUM)",
"CHROMEDRIVER_BIN": "../$(CHROMEDRIVER)",
Expand All @@ -207,20 +236,28 @@ architect(
"site:serve",
],
chdir = package_name(),
data = APPLICATION_DEPS + APPLICATION_FILES,
data = APPLICATION_FILES + select({
":aio_local_deps": substitute_local_packages(APPLICATION_DEPS),
"//conditions:default": APPLICATION_DEPS,
}),
tags = ["ibazel_notify_changes"],
)

# Build and serve the app, watch for changes, and run a fast but low-fidelity
# rebuild when docs change. Watching and serving is a part of the node script,
# so there is no need to run with ibazel, which would be slow as it would redo
# the full dgeni build on each change.

nodejs_binary(
name = "fast-serve",
chdir = package_name(),
data = APPLICATION_DEPS + APPLICATION_FILES + [
data = APPLICATION_FILES + [
"//aio/scripts:fast-serve-and-watch",
],
] + select({
":aio_local_deps": substitute_local_packages(APPLICATION_DEPS),
"//conditions:default": APPLICATION_DEPS,
}),
enable_linker = True,
entry_point = "//aio/scripts:fast-serve-and-watch.js",
env = {
# Tell dgeni packages where the project root is since we used chdir
Expand Down
44 changes: 44 additions & 0 deletions aio/local_packages_util.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
load("//:packages.bzl", "ALL_PACKAGES", "to_package_label")
load("@build_bazel_rules_nodejs//internal/linker:npm_link.bzl", "npm_link")

def link_local_packages(deps):
"""Stamp npm_link targets for packages in deps that has a local package equivalent.
Args:
deps: list of npm dependency labels
"""
for dep in deps:
label = Label(dep)
if label.package in ALL_PACKAGES:
npm_link(
name = _npm_link_name(dep),
target = to_package_label(label.package),
package_name = label.package,
package_path = native.package_name(),
tags = ["manual"],
)

def substitute_local_packages(deps):
"""Substitute npm dependencies for their local npm_link equivalent.
Assumes that link_local_packages() was already called on these dependencies.
Dependencies that are not associated with a local package are left alone.
Args:
deps: list of npm dependency labels
Returns:
substituted list of dependencies
"""
substituted = []
for dep in deps:
label = Label(dep)
if label.package in ALL_PACKAGES:
substituted.append(_npm_link_name(dep))
else:
substituted.append(dep)
return substituted

def _npm_link_name(dep):
label = Label(dep)
return "local_%s" % label.package.replace("@", "_").replace("/", "_")
39 changes: 29 additions & 10 deletions aio/tools/defaults.bzl
Original file line number Diff line number Diff line change
@@ -1,49 +1,68 @@
load("@build_bazel_rules_nodejs//:index.bzl", _nodejs_binary = "nodejs_binary", _nodejs_test = "nodejs_test")

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

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

if not enable_linker:
templated_args = templated_args + [
# Disable the linker and rely on patched resolution which works better on Windows
# and is less prone to race conditions when targets build concurrently.
"--nobazel_run_linker",
]

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

_nodejs_binary(
data = data,
env = env,
templated_args = templated_args,
chdir = chdir,
**kwargs
)

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

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

if not enable_linker:
templated_args = templated_args + [
# Disable the linker and rely on patched resolution which works better on Windows
# and is less prone to race conditions when targets build concurrently.
"--nobazel_run_linker",
]

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

_nodejs_test(
data = data,
env = env,
templated_args = templated_args,
chdir = chdir,
**kwargs
)

def _esm_loader_path(chdir):
"""Adjust the path provided for the esm loader node option which
depends on the value of chdir."""
esm_loader_path_prefix = "./"
if chdir and len(chdir) > 0:
esm_loader_path_prefix = "".join(["../" for segment in chdir.split("/")])

return "%s$(rootpath //aio/tools/esm-loader:esm-loader.mjs)" % esm_loader_path_prefix
2 changes: 2 additions & 0 deletions packages/animations/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ ng_module(

ng_package(
name = "npm_package",
package_name = "@angular/animations",
srcs = [
"package.json",
],
Expand All @@ -26,6 +27,7 @@ ng_package(
# Do not add more to this list.
# Dependencies on the full npm_package cause long re-builds.
visibility = [
"//aio:__pkg__",
"//aio/tools/examples/shared:__pkg__",
"//integration:__subpackages__",
"//packages/compiler-cli/integrationtest:__pkg__",
Expand Down
2 changes: 2 additions & 0 deletions packages/bazel/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ load("//tools:defaults.bzl", "pkg_npm")

pkg_npm(
name = "npm_package",
package_name = "@angular/bazel",
srcs = glob(
["*"],
exclude = ["yarn.lock"],
Expand Down Expand Up @@ -30,6 +31,7 @@ pkg_npm(
# Do not add more to this list.
# Dependencies on the full npm_package cause long re-builds.
visibility = [
"//aio:__pkg__",
"//aio/tools/examples/shared:__pkg__",
"//integration:__subpackages__",
],
Expand Down
3 changes: 2 additions & 1 deletion packages/bazel/src/ng_package/ng_package.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ specification of this format at https://goo.gl/jB3GVv
"""

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

_NG_PACKAGE_DEPS_ASPECTS = [ng_package_module_mappings_aspect, node_modules_aspect]
Expand Down
6 changes: 5 additions & 1 deletion packages/benchpress/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ ts_library(

ng_package(
name = "npm_package",
package_name = "@angular/benchpress",
srcs = [
"README.md",
"package.json",
Expand All @@ -30,7 +31,10 @@ ng_package(
],
# Do not add more to this list.
# Dependencies on the full npm_package cause long re-builds.
visibility = ["//integration:__subpackages__"],
visibility = [
"//aio:__subpackages__",
"//integration:__subpackages__",
],
deps = [
":benchpress",
],
Expand Down
2 changes: 2 additions & 0 deletions packages/common/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ generated_file_test(

ng_module(
name = "common",
package_name = "@angular/common",
srcs = glob(
[
"*.ts",
Expand All @@ -45,6 +46,7 @@ ng_package(
# Do not add more to this list.
# Dependencies on the full npm_package cause long re-builds.
visibility = [
"//aio:__pkg__",
"//aio/tools/examples/shared:__pkg__",
"//integration:__subpackages__",
"//packages/bazel/test/ng_package:__pkg__",
Expand Down
2 changes: 2 additions & 0 deletions packages/compiler-cli/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ extract_types(

pkg_npm(
name = "npm_package",
package_name = "@angular/compiler-cli",
srcs = [
"package.json",
],
Expand All @@ -130,6 +131,7 @@ pkg_npm(
# Do not add more to this list.
# Dependencies on the full npm_package cause long re-builds.
visibility = [
"//aio:__pkg__",
"//aio/tools/examples/shared:__pkg__",
"//integration:__subpackages__",
"//packages/compiler-cli/integrationtest:__pkg__",
Expand Down
1 change: 1 addition & 0 deletions packages/compiler/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ ng_package(
# Do not add more to this list.
# Dependencies on the full npm_package cause long re-builds.
visibility = [
"//aio:__pkg__",
"//aio/tools/examples/shared:__pkg__",
"//integration:__subpackages__",
"//packages/compiler-cli/integrationtest:__pkg__",
Expand Down
2 changes: 2 additions & 0 deletions packages/core/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ tsec_test(

ng_package(
name = "npm_package",
package_name = "@angular/core",
srcs = [
"package.json",
],
Expand All @@ -59,6 +60,7 @@ ng_package(
# Do not add more to this list.
# Dependencies on the full npm_package cause long re-builds.
visibility = [
"//aio:__pkg__",
"//aio/tools/examples/shared:__pkg__",
"//integration:__subpackages__",
"//packages/bazel/test/ng_package:__pkg__",
Expand Down
1 change: 1 addition & 0 deletions packages/core/schematics/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pkg_npm(
"migrations.json",
"package.json",
],
validate = False,
visibility = ["//packages/core:__pkg__"],
deps = [
"//packages/core/schematics/migrations/entry-components",
Expand Down
2 changes: 2 additions & 0 deletions packages/elements/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ ng_module(

ng_package(
name = "npm_package",
package_name = "@angular/elements",
srcs = ["package.json"],
tags = [
"release-with-framework",
],
# Do not add more to this list.
# Dependencies on the full npm_package cause long re-builds.
visibility = [
"//aio:__pkg__",
"//aio/tools/examples/shared:__pkg__",
"//integration:__subpackages__",
],
Expand Down
Loading

0 comments on commit 22a317d

Please sign in to comment.