Skip to content

Commit

Permalink
feat(builtin): expose the new linker to node programs
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
alexeagle committed Sep 10, 2019
1 parent 827ec95 commit 65d8a36
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 0 deletions.
7 changes: 7 additions & 0 deletions e2e/symlinked_node_modules_npm/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
7 changes: 7 additions & 0 deletions e2e/symlinked_node_modules_yarn/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
7 changes: 7 additions & 0 deletions internal/linker/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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"])

Expand Down
7 changes: 7 additions & 0 deletions internal/node/node.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions internal/node/node_launcher.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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.
Expand Down
Empty file.
1 change: 1 addition & 0 deletions tools/mock_npm_bazel_typescript/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
workspace(name = "npm_bazel_typescript")
6 changes: 6 additions & 0 deletions tools/mock_npm_bazel_typescript/index.from_src.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"Minimal implementation to make loading phase succeed"

def noop(**kwargs):
pass

checked_in_ts_library = noop

0 comments on commit 65d8a36

Please sign in to comment.