From b57e88269af11df9bd33f7f88c81d71e32ee8209 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 17 Aug 2022 11:53:13 +0200 Subject: [PATCH 01/12] Factor out list of POSIX toolchain commands --- sh/BUILD.bazel | 3 +- sh/posix.bzl | 167 +---------------------------------------- sh/private/BUILD.bazel | 20 ++++- sh/private/posix.bzl | 165 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 187 insertions(+), 168 deletions(-) create mode 100644 sh/private/posix.bzl diff --git a/sh/BUILD.bazel b/sh/BUILD.bazel index 9daa772..93ec892 100644 --- a/sh/BUILD.bazel +++ b/sh/BUILD.bazel @@ -31,7 +31,7 @@ bzl_library( ":bazel_tools", "@bazel_skylib//lib:paths", "@bazel_skylib//lib:dicts", - "//sh/private:defs.bzl" + "//sh/private:defs", ], ) @@ -43,6 +43,7 @@ bzl_library( visibility = ["//visibility:public"], deps = [ ":bazel_tools", + "//sh/private:posix", "@bazel_skylib//lib:paths", ], ) diff --git a/sh/posix.bzl b/sh/posix.bzl index 6392d59..a102892 100644 --- a/sh/posix.bzl +++ b/sh/posix.bzl @@ -9,172 +9,7 @@ available in `posix.commands`. load("@bazel_skylib//lib:paths.bzl", "paths") load("@bazel_tools//tools/cpp:lib_cc_configure.bzl", "get_cpu_value") - -# List of Unix commands as specified by IEEE Std 1003.1-2008. -# Extracted from https://en.wikipedia.org/wiki/List_of_Unix_commands. -_commands = [ - "admin", - "alias", - "ar", - "asa", - "at", - "awk", - "basename", - "batch", - "bc", - "bg", - "cc", - "c99", - "cal", - "cat", - "cd", - "cflow", - "chgrp", - "chmod", - "chown", - "cksum", - "cmp", - "comm", - "command", - "compress", - "cp", - "crontab", - "csplit", - "ctags", - "cut", - "cxref", - "date", - "dd", - "delta", - "df", - "diff", - "dirname", - "du", - "echo", - "ed", - "env", - "ex", - "expand", - "expr", - "false", - "fc", - "fg", - "file", - "find", - "fold", - "fort77", - "fuser", - "gencat", - "get", - "getconf", - "getopts", - "grep", - "hash", - "head", - "iconv", - "id", - "ipcrm", - "ipcs", - "jobs", - "join", - "kill", - "lex", - "link", - "ln", - "locale", - "localedef", - "logger", - "logname", - "lp", - "ls", - "m4", - "mailx", - "make", - "man", - "mesg", - "mkdir", - "mkfifo", - "more", - "mv", - "newgrp", - "nice", - "nl", - "nm", - "nohup", - "od", - "paste", - "patch", - "pathchk", - "pax", - "pr", - "printf", - "prs", - "ps", - "pwd", - "qalter", - "qdel", - "qhold", - "qmove", - "qmsg", - "qrerun", - "qrls", - "qselect", - "qsig", - "qstat", - "qsub", - "read", - "renice", - "rm", - "rmdel", - "rmdir", - "sact", - "sccs", - "sed", - "sh", - "sleep", - "sort", - "split", - "strings", - "strip", - "stty", - "tabs", - "tail", - "talk", - "tee", - "test", - "time", - "touch", - "tput", - "tr", - "true", - "tsort", - "tty", - "type", - "ulimit", - "umask", - "unalias", - "uname", - "uncompress", - "unexpand", - "unget", - "uniq", - "unlink", - "uucp", - "uudecode", - "uuencode", - "uustat", - "uux", - "val", - "vi", - "wait", - "wc", - "what", - "who", - "write", - "xargs", - "yacc", - "zcat", -] +load("//sh/private:posix.bzl", _commands = "commands") TOOLCHAIN_TYPE = "@rules_sh//sh/posix:toolchain_type" MAKE_VARIABLES = "@rules_sh//sh/posix:make_variables" diff --git a/sh/private/BUILD.bazel b/sh/private/BUILD.bazel index e70e2b9..d138dd5 100644 --- a/sh/private/BUILD.bazel +++ b/sh/private/BUILD.bazel @@ -1,3 +1,4 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") load(":defs.bzl", "bool_constant") bool_constant( @@ -9,4 +10,21 @@ bool_constant( visibility = ["//visibility:public"], ) -exports_files(["defs.bzl"]) +bzl_library( + name = "defs", + srcs = [ + "defs.bzl", + ], + deps = [ + "@bazel_skylib//lib:dicts", + ], + visibility = ["//sh:__subpackages__"], +) + +bzl_library( + name = "posix", + srcs = [ + "posix.bzl", + ], + visibility = ["//sh:__subpackages__"], +) diff --git a/sh/private/posix.bzl b/sh/private/posix.bzl new file mode 100644 index 0000000..421bcfb --- /dev/null +++ b/sh/private/posix.bzl @@ -0,0 +1,165 @@ +# List of Unix commands as specified by IEEE Std 1003.1-2008. +# Extracted from https://en.wikipedia.org/wiki/List_of_Unix_commands. +commands = [ + "admin", + "alias", + "ar", + "asa", + "at", + "awk", + "basename", + "batch", + "bc", + "bg", + "cc", + "c99", + "cal", + "cat", + "cd", + "cflow", + "chgrp", + "chmod", + "chown", + "cksum", + "cmp", + "comm", + "command", + "compress", + "cp", + "crontab", + "csplit", + "ctags", + "cut", + "cxref", + "date", + "dd", + "delta", + "df", + "diff", + "dirname", + "du", + "echo", + "ed", + "env", + "ex", + "expand", + "expr", + "false", + "fc", + "fg", + "file", + "find", + "fold", + "fort77", + "fuser", + "gencat", + "get", + "getconf", + "getopts", + "grep", + "hash", + "head", + "iconv", + "id", + "ipcrm", + "ipcs", + "jobs", + "join", + "kill", + "lex", + "link", + "ln", + "locale", + "localedef", + "logger", + "logname", + "lp", + "ls", + "m4", + "mailx", + "make", + "man", + "mesg", + "mkdir", + "mkfifo", + "more", + "mv", + "newgrp", + "nice", + "nl", + "nm", + "nohup", + "od", + "paste", + "patch", + "pathchk", + "pax", + "pr", + "printf", + "prs", + "ps", + "pwd", + "qalter", + "qdel", + "qhold", + "qmove", + "qmsg", + "qrerun", + "qrls", + "qselect", + "qsig", + "qstat", + "qsub", + "read", + "renice", + "rm", + "rmdel", + "rmdir", + "sact", + "sccs", + "sed", + "sh", + "sleep", + "sort", + "split", + "strings", + "strip", + "stty", + "tabs", + "tail", + "talk", + "tee", + "test", + "time", + "touch", + "tput", + "tr", + "true", + "tsort", + "tty", + "type", + "ulimit", + "umask", + "unalias", + "uname", + "uncompress", + "unexpand", + "unget", + "uniq", + "unlink", + "uucp", + "uudecode", + "uuencode", + "uustat", + "uux", + "val", + "vi", + "wait", + "wc", + "what", + "who", + "write", + "xargs", + "yacc", + "zcat", +] From e698b13d446aa7ed148a5307b440a5fbd7913204 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Fri, 19 Aug 2022 16:00:45 +0200 Subject: [PATCH 02/12] Factor out mk_template_variable_info --- sh/private/defs.bzl | 21 +++++++++++++++++++++ sh/sh.bzl | 27 ++++++--------------------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/sh/private/defs.bzl b/sh/private/defs.bzl index f917db3..5fbb1f4 100644 --- a/sh/private/defs.bzl +++ b/sh/private/defs.bzl @@ -1,3 +1,5 @@ +load("@bazel_skylib//lib:dicts.bzl", "dicts") + ConstantInfo = provider(fields = ["value"]) def _constant_impl(ctx): @@ -9,3 +11,22 @@ bool_constant = rule( "value": attr.bool(), }, ) + +def to_var_name(label_name): + """Turn a label name into a template variable info. + + Uses all upper case variable names with `_` as separator. + """ + return label_name.upper().replace("-", "_") + +def mk_template_variable_info(name, sh_binaries_info): + var_prefix = to_var_name(name) + return platform_common.TemplateVariableInfo(dicts.add( + { + "{}_{}".format(var_prefix, to_var_name(name)): file.path + for name, file in sh_binaries_info.executables.items() + }, + { + "_{}_PATH".format(var_prefix): ":".join(sh_binaries_info.paths.to_list()), + }, + )) diff --git a/sh/sh.bzl b/sh/sh.bzl index a9efc4f..677a35f 100644 --- a/sh/sh.bzl +++ b/sh/sh.bzl @@ -1,6 +1,10 @@ load("@bazel_skylib//lib:dicts.bzl", "dicts") load("@bazel_skylib//lib:paths.bzl", "paths") -load("@rules_sh//sh/private:defs.bzl", "ConstantInfo") +load( + "@rules_sh//sh/private:defs.bzl", + "ConstantInfo", + "mk_template_variable_info", +) ShBinariesInfo = provider( doc = "The description of a sh_binaries target.", @@ -10,13 +14,6 @@ ShBinariesInfo = provider( }, ) -def _to_var_name(label_name): - """Turn a label name into a template variable info. - - Uses all upper case variable names with `_` as separator. - """ - return label_name.upper().replace("-", "_") - _WINDOWS_EXE_EXTENSIONS = [".exe", ".cmd", ".bat", ".ps1"] def _sh_binaries_from_srcs(ctx, srcs, is_windows): @@ -101,18 +98,6 @@ def _mk_sh_binaries_info(direct, transitive): ), ) -def _mk_template_variable_info(name, sh_binaries_info): - var_prefix = _to_var_name(name) - return platform_common.TemplateVariableInfo(dicts.add( - { - "{}_{}".format(var_prefix, _to_var_name(name)): file.path - for name, file in sh_binaries_info.executables.items() - }, - { - "_{}_PATH".format(var_prefix): ":".join(sh_binaries_info.paths.to_list()), - }, - )) - def _mk_default_info(ctx, direct, transitive, data_runfiles): # Create a dummy executable for this target to trigger the generation of a # FilesToRun provider which can be used in custom rules depending on this @@ -134,7 +119,7 @@ def _sh_binaries_impl(ctx): data_runfiles = _runfiles_from_data(ctx, ctx.attr.data) sh_binaries_info = _mk_sh_binaries_info(direct, transitive) - template_variable_info = _mk_template_variable_info(ctx.label.name, sh_binaries_info) + template_variable_info = mk_template_variable_info(ctx.label.name, sh_binaries_info) default_info = _mk_default_info(ctx, direct, transitive, data_runfiles) return [sh_binaries_info, template_variable_info, default_info] From e351dc59fbb8ccb0277c74540ecab0794e457691 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 1 Sep 2022 14:14:46 +0200 Subject: [PATCH 03/12] Factor out DefaultInfo with FilesToRun --- sh/private/defs.bzl | 13 +++++++++++++ sh/sh.bzl | 22 +++++++--------------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/sh/private/defs.bzl b/sh/private/defs.bzl index 5fbb1f4..558c76f 100644 --- a/sh/private/defs.bzl +++ b/sh/private/defs.bzl @@ -30,3 +30,16 @@ def mk_template_variable_info(name, sh_binaries_info): "_{}_PATH".format(var_prefix): ":".join(sh_binaries_info.paths.to_list()), }, )) + +def mk_default_info_with_files_to_run(ctx, name, files, runfiles): + # Create a dummy executable to trigger the generation of a FilesToRun + # provider which can be used in custom rules depending on this bundle to + # input the needed runfiles into build actions. + # This is a workaround for https://github.com/bazelbuild/bazel/issues/15486 + executable = ctx.actions.declare_file(name) + ctx.actions.write(executable, "", is_executable = True) + return DefaultInfo( + executable = executable, + files = files, + runfiles = runfiles, + ) diff --git a/sh/sh.bzl b/sh/sh.bzl index 677a35f..10bc40d 100644 --- a/sh/sh.bzl +++ b/sh/sh.bzl @@ -3,6 +3,7 @@ load("@bazel_skylib//lib:paths.bzl", "paths") load( "@rules_sh//sh/private:defs.bzl", "ConstantInfo", + "mk_default_info_with_files_to_run", "mk_template_variable_info", ) @@ -98,20 +99,6 @@ def _mk_sh_binaries_info(direct, transitive): ), ) -def _mk_default_info(ctx, direct, transitive, data_runfiles): - # Create a dummy executable for this target to trigger the generation of a - # FilesToRun provider which can be used in custom rules depending on this - # bundle to input the needed runfiles into build actions. - # This is a workaround for https://github.com/bazelbuild/bazel/issues/15486 - executable = ctx.actions.declare_file(ctx.label.name) - ctx.actions.write(executable, "", is_executable = True) - - return DefaultInfo( - executable = executable, - files = depset(direct = direct.executable_files, transitive = transitive.executable_files), - runfiles = direct.runfiles.merge(transitive.runfiles).merge(data_runfiles), - ) - def _sh_binaries_impl(ctx): is_windows = ctx.attr._is_windows[ConstantInfo].value direct = _sh_binaries_from_srcs(ctx, ctx.attr.srcs, is_windows) @@ -120,7 +107,12 @@ def _sh_binaries_impl(ctx): sh_binaries_info = _mk_sh_binaries_info(direct, transitive) template_variable_info = mk_template_variable_info(ctx.label.name, sh_binaries_info) - default_info = _mk_default_info(ctx, direct, transitive, data_runfiles) + default_info = mk_default_info_with_files_to_run( + ctx, + ctx.label.name, + depset(direct = direct.executable_files, transitive = transitive.executable_files), + direct.runfiles.merge(transitive.runfiles).merge(data_runfiles), + ) return [sh_binaries_info, template_variable_info, default_info] From a665ba139484c8149040bb0db7f9c7a68e7a34de Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Fri, 19 Aug 2022 15:40:49 +0200 Subject: [PATCH 04/12] Widen visibility for //sh:bazel_tools It is a helper target also required in other parts of rules_sh. --- sh/BUILD.bazel | 1 + 1 file changed, 1 insertion(+) diff --git a/sh/BUILD.bazel b/sh/BUILD.bazel index 93ec892..5d51537 100644 --- a/sh/BUILD.bazel +++ b/sh/BUILD.bazel @@ -8,6 +8,7 @@ bzl_library( srcs = [ "@bazel_tools//tools:bzl_srcs", ], + visibility = ["//:__subpackages__"], ) bzl_library( From 4b0dc253d818e9c511876c16f90abc5d716e21f9 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 17 Aug 2022 11:53:24 +0200 Subject: [PATCH 05/12] Implement hemetic POSIX toolchain --- sh/experimental/BUILD.bazel | 13 +++++++ sh/experimental/posix_hermetic.bzl | 55 ++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 sh/experimental/BUILD.bazel create mode 100644 sh/experimental/posix_hermetic.bzl diff --git a/sh/experimental/BUILD.bazel b/sh/experimental/BUILD.bazel new file mode 100644 index 0000000..c3afaa5 --- /dev/null +++ b/sh/experimental/BUILD.bazel @@ -0,0 +1,13 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +bzl_library( + name = "posix_hermetic", + srcs = [ + "posix_hermetic.bzl", + ], + visibility = ["//visibility:public"], + deps = [ + "//sh:bazel_tools", + "@bazel_skylib//lib:paths", + ], +) diff --git a/sh/experimental/posix_hermetic.bzl b/sh/experimental/posix_hermetic.bzl new file mode 100644 index 0000000..9758928 --- /dev/null +++ b/sh/experimental/posix_hermetic.bzl @@ -0,0 +1,55 @@ +"""Unix shell commands toolchain support. + +Defines a hermetic version of the POSIX toolchain defined in +@rules_sh//sh:posix.bzl. Long-term this hermetic version will replace the old, +less hermetic version of the POSIX toolchain. +""" + +load("@bazel_skylib//lib:paths.bzl", "paths") +load("@bazel_tools//tools/cpp:lib_cc_configure.bzl", "get_cpu_value") +load("//sh/private:posix.bzl", _commands = "commands") +load("//sh:posix.bzl", "MAKE_VARIABLES", "TOOLCHAIN_TYPE") +load("//sh:sh.bzl", "ShBinariesInfo") + +def _sh_posix_hermetic_toolchain_impl(ctx): + if not ShBinariesInfo in ctx.attr.cmds: + fail("The cmds attribute must be given a sh_binaries target.") + + sh_binaries_info = ctx.attr.cmds[ShBinariesInfo] + + unrecognizeds = [ + cmd + for cmd in sh_binaries_info.executables.keys() + if cmd not in _commands + ] + if unrecognizeds: + fail("Unrecognized commands in keys of sh_posix_hermetic_toolchain's \"cmds\" attribute: {}. See posix_hermetic.commands in @rules_sh//sh:posix_hermetic.bzl for the list of recognized commands.".format(", ".join(unrecognizeds))) + + return [platform_common.ToolchainInfo( + sh_binaries_info = sh_binaries_info, + # exposed for use-cases requiring runfiles access. + tool = ctx.attr.cmds, + # exposed for backwards compatibility. + commands = { + cmd: sh_binaries_info.executables[cmd].path if cmd in sh_binaries_info.executables else None + for cmd in _commands + }, + paths = sh_binaries_info.paths.to_list(), + )] + +sh_posix_hermetic_toolchain = rule( + attrs = { + "cmds": attr.label( + doc = "sh_binaries target that captures the tools to include in this toolchain.", + mandatory = True, + ), + }, + # TODO[AH]: doc + implementation = _sh_posix_hermetic_toolchain_impl, +) + +posix_hermetic = struct( + commands = _commands, + TOOLCHAIN_TYPE = TOOLCHAIN_TYPE, + MAKE_VARIABLES = MAKE_VARIABLES, +) From d5901f6c8a8ecc0f9034062677d9828381cfc7b1 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Fri, 19 Aug 2022 15:38:45 +0200 Subject: [PATCH 06/12] Support hermetic POSIX toolchain in MAKE_VARIABLES --- sh/BUILD.bazel | 1 + sh/posix.bzl | 35 ++++++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/sh/BUILD.bazel b/sh/BUILD.bazel index 5d51537..ada9e49 100644 --- a/sh/BUILD.bazel +++ b/sh/BUILD.bazel @@ -44,6 +44,7 @@ bzl_library( visibility = ["//visibility:public"], deps = [ ":bazel_tools", + "//sh/private:defs", "//sh/private:posix", "@bazel_skylib//lib:paths", ], diff --git a/sh/posix.bzl b/sh/posix.bzl index a102892..2e52784 100644 --- a/sh/posix.bzl +++ b/sh/posix.bzl @@ -9,6 +9,11 @@ available in `posix.commands`. load("@bazel_skylib//lib:paths.bzl", "paths") load("@bazel_tools//tools/cpp:lib_cc_configure.bzl", "get_cpu_value") +load( + "//sh/private:defs.bzl", + "mk_default_info_with_files_to_run", + "mk_template_variable_info", +) load("//sh/private:posix.bzl", _commands = "commands") TOOLCHAIN_TYPE = "@rules_sh//sh/posix:toolchain_type" @@ -57,13 +62,29 @@ See `sh_posix_make_variables` on how to use this toolchain in genrules. def _sh_posix_make_variables_impl(ctx): toolchain = ctx.toolchains[TOOLCHAIN_TYPE] - cmd_vars = { - "POSIX_%s" % cmd.upper(): cmd_path - for cmd in _commands - for cmd_path in [toolchain.commands[cmd]] - if cmd_path - } - return [platform_common.TemplateVariableInfo(cmd_vars)] + + if not hasattr(toolchain, "sh_binaries_info"): + cmd_vars = { + "POSIX_%s" % cmd.upper(): cmd_path + for cmd in _commands + for cmd_path in [toolchain.commands[cmd]] + if cmd_path + } + return [platform_common.TemplateVariableInfo(cmd_vars)] + + template_variable_info = mk_template_variable_info( + "posix", + toolchain.sh_binaries_info, + ) + + default_info = mk_default_info_with_files_to_run( + ctx, + ctx.label.name, + toolchain.tool[DefaultInfo].files, + toolchain.tool[DefaultInfo].default_runfiles, + ) + + return [template_variable_info, default_info] sh_posix_make_variables = rule( doc = """ From 2bdaa5d082a7d75f7a6a3597ebdf8687dd49371f Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 17 Aug 2022 16:34:28 +0200 Subject: [PATCH 07/12] Test hermetic POSIX toolchain --- tests/posix_hermetic/BUILD.bazel | 3 + .../posix_hermetic/custom_rule_output_test.sh | 28 + tests/posix_hermetic/echo.sh | 15 + tests/posix_hermetic/echo_data.txt | 1 + tests/posix_hermetic/false.sh | 3 + .../genrule_explicit_output_test.sh | 25 + .../genrule_path_output_test.sh | 25 + tests/posix_hermetic/posix_hermetic_test.bzl | 734 ++++++++++++++++++ .../runfiles_custom_rule_test.sh | 24 + tests/posix_hermetic/runfiles_genrule_test.sh | 24 + tests/posix_hermetic/true.sh | 3 + tests/posix_hermetic/unrecognized.sh | 2 + 12 files changed, 887 insertions(+) create mode 100644 tests/posix_hermetic/BUILD.bazel create mode 100755 tests/posix_hermetic/custom_rule_output_test.sh create mode 100755 tests/posix_hermetic/echo.sh create mode 100644 tests/posix_hermetic/echo_data.txt create mode 100755 tests/posix_hermetic/false.sh create mode 100755 tests/posix_hermetic/genrule_explicit_output_test.sh create mode 100755 tests/posix_hermetic/genrule_path_output_test.sh create mode 100644 tests/posix_hermetic/posix_hermetic_test.bzl create mode 100755 tests/posix_hermetic/runfiles_custom_rule_test.sh create mode 100755 tests/posix_hermetic/runfiles_genrule_test.sh create mode 100755 tests/posix_hermetic/true.sh create mode 100755 tests/posix_hermetic/unrecognized.sh diff --git a/tests/posix_hermetic/BUILD.bazel b/tests/posix_hermetic/BUILD.bazel new file mode 100644 index 0000000..9d7207b --- /dev/null +++ b/tests/posix_hermetic/BUILD.bazel @@ -0,0 +1,3 @@ +load(":posix_hermetic_test.bzl", "posix_hermetic_test_suite") + +posix_hermetic_test_suite(name = "posix_hermetic_test") diff --git a/tests/posix_hermetic/custom_rule_output_test.sh b/tests/posix_hermetic/custom_rule_output_test.sh new file mode 100755 index 0000000..8a0179a --- /dev/null +++ b/tests/posix_hermetic/custom_rule_output_test.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# --- begin runfiles.bash initialization v2 --- +# Copy-pasted from the Bazel Bash runfiles library v2. +set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ + source "$0.runfiles/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v2 --- +set -euo pipefail + +assert_eq() { + if [[ $1 != $2 ]]; then + echo -e "Wrong output found in $3:\nExpected: '$1'\nGot: '$2'" + return 1 + fi +} + +EXPECTED="1 +0" + +ACTUAL="$(cat "$(rlocation rules_sh/tests/posix_hermetic/custom_rule_explicit.txt)")" +assert_eq "$EXPECTED" "$ACTUAL" "custom_rule.txt" + +ACTUAL="$(cat "$(rlocation rules_sh/tests/posix_hermetic/custom_rule_path.txt)")" +assert_eq "$EXPECTED" "$ACTUAL" "custom_rule.txt" diff --git a/tests/posix_hermetic/echo.sh b/tests/posix_hermetic/echo.sh new file mode 100755 index 0000000..cf4d35b --- /dev/null +++ b/tests/posix_hermetic/echo.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +# --- begin runfiles.bash initialization v2 --- +# Copy-pasted from the Bazel Bash runfiles library v2. +set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ + source "$0.runfiles/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v2 --- +set -euo pipefail + +SUFFIX="$(cat "$(rlocation rules_sh/tests/posix_hermetic/echo_data.txt)")" +echo "$@" "$SUFFIX" diff --git a/tests/posix_hermetic/echo_data.txt b/tests/posix_hermetic/echo_data.txt new file mode 100644 index 0000000..4a39433 --- /dev/null +++ b/tests/posix_hermetic/echo_data.txt @@ -0,0 +1 @@ +ECHO SUFFIX diff --git a/tests/posix_hermetic/false.sh b/tests/posix_hermetic/false.sh new file mode 100755 index 0000000..a447767 --- /dev/null +++ b/tests/posix_hermetic/false.sh @@ -0,0 +1,3 @@ +#!/bin/sh +# Intentionally inverted to distinguish from the builtin false command. +exit 0 diff --git a/tests/posix_hermetic/genrule_explicit_output_test.sh b/tests/posix_hermetic/genrule_explicit_output_test.sh new file mode 100755 index 0000000..f87d513 --- /dev/null +++ b/tests/posix_hermetic/genrule_explicit_output_test.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# --- begin runfiles.bash initialization v2 --- +# Copy-pasted from the Bazel Bash runfiles library v2. +set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ + source "$0.runfiles/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v2 --- +set -euo pipefail + +assert_eq() { + if [[ $1 != $2 ]]; then + echo -e "Wrong output found in $3:\nExpected: '$1'\nGot: '$2'" + return 1 + fi +} + +EXPECTED="1 +0" + +ACTUAL="$(cat "$(rlocation rules_sh/tests/posix_hermetic/genrule_explicit.txt)")" +assert_eq "$EXPECTED" "$ACTUAL" "custom_rule.txt" diff --git a/tests/posix_hermetic/genrule_path_output_test.sh b/tests/posix_hermetic/genrule_path_output_test.sh new file mode 100755 index 0000000..81d1d63 --- /dev/null +++ b/tests/posix_hermetic/genrule_path_output_test.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# --- begin runfiles.bash initialization v2 --- +# Copy-pasted from the Bazel Bash runfiles library v2. +set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ + source "$0.runfiles/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v2 --- +set -euo pipefail + +assert_eq() { + if [[ $1 != $2 ]]; then + echo -e "Wrong output found in $3:\nExpected: '$1'\nGot: '$2'" + return 1 + fi +} + +EXPECTED="1 +0" + +ACTUAL="$(cat "$(rlocation rules_sh/tests/posix_hermetic/genrule_path.txt)")" +assert_eq "$EXPECTED" "$ACTUAL" "custom_rule.txt" diff --git a/tests/posix_hermetic/posix_hermetic_test.bzl b/tests/posix_hermetic/posix_hermetic_test.bzl new file mode 100644 index 0000000..dd9db6b --- /dev/null +++ b/tests/posix_hermetic/posix_hermetic_test.bzl @@ -0,0 +1,734 @@ +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") +load( + "//sh:sh.bzl", + "ShBinariesInfo", + "sh_binaries", +) +load( + "//sh/experimental:posix_hermetic.bzl", + "posix_hermetic", + "sh_posix_hermetic_toolchain", +) + +# empty toolchain #################################################### + +def _empty_toolchain(): + sh_binaries( + name = "binaries-empty", + srcs = [], + ) + sh_posix_hermetic_toolchain( + name = "posix-toolchain-empty", + cmds = ":binaries-empty", + ) + +def _empty_toolchain_test_impl(ctx): + env = analysistest.begin(ctx) + + toolchain = analysistest.target_under_test(env)[platform_common.ToolchainInfo] + + # -------------------------------------------- + # sh_binaries attribute + + asserts.true( + env, + hasattr(toolchain, "sh_binaries_info"), + "Expected 'sh_binaries_info' attribute", + ) + asserts.equals( + env, + toolchain.sh_binaries_info.executables, + {}, + ) + asserts.equals( + env, + toolchain.sh_binaries_info.paths.to_list(), + [], + ) + + # -------------------------------------------- + # Backwards compatible attributes + + asserts.true( + env, + hasattr(toolchain, "commands"), + "Expected 'commands' attribute for backwards compatibility", + ) + asserts.equals( + env, + {cmd: None for cmd in posix_hermetic.commands}, + getattr(toolchain, "commands", None), + "Malformed backwards-compatible 'commands' attribute", + ) + asserts.true( + env, + hasattr(toolchain, "paths"), + "Expected 'paths' attribute for backwards compatibility", + ) + asserts.equals( + env, + getattr(toolchain, "paths", None), + [], + "Malformed backwards-compatible 'paths' attribute", + ) + + return analysistest.end(env) + +empty_toolchain_test = analysistest.make( + _empty_toolchain_test_impl, +) + +def _test_empty_toolchain(): + _empty_toolchain() + empty_toolchain_test( + name = "empty_toolchain_test", + target_under_test = ":posix-toolchain-empty", + ) + +# unrecognized tool ################################################## + +def _unrecognized_tool_toolchain(): + native.sh_binary( + name = "unrecognized", + srcs = ["unrecognized.sh"], + ) + sh_binaries( + name = "binaries-unrecognized", + srcs = [":unrecognized"], + ) + sh_posix_hermetic_toolchain( + name = "posix-toolchain-unrecognized", + cmds = ":binaries-unrecognized", + tags = ["manual"], + ) + +def _unrecognized_tool_toolchain_test_impl(ctx): + env = analysistest.begin(ctx) + + asserts.expect_failure( + env, + """Unrecognized commands in keys of sh_posix_hermetic_toolchain's "cmds" attribute: unrecognized""", + ) + + return analysistest.end(env) + +unrecognized_tool_toolchain_test = analysistest.make( + _unrecognized_tool_toolchain_test_impl, + expect_failure = True, +) + +def _test_unrecognized_tool_toolchain(): + _unrecognized_tool_toolchain() + unrecognized_tool_toolchain_test( + name = "unrecognized_tool_toolchain_test", + target_under_test = ":posix-toolchain-unrecognized", + ) + +# shell scripts toolchain ############################################ + +# A toolchain that depends on local files, but has no further runtime +# dependencies, like runfiles resolution. + +def _shell_scripts_toolchain(): + native.sh_binary( + name = "false", + srcs = ["false.sh"], + ) + native.sh_binary( + name = "true", + srcs = ["true.sh"], + ) + sh_binaries( + name = "binaries-shell-scripts", + srcs = [ + "false", + "true", + ], + ) + sh_posix_hermetic_toolchain( + name = "posix-toolchain-shell-scripts", + cmds = ":binaries-shell-scripts", + ) + native.toolchain( + name = "toolchain-shell-scripts", + toolchain = ":posix-toolchain-shell-scripts", + toolchain_type = "//sh/posix:toolchain_type", + ) + +def _shell_scripts_toolchain_transition_impl(settings, attr): + return { + "//command_line_option:extra_toolchains": "//tests/posix_hermetic:toolchain-shell-scripts", + } + +_shell_scripts_toolchain_transition = transition( + implementation = _shell_scripts_toolchain_transition_impl, + inputs = [], + outputs = ["//command_line_option:extra_toolchains"], +) + +def _use_shell_scripts_toolchain_impl(ctx): + src = ctx.attr.src[DefaultInfo] + return [ + DefaultInfo( + files = src.files, + runfiles = ctx + .runfiles(files = src.files.to_list()) + .merge(src.default_runfiles), + ), + ] + +_use_shell_scripts_toolchain = rule( + _use_shell_scripts_toolchain_impl, + cfg = _shell_scripts_toolchain_transition, + attrs = { + "src": attr.label(), + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist", + ), + }, +) + +def _shell_scripts_toolchain_test_impl(ctx): + env = analysistest.begin(ctx) + + toolchain = analysistest.target_under_test(env)[platform_common.ToolchainInfo] + + # -------------------------------------------- + # sh_binaries attribute + + asserts.true( + env, + hasattr(toolchain, "sh_binaries_info"), + "Expected 'sh_binaries_info' attribute", + ) + asserts.equals( + env, + len(toolchain.sh_binaries_info.executables), + 2, + ) + asserts.true( + env, + "false" in toolchain.sh_binaries_info.executables, + "Expected 'false' to be a member of the executables dict", + ) + asserts.true( + env, + ctx.executable.false_binary in toolchain.sh_binaries_info.executables.values(), + "Expected 'false' binary to be a member of the executables", + ) + asserts.true( + env, + "true" in toolchain.sh_binaries_info.executables, + "Expected 'true' to be a member of the executables dict", + ) + asserts.true( + env, + ctx.executable.true_binary in toolchain.sh_binaries_info.executables.values(), + "Expected 'true' binary to be a member of the executables", + ) + asserts.equals( + env, + len(toolchain.sh_binaries_info.paths.to_list()), + 1, + ) + asserts.equals( + env, + toolchain.sh_binaries_info.paths.to_list()[0], + ctx.executable.false_binary.dirname, + ) + + # -------------------------------------------- + # Backwards compatible attributes + + asserts.true( + env, + hasattr(toolchain, "commands"), + "Expected 'commands' attribute for backwards compatibility", + ) + asserts.equals( + env, + len(getattr(toolchain, "commands", None)), + len(posix_hermetic.commands), + "Malformed backwards-compatible 'commands' attribute", + ) + asserts.equals( + env, + toolchain.commands["false"], + ctx.executable.false_binary.path, + ) + asserts.equals( + env, + toolchain.commands["true"], + ctx.executable.true_binary.path, + ) + asserts.true( + env, + all([ + toolchain.commands[cmd] == None + for cmd in posix_hermetic.commands + if not cmd in ["false", "true"] + ]), + ) + asserts.true( + env, + hasattr(toolchain, "paths"), + "Expected 'paths' attribute for backwards compatibility", + ) + asserts.equals( + env, + len(getattr(toolchain, "paths", None)), + 1, + "Malformed backwards-compatible 'paths' attribute", + ) + asserts.equals( + env, + toolchain.paths[0], + ctx.executable.false_binary.dirname, + ) + + return analysistest.end(env) + +shell_scripts_toolchain_test = analysistest.make( + _shell_scripts_toolchain_test_impl, + attrs = { + "false_binary": attr.label( + executable = True, + # TODO[AH] Both the target_under_test and the reference should be + # provided in the exec configuration. + # See https://github.com/bazelbuild/bazel-skylib/issues/377 + # cfg = "exec", + cfg = "target", + ), + "true_binary": attr.label( + executable = True, + # TODO[AH] Both the target_under_test and the reference should be + # provided in the exec configuration. + # See https://github.com/bazelbuild/bazel-skylib/issues/377 + # cfg = "exec", + cfg = "target", + ), + }, +) + +def _test_shell_scripts_toolchain(): + _shell_scripts_toolchain() + shell_scripts_toolchain_test( + name = "shell_scripts_toolchain_test", + target_under_test = ":posix-toolchain-shell-scripts", + false_binary = ":false", + true_binary = ":true", + ) + +# custom rule usage ################################################## + +CustomRuleInfo = provider() + +def _custom_rule_impl(ctx): + toolchain = ctx.toolchains["//sh/posix:toolchain_type"] + + explicit_output = ctx.actions.declare_file("{}_explicit.txt".format(ctx.label.name)) + ctx.actions.run_shell( + outputs = [explicit_output], + tools = [ + toolchain.sh_binaries_info.executables["false"], + toolchain.sh_binaries_info.executables["true"], + ], + arguments = [ + toolchain.sh_binaries_info.executables["false"].path, + toolchain.sh_binaries_info.executables["true"].path, + explicit_output.path, + ], + command = """\ +FALSE="$1" +TRUE="$2" +OUT="$3" +{ $FALSE && echo 1 || echo 0; } >>$OUT +{ $TRUE && echo 1 || echo 0; } >>$OUT +""", + ) + + path_output = ctx.actions.declare_file("{}_path.txt".format(ctx.label.name)) + ctx.actions.run_shell( + outputs = [path_output], + tools = [ + toolchain.sh_binaries_info.executables["false"], + toolchain.sh_binaries_info.executables["true"], + ], + arguments = [ + ":".join(toolchain.sh_binaries_info.paths.to_list()), + path_output.path, + ], + command = """\ +# Disable the shell builtins and standard PATH to ensure +# that we use the commands provided by the toolchain. +enable -n false true +export PATH="$1" +OUT="$2" +{ false && echo 1 || echo 0; } >>$OUT +{ true && echo 1 || echo 0; } >>$OUT +""", + ) + + return [ + DefaultInfo( + files = depset(direct = [explicit_output, path_output]), + runfiles = ctx.runfiles(files = [explicit_output, path_output]), + ), + CustomRuleInfo( + false_binary = toolchain.sh_binaries_info.executables["false"], + ), + ] + +_custom_rule = rule( + _custom_rule_impl, + cfg = _shell_scripts_toolchain_transition, + toolchains = ["//sh/posix:toolchain_type"], + attrs = { + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist", + ), + }, +) + +def _custom_rule_test_impl(ctx): + env = analysistest.begin(ctx) + + rule_info = analysistest.target_under_test(env)[CustomRuleInfo] + + asserts.equals( + env, + rule_info.false_binary, + ctx.executable.false_binary, + ) + + return analysistest.end(env) + +custom_rule_test = analysistest.make( + _custom_rule_test_impl, + attrs = { + "false_binary": attr.label( + executable = True, + # The _shell_scripts_toolchain_transition places the toolchain + # provided binary under a different configuration than the + # reference binary would be under the regular `host` configuration. + # We apply the same transition to the reference to align the + # configurations. + cfg = _shell_scripts_toolchain_transition, + ), + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist", + ), + }, +) + +def _test_custom_rule(): + _custom_rule( + name = "custom_rule", + tags = ["manual"], + ) + custom_rule_test( + name = "custom_rule_analysis_test", + target_under_test = ":custom_rule", + false_binary = ":false", + ) + native.sh_test( + name = "custom_rule_output_test", + srcs = ["custom_rule_output_test.sh"], + deps = ["@bazel_tools//tools/bash/runfiles"], + data = [":custom_rule"], + ) + native.test_suite( + name = "custom_rule_test", + tests = [ + ":custom_rule_analysis_test", + ":custom_rule_output_test", + ], + ) + +# genrule usage ###################################################### + +def _test_genrule(): + native.genrule( + name = "genrule_explicit", + tags = ["manual"], + outs = ["genrule_explicit.txt"], + cmd = """\ +{ $(POSIX_FALSE) && echo 1 || echo 0; } >> $(OUTS) +{ $(POSIX_TRUE) && echo 1 || echo 0; } >> $(OUTS) +""", + toolchains = [posix_hermetic.MAKE_VARIABLES], + ) + native.genrule( + name = "genrule_path", + tags = ["manual"], + outs = ["genrule_path.txt"], + cmd = """\ +# Disable the shell builtins and standard PATH to ensure +# that we use the commands provided by the toolchain. +enable -n false true +export PATH="$(_POSIX_PATH)" +{ false && echo 1 || echo 0; } >> $(OUTS) +{ true && echo 1 || echo 0; } >> $(OUTS) +""", + toolchains = [posix_hermetic.MAKE_VARIABLES], + ) + _use_shell_scripts_toolchain( + name = "genrule_explicit_transitioned", + src = ":genrule_explicit", + ) + _use_shell_scripts_toolchain( + name = "genrule_path_transitioned", + src = ":genrule_path", + ) + native.sh_test( + name = "genrule_explicit_output_test", + srcs = ["genrule_explicit_output_test.sh"], + deps = ["@bazel_tools//tools/bash/runfiles"], + data = [":genrule_explicit_transitioned"], + ) + native.sh_test( + name = "genrule_path_output_test", + srcs = ["genrule_path_output_test.sh"], + deps = ["@bazel_tools//tools/bash/runfiles"], + data = [":genrule_path_transitioned"], + ) + native.test_suite( + name = "genrule_test", + tests = [ + ":genrule_explicit_output_test", + ":genrule_path_output_test", + ], + ) + +# runfiles toolchain ################################################# + +# A toolchain that depends on runfiles resolution. + +def _runfiles_toolchain(): + native.sh_binary( + name = "echo", + srcs = ["echo.sh"], + deps = ["@bazel_tools//tools/bash/runfiles"], + data = [":echo_data.txt"], + ) + sh_binaries( + name = "binaries-runfiles", + srcs = [":echo"], + ) + sh_posix_hermetic_toolchain( + name = "posix-toolchain-runfiles", + cmds = ":binaries-runfiles", + ) + native.toolchain( + name = "toolchain-runfiles", + toolchain = ":posix-toolchain-runfiles", + toolchain_type = "//sh/posix:toolchain_type", + ) + +def _runfiles_toolchain_transition_impl(settings, attr): + return { + "//command_line_option:extra_toolchains": "//tests/posix_hermetic:toolchain-runfiles", + } + +_runfiles_toolchain_transition = transition( + implementation = _runfiles_toolchain_transition_impl, + inputs = [], + outputs = ["//command_line_option:extra_toolchains"], +) + +def _use_runfiles_toolchain_impl(ctx): + src = ctx.attr.src[DefaultInfo] + return [ + DefaultInfo( + files = src.files, + runfiles = ctx + .runfiles(files = src.files.to_list()) + .merge(src.default_runfiles), + ), + ] + +_use_runfiles_toolchain = rule( + _use_runfiles_toolchain_impl, + cfg = _runfiles_toolchain_transition, + attrs = { + "src": attr.label(), + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist", + ), + }, +) + +def _runfiles_toolchain_test_impl(ctx): + env = analysistest.begin(ctx) + + toolchain = analysistest.target_under_test(env)[platform_common.ToolchainInfo] + + # -------------------------------------------- + # runfiles forwarding + + toolchain_runfiles = toolchain.tool[DefaultInfo].default_runfiles.files.to_list() + echo_runfiles = ctx.attr.echo_binary[DefaultInfo].default_runfiles.files.to_list() + asserts.true( + env, + all([ + runfile in toolchain_runfiles + for runfile in echo_runfiles + ]), + "Expected that all of echo's runfiles are forwared in the toolchain runfiles.", + ) + + return analysistest.end(env) + +runfiles_toolchain_test = analysistest.make( + _runfiles_toolchain_test_impl, + attrs = { + "echo_binary": attr.label( + executable = True, + # TODO[AH] Both the target_under_test and the reference should be + # provided in the exec configuration. + # See https://github.com/bazelbuild/bazel-skylib/issues/377 + # cfg = "exec", + cfg = "target", + ), + "echo_data": attr.label(allow_single_file = True), + }, +) + +def _test_runfiles_toolchain(): + _runfiles_toolchain() + runfiles_toolchain_test( + name = "runfiles_toolchain_test", + target_under_test = ":posix-toolchain-runfiles", + echo_binary = ":echo", + echo_data = ":echo_data.txt", + ) + +# runfiles in custom rule ############################################ + +def _runfiles_custom_rule_impl(ctx): + toolchain = ctx.toolchains["//sh/posix:toolchain_type"] + + (tools_inputs, tools_manifest) = ctx.resolve_tools(tools = [toolchain.tool]) + + # Override the argv[0] relative runfiles tree or manifest by the bundle's. + # This is a workaround for https://github.com/bazelbuild/bazel/issues/15486 + tools_env = { + "RUNFILES_DIR": toolchain.tool[DefaultInfo].files_to_run.runfiles_manifest.dirname, + "RUNFILES_MANIFEST_FILE": toolchain.tool[DefaultInfo].files_to_run.runfiles_manifest.path, + } + + output = ctx.actions.declare_file("{}.txt".format(ctx.label.name)) + ctx.actions.run_shell( + outputs = [output], + inputs = tools_inputs, + input_manifests = tools_manifest, + env = tools_env, + tools = [ + toolchain.sh_binaries_info.executables["echo"], + ], + arguments = [ + toolchain.sh_binaries_info.executables["echo"].path, + output.path, + ], + command = """\ +ECHO="$1" +OUT="$2" +$ECHO message >>$OUT +""", + ) + + return [ + DefaultInfo( + files = depset(direct = [output]), + runfiles = ctx.runfiles(files = [output]), + ), + ] + +_runfiles_custom_rule = rule( + _runfiles_custom_rule_impl, + cfg = _runfiles_toolchain_transition, + toolchains = ["//sh/posix:toolchain_type"], + attrs = { + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist", + ), + }, +) + +def _test_runfiles_custom_rule(): + _runfiles_custom_rule( + name = "runfiles_custom_rule", + tags = ["manual"], + ) + native.sh_test( + name = "runfiles_custom_rule_test", + srcs = ["runfiles_custom_rule_test.sh"], + deps = ["@bazel_tools//tools/bash/runfiles"], + data = ["runfiles_custom_rule"], + ) + +# runfiles in genrule ################################################ + +def _test_runfiles_genrule(): + native.genrule( + name = "runfiles_genrule", + tags = ["manual"], + outs = ["runfiles_genrule.txt"], + cmd = """\ +IS_WINDOWS= +case "$$OSTYPE" in + cygwin|msys|win32) IS_WINDOWS=1;; +esac + +with_runfiles() { + # The explicit RUNFILES_DIR|RUNFILES_MANIFEST_FILE is a workaround for + # https://github.com/bazelbuild/bazel/issues/15486 + if [[ -n $$IS_WINDOWS ]]; then + RUNFILES_MANIFEST_FILE=$(execpath @rules_sh//sh/posix:make_variables).runfiles_manifest \\ + eval "$$@" + else + RUNFILES_DIR=$(execpath @rules_sh//sh/posix:make_variables).runfiles \\ + eval "$$@" + fi +} + +with_runfiles $(POSIX_ECHO) message >>$(OUTS) +""", + toolchains = [posix_hermetic.MAKE_VARIABLES], + ) + _use_runfiles_toolchain( + name = "runfiles_genrule_transitioned", + src = ":runfiles_genrule", + ) + native.sh_test( + name = "runfiles_genrule_test", + srcs = ["runfiles_genrule_test.sh"], + deps = ["@bazel_tools//tools/bash/runfiles"], + data = [":runfiles_genrule_transitioned"], + ) + +# test suite ######################################################### + +def posix_hermetic_test_suite(name): + _test_empty_toolchain() + _test_unrecognized_tool_toolchain() + _test_shell_scripts_toolchain() + _test_custom_rule() + _test_genrule() + _test_runfiles_toolchain() + _test_runfiles_custom_rule() + _test_runfiles_genrule() + + native.test_suite( + name = name, + tests = [ + ":empty_toolchain_test", + ":unrecognized_tool_toolchain_test", + ":shell_scripts_toolchain_test", + ":custom_rule_test", + ":genrule_test", + ":runfiles_toolchain_test", + ":runfiles_custom_rule_test", + ":runfiles_genrule_test", + ], + ) diff --git a/tests/posix_hermetic/runfiles_custom_rule_test.sh b/tests/posix_hermetic/runfiles_custom_rule_test.sh new file mode 100755 index 0000000..9ee8685 --- /dev/null +++ b/tests/posix_hermetic/runfiles_custom_rule_test.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# --- begin runfiles.bash initialization v2 --- +# Copy-pasted from the Bazel Bash runfiles library v2. +set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ + source "$0.runfiles/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v2 --- +set -euo pipefail + +assert_eq() { + if [[ $1 != $2 ]]; then + echo -e "Wrong output found in $3:\nExpected: '$1'\nGot: '$2'" + return 1 + fi +} + +EXPECTED="message ECHO SUFFIX" + +ACTUAL="$(cat "$(rlocation rules_sh/tests/posix_hermetic/runfiles_custom_rule.txt)")" +assert_eq "$EXPECTED" "$ACTUAL" "runfiles_custom_rule.txt" diff --git a/tests/posix_hermetic/runfiles_genrule_test.sh b/tests/posix_hermetic/runfiles_genrule_test.sh new file mode 100755 index 0000000..c05bc55 --- /dev/null +++ b/tests/posix_hermetic/runfiles_genrule_test.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# --- begin runfiles.bash initialization v2 --- +# Copy-pasted from the Bazel Bash runfiles library v2. +set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ + source "$0.runfiles/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v2 --- +set -euo pipefail + +assert_eq() { + if [[ $1 != $2 ]]; then + echo -e "Wrong output found in $3:\nExpected: '$1'\nGot: '$2'" + return 1 + fi +} + +EXPECTED="message ECHO SUFFIX" + +ACTUAL="$(cat "$(rlocation rules_sh/tests/posix_hermetic/runfiles_genrule.txt)")" +assert_eq "$EXPECTED" "$ACTUAL" "runfiles_genrule.txt" diff --git a/tests/posix_hermetic/true.sh b/tests/posix_hermetic/true.sh new file mode 100755 index 0000000..01ca55a --- /dev/null +++ b/tests/posix_hermetic/true.sh @@ -0,0 +1,3 @@ +#!/bin/sh +# Intentionally inverted to distinguish from the builtin false command. +exit 1 diff --git a/tests/posix_hermetic/unrecognized.sh b/tests/posix_hermetic/unrecognized.sh new file mode 100755 index 0000000..3af18e2 --- /dev/null +++ b/tests/posix_hermetic/unrecognized.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +echo "Unrecognized tool" From 72221efb6f04662826a03a0350b60a0e2fcb01e4 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 1 Sep 2022 16:30:05 +0200 Subject: [PATCH 08/12] Document the hermetic POSIX toolchain --- sh/experimental/posix_hermetic.bzl | 163 ++++++++++++++++++++++++++++- 1 file changed, 162 insertions(+), 1 deletion(-) diff --git a/sh/experimental/posix_hermetic.bzl b/sh/experimental/posix_hermetic.bzl index 9758928..d7e5f60 100644 --- a/sh/experimental/posix_hermetic.bzl +++ b/sh/experimental/posix_hermetic.bzl @@ -44,8 +44,169 @@ sh_posix_hermetic_toolchain = rule( mandatory = True, ), }, - # TODO[AH]: doc implementation = _sh_posix_hermetic_toolchain_impl, + # TODO[AH] Add a reference to repository rules that generate this toolchain. + doc = """\ +Defines a POSIX toolchain based on an sh_binaries bundle. + +Provides: + sh_binaries_info: ShBinariesInfo, for use in custom rules, see `sh_binaries`. + tool: Target, the sh_binaries target for use in custom rules that requires runfiles, see `sh_binaries`. + commands: Dict of String, an item per command holding the path to the executable or None. Provided for backwards compatibility with `sh_posix_toolchain`. + paths: List of String, deduplicated bindir paths. Suitable for generating `$PATH`. Provided for backwards compatibility with `sh_posix_toolchain`. + +#### Example + +*Using the toolchain in a genrule* + +You need to add a dependency on the `@rules_sh//sh/posix:make_variables` target +to the `toolchains` attribute to import the toolchain into a `genrule`. You can +then use specific tools through make-variables of the form `POSIX_`, or +by extending the `PATH` variable with `$(_POSIX_PATH)`. For example: + +```bzl +genrule( + name = "a-genrule", + toolchains = ["@rules_sh//sh/posix:make_variables"], + cmd = "\\n".join([ + "FILE=$(execpath :some-input-file.bzl)", + "$(POSIX_GREP) some-pattern $$FILE > $(OUTS)", + "PATH=$(_POSIX_PATH)", + "grep some-pattern $$FILE >> $(OUTS)", + ]), + srcs = [":some-input-file"], + outs = ["some-output-file"], +) +``` + +*Using the toolchain in a custom rule* + +You need to add a dependency on the `@rules_sh//sh/posix:toolchain_type` to +your custom rule. For example: + +```bzl +custom_rule = rule( + _custom_rule_impl, + toolchains = ["//sh/posix:toolchain_type"], + ... +) +``` + +You can then access the `ShBinariesInfo` provider through the +`sh_binaries_info` attribute of the toolchain object. See `sh_binaries` for +details on the use of that provider. The example below illustrates how to +access the `grep` tool directly, or how to expose it through the `PATH` +environment variable. + +```bzl +load("@rules_sh//sh:sh.bzl", "ShBinariesInfo") + +def _custom_rule_impl(ctx): + toolchain = ctx.toolchains["//sh/posix:toolchain_type"] + sh_binaries_info = toolchain.sh_binaries_info + + ctx.actions.run( + executable = sh_binaries_info.executables["grep"], + ... + ) + + ctx.actions.run_shell( + command = "grep ...", + tools = [tools.executables["grep"]], + env = {"PATH": ":".join(sh_binaries_info.paths.to_list())}, + ... + ) +``` + +Note that the `grep` tool still needs to be declared as an explicit dependency +of the action in the `PATH` use-case using the `tools` parameter. + +The toolchain also exposes the attributes `commands` and `paths` exposed by the +non-hermetic POSIX toolchain for backwards compatibility. Note, however, that +actions still need to explicitly declare the relevant tool files as inputs +explicitly. + +*Caveat: Using Binaries that require Runfiles* + +If the tools bundled by the hermetic POSIX toolchains require Bazel runfiles +access then the same caveats as for `sh_binaries` apply. + +For example, use in a `genrule` looks like this: + +```bzl +genrule( + name = "runfiles-genrule", + toolchains = ["@rules_sh//sh/posix:make_variables"], + cmd = "\\n".join([ + # The explicit RUNFILES_DIR/RUNFILES_MANIFEST_FILE is a workaround for + # https://github.com/bazelbuild/bazel/issues/15486 + "RUNFILES_DIR=$(execpath @rules_sh//sh/posix:make_variables).runfiles", + "RUNFILES_MANIFEST_FILE=$(execpath @rules_sh//sh/posix:make_variables).runfiles_manifest", + "FILE=$(execpath :some-input-file.bzl)", + "$(POSIX_GREP) some-pattern $$FILE > $(OUTS)", + "PATH=$(_POSIX_PATH)", + "grep some-pattern $$FILE >> $(OUTS)", + ]), + srcs = [":some-input-file"], + outs = ["some-output-file"], +) +``` + +And use in a custom rule looks like this: + +```bzl +def _custom_rule_impl(ctx): + toolchain = ctx.toolchains["//sh/posix:toolchain_type"] + sh_binaries_info = toolchain.sh_binaries_info + + # The explicit RUNFILES_DIR/RUNFILES_MANIFEST_FILE is a workaround for + # https://github.com/bazelbuild/bazel/issues/15486 + tools_env = { + "RUNFILES_DIR": toolchain.tool[DefaultInfo].files_to_run.runfiles_manifest.dirname, + "RUNFILES_MANIFEST_FILE": toolchain.tool[DefaultInfo].files_to_run.runfiles_manifest.path, + } + (tools_inputs, tools_manifest) = ctx.resolve_tools(tools = [toolchain.tool]) + + ctx.actions.run( + executable = sh_binaries_info.executables["grep"], + env = tools_env, # Pass the environment into the action. + inputs = tools_inputs, + input_manifests = tools_manifest, + ... + ) +``` + +*Defining a toolchain* + +A hermetic POSIX toolchain can be defined by capturing an `sh_binaries` bundle +that provides the required tools. For example: + +```bzl +sh_binaries( + name = "commands", + srcs = [ + ... + ], +) + +sh_posix_hermetic_toolchain( + name = "posix", + cmds = ":commands", +) + +toolchain( + name = "posix_toolchain", + toolchain = ":posix", + toolchain_type = "@rules_sh//sh/posix:toolchain_type", + exec_compatible_with = [ + ... + ], + target_compatible_with = [ + ... + ], +) +``` +""", ) posix_hermetic = struct( From a671df2bfeefe03e965a1444acf8134108d8926e Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Fri, 2 Sep 2022 17:38:18 +0200 Subject: [PATCH 09/12] Add changelog entry --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bab329..20012d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/). [Unreleased]: https://github.com/tweag/rules_sh/compare/v0.3.0...HEAD +### Added + +- The new experimental `sh_posix_hermetic_toolchain` rule provides a hermetic + alternative to `sh_posix_toolchain` based on binary bundles defined by + `sh_binaries`. + See [PR #34][#34]. + +[#34]: https://github.com/tweag/rules_sh/issues/34 + ## [0.3.0] - 2022-07-19 [0.3.0]: https://github.com/tweag/rules_sh/compare/v0.2.0...v0.3.0 From 9b641e84a842313a0621ddb3ba8877a5be349bdc Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 5 Sep 2022 17:39:02 +0200 Subject: [PATCH 10/12] Avoid runfiles dependency for true/false sh_binary for a Shell script creates a wrapper binary that relies on the runfiles mechanism to discover the corresponding shell script at runtime. This introduces an implicit dependency on the runfiles mechanism. The purpose of the true/false toolchain is to test sh_binaries that don't depend on runfiles, therefore the shell script approach is not appropriate. This uses C++ binaries instead. --- tests/posix_hermetic/false.cc | 4 ++ tests/posix_hermetic/false.sh | 3 - tests/posix_hermetic/posix_hermetic_test.bzl | 68 ++++++++++---------- tests/posix_hermetic/true.cc | 4 ++ tests/posix_hermetic/true.sh | 3 - 5 files changed, 42 insertions(+), 40 deletions(-) create mode 100644 tests/posix_hermetic/false.cc delete mode 100755 tests/posix_hermetic/false.sh create mode 100644 tests/posix_hermetic/true.cc delete mode 100755 tests/posix_hermetic/true.sh diff --git a/tests/posix_hermetic/false.cc b/tests/posix_hermetic/false.cc new file mode 100644 index 0000000..d404e74 --- /dev/null +++ b/tests/posix_hermetic/false.cc @@ -0,0 +1,4 @@ +int main() { + // Intentionally inverted to distinguish from the builtin false command. + return 0; +} diff --git a/tests/posix_hermetic/false.sh b/tests/posix_hermetic/false.sh deleted file mode 100755 index a447767..0000000 --- a/tests/posix_hermetic/false.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -# Intentionally inverted to distinguish from the builtin false command. -exit 0 diff --git a/tests/posix_hermetic/posix_hermetic_test.bzl b/tests/posix_hermetic/posix_hermetic_test.bzl index dd9db6b..67af9a9 100644 --- a/tests/posix_hermetic/posix_hermetic_test.bzl +++ b/tests/posix_hermetic/posix_hermetic_test.bzl @@ -124,49 +124,49 @@ def _test_unrecognized_tool_toolchain(): target_under_test = ":posix-toolchain-unrecognized", ) -# shell scripts toolchain ############################################ +# local binaries toolchian ########################################### # A toolchain that depends on local files, but has no further runtime # dependencies, like runfiles resolution. -def _shell_scripts_toolchain(): - native.sh_binary( +def _local_binaries_toolchain(): + native.cc_binary( name = "false", - srcs = ["false.sh"], + srcs = ["false.cc"], ) - native.sh_binary( + native.cc_binary( name = "true", - srcs = ["true.sh"], + srcs = ["true.cc"], ) sh_binaries( - name = "binaries-shell-scripts", + name = "binaries-local-binaries", srcs = [ "false", "true", ], ) sh_posix_hermetic_toolchain( - name = "posix-toolchain-shell-scripts", - cmds = ":binaries-shell-scripts", + name = "posix-toolchain-local-binaries", + cmds = ":binaries-local-binaries", ) native.toolchain( - name = "toolchain-shell-scripts", - toolchain = ":posix-toolchain-shell-scripts", + name = "toolchain-local-binaries", + toolchain = ":posix-toolchain-local-binaries", toolchain_type = "//sh/posix:toolchain_type", ) -def _shell_scripts_toolchain_transition_impl(settings, attr): +def _local_binaries_toolchain_transition_impl(settings, attr): return { - "//command_line_option:extra_toolchains": "//tests/posix_hermetic:toolchain-shell-scripts", + "//command_line_option:extra_toolchains": "//tests/posix_hermetic:toolchain-local-binaries", } -_shell_scripts_toolchain_transition = transition( - implementation = _shell_scripts_toolchain_transition_impl, +_local_binaries_toolchain_transition = transition( + implementation = _local_binaries_toolchain_transition_impl, inputs = [], outputs = ["//command_line_option:extra_toolchains"], ) -def _use_shell_scripts_toolchain_impl(ctx): +def _use_local_binaries_toolchain_impl(ctx): src = ctx.attr.src[DefaultInfo] return [ DefaultInfo( @@ -177,9 +177,9 @@ def _use_shell_scripts_toolchain_impl(ctx): ), ] -_use_shell_scripts_toolchain = rule( - _use_shell_scripts_toolchain_impl, - cfg = _shell_scripts_toolchain_transition, +_use_local_binaries_toolchain = rule( + _use_local_binaries_toolchain_impl, + cfg = _local_binaries_toolchain_transition, attrs = { "src": attr.label(), "_allowlist_function_transition": attr.label( @@ -188,7 +188,7 @@ _use_shell_scripts_toolchain = rule( }, ) -def _shell_scripts_toolchain_test_impl(ctx): +def _local_binaries_toolchain_test_impl(ctx): env = analysistest.begin(ctx) toolchain = analysistest.target_under_test(env)[platform_common.ToolchainInfo] @@ -288,8 +288,8 @@ def _shell_scripts_toolchain_test_impl(ctx): return analysistest.end(env) -shell_scripts_toolchain_test = analysistest.make( - _shell_scripts_toolchain_test_impl, +local_binaries_toolchain_test = analysistest.make( + _local_binaries_toolchain_test_impl, attrs = { "false_binary": attr.label( executable = True, @@ -310,11 +310,11 @@ shell_scripts_toolchain_test = analysistest.make( }, ) -def _test_shell_scripts_toolchain(): - _shell_scripts_toolchain() - shell_scripts_toolchain_test( - name = "shell_scripts_toolchain_test", - target_under_test = ":posix-toolchain-shell-scripts", +def _test_local_binaries_toolchain(): + _local_binaries_toolchain() + local_binaries_toolchain_test( + name = "local_binaries_toolchain_test", + target_under_test = ":posix-toolchain-local-binaries", false_binary = ":false", true_binary = ":true", ) @@ -381,7 +381,7 @@ OUT="$2" _custom_rule = rule( _custom_rule_impl, - cfg = _shell_scripts_toolchain_transition, + cfg = _local_binaries_toolchain_transition, toolchains = ["//sh/posix:toolchain_type"], attrs = { "_allowlist_function_transition": attr.label( @@ -408,12 +408,12 @@ custom_rule_test = analysistest.make( attrs = { "false_binary": attr.label( executable = True, - # The _shell_scripts_toolchain_transition places the toolchain + # The _local_binaries_toolchain_transition places the toolchain # provided binary under a different configuration than the # reference binary would be under the regular `host` configuration. # We apply the same transition to the reference to align the # configurations. - cfg = _shell_scripts_toolchain_transition, + cfg = _local_binaries_toolchain_transition, ), "_allowlist_function_transition": attr.label( default = "@bazel_tools//tools/allowlists/function_transition_allowlist", @@ -472,11 +472,11 @@ export PATH="$(_POSIX_PATH)" """, toolchains = [posix_hermetic.MAKE_VARIABLES], ) - _use_shell_scripts_toolchain( + _use_local_binaries_toolchain( name = "genrule_explicit_transitioned", src = ":genrule_explicit", ) - _use_shell_scripts_toolchain( + _use_local_binaries_toolchain( name = "genrule_path_transitioned", src = ":genrule_path", ) @@ -712,7 +712,7 @@ with_runfiles $(POSIX_ECHO) message >>$(OUTS) def posix_hermetic_test_suite(name): _test_empty_toolchain() _test_unrecognized_tool_toolchain() - _test_shell_scripts_toolchain() + _test_local_binaries_toolchain() _test_custom_rule() _test_genrule() _test_runfiles_toolchain() @@ -724,7 +724,7 @@ def posix_hermetic_test_suite(name): tests = [ ":empty_toolchain_test", ":unrecognized_tool_toolchain_test", - ":shell_scripts_toolchain_test", + ":local_binaries_toolchain_test", ":custom_rule_test", ":genrule_test", ":runfiles_toolchain_test", diff --git a/tests/posix_hermetic/true.cc b/tests/posix_hermetic/true.cc new file mode 100644 index 0000000..3b65bc7 --- /dev/null +++ b/tests/posix_hermetic/true.cc @@ -0,0 +1,4 @@ +int main() { + // Intentionally inverted to distinguish from the builtin true command. + return 1; +} diff --git a/tests/posix_hermetic/true.sh b/tests/posix_hermetic/true.sh deleted file mode 100755 index 01ca55a..0000000 --- a/tests/posix_hermetic/true.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -# Intentionally inverted to distinguish from the builtin false command. -exit 1 From 64f44e895a8214863546efebe8dfa1c3fe0ce974 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Tue, 13 Dec 2022 11:13:00 +0100 Subject: [PATCH 11/12] Correct path in error message --- sh/experimental/posix_hermetic.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sh/experimental/posix_hermetic.bzl b/sh/experimental/posix_hermetic.bzl index d7e5f60..504215e 100644 --- a/sh/experimental/posix_hermetic.bzl +++ b/sh/experimental/posix_hermetic.bzl @@ -23,7 +23,7 @@ def _sh_posix_hermetic_toolchain_impl(ctx): if cmd not in _commands ] if unrecognizeds: - fail("Unrecognized commands in keys of sh_posix_hermetic_toolchain's \"cmds\" attribute: {}. See posix_hermetic.commands in @rules_sh//sh:posix_hermetic.bzl for the list of recognized commands.".format(", ".join(unrecognizeds))) + fail("Unrecognized commands in keys of sh_posix_hermetic_toolchain's \"cmds\" attribute: {}. See posix_hermetic.commands in @rules_sh//sh/experimental:posix_hermetic.bzl for the list of recognized commands.".format(", ".join(unrecognizeds))) return [platform_common.ToolchainInfo( sh_binaries_info = sh_binaries_info, From 32e9b6fb7514d7a2223a886a542354b9c64188e9 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Tue, 13 Dec 2022 11:14:26 +0100 Subject: [PATCH 12/12] Fix assert_eq messages --- tests/posix_hermetic/custom_rule_output_test.sh | 4 ++-- tests/posix_hermetic/genrule_explicit_output_test.sh | 2 +- tests/posix_hermetic/genrule_path_output_test.sh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/posix_hermetic/custom_rule_output_test.sh b/tests/posix_hermetic/custom_rule_output_test.sh index 8a0179a..a116937 100755 --- a/tests/posix_hermetic/custom_rule_output_test.sh +++ b/tests/posix_hermetic/custom_rule_output_test.sh @@ -22,7 +22,7 @@ EXPECTED="1 0" ACTUAL="$(cat "$(rlocation rules_sh/tests/posix_hermetic/custom_rule_explicit.txt)")" -assert_eq "$EXPECTED" "$ACTUAL" "custom_rule.txt" +assert_eq "$EXPECTED" "$ACTUAL" "custom_rule_explicit.txt" ACTUAL="$(cat "$(rlocation rules_sh/tests/posix_hermetic/custom_rule_path.txt)")" -assert_eq "$EXPECTED" "$ACTUAL" "custom_rule.txt" +assert_eq "$EXPECTED" "$ACTUAL" "custom_rule_path.txt" diff --git a/tests/posix_hermetic/genrule_explicit_output_test.sh b/tests/posix_hermetic/genrule_explicit_output_test.sh index f87d513..00b60a0 100755 --- a/tests/posix_hermetic/genrule_explicit_output_test.sh +++ b/tests/posix_hermetic/genrule_explicit_output_test.sh @@ -22,4 +22,4 @@ EXPECTED="1 0" ACTUAL="$(cat "$(rlocation rules_sh/tests/posix_hermetic/genrule_explicit.txt)")" -assert_eq "$EXPECTED" "$ACTUAL" "custom_rule.txt" +assert_eq "$EXPECTED" "$ACTUAL" "genrule_explicit.txt" diff --git a/tests/posix_hermetic/genrule_path_output_test.sh b/tests/posix_hermetic/genrule_path_output_test.sh index 81d1d63..8e4e273 100755 --- a/tests/posix_hermetic/genrule_path_output_test.sh +++ b/tests/posix_hermetic/genrule_path_output_test.sh @@ -22,4 +22,4 @@ EXPECTED="1 0" ACTUAL="$(cat "$(rlocation rules_sh/tests/posix_hermetic/genrule_path.txt)")" -assert_eq "$EXPECTED" "$ACTUAL" "custom_rule.txt" +assert_eq "$EXPECTED" "$ACTUAL" "genrule_path.txt"