From 65d8a36c3999f010b3b08599cd301cfaa3dc1c65 Mon Sep 17 00:00:00 2001 From: Alex Eagle Date: Thu, 5 Sep 2019 15:10:55 -0700 Subject: [PATCH] feat(builtin): expose the new linker to node programs If the magic --bazel_node_modules_manifest flag is passed to a nodejs_binary, we peel it off and run the linker first This lets programs avoid having custom resolution logic. --- e2e/symlinked_node_modules_npm/WORKSPACE | 7 +++++++ e2e/symlinked_node_modules_yarn/WORKSPACE | 7 +++++++ internal/linker/BUILD.bazel | 7 +++++++ internal/node/node.bzl | 7 +++++++ internal/node/node_launcher.sh | 7 +++++++ tools/mock_npm_bazel_typescript/BUILD.bazel | 0 tools/mock_npm_bazel_typescript/WORKSPACE | 1 + tools/mock_npm_bazel_typescript/index.from_src.bzl | 6 ++++++ 8 files changed, 42 insertions(+) create mode 100644 tools/mock_npm_bazel_typescript/BUILD.bazel create mode 100644 tools/mock_npm_bazel_typescript/WORKSPACE create mode 100644 tools/mock_npm_bazel_typescript/index.from_src.bzl diff --git a/e2e/symlinked_node_modules_npm/WORKSPACE b/e2e/symlinked_node_modules_npm/WORKSPACE index 472a82576e..07d23108f9 100644 --- a/e2e/symlinked_node_modules_npm/WORKSPACE +++ b/e2e/symlinked_node_modules_npm/WORKSPACE @@ -11,6 +11,13 @@ local_repository( path = "../..", ) +# We don't really need to run TypeScript rules, but we'll encounter some during +# the loading phase because some built-in code uses TypeScript +local_repository( + name = "npm_bazel_typescript", + path = "../../tools/mock_npm_bazel_typescript", +) + # rules_nodejs_dev_dependencies() required since we're using local_repository for # build_bazel_rules_nodejs above. load("@build_bazel_rules_nodejs//:package.bzl", "rules_nodejs_dev_dependencies") diff --git a/e2e/symlinked_node_modules_yarn/WORKSPACE b/e2e/symlinked_node_modules_yarn/WORKSPACE index 72d286e30d..0188fa04ed 100644 --- a/e2e/symlinked_node_modules_yarn/WORKSPACE +++ b/e2e/symlinked_node_modules_yarn/WORKSPACE @@ -11,6 +11,13 @@ local_repository( path = "../..", ) +# We don't really need to run TypeScript rules, but we'll encounter some during +# the loading phase because some built-in code uses TypeScript +local_repository( + name = "npm_bazel_typescript", + path = "../../tools/mock_npm_bazel_typescript", +) + # rules_nodejs_dev_dependencies() required since we're using local_repository for # build_bazel_rules_nodejs above. load("@build_bazel_rules_nodejs//:package.bzl", "rules_nodejs_dev_dependencies") diff --git a/internal/linker/BUILD.bazel b/internal/linker/BUILD.bazel index 77c4aef088..f79e7fd1ed 100644 --- a/internal/linker/BUILD.bazel +++ b/internal/linker/BUILD.bazel @@ -1,4 +1,5 @@ # BEGIN-INTERNAL +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") load("@npm_bazel_typescript//:index.from_src.bzl", "checked_in_ts_library") # We can't bootstrap the ts_library rule using the linker itself, @@ -12,6 +13,12 @@ checked_in_ts_library( deps = ["@npm//@types/node"], ) +bzl_library( + name = "bzl", + srcs = glob(["*.bzl"]), + visibility = ["//visibility:public"], +) + # END-INTERNAL exports_files(["index.js"]) diff --git a/internal/node/node.bzl b/internal/node/node.bzl index 15af9aac56..bc4f4fc9a0 100644 --- a/internal/node/node.bzl +++ b/internal/node/node.bzl @@ -169,6 +169,8 @@ def _nodejs_binary_impl(ctx): # attempts to do bazel run fail("The node toolchain was not properly configured so %s cannot be executed. Make sure that target_tool_path or target_tool is set." % ctx.attr.name) + node_tool_files.append(ctx.file._link_modules_script) + if not ctx.outputs.templated_args_file: templated_args = ctx.attr.templated_args else: @@ -201,6 +203,7 @@ def _nodejs_binary_impl(ctx): ]), "TEMPLATED_env_vars": env_vars, "TEMPLATED_expected_exit_code": str(expected_exit_code), + "TEMPLATED_link_modules_script": _to_manifest_path(ctx, ctx.file._link_modules_script), "TEMPLATED_node": node_tool_info.target_tool_path, "TEMPLATED_repository_args": _to_manifest_path(ctx, ctx.file._repository_args), "TEMPLATED_script_path": script_path, @@ -425,6 +428,10 @@ The set of default environment variables is: default = Label("//internal/node:node_launcher.sh"), allow_single_file = True, ), + "_link_modules_script": attr.label( + default = Label("//internal/linker:index.js"), + allow_single_file = True, + ), "_loader_template": attr.label( default = Label("//internal/node:node_loader.js"), allow_single_file = True, diff --git a/internal/node/node_launcher.sh b/internal/node/node_launcher.sh index 3a2bb376f2..e70f580d67 100644 --- a/internal/node/node_launcher.sh +++ b/internal/node/node_launcher.sh @@ -117,6 +117,7 @@ TEMPLATED_env_vars readonly node=$(rlocation "TEMPLATED_node") readonly repository_args=$(rlocation "TEMPLATED_repository_args") readonly script=$(rlocation "TEMPLATED_script_path") +readonly link_modules_script=$(rlocation "TEMPLATED_link_modules_script") source $repository_args @@ -125,11 +126,17 @@ NODE_OPTIONS=() ALL_ARGS=(TEMPLATED_args $NODE_REPOSITORY_ARGS "$@") for ARG in "${ALL_ARGS[@]}"; do case "$ARG" in + --bazel_node_modules_manifest=*) MODULES_MANIFEST="${ARG#--bazel_node_modules_manifest=}" ;; --node_options=*) NODE_OPTIONS+=( "${ARG#--node_options=}" ) ;; *) ARGS+=( "$ARG" ) esac done +# Link the first-party modules into node_modules directory before running the actual program +if [[ -n "$MODULES_MANIFEST" ]]; then + "${node}" "${link_modules_script}" "${MODULES_MANIFEST}" +fi + # The EXPECTED_EXIT_CODE lets us write bazel tests which assert that # a binary fails to run. Otherwise any failure would make such a test # fail before we could assert that we expected that failure. diff --git a/tools/mock_npm_bazel_typescript/BUILD.bazel b/tools/mock_npm_bazel_typescript/BUILD.bazel new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/mock_npm_bazel_typescript/WORKSPACE b/tools/mock_npm_bazel_typescript/WORKSPACE new file mode 100644 index 0000000000..c299b714ae --- /dev/null +++ b/tools/mock_npm_bazel_typescript/WORKSPACE @@ -0,0 +1 @@ +workspace(name = "npm_bazel_typescript") diff --git a/tools/mock_npm_bazel_typescript/index.from_src.bzl b/tools/mock_npm_bazel_typescript/index.from_src.bzl new file mode 100644 index 0000000000..87230871fb --- /dev/null +++ b/tools/mock_npm_bazel_typescript/index.from_src.bzl @@ -0,0 +1,6 @@ +"Minimal implementation to make loading phase succeed" + +def noop(**kwargs): + pass + +checked_in_ts_library = noop