Skip to content

Commit

Permalink
feat(builtin): add silent_on_success option to npm_package_bin
Browse files Browse the repository at this point in the history
  • Loading branch information
ptarjan committed Feb 22, 2022
1 parent 2bef49d commit 07542f4
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 1 deletion.
9 changes: 8 additions & 1 deletion docs/Built-ins.md
Original file line number Diff line number Diff line change
Expand Up @@ -1859,7 +1859,7 @@ Other attributes

<pre>
npm_package_bin(<a href="#npm_package_bin-tool">tool</a>, <a href="#npm_package_bin-package">package</a>, <a href="#npm_package_bin-package_bin">package_bin</a>, <a href="#npm_package_bin-data">data</a>, <a href="#npm_package_bin-env">env</a>, <a href="#npm_package_bin-outs">outs</a>, <a href="#npm_package_bin-args">args</a>, <a href="#npm_package_bin-stderr">stderr</a>, <a href="#npm_package_bin-stdout">stdout</a>, <a href="#npm_package_bin-exit_code_out">exit_code_out</a>,
<a href="#npm_package_bin-output_dir">output_dir</a>, <a href="#npm_package_bin-link_workspace_root">link_workspace_root</a>, <a href="#npm_package_bin-chdir">chdir</a>, <a href="#npm_package_bin-kwargs">kwargs</a>)
<a href="#npm_package_bin-output_dir">output_dir</a>, <a href="#npm_package_bin-link_workspace_root">link_workspace_root</a>, <a href="#npm_package_bin-chdir">chdir</a>, <a href="#npm_package_bin-silent_on_success">silent_on_success</a>, <a href="#npm_package_bin-kwargs">kwargs</a>)
</pre>

Run an arbitrary npm package binary (e.g. a program under node_modules/.bin/*) under Bazel.
Expand Down Expand Up @@ -2027,6 +2027,13 @@ npm_package_bin(

Defaults to `None`

<h4 id="npm_package_bin-silent_on_success">silent_on_success</h4>

produce no output on stdout nor stderr when program exits with status code 0.
This makes node binaries match the expected bazel paradigm.

Defaults to `False`

<h4 id="npm_package_bin-kwargs">kwargs</h4>

additional undocumented keyword args
Expand Down
31 changes: 31 additions & 0 deletions internal/node/launcher.sh
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ for ARG in ${ALL_ARGS[@]+"${ALL_ARGS[@]}"}; do
--bazel_capture_stderr=*) STDERR_CAPTURE="${PWD}/${ARG#--bazel_capture_stderr=}" ;;
# Captures the exit code of the node process to the file specified
--bazel_capture_exit_code=*) EXIT_CODE_CAPTURE="${PWD}/${ARG#--bazel_capture_exit_code=}" ;;
# Outputs nothing on success
--bazel_silent_on_success=*) SILENT_ON_SUCCESS=true ;;
# Disable the node_loader.js monkey patches for require()
# Note that this means you need an explicit runfiles helper library
# This flag is now a no-op since the default is also false
Expand Down Expand Up @@ -306,6 +308,17 @@ else
fi
fi

if [ "${SILENT_ON_SUCCESS:-}" = true ]; then
if [[ -z "${STDOUT_CAPTURE}" ]]; then
STDOUT_CAPTURE_IS_NOT_AN_OUTPUT=true
STDOUT_CAPTURE=$(mktemp)
fi
if [[ -z "${STDERR_CAPTURE}" ]]; then
STDERR_CAPTURE_IS_NOT_AN_OUTPUT=true
STDERR_CAPTURE=$(mktemp)
fi
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 All @@ -330,6 +343,23 @@ _int() {
kill -INT "${child}" 2>/dev/null
}

_exit() {
EXIT_CODE=$?

if [[ "$EXIT_CODE" != 0 ]]; then
if [ ${STDOUT_CAPTURE_IS_NOT_AN_OUTPUT} = true ]; then
cat "$STDOUT_CAPTURE"
rm "$STDOUT_CAPTURE"
fi
if [ ${STDERR_CAPTURE_IS_NOT_AN_OUTPUT} = true ]; then
cat "$STDERR_CAPTURE"
rm "$STDERR_CAPTURE"
fi
fi

exit $EXIT_CODE
}

# Execute the main program
if [[ -n "$NODE_WORKING_DIR" ]]; then
cd "$NODE_WORKING_DIR"
Expand All @@ -348,6 +378,7 @@ fi
readonly child=$!
trap _term SIGTERM
trap _int SIGINT
trap _exit EXIT
wait "${child}"
# Remove trap after first signal has been receieved and wait for child to exit
# (first wait returns immediatel if SIGTERM is received while waiting). Second
Expand Down
6 changes: 6 additions & 0 deletions internal/node/npm_package_bin.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ _ATTRS = {
"link_workspace_root": attr.bool(),
"output_dir": attr.bool(),
"outs": attr.output_list(),
"silent_on_success": attr.bool(),
"stderr": attr.output(),
"stdout": attr.output(),
"tool": attr.label(
Expand Down Expand Up @@ -87,6 +88,7 @@ def _impl(ctx):
stdout = ctx.outputs.stdout,
stderr = ctx.outputs.stderr,
exit_code_out = ctx.outputs.exit_code_out,
silent_on_success = ctx.attr.silent_on_success,
link_workspace_root = ctx.attr.link_workspace_root,
)
files = outputs + tool_outputs
Expand Down Expand Up @@ -114,6 +116,7 @@ def npm_package_bin(
output_dir = False,
link_workspace_root = False,
chdir = None,
silent_on_success = False,
**kwargs):
"""Run an arbitrary npm package binary (e.g. a program under node_modules/.bin/*) under Bazel.
Expand Down Expand Up @@ -142,6 +145,8 @@ def npm_package_bin(
exit_code_out: set to capture the exit code of the binary to a file, which can later be used as an input to another target
subject to the same semantics as `outs`. Note that setting this will force the binary to exit 0.
If the binary creates outputs and these are declared, they must still be created
silent_on_success: produce no output on stdout nor stderr when program exits with status code 0.
This makes node binaries match the expected bazel paradigm.
args: Command-line arguments to the tool.
Expand Down Expand Up @@ -234,5 +239,6 @@ def npm_package_bin(
output_dir = output_dir,
tool = tool,
link_workspace_root = link_workspace_root,
silent_on_success = silent_on_success,
**kwargs
)
15 changes: 15 additions & 0 deletions internal/node/test/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,21 @@ generated_file_test(
generated = ":minified.stdout.js",
)

# target that shouldn't print anything on stdout nor stderr when built even through the binary does
npm_package_bin(
name = "loud_binary",
args = [
"$(execpath terser_input_with_diagnostics.js)",
"--compress",
"--verbose",
"--warn",
],
data = ["terser_input_with_diagnostics.js"],
package = "terser",
output_dir = True,
silent_on_success = True,
)

# capture stderr to diagnostics.out, then analyze it in terser_diagnostics_stats printing some stats
# stdout is captured into greeter.min.js (again, without the --output $@ flags)
# the exit code is also capture to a file with exit_code_out, allowing downstream actions to read it
Expand Down
4 changes: 4 additions & 0 deletions internal/providers/node_runtime_deps_info.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ def run_node(ctx, inputs, arguments, executable, chdir = None, **kwargs):
add_arg(arguments, "--bazel_capture_exit_code=%s" % exit_code_file.path)
outputs = outputs + [exit_code_file]

silent_on_success = kwargs.pop("silent_on_success", False)
if silent_on_success:
add_arg(arguments, "--bazel_silent_on_success=1")

if chdir:
add_arg(arguments, "--bazel_node_working_dir=" + chdir)

Expand Down

0 comments on commit 07542f4

Please sign in to comment.