Skip to content

Commit

Permalink
build: migrate @angular-devkit/architect to npm_package
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
devversion authored and alan-agius4 committed Jan 10, 2025
1 parent aaf114f commit 2218b0d
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 27 deletions.
15 changes: 7 additions & 8 deletions packages/angular_devkit/architect/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@

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

licenses(["notice"])
Expand Down Expand Up @@ -99,18 +98,18 @@ genrule(
cmd = "cp $(execpath //:LICENSE) $@",
)

pkg_npm(
name = "npm_package",
npm_package(
name = "pkg",
pkg_deps = [
"//packages/angular_devkit/core:package.json",
],
tags = ["release-package"],
deps = [
":README.md",
":architect",
"README.md",
":architect_rjs",
":license",
"//packages/angular_devkit/architect/node",
"//packages/angular_devkit/architect/testing",
"//packages/angular_devkit/architect/node:node_rjs",
"//packages/angular_devkit/architect/testing:testing_rjs",
],
)

Expand Down
2 changes: 1 addition & 1 deletion scripts/build-packages-dist.mts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const bazelCmd = process.env.BAZEL || `yarn bazel`;
/** Command that queries Bazel for all release package targets. */
const queryPackagesCmd =
`${bazelCmd} query --output=label "attr('tags', '\\[.*${releaseTargetTag}.*\\]', //packages/...) ` +
`intersect kind('ng_package|pkg_npm', //packages/...)"`;
`intersect kind('ng_package|pkg_npm|^_npm_package rule$', //packages/...)"`;

/** Path for the default distribution output directory. */
const defaultDistPath = join(projectDir, 'dist/releases');
Expand Down
Empty file added tools/bazel/BUILD.bazel
Empty file.
109 changes: 109 additions & 0 deletions tools/bazel/npm_package.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin")
load("@aspect_bazel_lib//lib:expand_template.bzl", "expand_template")
load("@aspect_bazel_lib//lib:jq.bzl", "jq")
load("@aspect_bazel_lib//lib:utils.bzl", "to_label")
load("@aspect_rules_js//npm:defs.bzl", _npm_package = "npm_package")
load("@rules_pkg//:pkg.bzl", "pkg_tar")
load("//tools:link_package_json_to_tarballs.bzl", "link_package_json_to_tarballs")
load("//tools:snapshot_repo_filter.bzl", "SNAPSHOT_REPO_JQ_FILTER")
load("//tools:substitutions.bzl", "NO_STAMP_PACKAGE_SUBSTITUTIONS", "get_npm_package_substitutions_for_rjs")

def npm_package(
name,
deps = [],
visibility = None,
pkg_deps = [],
pkg_json = "package.json",
**kwargs):
if name != "pkg":
fail("Expected npm_package to be named `pkg`. " +
"This is needed for pnpm workspace integration.")

# Merge package.json with root package.json and perform various substitutions to
# prepare it for release. For jq docs, see https://stedolan.github.io/jq/manual/.
jq(
name = "basic_substitutions",
# Note: this jq filter relies on the order of the inputs
# buildifier: do not sort
srcs = ["//:package.json", pkg_json],
filter_file = "//tools:package_json_release_filter.jq",
args = ["--slurp"],
out = "substituted/package.json",
)

# Copy package.json files to bazel-out so we can use their bazel-out paths to determine
# the corresponding package npm package tgz path for substitutions.
copy_to_bin(
name = "package_json_copy",
srcs = [pkg_json],
)
pkg_deps_copies = []
for pkg_dep in pkg_deps:
pkg_label = to_label(pkg_dep)
if pkg_label.name != "package.json":
fail("ERROR: only package.json files allowed in pkg_deps of pkg_npm macro")
pkg_deps_copies.append("@%s//%s:package_json_copy" % (pkg_label.workspace_name, pkg_label.package))

# Substitute dependencies on other packages in this repo with tarballs.
link_package_json_to_tarballs(
name = "tar_substitutions",
src = "substituted/package.json",
pkg_deps = [":package_json_copy"] + pkg_deps_copies,
out = "substituted_with_tars/package.json",
)

# Substitute dependencies on other packages in this repo with snapshot repos.
jq(
name = "snapshot_repo_substitutions",
srcs = ["substituted/package.json"],
filter = SNAPSHOT_REPO_JQ_FILTER,
out = "substituted_with_snapshot_repos/package.json",
)

expand_template(
name = "final_package_json",
template = select({
# Do local tar substitution if config_setting is true.
"//:package_json_use_tar_deps": "substituted_with_tars/package.json",
# Do snapshot repo substitution if config_setting is true.
"//:package_json_use_snapshot_repo_deps": "substituted_with_snapshot_repos/package.json",
"//conditions:default": "substituted/package.json",
}),
out = "substituted_final/package.json",
substitutions = NO_STAMP_PACKAGE_SUBSTITUTIONS,
stamp_substitutions = get_npm_package_substitutions_for_rjs(),
)

_npm_package(
name = "npm_package",
visibility = visibility,
srcs = [":final_package_json"] + deps,
replace_prefixes = {
"substituted_final/": "",
"substituted_with_tars/": "",
"substituted_with_snapshot_repos/": "",
"substituted/": "",
},
exclude_srcs_patterns = [
# Exclude `node_modules` which may be pulled by the `js_module_output` runfiles.
"node_modules/**/*",
],
allow_overwrites = True,
**kwargs
)

# Note: For now, in hybrid mode with RNJS and RJS, we ensure
# both `:pkg` and `:npm_package` work.
native.alias(
name = "pkg",
actual = ":npm_package",
)

if pkg_json:
pkg_tar(
name = "npm_package_archive",
srcs = [":pkg"],
extension = "tgz",
strip_prefix = "./npm_package",
visibility = visibility,
)
19 changes: 1 addition & 18 deletions tools/defaults.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,13 @@ load("@build_bazel_rules_nodejs//:index.bzl", _js_library = "js_library", _pkg_n
load("@npm//@angular/bazel:index.bzl", _ng_module = "ng_module", _ng_package = "ng_package")
load("@npm//@angular/build-tooling/bazel:extract_js_module_output.bzl", "extract_js_module_output")
load("@rules_pkg//:pkg.bzl", "pkg_tar")
load("//:constants.bzl", "RELEASE_ENGINES_NODE", "RELEASE_ENGINES_NPM", "RELEASE_ENGINES_YARN")
load("//tools:link_package_json_to_tarballs.bzl", "link_package_json_to_tarballs")
load("//tools:snapshot_repo_filter.bzl", "SNAPSHOT_REPO_JQ_FILTER")
load("//tools:substitutions.bzl", "NO_STAMP_PACKAGE_SUBSTITUTIONS", "NPM_PACKAGE_SUBSTITUTIONS")

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

NPM_PACKAGE_SUBSTITUTIONS = {
# Version of the local package being built, generated via the `--workspace_status_command` flag.
"0.0.0-PLACEHOLDER": "{STABLE_PROJECT_VERSION}",
"0.0.0-EXPERIMENTAL-PLACEHOLDER": "{STABLE_PROJECT_EXPERIMENTAL_VERSION}",
"BUILD_SCM_HASH-PLACEHOLDER": "{BUILD_SCM_ABBREV_HASH}",
"0.0.0-ENGINES-NODE": RELEASE_ENGINES_NODE,
"0.0.0-ENGINES-NPM": RELEASE_ENGINES_NPM,
"0.0.0-ENGINES-YARN": RELEASE_ENGINES_YARN,
# The below is needed for @angular/ssr FESM file.
"\\./(.+)/packages/angular/ssr/third_party/beasties": "../third_party/beasties/index.js",
}

NO_STAMP_PACKAGE_SUBSTITUTIONS = dict(NPM_PACKAGE_SUBSTITUTIONS, **{
"0.0.0-PLACEHOLDER": "0.0.0",
"0.0.0-EXPERIMENTAL-PLACEHOLDER": "0.0.0",
})

def _default_module_name(testonly):
""" Provide better defaults for package names.
Expand Down
8 changes: 8 additions & 0 deletions tools/defaults2.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
load("//tools:interop.bzl", _ts_project = "ts_project")
load("//tools/bazel:npm_package.bzl", _npm_package = "npm_package")

def ts_project(**kwargs):
_ts_project(**kwargs)

def npm_package(**kwargs):
_npm_package(**kwargs)
26 changes: 26 additions & 0 deletions tools/substitutions.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
load("//:constants.bzl", "RELEASE_ENGINES_NODE", "RELEASE_ENGINES_NPM", "RELEASE_ENGINES_YARN")

NPM_PACKAGE_SUBSTITUTIONS = {
# Version of the local package being built, generated via the `--workspace_status_command` flag.
"0.0.0-PLACEHOLDER": "{STABLE_PROJECT_VERSION}",
"0.0.0-EXPERIMENTAL-PLACEHOLDER": "{STABLE_PROJECT_EXPERIMENTAL_VERSION}",
"BUILD_SCM_HASH-PLACEHOLDER": "{BUILD_SCM_ABBREV_HASH}",
"0.0.0-ENGINES-NODE": RELEASE_ENGINES_NODE,
"0.0.0-ENGINES-NPM": RELEASE_ENGINES_NPM,
"0.0.0-ENGINES-YARN": RELEASE_ENGINES_YARN,
# The below is needed for @angular/ssr FESM file.
"\\./(.+)/packages/angular/ssr/third_party/beasties": "../third_party/beasties/index.js",
}

NO_STAMP_PACKAGE_SUBSTITUTIONS = dict(NPM_PACKAGE_SUBSTITUTIONS, **{
"0.0.0-PLACEHOLDER": "0.0.0",
"0.0.0-EXPERIMENTAL-PLACEHOLDER": "0.0.0",
})

def get_npm_package_substitutions_for_rjs():
result = {}
for key, value in NPM_PACKAGE_SUBSTITUTIONS.items():
# in `rules_js`, or `expand_template` from `bazel-lib`, stamp variables
# can only be retrieved via `{{X}}` syntax.
result[key] = value.replace("{", "{{").replace("}", "}}")
return result

0 comments on commit 2218b0d

Please sign in to comment.