Skip to content

Commit fb75758

Browse files
committed
build: migrate @angular-devkit/architect to npm_package
Migrates the `@angular-devkit/architect` package to the `rules_js` npm package rule, consuming the direct `rules_ts` output JS files. Notably, substitution is FAR different than what it used to be with `rules_nodejs`, so we needed some extra work to leverage `make_template` for substitutions in `package.json` files. **Keep in mind** that for now, this does not apply to any other files; so we only substitute in the `package.json`, but not in e.g. `.js` files as before. We will follow-up on this. The other jq merging/filtering for snapshot or tar references in `package.json` files is kept as is, and is temporarily duplicated. This is acceptable as the migration should be pretty smooth and quick.
1 parent a8335cf commit fb75758

File tree

6 files changed

+160
-31
lines changed

6 files changed

+160
-31
lines changed

packages/angular_devkit/architect/BUILD.bazel

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55

66
load("@npm//@angular/build-tooling/bazel/api-golden:index.bzl", "api_golden_test_npm_package")
77
load("@npm//@bazel/jasmine:index.bzl", "jasmine_node_test")
8-
load("//tools:defaults.bzl", "pkg_npm")
9-
load("//tools:interop.bzl", "ts_project")
8+
load("//tools:defaults2.bzl", "npm_package", "ts_project")
109
load("//tools:ts_json_schema.bzl", "ts_json_schema")
1110

1211
licenses(["notice"])
@@ -99,18 +98,18 @@ genrule(
9998
cmd = "cp $(execpath //:LICENSE) $@",
10099
)
101100

102-
pkg_npm(
103-
name = "npm_package",
101+
npm_package(
102+
name = "pkg",
104103
pkg_deps = [
105104
"//packages/angular_devkit/core:package.json",
106105
],
107106
tags = ["release-package"],
108107
deps = [
109-
":README.md",
110-
":architect",
108+
"README.md",
109+
":architect_rjs",
111110
":license",
112-
"//packages/angular_devkit/architect/node",
113-
"//packages/angular_devkit/architect/testing",
111+
"//packages/angular_devkit/architect/node:node_rjs",
112+
"//packages/angular_devkit/architect/testing:testing_rjs",
114113
],
115114
)
116115

scripts/build-packages-dist.mts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const bazelCmd = process.env.BAZEL || `yarn bazel`;
3131
/** Command that queries Bazel for all release package targets. */
3232
const queryPackagesCmd =
3333
`${bazelCmd} query --output=label "attr('tags', '\\[.*${releaseTargetTag}.*\\]', //packages/...) ` +
34-
`intersect kind('ng_package|pkg_npm', //packages/...)"`;
34+
`intersect kind('ng_package|pkg_npm|^_npm_package rule$', //packages/...)"`;
3535

3636
/** Path for the default distribution output directory. */
3737
const defaultDistPath = join(projectDir, 'dist/releases');

scripts/build.mts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ async function _build(logger: Console, mode: BuildMode): Promise<string[]> {
9595
logger.group(`Building (mode=${mode})...`);
9696

9797
logger.group('Finding targets...');
98-
const queryTargetsCmd = `${bazelCmd} query --output=label "attr(name, npm_package_archive, //packages/...)"`;
98+
const queryTargetsCmd = `${bazelCmd} query --output=label "attr(name, 'npm_package_archive|pkg_archive', //packages/...)"`;
9999
const targets = (await _exec(queryTargetsCmd, true, logger)).split(/\r?\n/);
100100
logger.groupEnd();
101101

@@ -142,9 +142,10 @@ export default async function (
142142
logger.group('Moving packages and tars to dist/');
143143

144144
for (const target of targets) {
145-
const packageDir = target.replace(/\/\/packages\/(.*):npm_package_archive/, '$1');
146-
const bazelOutDir = join(bazelBin, 'packages', packageDir, 'npm_package');
147-
const tarPathInBin = `${bazelBin}/packages/${packageDir}/npm_package_archive.tgz`;
145+
const targetBaseName = target.replace(/.*:(.*)_archive/, '$1');
146+
const packageDir = target.replace(/\/\/packages\/(.*):.*_archive/, '$1');
147+
const bazelOutDir = join(bazelBin, 'packages', packageDir, targetBaseName);
148+
const tarPathInBin = `${bazelBin}/packages/${packageDir}/${targetBaseName}_archive.tgz`;
148149
const packageJsonPath = `${bazelOutDir}/package.json`;
149150
const packageName = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')).name;
150151
const destDir = `${distRoot}/${packageName}`;

tools/defaults.bzl

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,13 @@ load("@build_bazel_rules_nodejs//:index.bzl", _js_library = "js_library", _pkg_n
88
load("@npm//@angular/bazel:index.bzl", _ng_module = "ng_module", _ng_package = "ng_package")
99
load("@npm//@angular/build-tooling/bazel:extract_js_module_output.bzl", "extract_js_module_output")
1010
load("@rules_pkg//:pkg.bzl", "pkg_tar")
11-
load("//:constants.bzl", "RELEASE_ENGINES_NODE", "RELEASE_ENGINES_NPM", "RELEASE_ENGINES_YARN")
1211
load("//tools:link_package_json_to_tarballs.bzl", "link_package_json_to_tarballs")
1312
load("//tools:snapshot_repo_filter.bzl", "SNAPSHOT_REPO_JQ_FILTER")
13+
load("//tools:substitutions.bzl", "NO_STAMP_PACKAGE_SUBSTITUTIONS", "NPM_PACKAGE_SUBSTITUTIONS")
1414

1515
_DEFAULT_TSCONFIG_NG = "//:tsconfig-build-ng"
1616
_DEFAULT_TSCONFIG_TEST = "//:tsconfig-test.json"
1717

18-
NPM_PACKAGE_SUBSTITUTIONS = {
19-
# Version of the local package being built, generated via the `--workspace_status_command` flag.
20-
"0.0.0-PLACEHOLDER": "{STABLE_PROJECT_VERSION}",
21-
"0.0.0-EXPERIMENTAL-PLACEHOLDER": "{STABLE_PROJECT_EXPERIMENTAL_VERSION}",
22-
"BUILD_SCM_HASH-PLACEHOLDER": "{BUILD_SCM_ABBREV_HASH}",
23-
"0.0.0-ENGINES-NODE": RELEASE_ENGINES_NODE,
24-
"0.0.0-ENGINES-NPM": RELEASE_ENGINES_NPM,
25-
"0.0.0-ENGINES-YARN": RELEASE_ENGINES_YARN,
26-
# The below is needed for @angular/ssr FESM file.
27-
"\\./(.+)/packages/angular/ssr/third_party/beasties": "../third_party/beasties/index.js",
28-
}
29-
30-
NO_STAMP_PACKAGE_SUBSTITUTIONS = dict(NPM_PACKAGE_SUBSTITUTIONS, **{
31-
"0.0.0-PLACEHOLDER": "0.0.0",
32-
"0.0.0-EXPERIMENTAL-PLACEHOLDER": "0.0.0",
33-
})
34-
3518
def _default_module_name(testonly):
3619
""" Provide better defaults for package names.
3720

tools/defaults2.bzl

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin")
2+
load("@aspect_bazel_lib//lib:expand_template.bzl", "expand_template")
3+
load("@aspect_bazel_lib//lib:jq.bzl", "jq")
4+
load("@aspect_bazel_lib//lib:utils.bzl", "to_label")
5+
load("@aspect_rules_jasmine//jasmine:defs.bzl", _jasmine_test = "jasmine_test")
6+
load("@aspect_rules_js//npm:defs.bzl", _npm_package = "npm_package")
7+
load("@rules_pkg//:pkg.bzl", "pkg_tar")
8+
load("//tools:interop.bzl", _ts_project = "ts_project")
9+
load("//tools:link_package_json_to_tarballs.bzl", "link_package_json_to_tarballs")
10+
load("//tools:snapshot_repo_filter.bzl", "SNAPSHOT_REPO_JQ_FILTER")
11+
load("//tools:substitutions.bzl", "NO_STAMP_PACKAGE_SUBSTITUTIONS", "get_npm_package_substitutions_for_rjs")
12+
13+
def jasmine_test(**kwargs):
14+
_jasmine_test(
15+
node_modules = "//:root_modules",
16+
**kwargs
17+
)
18+
19+
def ts_project(**kwargs):
20+
_ts_project(**kwargs)
21+
22+
def npm_package(
23+
name,
24+
deps = [],
25+
visibility = None,
26+
pkg_deps = [],
27+
pkg_json = "package.json",
28+
**kwargs):
29+
if name != "pkg":
30+
fail("Expected npm_package to be named `pkg`. " +
31+
"This is needed for pnpm workspace integration.")
32+
33+
# Merge package.json with root package.json and perform various substitutions to
34+
# prepare it for release. For jq docs, see https://stedolan.github.io/jq/manual/.
35+
jq(
36+
name = "basic_substitutions",
37+
# Note: this jq filter relies on the order of the inputs
38+
# buildifier: do not sort
39+
srcs = ["//:package.json", pkg_json],
40+
filter_file = "//tools:package_json_release_filter.jq",
41+
args = ["--slurp"],
42+
out = "substituted/package.json",
43+
)
44+
45+
# Copy package.json files to bazel-out so we can use their bazel-out paths to determine
46+
# the corresponding package npm package tgz path for substitutions.
47+
copy_to_bin(
48+
name = "package_json_copy",
49+
srcs = [pkg_json],
50+
)
51+
pkg_deps_copies = []
52+
for pkg_dep in pkg_deps:
53+
pkg_label = to_label(pkg_dep)
54+
if pkg_label.name != "package.json":
55+
fail("ERROR: only package.json files allowed in pkg_deps of pkg_npm macro")
56+
pkg_deps_copies.append("@%s//%s:package_json_copy" % (pkg_label.workspace_name, pkg_label.package))
57+
58+
# Substitute dependencies on other packages in this repo with tarballs.
59+
link_package_json_to_tarballs(
60+
name = "tar_substitutions",
61+
src = "substituted/package.json",
62+
pkg_deps = [":package_json_copy"] + pkg_deps_copies,
63+
out = "substituted_with_tars/package.json",
64+
)
65+
66+
# Substitute dependencies on other packages in this repo with snapshot repos.
67+
jq(
68+
name = "snapshot_repo_substitutions",
69+
srcs = ["substituted/package.json"],
70+
filter = SNAPSHOT_REPO_JQ_FILTER,
71+
out = "substituted_with_snapshot_repos/package.json",
72+
)
73+
74+
expand_template(
75+
name = "final_package_json",
76+
template = select({
77+
# Do local tar substitution if config_setting is true.
78+
"//:package_json_use_tar_deps": "substituted_with_tars/package.json",
79+
# Do snapshot repo substitution if config_setting is true.
80+
"//:package_json_use_snapshot_repo_deps": "substituted_with_snapshot_repos/package.json",
81+
"//conditions:default": "substituted/package.json",
82+
}),
83+
out = "substituted_final/package.json",
84+
substitutions = NO_STAMP_PACKAGE_SUBSTITUTIONS,
85+
stamp_substitutions = get_npm_package_substitutions_for_rjs(),
86+
)
87+
88+
_npm_package(
89+
name = "npm_package",
90+
visibility = visibility,
91+
srcs = [":final_package_json"] + deps,
92+
replace_prefixes = {
93+
"substituted_final/": "",
94+
"substituted_with_tars/": "",
95+
"substituted_with_snapshot_repos/": "",
96+
"substituted/": "",
97+
},
98+
exclude_srcs_patterns = [
99+
# Exclude `node_modules` which may be pulled by the `js_module_output` runfiles.
100+
"node_modules/**/*",
101+
],
102+
allow_overwrites = True,
103+
**kwargs
104+
)
105+
106+
# Note: For now, in hybrid mode with RNJS and RJS, we ensure
107+
# both `:pkg` and `:npm_package` work.
108+
native.alias(
109+
name = "pkg",
110+
actual = ":npm_package",
111+
)
112+
113+
if pkg_json:
114+
pkg_tar(
115+
name = "npm_package_archive",
116+
srcs = [":pkg"],
117+
extension = "tgz",
118+
strip_prefix = "./pkg",
119+
visibility = visibility,
120+
)

tools/substitutions.bzl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
load("//:constants.bzl", "RELEASE_ENGINES_NODE", "RELEASE_ENGINES_NPM", "RELEASE_ENGINES_YARN")
2+
3+
NPM_PACKAGE_SUBSTITUTIONS = {
4+
# Version of the local package being built, generated via the `--workspace_status_command` flag.
5+
"0.0.0-PLACEHOLDER": "{STABLE_PROJECT_VERSION}",
6+
"0.0.0-EXPERIMENTAL-PLACEHOLDER": "{STABLE_PROJECT_EXPERIMENTAL_VERSION}",
7+
"BUILD_SCM_HASH-PLACEHOLDER": "{BUILD_SCM_ABBREV_HASH}",
8+
"0.0.0-ENGINES-NODE": RELEASE_ENGINES_NODE,
9+
"0.0.0-ENGINES-NPM": RELEASE_ENGINES_NPM,
10+
"0.0.0-ENGINES-YARN": RELEASE_ENGINES_YARN,
11+
# The below is needed for @angular/ssr FESM file.
12+
"\\./(.+)/packages/angular/ssr/third_party/beasties": "../third_party/beasties/index.js",
13+
}
14+
15+
NO_STAMP_PACKAGE_SUBSTITUTIONS = dict(NPM_PACKAGE_SUBSTITUTIONS, **{
16+
"0.0.0-PLACEHOLDER": "0.0.0",
17+
"0.0.0-EXPERIMENTAL-PLACEHOLDER": "0.0.0",
18+
})
19+
20+
def get_npm_package_substitutions_for_rjs():
21+
result = {}
22+
for key, value in NPM_PACKAGE_SUBSTITUTIONS.items():
23+
# in `rules_js`, or `expand_template` from `bazel-lib`, stamp variables
24+
# can only be retrieved via `{{X}}` syntax.
25+
result[key] = value.replace("{", "{{").replace("}", "}}")
26+
return result

0 commit comments

Comments
 (0)