From 8187542c6918da4fe2e3c8dcb0909b16a410618d Mon Sep 17 00:00:00 2001 From: Greg Magolan Date: Mon, 15 Apr 2024 15:52:27 -0700 Subject: [PATCH] feat: add support for linking js_library as 1p npm deps (#1646) --- .../npm_translate_lock_LTE4Nzc1MDcwNjU= | 9 ++- .bazelignore | 2 + examples/npm_deps/BUILD.bazel | 17 ++++ examples/npm_deps/package.json | 2 + .../npm_package/packages/pkg_d/BUILD.bazel | 19 +++++ examples/npm_package/packages/pkg_d/README.md | 3 + examples/npm_package/packages/pkg_d/index.js | 19 +++++ .../npm_package/packages/pkg_d/package.json | 10 +++ js/private/js_info.bzl | 7 ++ js/private/js_library.bzl | 1 + npm/private/npm_link_package_store.bzl | 1 + npm/private/npm_package_store.bzl | 79 ++++++++++++++----- npm/private/npm_package_store_internal.bzl | 2 - .../test/snapshots/bzlmod/npm_defs.bzl | 53 ++++++++++++- npm/private/test/snapshots/wksp/npm_defs.bzl | 53 ++++++++++++- .../test/snapshots/wksp/repositories.bzl | 3 + pnpm-lock.yaml | 16 +++- pnpm-workspace.yaml | 1 + 18 files changed, 270 insertions(+), 27 deletions(-) create mode 100644 examples/npm_package/packages/pkg_d/BUILD.bazel create mode 100644 examples/npm_package/packages/pkg_d/README.md create mode 100644 examples/npm_package/packages/pkg_d/index.js create mode 100644 examples/npm_package/packages/pkg_d/package.json diff --git a/.aspect/rules/external_repository_action_cache/npm_translate_lock_LTE4Nzc1MDcwNjU= b/.aspect/rules/external_repository_action_cache/npm_translate_lock_LTE4Nzc1MDcwNjU= index 595eae079..98697c7f8 100755 --- a/.aspect/rules/external_repository_action_cache/npm_translate_lock_LTE4Nzc1MDcwNjU= +++ b/.aspect/rules/external_repository_action_cache/npm_translate_lock_LTE4Nzc1MDcwNjU= @@ -1,14 +1,14 @@ # @generated -# Input hashes for repository rule npm_translate_lock(name = "npm", pnpm_lock = "//:pnpm-lock.yaml"). +# Input hashes for repository rule npm_translate_lock(name = "npm", pnpm_lock = "@@//:pnpm-lock.yaml"). # This file should be checked into version control along with the pnpm-lock.yaml file. .npmrc=-2065072158 -pnpm-lock.yaml=915811237 +pnpm-lock.yaml=1142601305 examples/npm_deps/patches/meaning-of-life@1.0.0-pnpm.patch=-442666336 package.json=-275319675 -pnpm-workspace.yaml=-871530930 +pnpm-workspace.yaml=-1178830835 examples/js_binary/package.json=-41174383 examples/macro/package.json=857146175 -examples/npm_deps/package.json=283109008 +examples/npm_deps/package.json=-1377141392 examples/npm_package/libs/lib_a/package.json=-1377103079 examples/npm_package/packages/pkg_a/package.json=1006424040 examples/npm_package/packages/pkg_b/package.json=1041247977 @@ -21,6 +21,7 @@ npm/private/test/npm_package/package.json=-1991705133 npm/private/test/vendored/is-odd/package.json=1041695223 npm/private/test/vendored/semver-max/package.json=578664053 examples/linked_empty_node_modules/package.json=-1039372825 +examples/npm_package/packages/pkg_d/package.json=1110895851 js/private/image/package.json=-1260474848 js/private/test/image/package.json=1286417612 js/private/test/js_run_devserver/package.json=-260856079 diff --git a/.bazelignore b/.bazelignore index bd95bc483..cea9bbcc7 100644 --- a/.bazelignore +++ b/.bazelignore @@ -6,6 +6,8 @@ examples/npm_deps/node_modules/ examples/npm_package/libs/lib_a/node_modules/ examples/npm_package/packages/pkg_a/node_modules/ examples/npm_package/packages/pkg_b/node_modules/ +examples/npm_package/packages/pkg_c/node_modules/ +examples/npm_package/packages/pkg_d/node_modules/ examples/webpack_cli/node_modules/ js/private/coverage/bundle/node_modules js/private/image/node_modules diff --git a/examples/npm_deps/BUILD.bazel b/examples/npm_deps/BUILD.bazel index f9cc6b467..1a987fd35 100644 --- a/examples/npm_deps/BUILD.bazel +++ b/examples/npm_deps/BUILD.bazel @@ -262,3 +262,20 @@ js_test( ], entry_point = "patched-dependencies-test.js", ) + +####################################### +# Case 9: use a first-party npm package within our Bazel monorepo workspace from a js_library target + +write_file( + name = "write9", + out = "case9.js", + content = ["require('@mycorp/pkg-d')"], +) + +js_test( + name = "test9", + data = [ + ":node_modules/@mycorp/pkg-d", + ], + entry_point = "case9.js", +) diff --git a/examples/npm_deps/package.json b/examples/npm_deps/package.json index ad1e900d1..bf297409a 100644 --- a/examples/npm_deps/package.json +++ b/examples/npm_deps/package.json @@ -5,7 +5,9 @@ "@aspect-test/c": "2.0.2", "@gregmagolan/test-b": "0.0.2", "@mycorp/pkg-a": "workspace:*", + "@mycorp/pkg-d": "workspace:*", "@rollup/plugin-commonjs": "21.1.0", + "acorn": "8.7.1", "debug": "3.2.7", "meaning-of-life": "1.0.0", "mobx-react": "7.3.0", diff --git a/examples/npm_package/packages/pkg_d/BUILD.bazel b/examples/npm_package/packages/pkg_d/BUILD.bazel new file mode 100644 index 000000000..f2fbdd4b8 --- /dev/null +++ b/examples/npm_package/packages/pkg_d/BUILD.bazel @@ -0,0 +1,19 @@ +load("@aspect_rules_js//js:defs.bzl", "js_library") +load("@npm//:defs.bzl", "npm_link_all_packages") + +npm_link_all_packages(name = "node_modules") + +js_library( + name = "pkg_d", + srcs = [ + "index.js", + "package.json", + ], + visibility = ["//visibility:public"], + # because we're linking this js_library, we must explictly add our npm dependendies to `deps` so + # they are picked up my the linker. npm dependendies in `data` are not propogated through the + # linker when linking a js_libary. + deps = [ + ":node_modules", + ], +) diff --git a/examples/npm_package/packages/pkg_d/README.md b/examples/npm_package/packages/pkg_d/README.md new file mode 100644 index 000000000..74f4c65c9 --- /dev/null +++ b/examples/npm_package/packages/pkg_d/README.md @@ -0,0 +1,3 @@ +# @mycorp/pkg-d package + +'@mycorp/pkg-d' is an example of a first party package that is linked as a js_library diff --git a/examples/npm_package/packages/pkg_d/index.js b/examples/npm_package/packages/pkg_d/index.js new file mode 100644 index 000000000..fef566508 --- /dev/null +++ b/examples/npm_package/packages/pkg_d/index.js @@ -0,0 +1,19 @@ +/** + * @fileoverview minimal test program that requires a third-party package from npm + */ +const acorn = require('acorn') +const { v4: uuid } = require('uuid') + +function toAst(program) { + return JSON.stringify(acorn.parse(program, { ecmaVersion: 2020 })) + '\n' +} + +function getAcornVersion() { + return acorn.version +} + +module.exports = { + toAst, + getAcornVersion, + uuid, +} diff --git a/examples/npm_package/packages/pkg_d/package.json b/examples/npm_package/packages/pkg_d/package.json new file mode 100644 index 000000000..f6bd81125 --- /dev/null +++ b/examples/npm_package/packages/pkg_d/package.json @@ -0,0 +1,10 @@ +{ + "name": "@mycorp/pkg-d", + "private": true, + "dependencies": { + "uuid": "8.3.2" + }, + "peerDependencies": { + "acorn": "8.x.x" + } +} diff --git a/js/private/js_info.bzl b/js/private/js_info.bzl index af2df9f44..caac17610 100644 --- a/js/private/js_info.bzl +++ b/js/private/js_info.bzl @@ -3,6 +3,7 @@ JsInfo = provider( doc = "Encapsulates information provided by rules in rules_js and derivative rule sets", fields = { + "target": "The label of target that created this JsInfo", "sources": "A depset of source files produced by the target", "types": "A depset of typings files produced by the target", "transitive_sources": "A depset of source files produced by the target and the target's transitive deps", @@ -13,6 +14,7 @@ JsInfo = provider( ) def js_info( + target, sources = depset(), types = depset(), transitive_sources = depset(), @@ -22,6 +24,7 @@ def js_info( """Construct a JsInfo. Args: + target: See JsInfo documentation sources: See JsInfo documentation types: See JsInfo documentation transitive_sources: See JsInfo documentation @@ -32,6 +35,9 @@ def js_info( Returns: A JsInfo provider """ + if type(target) != "Label": + msg = "Expected target to be a Label but got {}".format(type(target)) + fail(msg) if type(sources) != "depset": msg = "Expected sources to be a depset but got {}".format(type(sources)) fail(msg) @@ -52,6 +58,7 @@ def js_info( fail(msg) return JsInfo( + target = target, sources = sources, types = types, transitive_sources = transitive_sources, diff --git a/js/private/js_library.bzl b/js/private/js_library.bzl index d02768d8f..62af932d1 100644 --- a/js/private/js_library.bzl +++ b/js/private/js_library.bzl @@ -214,6 +214,7 @@ def _js_library_impl(ctx): return [ js_info( + target = ctx.label, sources = sources, types = types, transitive_sources = transitive_sources, diff --git a/npm/private/npm_link_package_store.bzl b/npm/private/npm_link_package_store.bzl index 184727f00..7fdfc14fa 100644 --- a/npm/private/npm_link_package_store.bzl +++ b/npm/private/npm_link_package_store.bzl @@ -105,6 +105,7 @@ def _npm_link_package_store_impl(ctx): runfiles = ctx.runfiles(transitive_files = transitive_files_depset), ), js_info( + target = ctx.label, npm_sources = transitive_files_depset, # only propagate non-dev npm dependencies to use as direct dependencies when linking downstream npm_package targets with npm_link_package npm_package_store_infos = depset([store_info]) if not store_info.dev else depset(), diff --git a/npm/private/npm_package_store.bzl b/npm/private/npm_package_store.bzl index 42e0cbe09..c20731560 100644 --- a/npm/private/npm_package_store.bzl +++ b/npm/private/npm_package_store.bzl @@ -6,6 +6,9 @@ load(":utils.bzl", "utils") load(":npm_package_info.bzl", "NpmPackageInfo") load(":npm_package_store_info.bzl", "NpmPackageStoreInfo") +# buildifier: disable=bzl-visibility +load("//js/private:js_info.bzl", "JsInfo") + _DOC = """Defines a npm package that is linked into a node_modules tree. The npm package is linked with a pnpm style symlinked node_modules output tree. @@ -24,7 +27,6 @@ _ATTRS = { "src": attr.label( doc = """A npm_package target or or any other target that provides a NpmPackageInfo. """, - providers = [NpmPackageInfo], mandatory = True, ), "deps": attr.label_keyed_string_dict( @@ -150,8 +152,26 @@ If set, takes precendance over the package version in the NpmPackageInfo src. } def _npm_package_store_impl(ctx): - package = ctx.attr.package if ctx.attr.package else ctx.attr.src[NpmPackageInfo].package - version = ctx.attr.version if ctx.attr.version else ctx.attr.src[NpmPackageInfo].version + if ctx.attr.src: + if NpmPackageInfo in ctx.attr.src: + package = ctx.attr.package if ctx.attr.package else ctx.attr.src[NpmPackageInfo].package + version = ctx.attr.version if ctx.attr.version else ctx.attr.src[NpmPackageInfo].version + elif JsInfo in ctx.attr.src: + if not ctx.attr.package: + msg = "Expected package to be specified in '{}' when src '{}' provides a JsInfo".format(ctx.label, ctx.attr.src[JsInfo].target) + fail(msg) + package = ctx.attr.package + version = ctx.attr.version if ctx.attr.version else "0.0.0" + else: + msg = "Expected src of '{}' to provide either NpmPackageInfo or JsInfo".format(ctx.label) + fail(msg) + else: + # ctx.attr.src can be unspecified when the rule is a npm_package_store_internal; when it is _not_ + # set, this is a terminal 3p package with ctx.attr.deps being the transitive closure of + # deps; this pattern is used to break circular dependencies between 3rd party npm deps; it + # is not used for 1st party deps + package = ctx.attr.package + version = ctx.attr.version if not package: fail("No package name specified to link to. Package name must either be specified explicitly via 'package' attribute or come from the 'src' 'NpmPackageInfo', typically a 'npm_package' target") @@ -159,19 +179,20 @@ def _npm_package_store_impl(ctx): fail("No package version specified to link to. Package version must either be specified explicitly via 'version' attribute or come from the 'src' 'NpmPackageInfo', typically a 'npm_package' target") package_store_name = utils.package_store_name(package, version) - - src = None package_store_directory = None + files = [] + transitive_files_depsets = [] + transitive_package_store_infos_depsets = [] + npm_package_store_infos = [] direct_ref_deps = {} - npm_package_store_infos = [] + # the path to the package store location for this package + # "node_modules/{package_store_root}/{package_store_name}/node_modules/{package}" + package_store_directory_path = paths.join("node_modules", utils.package_store_root, package_store_name, "node_modules", package) - if ctx.attr.src: + if ctx.attr.src and NpmPackageInfo in ctx.attr.src: # output the package as a TreeArtifact to its package store location - # "node_modules/{package_store_root}/{package_store_name}/node_modules/{package}" - package_store_directory_path = paths.join("node_modules", utils.package_store_root, package_store_name, "node_modules", package) - if ctx.label.workspace_name: expected_short_path = paths.join("..", ctx.label.workspace_name, ctx.label.package, package_store_directory_path) else: @@ -253,7 +274,22 @@ deps of npm_package_store must be in the same package.""" % (ctx.label.package, dep_symlink_path = paths.join("node_modules", utils.package_store_root, package_store_name, "node_modules", dep_package) files.append(utils.make_symlink(ctx, dep_symlink_path, dep_package_store_directory.path)) npm_package_store_infos.append(store) - else: + elif ctx.attr.src and JsInfo in ctx.attr.src: + # Symlink to the directory of the target that created this JsInfo + if ctx.label.workspace_name: + symlink_path = paths.join("external", ctx.label.workspace_name, ctx.label.package, package_store_directory_path) + else: + symlink_path = paths.join(ctx.label.package, package_store_directory_path) + transitive_files_depsets.append(ctx.attr.src[JsInfo].transitive_sources) + transitive_files_depsets.append(ctx.attr.src[JsInfo].transitive_types) + transitive_package_store_infos_depsets.append(ctx.attr.src[JsInfo].npm_package_store_infos) + if ctx.attr.src[JsInfo].target.workspace_name: + target_path = paths.join(ctx.bin_dir.path, "external", ctx.attr.src[JsInfo].target.workspace_name, ctx.attr.src[JsInfo].target.package) + package_store_directory = utils.make_symlink(ctx, symlink_path, target_path) + else: + target_path = paths.join(ctx.bin_dir.path, ctx.attr.src[JsInfo].target.package) + package_store_directory = utils.make_symlink(ctx, symlink_path, target_path) + elif not ctx.attr.src: # ctx.attr.src can be unspecified when the rule is a npm_package_store_internal; when it is _not_ # set, this is a terminal 3p package with ctx.attr.deps being the transitive closure of # deps; this pattern is used to break circular dependencies between 3rd party npm deps; it @@ -292,6 +328,9 @@ deps of npm_package_store must be in the same package.""" % (ctx.label.package, # "node_modules/{package_store_root}/{package_store_name}/node_modules/{package}" dep_ref_dep_symlink_path = paths.join("node_modules", utils.package_store_root, dep_package_store_name, "node_modules", dep_ref_dep_alias) files.append(utils.make_symlink(ctx, dep_ref_dep_symlink_path, dep_ref_def_package_store_directory.path)) + else: + # We should _never_ get here + fail("Internal error") if package_store_directory: files.append(package_store_directory) @@ -303,10 +342,14 @@ deps of npm_package_store must be in the same package.""" % (ctx.label.package, files_depset = depset(files) + for transitive_package_store_infos_depset in transitive_package_store_infos_depsets: + for npm_package_store_info in transitive_package_store_infos_depset.to_list(): + npm_package_store_infos.append(npm_package_store_info) + if ctx.attr.src: - transitive_files_depset = depset(files, transitive = [ - npm_package_store.transitive_files - for npm_package_store in npm_package_store_infos + transitive_files_depset = depset(files, transitive = transitive_files_depsets + [ + npm_package_store_info.transitive_files + for npm_package_store_info in npm_package_store_infos ]) else: # ctx.attr.src can be unspecified when the rule is a npm_package_store_internal; when ctx.attr.src is @@ -316,9 +359,9 @@ deps of npm_package_store must be in the same package.""" % (ctx.label.package, # closure of all the entire package store deps, we can safely add just `files` from each of # these to `transitive_files_depset`; doing so reduces the size of `transitive_files_depset` # significantly and reduces analysis time and Bazel memory usage during analysis - transitive_files_depset = depset(files, transitive = [ - npm_package_store.files - for npm_package_store in npm_package_store_infos + transitive_files_depset = depset(files, transitive = transitive_files_depsets + [ + npm_package_store_info.files + for npm_package_store_info in npm_package_store_infos ]) providers = [ @@ -336,7 +379,7 @@ deps of npm_package_store must be in the same package.""" % (ctx.label.package, dev = ctx.attr.dev, ), ] - if package_store_directory: + if package_store_directory and package_store_directory.is_directory: # Provide an output group that provides a single file which is the # package directory for use in $(execpath) and $(rootpath). # Output group name must match utils.package_directory_output_group diff --git a/npm/private/npm_package_store_internal.bzl b/npm/private/npm_package_store_internal.bzl index 4401702a1..2c2f0b138 100644 --- a/npm/private/npm_package_store_internal.bzl +++ b/npm/private/npm_package_store_internal.bzl @@ -2,7 +2,6 @@ load("@bazel_skylib//lib:dicts.bzl", "dicts") load(":npm_package_store.bzl", _npm_package_store_lib = "npm_package_store_lib") -load(":npm_package_info.bzl", "NpmPackageInfo") _INTERNAL_ATTRS_STORE = dicts.add(_npm_package_store_lib.attrs, { "src": attr.label( @@ -15,7 +14,6 @@ _INTERNAL_ATTRS_STORE = dicts.add(_npm_package_store_lib.attrs, { complication. Outside our `npm_import` you should structure you `npm_link_package` targets in a DAG (without cycles). """, - providers = [NpmPackageInfo], ), "package": attr.string( doc = """The package name to link to. diff --git a/npm/private/test/snapshots/bzlmod/npm_defs.bzl b/npm/private/test/snapshots/bzlmod/npm_defs.bzl index 32d8350c5..0144d97b3 100644 --- a/npm/private/test/snapshots/bzlmod/npm_defs.bzl +++ b/npm/private/test/snapshots/bzlmod/npm_defs.bzl @@ -982,7 +982,7 @@ load("@@_main~npm~npm__at_types_underscore__registry.npmjs.org_at_types_undersco load("@@_main~npm~npm__at_types_ws__registry.npmjs.org_at_types_ws_8.5.5__links//:defs.bzl", store_975 = "npm_imported_package_store") load("@@_main~npm~npm__at_types_yauzl__registry.npmjs.org_at_types_yauzl_2.10.0__links//:defs.bzl", store_976 = "npm_imported_package_store") -_LINK_PACKAGES = ["", "examples/js_binary", "examples/linked_empty_node_modules", "examples/macro", "examples/npm_deps", "examples/npm_package/libs/lib_a", "examples/npm_package/packages/pkg_a", "examples/npm_package/packages/pkg_b", "examples/webpack_cli", "js/private/coverage/bundle", "js/private/image", "js/private/test/image", "js/private/test/js_run_devserver", "js/private/worker/src", "npm/private/test", "npm/private/test/npm_package"] +_LINK_PACKAGES = ["", "examples/js_binary", "examples/linked_empty_node_modules", "examples/macro", "examples/npm_deps", "examples/npm_package/libs/lib_a", "examples/npm_package/packages/pkg_a", "examples/npm_package/packages/pkg_b", "examples/npm_package/packages/pkg_d", "examples/webpack_cli", "js/private/coverage/bundle", "js/private/image", "js/private/test/image", "js/private/test/js_run_devserver", "js/private/worker/src", "npm/private/test", "npm/private/test/npm_package"] # buildifier: disable=function-docstring def npm_link_all_packages(name = "node_modules", imported_links = []): @@ -1994,6 +1994,8 @@ def npm_link_all_packages(name = "node_modules", imported_links = []): link_88(name = "{}/@rollup/plugin-commonjs".format(name)) link_targets.append("//{}:{}/@rollup/plugin-commonjs".format(bazel_package, name)) scope_targets["@rollup"] = scope_targets["@rollup"] + [link_targets[-1]] if "@rollup" in scope_targets else [link_targets[-1]] + link_142(name = "{}/acorn".format(name)) + link_targets.append("//{}:{}/acorn".format(bazel_package, name)) link_296(name = "{}/debug".format(name)) link_targets.append("//{}:{}/debug".format(bazel_package, name)) link_584(name = "{}/meaning-of-life".format(name)) @@ -2155,6 +2157,11 @@ def npm_link_all_packages(name = "node_modules", imported_links = []): link_targets.append("//{}:{}/acorn".format(bazel_package, name)) link_900(name = "{}/uuid".format(name)) link_targets.append("//{}:{}/uuid".format(bazel_package, name)) + elif bazel_package == "examples/npm_package/packages/pkg_d": + link_142(name = "{}/acorn".format(name)) + link_targets.append("//{}:{}/acorn".format(bazel_package, name)) + link_900(name = "{}/uuid".format(name)) + link_targets.append("//{}:{}/uuid".format(bazel_package, name)) elif bazel_package == "examples/npm_package/packages/pkg_b": link_143(name = "{}/acorn".format(name)) link_targets.append("//{}:{}/acorn".format(bazel_package, name)) @@ -2258,6 +2265,42 @@ def npm_link_all_packages(name = "node_modules", imported_links = []): tags = ["manual"], ) + if is_root: + _npm_package_store( + name = ".aspect_rules_js/{}/@mycorp+pkg-d@0.0.0".format(name), + src = "//examples/npm_package/packages/pkg_d:pkg_d", + package = "@mycorp/pkg-d", + version = "0.0.0", + deps = { + "//:.aspect_rules_js/{}/acorn@8.7.1".format(name): "acorn", + "//:.aspect_rules_js/{}/uuid@8.3.2".format(name): "uuid", + }, + visibility = ["//visibility:public"], + tags = ["manual"], + ) + + for link_package in ["examples/npm_deps"]: + if link_package == native.package_name(): + # terminal target for direct dependencies + _npm_link_package_store( + name = "{}/@mycorp/pkg-d".format(name), + src = "//:.aspect_rules_js/{}/@mycorp+pkg-d@0.0.0".format(name), + visibility = ["//visibility:public"], + tags = ["manual"], + ) + + # filegroup target that provides a single file which is + # package directory for use in $(execpath) and $(rootpath) + native.filegroup( + name = "{}/@mycorp/pkg-d/dir".format(name), + srcs = [":{}/@mycorp/pkg-d".format(name)], + output_group = "package_directory", + visibility = ["//visibility:public"], + tags = ["manual"], + ) + link_targets.append(":{}/@mycorp/pkg-d".format(name)) + scope_targets["@mycorp"] = scope_targets["@mycorp"] + [link_targets[-1]] if "@mycorp" in scope_targets else [link_targets[-1]] + if is_root: _npm_package_store( name = ".aspect_rules_js/{}/test-npm_package@0.0.0".format(name), @@ -2321,6 +2364,7 @@ def npm_link_targets(name = "node_modules", package = None): link_targets.append("//{}:{}/@aspect-test/c".format(bazel_package, name)) link_targets.append("//{}:{}/@gregmagolan/test-b".format(bazel_package, name)) link_targets.append("//{}:{}/@rollup/plugin-commonjs".format(bazel_package, name)) + link_targets.append("//{}:{}/acorn".format(bazel_package, name)) link_targets.append("//{}:{}/debug".format(bazel_package, name)) link_targets.append("//{}:{}/meaning-of-life".format(bazel_package, name)) link_targets.append("//{}:{}/mobx-react".format(bazel_package, name)) @@ -2393,6 +2437,9 @@ def npm_link_targets(name = "node_modules", package = None): elif bazel_package == "examples/npm_package/packages/pkg_a": link_targets.append("//{}:{}/acorn".format(bazel_package, name)) link_targets.append("//{}:{}/uuid".format(bazel_package, name)) + elif bazel_package == "examples/npm_package/packages/pkg_d": + link_targets.append("//{}:{}/acorn".format(bazel_package, name)) + link_targets.append("//{}:{}/uuid".format(bazel_package, name)) elif bazel_package == "examples/npm_package/packages/pkg_b": link_targets.append("//{}:{}/acorn".format(bazel_package, name)) link_targets.append("//{}:{}/uuid".format(bazel_package, name)) @@ -2421,6 +2468,10 @@ def npm_link_targets(name = "node_modules", package = None): if link_package == bazel_package: link_targets.append("//{}:{}/@mycorp/pkg-a".format(bazel_package, name)) + for link_package in ["examples/npm_deps"]: + if link_package == bazel_package: + link_targets.append("//{}:{}/@mycorp/pkg-d".format(bazel_package, name)) + for link_package in ["npm/private/test"]: if link_package == bazel_package: link_targets.append("//{}:{}/test-npm_package".format(bazel_package, name)) diff --git a/npm/private/test/snapshots/wksp/npm_defs.bzl b/npm/private/test/snapshots/wksp/npm_defs.bzl index ffd03b2a9..a2c6f12b6 100644 --- a/npm/private/test/snapshots/wksp/npm_defs.bzl +++ b/npm/private/test/snapshots/wksp/npm_defs.bzl @@ -982,7 +982,7 @@ load("@@npm__at_types_underscore__registry.npmjs.org_at_types_underscore_1.11.4_ load("@@npm__at_types_ws__registry.npmjs.org_at_types_ws_8.5.5__links//:defs.bzl", store_975 = "npm_imported_package_store") load("@@npm__at_types_yauzl__registry.npmjs.org_at_types_yauzl_2.10.0__links//:defs.bzl", store_976 = "npm_imported_package_store") -_LINK_PACKAGES = ["", "examples/js_binary", "examples/linked_empty_node_modules", "examples/macro", "examples/npm_deps", "examples/npm_package/libs/lib_a", "examples/npm_package/packages/pkg_a", "examples/npm_package/packages/pkg_b", "examples/webpack_cli", "js/private/coverage/bundle", "js/private/image", "js/private/test/image", "js/private/test/js_run_devserver", "js/private/worker/src", "npm/private/test", "npm/private/test/npm_package"] +_LINK_PACKAGES = ["", "examples/js_binary", "examples/linked_empty_node_modules", "examples/macro", "examples/npm_deps", "examples/npm_package/libs/lib_a", "examples/npm_package/packages/pkg_a", "examples/npm_package/packages/pkg_b", "examples/npm_package/packages/pkg_d", "examples/webpack_cli", "js/private/coverage/bundle", "js/private/image", "js/private/test/image", "js/private/test/js_run_devserver", "js/private/worker/src", "npm/private/test", "npm/private/test/npm_package"] # buildifier: disable=function-docstring def npm_link_all_packages(name = "node_modules", imported_links = []): @@ -1994,6 +1994,8 @@ def npm_link_all_packages(name = "node_modules", imported_links = []): link_88(name = "{}/@rollup/plugin-commonjs".format(name)) link_targets.append("//{}:{}/@rollup/plugin-commonjs".format(bazel_package, name)) scope_targets["@rollup"] = scope_targets["@rollup"] + [link_targets[-1]] if "@rollup" in scope_targets else [link_targets[-1]] + link_142(name = "{}/acorn".format(name)) + link_targets.append("//{}:{}/acorn".format(bazel_package, name)) link_296(name = "{}/debug".format(name)) link_targets.append("//{}:{}/debug".format(bazel_package, name)) link_584(name = "{}/meaning-of-life".format(name)) @@ -2155,6 +2157,11 @@ def npm_link_all_packages(name = "node_modules", imported_links = []): link_targets.append("//{}:{}/acorn".format(bazel_package, name)) link_900(name = "{}/uuid".format(name)) link_targets.append("//{}:{}/uuid".format(bazel_package, name)) + elif bazel_package == "examples/npm_package/packages/pkg_d": + link_142(name = "{}/acorn".format(name)) + link_targets.append("//{}:{}/acorn".format(bazel_package, name)) + link_900(name = "{}/uuid".format(name)) + link_targets.append("//{}:{}/uuid".format(bazel_package, name)) elif bazel_package == "examples/npm_package/packages/pkg_b": link_143(name = "{}/acorn".format(name)) link_targets.append("//{}:{}/acorn".format(bazel_package, name)) @@ -2258,6 +2265,42 @@ def npm_link_all_packages(name = "node_modules", imported_links = []): tags = ["manual"], ) + if is_root: + _npm_package_store( + name = ".aspect_rules_js/{}/@mycorp+pkg-d@0.0.0".format(name), + src = "//examples/npm_package/packages/pkg_d:pkg_d", + package = "@mycorp/pkg-d", + version = "0.0.0", + deps = { + "//:.aspect_rules_js/{}/acorn@8.7.1".format(name): "acorn", + "//:.aspect_rules_js/{}/uuid@8.3.2".format(name): "uuid", + }, + visibility = ["//visibility:public"], + tags = ["manual"], + ) + + for link_package in ["examples/npm_deps"]: + if link_package == native.package_name(): + # terminal target for direct dependencies + _npm_link_package_store( + name = "{}/@mycorp/pkg-d".format(name), + src = "//:.aspect_rules_js/{}/@mycorp+pkg-d@0.0.0".format(name), + visibility = ["//visibility:public"], + tags = ["manual"], + ) + + # filegroup target that provides a single file which is + # package directory for use in $(execpath) and $(rootpath) + native.filegroup( + name = "{}/@mycorp/pkg-d/dir".format(name), + srcs = [":{}/@mycorp/pkg-d".format(name)], + output_group = "package_directory", + visibility = ["//visibility:public"], + tags = ["manual"], + ) + link_targets.append(":{}/@mycorp/pkg-d".format(name)) + scope_targets["@mycorp"] = scope_targets["@mycorp"] + [link_targets[-1]] if "@mycorp" in scope_targets else [link_targets[-1]] + if is_root: _npm_package_store( name = ".aspect_rules_js/{}/test-npm_package@0.0.0".format(name), @@ -2321,6 +2364,7 @@ def npm_link_targets(name = "node_modules", package = None): link_targets.append("//{}:{}/@aspect-test/c".format(bazel_package, name)) link_targets.append("//{}:{}/@gregmagolan/test-b".format(bazel_package, name)) link_targets.append("//{}:{}/@rollup/plugin-commonjs".format(bazel_package, name)) + link_targets.append("//{}:{}/acorn".format(bazel_package, name)) link_targets.append("//{}:{}/debug".format(bazel_package, name)) link_targets.append("//{}:{}/meaning-of-life".format(bazel_package, name)) link_targets.append("//{}:{}/mobx-react".format(bazel_package, name)) @@ -2393,6 +2437,9 @@ def npm_link_targets(name = "node_modules", package = None): elif bazel_package == "examples/npm_package/packages/pkg_a": link_targets.append("//{}:{}/acorn".format(bazel_package, name)) link_targets.append("//{}:{}/uuid".format(bazel_package, name)) + elif bazel_package == "examples/npm_package/packages/pkg_d": + link_targets.append("//{}:{}/acorn".format(bazel_package, name)) + link_targets.append("//{}:{}/uuid".format(bazel_package, name)) elif bazel_package == "examples/npm_package/packages/pkg_b": link_targets.append("//{}:{}/acorn".format(bazel_package, name)) link_targets.append("//{}:{}/uuid".format(bazel_package, name)) @@ -2421,6 +2468,10 @@ def npm_link_targets(name = "node_modules", package = None): if link_package == bazel_package: link_targets.append("//{}:{}/@mycorp/pkg-a".format(bazel_package, name)) + for link_package in ["examples/npm_deps"]: + if link_package == bazel_package: + link_targets.append("//{}:{}/@mycorp/pkg-d".format(bazel_package, name)) + for link_package in ["npm/private/test"]: if link_package == bazel_package: link_targets.append("//{}:{}/test-npm_package".format(bazel_package, name)) diff --git a/npm/private/test/snapshots/wksp/repositories.bzl b/npm/private/test/snapshots/wksp/repositories.bzl index 2174a0155..7f426f638 100644 --- a/npm/private/test/snapshots/wksp/repositories.bzl +++ b/npm/private/test/snapshots/wksp/repositories.bzl @@ -4633,7 +4633,9 @@ def npm_repositories(): root_package = "", link_workspace = "", link_packages = { + "examples/npm_deps": ["acorn"], "examples/npm_package/packages/pkg_a": ["acorn"], + "examples/npm_package/packages/pkg_d": ["acorn"], }, package = "acorn", version = "8.7.1", @@ -23012,6 +23014,7 @@ def npm_repositories(): link_packages = { "examples/npm_package/packages/pkg_a": ["uuid"], "examples/npm_package/packages/pkg_b": ["uuid"], + "examples/npm_package/packages/pkg_d": ["uuid"], }, package = "uuid", version = "8.3.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3cd8a21f0..4c1d4d3d0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -70,9 +70,15 @@ importers: '@mycorp/pkg-a': specifier: workspace:* version: link:../npm_package/packages/pkg_a + '@mycorp/pkg-d': + specifier: workspace:* + version: link:../npm_package/packages/pkg_d '@rollup/plugin-commonjs': specifier: 21.1.0 version: 21.1.0(rollup@2.70.2) + acorn: + specifier: 8.7.1 + version: 8.7.1 debug: specifier: 3.2.7 version: 3.2.7 @@ -119,6 +125,15 @@ importers: specifier: 8.3.2 version: 8.3.2 + examples/npm_package/packages/pkg_d: + dependencies: + acorn: + specifier: 8.x.x + version: 8.7.1 + uuid: + specifier: 8.3.2 + version: 8.3.2 + examples/webpack_cli: dependencies: '@vanilla-extract/css': @@ -1550,7 +1565,6 @@ packages: resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==} engines: {node: '>=0.4.0'} hasBin: true - dev: false /acorn@8.8.2: resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index d9bac128e..41d12ea67 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -5,6 +5,7 @@ packages: - 'examples/npm_package/libs/lib_a' - 'examples/npm_package/packages/pkg_a' - 'examples/npm_package/packages/pkg_b' + - 'examples/npm_package/packages/pkg_d' - 'examples/webpack_cli' - 'examples/linked_empty_node_modules' - 'js/private/coverage/bundle'