From 57b5cc111008507ed6e1cdac9bd32fc101060705 Mon Sep 17 00:00:00 2001 From: Alex Eagle Date: Fri, 6 Dec 2019 11:14:50 -0800 Subject: [PATCH] feat(builtin): wire linker/node-patches to npm-generated bin and test - nodejs_binary and nodejs_test will always produce a modules manifest needed by the linker - if the program isn't run with a user-specific linker manifest, we use the static one as a default - always pass the flag to opt-out of custom module resolver for generated rules Fixes #1382 --- internal/node/node.bzl | 17 +++++++++-------- internal/node/node_launcher.sh | 6 ++++++ internal/npm_install/generate_build_file.js | 6 ++++-- internal/npm_install/generate_build_file.ts | 6 ++++-- .../golden/@gregmagolan/test-a/index.bzl.golden | 2 ++ .../test/golden/jasmine/index.bzl.golden | 2 ++ packages/node-patches/BUILD.bazel | 6 ++++-- 7 files changed, 31 insertions(+), 14 deletions(-) diff --git a/internal/node/node.bzl b/internal/node/node.bzl index 2ffe8355bb..17fd76d947 100644 --- a/internal/node/node.bzl +++ b/internal/node/node.bzl @@ -25,6 +25,7 @@ load("//internal/common:expand_into_runfiles.bzl", "expand_location_into_runfile load("//internal/common:module_mappings.bzl", "module_mappings_runtime_aspect") load("//internal/common:path_utils.bzl", "strip_external") load("//internal/common:windows_utils.bzl", "create_windows_native_launcher_script", "is_windows") +load("//internal/linker:link_node_modules.bzl", "write_node_modules_manifest") load("//internal/node:node_repositories.bzl", "BUILT_IN_NODE_PLATFORMS") def _trim_package_node_modules(package_name): @@ -132,18 +133,15 @@ def _to_manifest_path(ctx, file): def _to_execroot_path(ctx, file): parts = file.path.split("/") - #print("_to_execroot", file.path, file.is_source) if parts[0] == "external": if parts[2] == "node_modules": # external/npm/node_modules -> node_modules/foo # the linker will make sure we can resolve node_modules from npm return "/".join(parts[2:]) - if file.is_source: - return file.path - - return (" _to_execroot_path not yet implemented for " + file.path) + return file.path def _nodejs_binary_impl(ctx): + node_modules_manifest = write_node_modules_manifest(ctx) node_modules = depset(ctx.files.node_modules) # Also include files from npm fine grained deps as inputs. @@ -155,14 +153,15 @@ def _nodejs_binary_impl(ctx): # Using a depset will allow us to avoid flattening files and sources # inside this loop. This should reduce the performances hits, # since we don't need to call .to_list() - sources = depset() + sources_sets = [] for d in ctx.attr.data: # TODO: switch to JSModuleInfo when it is available if JSNamedModuleInfo in d: - sources = depset(transitive = [sources, d[JSNamedModuleInfo].sources]) + sources_sets.append(d[JSNamedModuleInfo].sources) if hasattr(d, "files"): - sources = depset(transitive = [sources, d.files]) + sources_sets.append(d.files) + sources = depset(transitive = sources_sets) _write_loader_script(ctx) @@ -198,6 +197,7 @@ def _nodejs_binary_impl(ctx): node_tool_files.append(ctx.file._link_modules_script) node_tool_files.append(ctx.file._bazel_require_script) + node_tool_files.append(node_modules_manifest) if not ctx.outputs.templated_args_file: templated_args = ctx.attr.templated_args @@ -236,6 +236,7 @@ def _nodejs_binary_impl(ctx): "TEMPLATED_expected_exit_code": str(expected_exit_code), "TEMPLATED_link_modules_script": _to_manifest_path(ctx, ctx.file._link_modules_script), "TEMPLATED_loader_path": script_path, + "TEMPLATED_modules_manifest": _to_manifest_path(ctx, node_modules_manifest), "TEMPLATED_repository_args": _to_manifest_path(ctx, ctx.file._repository_args), "TEMPLATED_script_path": _to_execroot_path(ctx, ctx.file.entry_point), "TEMPLATED_vendored_node": "" if is_builtin else strip_external(ctx.file._node.path), diff --git a/internal/node/node_launcher.sh b/internal/node/node_launcher.sh index 766ff47fad..6b7705073c 100644 --- a/internal/node/node_launcher.sh +++ b/internal/node/node_launcher.sh @@ -186,6 +186,12 @@ for ARG in "${ALL_ARGS[@]}"; do --nobazel_patch_module_resolver) MAIN="TEMPLATED_script_path" NODE_OPTIONS+=( "--require" "$bazel_require_script" ) + + # In this case we should always run the linker + # For programs which are called with bazel run or bazel test, there will be no additional runtime + # dependencies to link, so we use the default modules_manifest which has only the static dependencies + # of the binary itself + MODULES_MANIFEST=${MODULES_MANIFEST:-$(rlocation "TEMPLATED_modules_manifest")} ;; --node_options=*) NODE_OPTIONS+=( "${ARG#--node_options=}" ) ;; *) ARGS+=( "$ARG" ) diff --git a/internal/npm_install/generate_build_file.js b/internal/npm_install/generate_build_file.js index 97154ab32e..ff8b655571 100644 --- a/internal/npm_install/generate_build_file.js +++ b/internal/npm_install/generate_build_file.js @@ -982,7 +982,8 @@ def ${name.replace(/-/g, '_')}(**kwargs): nodejs_binary( entry_point = "@${WORKSPACE}//:node_modules/${pkg._dir}/${path}", install_source_map_support = False, - data = [${data.map(p => `"${p}"`).join(', ')}] + kwargs.pop("data", []),${additionalAttributes(pkg, name)} + data = [${data.map(p => `"${p}"`).join(', ')}] + kwargs.pop("data", []), + templated_args = ["--nobazel_patch_module_resolver"] + kwargs.pop("templated_args", []),${additionalAttributes(pkg, name)} **kwargs ) @@ -991,7 +992,8 @@ def ${name.replace(/-/g, '_')}_test(**kwargs): nodejs_test( entry_point = "@${WORKSPACE}//:node_modules/${pkg._dir}/${path}", install_source_map_support = False, - data = [${data.map(p => `"${p}"`).join(', ')}] + kwargs.pop("data", []),${additionalAttributes(pkg, name)} + data = [${data.map(p => `"${p}"`).join(', ')}] + kwargs.pop("data", []), + templated_args = ["--nobazel_patch_module_resolver"] + kwargs.pop("templated_args", []),${additionalAttributes(pkg, name)} **kwargs ) `; diff --git a/internal/npm_install/generate_build_file.ts b/internal/npm_install/generate_build_file.ts index c2a8dec9bf..2de1035aeb 100644 --- a/internal/npm_install/generate_build_file.ts +++ b/internal/npm_install/generate_build_file.ts @@ -1084,7 +1084,8 @@ def ${name.replace(/-/g, '_')}(**kwargs): nodejs_binary( entry_point = "@${WORKSPACE}//:node_modules/${pkg._dir}/${path}", install_source_map_support = False, - data = [${data.map(p => `"${p}"`).join(', ')}] + kwargs.pop("data", []),${ + data = [${data.map(p => `"${p}"`).join(', ')}] + kwargs.pop("data", []), + templated_args = ["--nobazel_patch_module_resolver"] + kwargs.pop("templated_args", []),${ additionalAttributes(pkg, name)} **kwargs ) @@ -1094,7 +1095,8 @@ def ${name.replace(/-/g, '_')}_test(**kwargs): nodejs_test( entry_point = "@${WORKSPACE}//:node_modules/${pkg._dir}/${path}", install_source_map_support = False, - data = [${data.map(p => `"${p}"`).join(', ')}] + kwargs.pop("data", []),${ + data = [${data.map(p => `"${p}"`).join(', ')}] + kwargs.pop("data", []), + templated_args = ["--nobazel_patch_module_resolver"] + kwargs.pop("templated_args", []),${ additionalAttributes(pkg, name)} **kwargs ) diff --git a/internal/npm_install/test/golden/@gregmagolan/test-a/index.bzl.golden b/internal/npm_install/test/golden/@gregmagolan/test-a/index.bzl.golden index 34d685e941..8e3a864ddc 100644 --- a/internal/npm_install/test/golden/@gregmagolan/test-a/index.bzl.golden +++ b/internal/npm_install/test/golden/@gregmagolan/test-a/index.bzl.golden @@ -8,6 +8,7 @@ def test(**kwargs): entry_point = "@fine_grained_goldens//:node_modules/@gregmagolan/test-a/@bin/test.js", install_source_map_support = False, data = ["@fine_grained_goldens//@gregmagolan/test-a:test-a"] + kwargs.pop("data", []), + templated_args = ["--nobazel_patch_module_resolver"] + kwargs.pop("templated_args", []), **kwargs ) def test_test(**kwargs): @@ -15,5 +16,6 @@ def test_test(**kwargs): entry_point = "@fine_grained_goldens//:node_modules/@gregmagolan/test-a/@bin/test.js", install_source_map_support = False, data = ["@fine_grained_goldens//@gregmagolan/test-a:test-a"] + kwargs.pop("data", []), + templated_args = ["--nobazel_patch_module_resolver"] + kwargs.pop("templated_args", []), **kwargs ) diff --git a/internal/npm_install/test/golden/jasmine/index.bzl.golden b/internal/npm_install/test/golden/jasmine/index.bzl.golden index fb339b6688..d71afcd81f 100644 --- a/internal/npm_install/test/golden/jasmine/index.bzl.golden +++ b/internal/npm_install/test/golden/jasmine/index.bzl.golden @@ -8,6 +8,7 @@ def jasmine(**kwargs): entry_point = "@fine_grained_goldens//:node_modules/jasmine/bin/jasmine.js", install_source_map_support = False, data = ["@fine_grained_goldens//jasmine:jasmine"] + kwargs.pop("data", []), + templated_args = ["--nobazel_patch_module_resolver"] + kwargs.pop("templated_args", []), **kwargs ) def jasmine_test(**kwargs): @@ -15,5 +16,6 @@ def jasmine_test(**kwargs): entry_point = "@fine_grained_goldens//:node_modules/jasmine/bin/jasmine.js", install_source_map_support = False, data = ["@fine_grained_goldens//jasmine:jasmine"] + kwargs.pop("data", []), + templated_args = ["--nobazel_patch_module_resolver"] + kwargs.pop("templated_args", []), **kwargs ) diff --git a/packages/node-patches/BUILD.bazel b/packages/node-patches/BUILD.bazel index a927dc8dd9..d2c7becad0 100644 --- a/packages/node-patches/BUILD.bazel +++ b/packages/node-patches/BUILD.bazel @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_test") load("@npm_bazel_rollup//:index.bzl", "rollup_bundle") -load("@npm_node_patches//mocha:index.bzl", "mocha_test") load("@npm_node_patches//typescript:index.bzl", "tsc") package(default_visibility = ["//:__subpackages__"]) @@ -52,12 +52,14 @@ tsc( ], ) -mocha_test( +# Like the generated mocha_test but we don't want to run the patches before testing the patches +nodejs_test( name = "unit_test", args = ["$(location %s)" % s for s in test_js], data = js + test_js + [ "@npm_node_patches//:node_modules", ], + entry_point = "@npm_node_patches//:node_modules/mocha/bin/mocha", tags = [ "fix-windows", ],