Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions shell/private/sh_executable.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ def _sh_executable_impl(ctx):
direct_files = [src]
transitive_files = []
runfiles = ctx.runfiles(collect_default = True)
for target in ctx.attr.tools:
runfiles = runfiles.merge(target[DefaultInfo].default_runfiles)

entrypoint = ctx.actions.declare_file(ctx.label.name)
if ctx.attr.use_bash_launcher:
Expand Down Expand Up @@ -89,14 +91,16 @@ exec "$(rlocation "{src}")" "$@"
instrumented_files_info = coverage_common.instrumented_files_info(
ctx,
source_attributes = ["srcs"],
dependency_attributes = ["deps", "_runfiles_dep", "data"],
dependency_attributes = ["deps", "_runfiles_dep", "data", "tools"],
)

locations = ctx.attr.data + ctx.attr.tools

run_environment_info = RunEnvironmentInfo(
environment = {
key: ctx.expand_make_variables(
"env",
ctx.expand_location(value, ctx.attr.data, short_paths = True),
ctx.expand_location(value, locations, short_paths = True),
{},
)
for key, value in ctx.attr.env.items()
Expand Down Expand Up @@ -209,6 +213,15 @@ most build rules</a>.
),
"env": attr.string_dict(),
"env_inherit": attr.string_list(),
"tools": attr.label_list(
cfg = config.exec(),
allow_files = True,
doc = """
The list of tool dependencies, similar to genrule's equivalent. You can use
this to ensure that any helper binaries your scripts need are built in the exec
configuration.
""",
),
"use_bash_launcher": attr.bool(
doc = "Use a bash launcher initializing the runfiles library",
),
Expand Down
13 changes: 12 additions & 1 deletion shell/private/sh_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,16 @@ def _sh_library_impl(ctx):
transitive_files.append(target[DefaultInfo].files)
for target in ctx.attr.data:
transitive_files.append(target[DefaultInfo].files)
for target in ctx.attr.tools:
transitive_files.append(target[DefaultInfo].files)
files = depset(transitive = transitive_files)

runfiles = ctx.runfiles(transitive_files = files, collect_default = True)

instrumented_files_info = coverage_common.instrumented_files_info(
ctx,
source_attributes = ["srcs"],
dependency_attributes = ["deps", "data"],
dependency_attributes = ["deps", "data", "tools"],
)

return [
Expand Down Expand Up @@ -112,6 +114,15 @@ most build rules</a>.
interpreted program source code depended on by the code in <code>srcs</code>. The files
provided by these rules will be present among the <code>runfiles</code> of this target.
</p>
""",
),
"tools": attr.label_list(
cfg = config.exec(),
allow_files = True,
doc = """
The list of tool dependencies, similar to genrule's equivalent. You can use
this to ensure that any helper binaries your scripts need are built in the exec
configuration.
""",
),
},
Expand Down
21 changes: 21 additions & 0 deletions tests/bcr/BUILD
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
load("@rules_shell//shell:sh_binary.bzl", "sh_binary")
load("@rules_shell//shell:sh_library.bzl", "sh_library")
load("@rules_shell//shell:sh_test.bzl", "sh_test")
load(":is_exec_configuration.bzl", "is_exec_configuration")

is_exec_configuration(
name = "_is_exec_configuration",
visibility = ["//visibility:private"],
)

config_setting(
name = "config_exec",
flag_values = {":_is_exec_configuration": "yes"},
visibility = ["//visibility:private"],
)

alias(
name = "greetings",
actual = select({
":config_exec": "greeting_tool.txt",
"//conditions:default": "greeting.txt",
}),
)

sh_library(
name = "lib",
srcs = ["lib.sh"],
data = ["greeting.txt"],
tools = ["greetings"],
deps = ["@rules_shell//shell/runfiles"],
)

Expand Down
2 changes: 2 additions & 0 deletions tests/bcr/bin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@ source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
source "$(rlocation "rules_shell_tests/lib.sh")"

get_greeting

get_tool_greeting
1 change: 1 addition & 0 deletions tests/bcr/greeting_tool.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
and the tools
12 changes: 12 additions & 0 deletions tests/bcr/is_exec_configuration.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
def _is_exec_configuration(ctx):
# https://github.com/bazelbuild/bazel/issues/14444
return config_common.FeatureFlagInfo(
# feature flags must be strings, so we're avoiding True and False in
# favor of "yes" and "no" to avoid confusion between "True" and True
value = "yes" if "-exec" in ctx.bin_dir.path else "no",
)

is_exec_configuration = rule(
doc = "identify if the current target is in exec configuration",
implementation = _is_exec_configuration,
)
5 changes: 5 additions & 0 deletions tests/bcr/lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,8 @@ function get_greeting() {
greeting_path=$(rlocation "rules_shell_tests/greeting.txt")
cat "${greeting_path}"
}

function get_tool_greeting() {
greeting_path=$(rlocation "rules_shell_tests/greeting_tool.txt")
cat "${greeting_path}"
}
9 changes: 7 additions & 2 deletions tests/bcr/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,13 @@ fi

runfiles_export_envvars

read -r -d '' expected <<EOF || true
hello from rules_shell
and the tools
EOF

greeting=$("${bin_path}")
if [[ "${greeting}" != "hello from rules_shell" ]]; then
echo "Expected 'hello from rules_shell', got '${greeting}'"
if [[ "${greeting}" != "${expected}" ]]; then
printf "Expected '%s', got '%s'\n" "${expected}" "${greeting}"
exit 1
fi