From 5e06f39e88c537b23fa322fae877db22aa41f1f9 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 20 Dec 2023 16:23:40 +0100 Subject: [PATCH 01/25] Add `env` and `env_inherit` to `native_binary` and `native_test` --- rules/native_binary.bzl | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/rules/native_binary.bzl b/rules/native_binary.bzl index b33347b3..1edeb265 100644 --- a/rules/native_binary.bzl +++ b/rules/native_binary.bzl @@ -41,11 +41,17 @@ def _impl_rule(ctx): runfiles = runfiles.merge(d[DefaultInfo].default_runfiles) runfiles = runfiles.merge(ctx.attr.src[DefaultInfo].default_runfiles) - return DefaultInfo( - executable = out, - files = depset([out]), - runfiles = runfiles, - ) + return [ + DefaultInfo( + executable = out, + files = depset([out]), + runfiles = runfiles, + ), + RunEnvironmentInfo( + environment = ctx.attr.env, + inherited_environment = ctx.attr.env_inherit, + ), + ] _ATTRS = { "src": attr.label( @@ -65,6 +71,8 @@ _ATTRS = { ), # "out" is attr.string instead of attr.output, so that it is select()'able. "out": attr.string(mandatory = True, doc = "An output name for the copy of the binary"), + "env": attr.string_dict(doc = "Environment to provide to the execution of the binary", default = {}), + "env_inherit": attr.string_list(doc = "Environment to preserve for the execution of the binary", default = []), } native_binary = rule( From f59ff4a33512f253bf35a7ebb96e09fdc2b9c33d Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Dec 2023 11:30:41 +0100 Subject: [PATCH 02/25] Add test for `env` and `env_inherit` --- tests/native_binary/BUILD | 31 +++++++++++++++++++++++++++++++ tests/native_binary/assertenv.cc | 24 ++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 tests/native_binary/assertenv.cc diff --git a/tests/native_binary/BUILD b/tests/native_binary/BUILD index 997270f6..f9bf5a37 100644 --- a/tests/native_binary/BUILD +++ b/tests/native_binary/BUILD @@ -30,6 +30,11 @@ cc_binary( deps = ["@bazel_tools//tools/cpp/runfiles"], ) +cc_binary( + name="assertenv", + srcs=["assertenv.cc"], +) + # A rule that copies "assertarg"'s output as an opaque executable, simulating a # binary that's not built from source and needs to be wrapped in native_binary. copy_file( @@ -54,6 +59,16 @@ copy_file( is_executable = True, ) +copy_file( + name="copy_assertenv_exe", + src=":assertenv", + # On Windows we need the ".exe" extension. + # On other platforms the extension doesn't matter. + # Therefore we can use ".exe" on every platform. + out="assertenv_copy.exe", + is_executable=True, +) + _ARGS = [ "'a b'", "c\\ d", @@ -115,3 +130,19 @@ native_test( # Therefore we can use ".exe" on every platform. out = "data_from_binary_test.exe", ) + +native_test( + name="env_test", + src=":copy_assertenv_exe", + # On Windows we need the ".exe" extension. + # On other platforms the extension doesn't matter. + # Therefore we can use ".exe" on every platform. + out="env_test.exe", + env={ + "TEST_ENV_VAR": "test_env_var_value", + }, + env_inherit=[ + "HOME", # for POSIX + "HOMEPATH", # for Windows + ], +) diff --git a/tests/native_binary/assertenv.cc b/tests/native_binary/assertenv.cc new file mode 100644 index 00000000..4f33f837 --- /dev/null +++ b/tests/native_binary/assertenv.cc @@ -0,0 +1,24 @@ +#include +#include + +int main(int argc, char **argv, char **envp) { + bool test_env_found = false; + bool home_found = false; + for (char **env = envp; *env != NULL; ++env) { + if (strcmp(*env, "TEST_ENV_VAR=test_env_var_value") == 0) { + test_env_found = true; + } + if (strncmp(*env, "HOME=", strlen("HOME=")) == 0 || + strncasecmp(*env, "HOMEPATH=", strlen("HOMEPATH=")) == 0) { + home_found = true; + } + } + if (!test_env_found) { + fprintf(stderr, + "expected TEST_ENV_VAR=test_env_var_value in environment\n"); + } + if (!home_found) { + fprintf(stderr, "expected HOME or HOMEPATH in environment\n"); + } + return test_env_found && home_found ? 0 : 1; +} From 4dc1f9ab5575a6c1026aa349884d743b885aebb8 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Dec 2023 11:33:04 +0100 Subject: [PATCH 03/25] Make env and env_inherit parameters of native_binary depend on bazel version --- MODULE.bazel | 2 ++ extension.bzl | 6 ++++++ rules/native_binary.bzl | 41 ++++++++++++++++++++++++++++++++--------- workspace.bzl | 24 ++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 extension.bzl diff --git a/MODULE.bazel b/MODULE.bazel index 298974a3..99800914 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -11,6 +11,8 @@ register_toolchains( ) bazel_dep(name = "platforms", version = "0.0.4") +globals = use_extension("//:extension.bzl", "globals_extension") +use_repo(globals, "bazel_skylib_globals") ### INTERNAL ONLY - lines after this are not included in the release packaging. diff --git a/extension.bzl b/extension.bzl new file mode 100644 index 00000000..3727a355 --- /dev/null +++ b/extension.bzl @@ -0,0 +1,6 @@ +load("@bazel_skylib//:workspace.bzl", "globals_repo") + +def _globals_extension_impl(module_ctx): + globals_repo() + +globals_extension = module_extension(_globals_extension_impl) diff --git a/rules/native_binary.bzl b/rules/native_binary.bzl index 1edeb265..1abfe3c1 100644 --- a/rules/native_binary.bzl +++ b/rules/native_binary.bzl @@ -20,7 +20,15 @@ do, but they run the wrapped binary directly, instead of through Bash, so they don't depend on Bash and work with --shell_executable="". """ +load("@bazel_skylib//lib:versions.bzl", "versions") +load("@bazel_skylib_globals//:globals.bzl", "globals") + def _impl_rule(ctx): + if not globals.RunEnvironmentInfo: + for attr in ("env", "env_inherit"): + if getattr(ctx.attr, attr, None): + fail("Attribute %s specified for %s is only supported with bazel >= 5.3.0" % + (attr, ctx.label)) out = ctx.actions.declare_file(ctx.attr.out) ctx.actions.symlink( target_file = ctx.executable.src, @@ -41,17 +49,21 @@ def _impl_rule(ctx): runfiles = runfiles.merge(d[DefaultInfo].default_runfiles) runfiles = runfiles.merge(ctx.attr.src[DefaultInfo].default_runfiles) - return [ + ret = [ DefaultInfo( executable = out, files = depset([out]), runfiles = runfiles, ), - RunEnvironmentInfo( - environment = ctx.attr.env, - inherited_environment = ctx.attr.env_inherit, - ), ] + if globals.RunEnvironmentInfo: + ret += [ + globals.RunEnvironmentInfo( + environment = ctx.attr.env, + inherited_environment = getattr(ctx.attr, "env_inherit", []), + ), + ] + return ret _ATTRS = { "src": attr.label( @@ -67,14 +79,25 @@ _ATTRS = { "data": attr.label_list( allow_files = True, doc = "data dependencies. See" + - " https://bazel.build/reference/be/common-definitions#typical.data", + " https://bazel.build/reference/be/common-definitions#typical.data", ), # "out" is attr.string instead of attr.output, so that it is select()'able. "out": attr.string(mandatory = True, doc = "An output name for the copy of the binary"), - "env": attr.string_dict(doc = "Environment to provide to the execution of the binary", default = {}), - "env_inherit": attr.string_list(doc = "Environment to preserve for the execution of the binary", default = []), + "env": attr.string_dict( + doc = "additional environment variables to set when the target is executed by " + + "`bazel`", + default = {}, + ), } +_TEST_ATTRS = dict(_ATTRS, + env_inherit = attr.string_list( + doc = "additional environment variables to inherit from the external " + + "environment when the test is executed by `bazel test`", + default = [], + ), +) + native_binary = rule( implementation = _impl_rule, attrs = _ATTRS, @@ -89,7 +112,7 @@ in genrule.tools for example. You can also augment the binary with runfiles. native_test = rule( implementation = _impl_rule, - attrs = _ATTRS, + attrs = _TEST_ATTRS, test = True, doc = """ Wraps a pre-built binary or script with a test rule. diff --git a/workspace.bzl b/workspace.bzl index 29fd1e35..4f1e3080 100644 --- a/workspace.bzl +++ b/workspace.bzl @@ -15,7 +15,31 @@ """Dependency registration helpers for repositories which need to load bazel-skylib.""" load("@bazel_skylib//lib:unittest.bzl", "register_unittest_toolchains") +load("@bazel_skylib//lib:versions.bzl", "versions") + +def _globals_repo_impl(repository_ctx): + globals = { + "RunEnvironmentInfo": "5.3.0", + } + globals = { + k: k if versions.is_at_least(v, versions.get()) else "None" for k, v in globals.items() + } + + repository_ctx.file("globals.bzl", + "globals = struct(\n%s\n)\n" % "\n".join( + [" %s = %s" % item for item in globals.items()] + )) + repository_ctx.file("BUILD.bazel", "exports_files(['globals.bzl'])\n") + +_globals_repo = repository_rule( + implementation = _globals_repo_impl, + local = True, # required to make sure the version is updated if the bazel server restarts +) + +def globals_repo(): + _globals_repo(name = "bazel_skylib_globals") def bazel_skylib_workspace(): """Registers toolchains and declares repository dependencies of the bazel_skylib repository.""" register_unittest_toolchains() + globals_repo() From 10ea0af2a08c7df335fc45e31fb55124271e53b2 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Dec 2023 11:33:30 +0100 Subject: [PATCH 04/25] Update docs --- docs/BUILD | 1 + docs/native_binary_doc.md | 7 +++++-- docs/private/stardoc_with_diff_test.bzl | 5 +++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/BUILD b/docs/BUILD index a809f2f0..3d89f77d 100644 --- a/docs/BUILD +++ b/docs/BUILD @@ -66,6 +66,7 @@ stardoc_with_diff_test( name = "native_binary", bzl_library_target = "//rules:native_binary", out_label = "//docs:native_binary_doc.md", + deps = ["//lib:versions.bzl", "@bazel_skylib_globals//:globals.bzl"], ) stardoc_with_diff_test( diff --git a/docs/native_binary_doc.md b/docs/native_binary_doc.md index 2b603bed..21e41407 100755 --- a/docs/native_binary_doc.md +++ b/docs/native_binary_doc.md @@ -13,7 +13,7 @@ don't depend on Bash and work with --shell_executable="". ## native_binary
-native_binary(name, data, out, src)
+native_binary(name, data, env, out, src)
 
@@ -30,6 +30,7 @@ in genrule.tools for example. You can also augment the binary with runfiles. | :------------- | :------------- | :------------- | :------------- | :------------- | | name | A unique name for this target. | Name | required | | | data | data dependencies. See https://bazel.build/reference/be/common-definitions#typical.data | List of labels | optional | [] | +| env | additional environment variables to set when the target is executed by bazel | Dictionary: String -> String | optional | {} | | out | An output name for the copy of the binary | String | required | | | src | path of the pre-built executable | Label | required | | @@ -39,7 +40,7 @@ in genrule.tools for example. You can also augment the binary with runfiles. ## native_test
-native_test(name, data, out, src)
+native_test(name, data, env, env_inherit, out, src)
 
@@ -56,6 +57,8 @@ the binary with runfiles. | :------------- | :------------- | :------------- | :------------- | :------------- | | name | A unique name for this target. | Name | required | | | data | data dependencies. See https://bazel.build/reference/be/common-definitions#typical.data | List of labels | optional | [] | +| env | additional environment variables to set when the target is executed by bazel | Dictionary: String -> String | optional | {} | +| env_inherit | additional environment variables to inherit from the external environment when the test is executed by bazel test | List of strings | optional | [] | | out | An output name for the copy of the binary | String | required | | | src | path of the pre-built executable | Label | required | | diff --git a/docs/private/stardoc_with_diff_test.bzl b/docs/private/stardoc_with_diff_test.bzl index a8542f3f..ac353b31 100644 --- a/docs/private/stardoc_with_diff_test.bzl +++ b/docs/private/stardoc_with_diff_test.bzl @@ -30,7 +30,8 @@ load("@io_bazel_stardoc//stardoc:stardoc.bzl", "stardoc") def stardoc_with_diff_test( name, bzl_library_target, - out_label): + out_label, + deps = None): """Creates a stardoc target coupled with a `diff_test` for a given `bzl_library`. This is helpful for minimizing boilerplate in repos with lots of stardoc targets. @@ -47,7 +48,7 @@ def stardoc_with_diff_test( name = name, out = out_file.replace(".md", "-docgen.md"), input = bzl_library_target + ".bzl", - deps = [bzl_library_target], + deps = [bzl_library_target] + (deps or []), ) # Ensure that the generated MD has been updated in the local source tree From 70e6b777e0b5bfacb0309c19cb36fb0a0e6872a6 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Dec 2023 11:42:54 +0100 Subject: [PATCH 05/25] Update patch indexes --- MODULE.bazel-remove-override.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MODULE.bazel-remove-override.patch b/MODULE.bazel-remove-override.patch index 0f307770..e4c6ce00 100644 --- a/MODULE.bazel-remove-override.patch +++ b/MODULE.bazel-remove-override.patch @@ -1,6 +1,6 @@ --- MODULE.bazel +++ MODULE.bazel -@@ -22,8 +22,8 @@ +@@ -24,8 +24,8 @@ # Needed for bazelci and for building distribution tarballs. # If using an unreleased version of bazel_skylib via git_override, apply # MODULE.bazel-remove-override.patch to remove the following lines: From 6e83bfe7ef0e09079f0a15b6f7f1593c70ea1645 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Dec 2023 13:00:05 +0100 Subject: [PATCH 06/25] Fix windows compilation of `assertenv.cc` --- tests/native_binary/assertenv.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/native_binary/assertenv.cc b/tests/native_binary/assertenv.cc index 4f33f837..466def13 100644 --- a/tests/native_binary/assertenv.cc +++ b/tests/native_binary/assertenv.cc @@ -1,6 +1,16 @@ #include #include +#ifdef _WIN32 +bool is_home_env(const char *env) { + return _strnicmp(env, "HOMEPATH=", strlen("HOMEPATH=")) == 0; +} +#else +bool is_home_env(const char *env) { + return strncmp(env, "HOME=", strlen("HOME=")) == 0; +} +#endif + int main(int argc, char **argv, char **envp) { bool test_env_found = false; bool home_found = false; @@ -8,8 +18,7 @@ int main(int argc, char **argv, char **envp) { if (strcmp(*env, "TEST_ENV_VAR=test_env_var_value") == 0) { test_env_found = true; } - if (strncmp(*env, "HOME=", strlen("HOME=")) == 0 || - strncasecmp(*env, "HOMEPATH=", strlen("HOMEPATH=")) == 0) { + if (is_home_env(*env)) { home_found = true; } } From d53f28622244327f61679ae39c90980081fa6352 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Dec 2023 13:02:49 +0100 Subject: [PATCH 07/25] Autoformat --- rules/native_binary.bzl | 7 ++++--- tests/native_binary/BUILD | 22 +++++++++++----------- workspace.bzl | 11 +++++++---- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/rules/native_binary.bzl b/rules/native_binary.bzl index 1abfe3c1..4feb1208 100644 --- a/rules/native_binary.bzl +++ b/rules/native_binary.bzl @@ -28,7 +28,7 @@ def _impl_rule(ctx): for attr in ("env", "env_inherit"): if getattr(ctx.attr, attr, None): fail("Attribute %s specified for %s is only supported with bazel >= 5.3.0" % - (attr, ctx.label)) + (attr, ctx.label)) out = ctx.actions.declare_file(ctx.attr.out) ctx.actions.symlink( target_file = ctx.executable.src, @@ -79,7 +79,7 @@ _ATTRS = { "data": attr.label_list( allow_files = True, doc = "data dependencies. See" + - " https://bazel.build/reference/be/common-definitions#typical.data", + " https://bazel.build/reference/be/common-definitions#typical.data", ), # "out" is attr.string instead of attr.output, so that it is select()'able. "out": attr.string(mandatory = True, doc = "An output name for the copy of the binary"), @@ -90,7 +90,8 @@ _ATTRS = { ), } -_TEST_ATTRS = dict(_ATTRS, +_TEST_ATTRS = dict( + _ATTRS, env_inherit = attr.string_list( doc = "additional environment variables to inherit from the external " + "environment when the test is executed by `bazel test`", diff --git a/tests/native_binary/BUILD b/tests/native_binary/BUILD index f9bf5a37..77161498 100644 --- a/tests/native_binary/BUILD +++ b/tests/native_binary/BUILD @@ -31,8 +31,8 @@ cc_binary( ) cc_binary( - name="assertenv", - srcs=["assertenv.cc"], + name = "assertenv", + srcs = ["assertenv.cc"], ) # A rule that copies "assertarg"'s output as an opaque executable, simulating a @@ -60,13 +60,13 @@ copy_file( ) copy_file( - name="copy_assertenv_exe", - src=":assertenv", + name = "copy_assertenv_exe", + src = ":assertenv", # On Windows we need the ".exe" extension. # On other platforms the extension doesn't matter. # Therefore we can use ".exe" on every platform. - out="assertenv_copy.exe", - is_executable=True, + out = "assertenv_copy.exe", + is_executable = True, ) _ARGS = [ @@ -132,16 +132,16 @@ native_test( ) native_test( - name="env_test", - src=":copy_assertenv_exe", + name = "env_test", + src = ":copy_assertenv_exe", # On Windows we need the ".exe" extension. # On other platforms the extension doesn't matter. # Therefore we can use ".exe" on every platform. - out="env_test.exe", - env={ + out = "env_test.exe", + env = { "TEST_ENV_VAR": "test_env_var_value", }, - env_inherit=[ + env_inherit = [ "HOME", # for POSIX "HOMEPATH", # for Windows ], diff --git a/workspace.bzl b/workspace.bzl index 4f1e3080..f774fea8 100644 --- a/workspace.bzl +++ b/workspace.bzl @@ -22,13 +22,16 @@ def _globals_repo_impl(repository_ctx): "RunEnvironmentInfo": "5.3.0", } globals = { - k: k if versions.is_at_least(v, versions.get()) else "None" for k, v in globals.items() + k: k if versions.is_at_least(v, versions.get()) else "None" + for k, v in globals.items() } - repository_ctx.file("globals.bzl", + repository_ctx.file( + "globals.bzl", "globals = struct(\n%s\n)\n" % "\n".join( - [" %s = %s" % item for item in globals.items()] - )) + [" %s = %s" % item for item in globals.items()], + ), + ) repository_ctx.file("BUILD.bazel", "exports_files(['globals.bzl'])\n") _globals_repo = repository_rule( From 336176fa1eea97ce44656fc8b797779da3fa8120 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Dec 2023 13:11:28 +0100 Subject: [PATCH 08/25] Autoformat correctly --- MODULE.bazel | 1 + MODULE.bazel-remove-override.patch | 2 +- docs/BUILD | 5 ++++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 99800914..baef312e 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -11,6 +11,7 @@ register_toolchains( ) bazel_dep(name = "platforms", version = "0.0.4") + globals = use_extension("//:extension.bzl", "globals_extension") use_repo(globals, "bazel_skylib_globals") diff --git a/MODULE.bazel-remove-override.patch b/MODULE.bazel-remove-override.patch index e4c6ce00..2b9e7904 100644 --- a/MODULE.bazel-remove-override.patch +++ b/MODULE.bazel-remove-override.patch @@ -1,6 +1,6 @@ --- MODULE.bazel +++ MODULE.bazel -@@ -24,8 +24,8 @@ +@@ -25,8 +25,8 @@ # Needed for bazelci and for building distribution tarballs. # If using an unreleased version of bazel_skylib via git_override, apply # MODULE.bazel-remove-override.patch to remove the following lines: diff --git a/docs/BUILD b/docs/BUILD index 3d89f77d..953051f7 100644 --- a/docs/BUILD +++ b/docs/BUILD @@ -66,7 +66,10 @@ stardoc_with_diff_test( name = "native_binary", bzl_library_target = "//rules:native_binary", out_label = "//docs:native_binary_doc.md", - deps = ["//lib:versions.bzl", "@bazel_skylib_globals//:globals.bzl"], + deps = [ + "//lib:versions.bzl", + "@bazel_skylib_globals//:globals.bzl", + ], ) stardoc_with_diff_test( From b2b66770483ac5737682ac709fb6d7be98174329 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Dec 2023 13:16:43 +0100 Subject: [PATCH 09/25] Tweak `env_test` for Windows --- tests/native_binary/BUILD | 3 +-- tests/native_binary/assertenv.cc | 10 ++++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/native_binary/BUILD b/tests/native_binary/BUILD index 77161498..3174e952 100644 --- a/tests/native_binary/BUILD +++ b/tests/native_binary/BUILD @@ -142,7 +142,6 @@ native_test( "TEST_ENV_VAR": "test_env_var_value", }, env_inherit = [ - "HOME", # for POSIX - "HOMEPATH", # for Windows + "HOME", # only checked on POSIX ], ) diff --git a/tests/native_binary/assertenv.cc b/tests/native_binary/assertenv.cc index 466def13..d5bea742 100644 --- a/tests/native_binary/assertenv.cc +++ b/tests/native_binary/assertenv.cc @@ -2,11 +2,9 @@ #include #ifdef _WIN32 -bool is_home_env(const char *env) { - return _strnicmp(env, "HOMEPATH=", strlen("HOMEPATH=")) == 0; -} +bool check_home(const char *env) { return true; } #else -bool is_home_env(const char *env) { +bool check_home(const char *env) { return strncmp(env, "HOME=", strlen("HOME=")) == 0; } #endif @@ -18,7 +16,7 @@ int main(int argc, char **argv, char **envp) { if (strcmp(*env, "TEST_ENV_VAR=test_env_var_value") == 0) { test_env_found = true; } - if (is_home_env(*env)) { + if (check_home(*env)) { home_found = true; } } @@ -27,7 +25,7 @@ int main(int argc, char **argv, char **envp) { "expected TEST_ENV_VAR=test_env_var_value in environment\n"); } if (!home_found) { - fprintf(stderr, "expected HOME or HOMEPATH in environment\n"); + fprintf(stderr, "expected HOME in environment\n"); } return test_env_found && home_found ? 0 : 1; } From df44fa9bb6550ba819f1d069a3d113183d3125ce Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Dec 2023 14:41:15 +0100 Subject: [PATCH 10/25] Lint --- docs/private/stardoc_with_diff_test.bzl | 1 + extension.bzl | 19 ++++++++++++++++++- rules/native_binary.bzl | 5 ++--- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/docs/private/stardoc_with_diff_test.bzl b/docs/private/stardoc_with_diff_test.bzl index ac353b31..24be4a3a 100644 --- a/docs/private/stardoc_with_diff_test.bzl +++ b/docs/private/stardoc_with_diff_test.bzl @@ -40,6 +40,7 @@ def stardoc_with_diff_test( name: the stardoc target name bzl_library_target: the label of the `bzl_library` target to generate documentation for out_label: the label of the output MD file + deps: additional files loaded by the bazel library, if any """ out_file = out_label.replace("//", "").replace(":", "/") diff --git a/extension.bzl b/extension.bzl index 3727a355..09b43ccc 100644 --- a/extension.bzl +++ b/extension.bzl @@ -1,6 +1,23 @@ +# Copyright 2023 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Module extension to load additional repositories""" + load("@bazel_skylib//:workspace.bzl", "globals_repo") -def _globals_extension_impl(module_ctx): +def _globals_extension_impl( + module_ctx, # @unused +): globals_repo() globals_extension = module_extension(_globals_extension_impl) diff --git a/rules/native_binary.bzl b/rules/native_binary.bzl index 4feb1208..b91a1c6d 100644 --- a/rules/native_binary.bzl +++ b/rules/native_binary.bzl @@ -20,7 +20,6 @@ do, but they run the wrapped binary directly, instead of through Bash, so they don't depend on Bash and work with --shell_executable="". """ -load("@bazel_skylib//lib:versions.bzl", "versions") load("@bazel_skylib_globals//:globals.bzl", "globals") def _impl_rule(ctx): @@ -57,12 +56,12 @@ def _impl_rule(ctx): ), ] if globals.RunEnvironmentInfo: - ret += [ + ret.append( globals.RunEnvironmentInfo( environment = ctx.attr.env, inherited_environment = getattr(ctx.attr, "env_inherit", []), ), - ] + ) return ret _ATTRS = { From 5a73fbef0e2b5210c0888e70360617da7334a5fd Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Dec 2023 14:44:28 +0100 Subject: [PATCH 11/25] Mention bazel version in native_binary docs --- docs/native_binary_doc.md | 6 +++--- rules/native_binary.bzl | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/native_binary_doc.md b/docs/native_binary_doc.md index 21e41407..84ad00db 100755 --- a/docs/native_binary_doc.md +++ b/docs/native_binary_doc.md @@ -30,7 +30,7 @@ in genrule.tools for example. You can also augment the binary with runfiles. | :------------- | :------------- | :------------- | :------------- | :------------- | | name | A unique name for this target. | Name | required | | | data | data dependencies. See https://bazel.build/reference/be/common-definitions#typical.data | List of labels | optional | [] | -| env | additional environment variables to set when the target is executed by bazel | Dictionary: String -> String | optional | {} | +| env | additional environment variables to set when the target is executed by bazel. Setting this requires bazel version 5.3.0 or later. | Dictionary: String -> String | optional | {} | | out | An output name for the copy of the binary | String | required | | | src | path of the pre-built executable | Label | required | | @@ -57,8 +57,8 @@ the binary with runfiles. | :------------- | :------------- | :------------- | :------------- | :------------- | | name | A unique name for this target. | Name | required | | | data | data dependencies. See https://bazel.build/reference/be/common-definitions#typical.data | List of labels | optional | [] | -| env | additional environment variables to set when the target is executed by bazel | Dictionary: String -> String | optional | {} | -| env_inherit | additional environment variables to inherit from the external environment when the test is executed by bazel test | List of strings | optional | [] | +| env | additional environment variables to set when the target is executed by bazel. Setting this requires bazel version 5.3.0 or later. | Dictionary: String -> String | optional | {} | +| env_inherit | additional environment variables to inherit from the external environment when the test is executed by bazel test. Setting this requires bazel version 5.3.0 or later. | List of strings | optional | [] | | out | An output name for the copy of the binary | String | required | | | src | path of the pre-built executable | Label | required | | diff --git a/rules/native_binary.bzl b/rules/native_binary.bzl index b91a1c6d..e258818b 100644 --- a/rules/native_binary.bzl +++ b/rules/native_binary.bzl @@ -84,7 +84,7 @@ _ATTRS = { "out": attr.string(mandatory = True, doc = "An output name for the copy of the binary"), "env": attr.string_dict( doc = "additional environment variables to set when the target is executed by " + - "`bazel`", + "`bazel`. Setting this requires bazel version 5.3.0 or later.", default = {}, ), } @@ -93,7 +93,8 @@ _TEST_ATTRS = dict( _ATTRS, env_inherit = attr.string_list( doc = "additional environment variables to inherit from the external " + - "environment when the test is executed by `bazel test`", + "environment when the test is executed by `bazel test`. " + + "Setting this requires bazel version 5.3.0 or later.", default = [], ), ) From 2453f162e77e5542b0bf647c42a23e90632f7876 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Dec 2023 14:48:25 +0100 Subject: [PATCH 12/25] Fix formatting --- extension.bzl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/extension.bzl b/extension.bzl index 09b43ccc..fc361793 100644 --- a/extension.bzl +++ b/extension.bzl @@ -16,8 +16,7 @@ load("@bazel_skylib//:workspace.bzl", "globals_repo") def _globals_extension_impl( - module_ctx, # @unused -): + module_ctx): # @unused globals_repo() globals_extension = module_extension(_globals_extension_impl) From 20acd194aa94d7bd3e86ea66cb84a25c78fb608a Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 21 Dec 2023 15:03:59 +0100 Subject: [PATCH 13/25] Generalize again test to windows --- tests/native_binary/BUILD | 3 ++- tests/native_binary/assertenv.cc | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/tests/native_binary/BUILD b/tests/native_binary/BUILD index 3174e952..496f01a4 100644 --- a/tests/native_binary/BUILD +++ b/tests/native_binary/BUILD @@ -142,6 +142,7 @@ native_test( "TEST_ENV_VAR": "test_env_var_value", }, env_inherit = [ - "HOME", # only checked on POSIX + "HOME", # for POSIX + "APPDATA", # for Windows ], ) diff --git a/tests/native_binary/assertenv.cc b/tests/native_binary/assertenv.cc index d5bea742..84015ca6 100644 --- a/tests/native_binary/assertenv.cc +++ b/tests/native_binary/assertenv.cc @@ -2,30 +2,30 @@ #include #ifdef _WIN32 -bool check_home(const char *env) { return true; } +#define OS_VAR "APPDATA" +#define strncasecmp _strnicmp #else -bool check_home(const char *env) { - return strncmp(env, "HOME=", strlen("HOME=")) == 0; -} +#define OS_VAR "HOME" #endif int main(int argc, char **argv, char **envp) { bool test_env_found = false; - bool home_found = false; + bool inherited_var_found = false; for (char **env = envp; *env != NULL; ++env) { + printf("%s\n", *env); if (strcmp(*env, "TEST_ENV_VAR=test_env_var_value") == 0) { test_env_found = true; } - if (check_home(*env)) { - home_found = true; + if (strncasecmp(*env, OS_VAR "=", strlen(OS_VAR "=")) == 0) { + inherited_var_found = true; } } if (!test_env_found) { fprintf(stderr, "expected TEST_ENV_VAR=test_env_var_value in environment\n"); } - if (!home_found) { - fprintf(stderr, "expected HOME in environment\n"); + if (!inherited_var_found) { + fprintf(stderr, "expected " OS_VAR " in environment\n"); } - return test_env_found && home_found ? 0 : 1; + return test_env_found && inherited_var_found ? 0 : 1; } From 9ce0e556e2121422442b2f851ac2323ae71edde3 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 11 Jan 2024 09:39:04 +0100 Subject: [PATCH 14/25] Use `bazel_features` --- MODULE.bazel | 8 ++++--- MODULE.bazel-remove-override.patch | 11 +++++---- docs/BUILD | 3 +-- docs/maintainers_guide.md | 7 ++++++ docs/native_binary_doc.md | 7 ++++++ extension.bzl | 22 ------------------ rules/native_binary.bzl | 12 ++++++---- workspace.bzl | 36 ++++++++---------------------- 8 files changed, 42 insertions(+), 64 deletions(-) delete mode 100644 extension.bzl diff --git a/MODULE.bazel b/MODULE.bazel index baef312e..ae3d0447 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -11,9 +11,7 @@ register_toolchains( ) bazel_dep(name = "platforms", version = "0.0.4") - -globals = use_extension("//:extension.bzl", "globals_extension") -use_repo(globals, "bazel_skylib_globals") +bazel_dep(name = "bazel_features", version = "1.2.0") ### INTERNAL ONLY - lines after this are not included in the release packaging. @@ -30,3 +28,7 @@ local_path_override( module_name = "bazel_skylib_gazelle_plugin", path = "gazelle", ) +local_path_override( + module_name = "bazel_features", + path = "bazel_features_stub", +) diff --git a/MODULE.bazel-remove-override.patch b/MODULE.bazel-remove-override.patch index 2b9e7904..34a549b0 100644 --- a/MODULE.bazel-remove-override.patch +++ b/MODULE.bazel-remove-override.patch @@ -1,6 +1,6 @@ --- MODULE.bazel +++ MODULE.bazel -@@ -25,8 +25,8 @@ +@@ -23,12 +23,3 @@ # Needed for bazelci and for building distribution tarballs. # If using an unreleased version of bazel_skylib via git_override, apply # MODULE.bazel-remove-override.patch to remove the following lines: @@ -9,8 +9,7 @@ - module_name = "bazel_skylib_gazelle_plugin", - path = "gazelle", -) -+# bazel_dep(name = "bazel_skylib_gazelle_plugin", dev_dependency = True) -+# local_path_override( -+# module_name = "bazel_skylib_gazelle_plugin", -+# path = "gazelle", -+# ) +-local_path_override( +- module_name = "bazel_features", +- path = "bazel_features_stub", +-) diff --git a/docs/BUILD b/docs/BUILD index 953051f7..c70f531e 100644 --- a/docs/BUILD +++ b/docs/BUILD @@ -67,8 +67,7 @@ stardoc_with_diff_test( bzl_library_target = "//rules:native_binary", out_label = "//docs:native_binary_doc.md", deps = [ - "//lib:versions.bzl", - "@bazel_skylib_globals//:globals.bzl", + "@bazel_features//:features.bzl", ], ) diff --git a/docs/maintainers_guide.md b/docs/maintainers_guide.md index f5408ce1..0deee320 100644 --- a/docs/maintainers_guide.md +++ b/docs/maintainers_guide.md @@ -121,6 +121,13 @@ load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") bazel_skylib_workspace() ``` +***Additional WORKSPACE setup for `native_binary.bzl`*** + +```starlark +load("@bazel_features//:deps.bzl", "bazel_features_deps") +bazel_features_deps() +``` + ***Additional WORKSPACE setup for the Gazelle plugin*** ```starlark diff --git a/docs/native_binary_doc.md b/docs/native_binary_doc.md index 84ad00db..8c802665 100755 --- a/docs/native_binary_doc.md +++ b/docs/native_binary_doc.md @@ -7,6 +7,13 @@ and test rule respectively. They fulfill the same goal as sh_binary and sh_test do, but they run the wrapped binary directly, instead of through Bash, so they don't depend on Bash and work with --shell_executable="". +If `bazel_skylib` is loaded in `WORKSPACE`, using this library requires the +following additional setup: +```starlark +load("@bazel_features//:deps.bzl", "bazel_features_deps") +bazel_features_deps() +``` + diff --git a/extension.bzl b/extension.bzl deleted file mode 100644 index fc361793..00000000 --- a/extension.bzl +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 2023 The Bazel Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Module extension to load additional repositories""" - -load("@bazel_skylib//:workspace.bzl", "globals_repo") - -def _globals_extension_impl( - module_ctx): # @unused - globals_repo() - -globals_extension = module_extension(_globals_extension_impl) diff --git a/rules/native_binary.bzl b/rules/native_binary.bzl index e258818b..d87c524c 100644 --- a/rules/native_binary.bzl +++ b/rules/native_binary.bzl @@ -18,12 +18,16 @@ These rules let you wrap a pre-built binary or script in a conventional binary and test rule respectively. They fulfill the same goal as sh_binary and sh_test do, but they run the wrapped binary directly, instead of through Bash, so they don't depend on Bash and work with --shell_executable="". + +If `bazel_skylib` is loaded from `WORKSPACE` rather than with bzlmod, using +this library requires additional `WORKSPACE` setup as explained in the +[release page](https://github.com/bazelbuild/bazel-skylib/releases). """ -load("@bazel_skylib_globals//:globals.bzl", "globals") +load("@bazel_features//:features.bzl", "bazel_features") def _impl_rule(ctx): - if not globals.RunEnvironmentInfo: + if not bazel_features.globals.RunEnvironmentInfo: for attr in ("env", "env_inherit"): if getattr(ctx.attr, attr, None): fail("Attribute %s specified for %s is only supported with bazel >= 5.3.0" % @@ -55,9 +59,9 @@ def _impl_rule(ctx): runfiles = runfiles, ), ] - if globals.RunEnvironmentInfo: + if bazel_features.globals.RunEnvironmentInfo: ret.append( - globals.RunEnvironmentInfo( + bazel_features.globals.RunEnvironmentInfo( environment = ctx.attr.env, inherited_environment = getattr(ctx.attr, "env_inherit", []), ), diff --git a/workspace.bzl b/workspace.bzl index f774fea8..60c1b0b3 100644 --- a/workspace.bzl +++ b/workspace.bzl @@ -15,34 +15,16 @@ """Dependency registration helpers for repositories which need to load bazel-skylib.""" load("@bazel_skylib//lib:unittest.bzl", "register_unittest_toolchains") -load("@bazel_skylib//lib:versions.bzl", "versions") - -def _globals_repo_impl(repository_ctx): - globals = { - "RunEnvironmentInfo": "5.3.0", - } - globals = { - k: k if versions.is_at_least(v, versions.get()) else "None" - for k, v in globals.items() - } - - repository_ctx.file( - "globals.bzl", - "globals = struct(\n%s\n)\n" % "\n".join( - [" %s = %s" % item for item in globals.items()], - ), - ) - repository_ctx.file("BUILD.bazel", "exports_files(['globals.bzl'])\n") - -_globals_repo = repository_rule( - implementation = _globals_repo_impl, - local = True, # required to make sure the version is updated if the bazel server restarts -) - -def globals_repo(): - _globals_repo(name = "bazel_skylib_globals") +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") def bazel_skylib_workspace(): """Registers toolchains and declares repository dependencies of the bazel_skylib repository.""" register_unittest_toolchains() - globals_repo() + maybe( + http_archive, + name = "bazel_features", + sha256 = "b8789c83c893d7ef3041d3f2795774936b27ff61701a705df52fd41d6ddbf692", + strip_prefix = "bazel_features-1.2.0", + url = "https://github.com/bazel-contrib/bazel_features/releases/download/v1.2.0/bazel_features-v1.2.0.tar.gz", + ) From f1bd4e06441ec633ee23e567d1bee5e8948752c1 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 11 Jan 2024 10:18:07 +0100 Subject: [PATCH 15/25] Add missing directory and fix docs --- bazel_features_stub/BUILD | 1 + bazel_features_stub/MODULE.bazel | 5 +++++ bazel_features_stub/README.md | 2 ++ bazel_features_stub/WORKSPACE | 0 bazel_features_stub/features.bzl | 5 +++++ docs/native_binary_doc.md | 9 +++------ 6 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 bazel_features_stub/BUILD create mode 100644 bazel_features_stub/MODULE.bazel create mode 100644 bazel_features_stub/README.md create mode 100644 bazel_features_stub/WORKSPACE create mode 100644 bazel_features_stub/features.bzl diff --git a/bazel_features_stub/BUILD b/bazel_features_stub/BUILD new file mode 100644 index 00000000..24233e5b --- /dev/null +++ b/bazel_features_stub/BUILD @@ -0,0 +1 @@ +exports_files(["features.bzl"]) diff --git a/bazel_features_stub/MODULE.bazel b/bazel_features_stub/MODULE.bazel new file mode 100644 index 00000000..9225ef96 --- /dev/null +++ b/bazel_features_stub/MODULE.bazel @@ -0,0 +1,5 @@ +module( + name = "bazel_features", + version = "0.0.0", + compatibility_level = 1, +) diff --git a/bazel_features_stub/README.md b/bazel_features_stub/README.md new file mode 100644 index 00000000..430a6fcb --- /dev/null +++ b/bazel_features_stub/README.md @@ -0,0 +1,2 @@ +This is a stub for [bazel_features](https://github.com/bazel-contrib/bazel_features) used for +testing and updating docs. diff --git a/bazel_features_stub/WORKSPACE b/bazel_features_stub/WORKSPACE new file mode 100644 index 00000000..e69de29b diff --git a/bazel_features_stub/features.bzl b/bazel_features_stub/features.bzl new file mode 100644 index 00000000..70d8a5cc --- /dev/null +++ b/bazel_features_stub/features.bzl @@ -0,0 +1,5 @@ +bazel_features = struct( + globals = struct( + RunEnvironmentInfo = RunEnvironmentInfo, + ), +) diff --git a/docs/native_binary_doc.md b/docs/native_binary_doc.md index 8c802665..5ba1b922 100755 --- a/docs/native_binary_doc.md +++ b/docs/native_binary_doc.md @@ -7,12 +7,9 @@ and test rule respectively. They fulfill the same goal as sh_binary and sh_test do, but they run the wrapped binary directly, instead of through Bash, so they don't depend on Bash and work with --shell_executable="". -If `bazel_skylib` is loaded in `WORKSPACE`, using this library requires the -following additional setup: -```starlark -load("@bazel_features//:deps.bzl", "bazel_features_deps") -bazel_features_deps() -``` +If `bazel_skylib` is loaded from `WORKSPACE` rather than with bzlmod, using +this library requires additional `WORKSPACE` setup as explained in the +[release page](https://github.com/bazelbuild/bazel-skylib/releases). From 165e7ef96799ed0b920c151d27c5353f8a31216a Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 11 Jan 2024 10:23:15 +0100 Subject: [PATCH 16/25] Fix formatting --- MODULE.bazel | 1 + bazel_features_stub/README.md | 2 -- bazel_features_stub/features.bzl | 5 +++++ 3 files changed, 6 insertions(+), 2 deletions(-) delete mode 100644 bazel_features_stub/README.md diff --git a/MODULE.bazel b/MODULE.bazel index ae3d0447..b9ca75a4 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -28,6 +28,7 @@ local_path_override( module_name = "bazel_skylib_gazelle_plugin", path = "gazelle", ) + local_path_override( module_name = "bazel_features", path = "bazel_features_stub", diff --git a/bazel_features_stub/README.md b/bazel_features_stub/README.md deleted file mode 100644 index 430a6fcb..00000000 --- a/bazel_features_stub/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This is a stub for [bazel_features](https://github.com/bazel-contrib/bazel_features) used for -testing and updating docs. diff --git a/bazel_features_stub/features.bzl b/bazel_features_stub/features.bzl index 70d8a5cc..bcce627e 100644 --- a/bazel_features_stub/features.bzl +++ b/bazel_features_stub/features.bzl @@ -1,3 +1,8 @@ +""" +This is a stub for [bazel_features](https://github.com/bazel-contrib/bazel_features) used for +testing and updating docs. +""" + bazel_features = struct( globals = struct( RunEnvironmentInfo = RunEnvironmentInfo, From f05da8292ba72abee42c207467aaee20696ce39a Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 13 Jun 2024 08:39:28 +0200 Subject: [PATCH 17/25] Update `bazel_features` --- MODULE.bazel | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 00bf9a16..a593bd6e 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -10,8 +10,8 @@ register_toolchains( "//toolchains/unittest:bash_toolchain", ) -bazel_dep(name = "platforms", version = "0.0.4") -bazel_dep(name = "bazel_features", version = "1.2.0") +bazel_dep(name = "platforms", version = "0.0.9") +bazel_dep(name = "bazel_features", version = "1.12.0") bazel_dep(name = "rules_license", version = "0.0.7") ### INTERNAL ONLY - lines after this are not included in the release packaging. From 02c2708add7488349d8198e33dba47b3882c18a6 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 13 Jun 2024 08:40:59 +0200 Subject: [PATCH 18/25] Update `MODULE.bazle-remove-override.patch` --- MODULE.bazel-remove-override.patch | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/MODULE.bazel-remove-override.patch b/MODULE.bazel-remove-override.patch index 34a549b0..51b8589f 100644 --- a/MODULE.bazel-remove-override.patch +++ b/MODULE.bazel-remove-override.patch @@ -1,6 +1,6 @@ --- MODULE.bazel +++ MODULE.bazel -@@ -23,12 +23,3 @@ +@@ -24,16 +24,6 @@ bazel_dep(name = "rules_testing", version = "0.6.0", dev_dependency = True) # Needed for bazelci and for building distribution tarballs. # If using an unreleased version of bazel_skylib via git_override, apply # MODULE.bazel-remove-override.patch to remove the following lines: @@ -9,7 +9,11 @@ - module_name = "bazel_skylib_gazelle_plugin", - path = "gazelle", -) +- -local_path_override( - module_name = "bazel_features", - path = "bazel_features_stub", -) + + external_directory_tests_ext = use_extension("//tests/directory:external_directory_tests.bzl", "external_directory_tests_ext", dev_dependency = True) + use_repo(external_directory_tests_ext, "external_directory_tests") From f86cde0dbfaa326c61becac09a449347dcbadd22 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 13 Jun 2024 09:18:50 +0200 Subject: [PATCH 19/25] Add location expansion to `env` --- rules/native_binary.bzl | 7 ++++-- tests/native_binary/BUILD | 6 ++--- tests/native_binary/assertenv.cc | 39 +++++++++++++++++++++----------- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/rules/native_binary.bzl b/rules/native_binary.bzl index d5629fcc..1c680855 100644 --- a/rules/native_binary.bzl +++ b/rules/native_binary.bzl @@ -60,9 +60,11 @@ def _impl_rule(ctx): ), ] if bazel_features.globals.RunEnvironmentInfo: + targets = [ctx.attr.src] + ctx.attr.data + env = {k: ctx.expand_location(v, targets) for k, v in ctx.attr.env.items()} ret.append( bazel_features.globals.RunEnvironmentInfo( - environment = ctx.attr.env, + environment = env, inherited_environment = getattr(ctx.attr, "env_inherit", []), ), ) @@ -93,7 +95,8 @@ _ATTRS = { ), "env": attr.string_dict( doc = "additional environment variables to set when the target is executed by " + - "`bazel`. Setting this requires bazel version 5.3.0 or later.", + "`bazel`. Setting this requires bazel version 5.3.0 or later. " + + "Values are subject to location expansion for labels in `data`.", default = {}, ), } diff --git a/tests/native_binary/BUILD b/tests/native_binary/BUILD index 350dc716..d3f98f1e 100644 --- a/tests/native_binary/BUILD +++ b/tests/native_binary/BUILD @@ -140,12 +140,10 @@ native_test( native_test( name = "env_test", src = ":copy_assertenv_exe", - # On Windows we need the ".exe" extension. - # On other platforms the extension doesn't matter. - # Therefore we can use ".exe" on every platform. - out = "env_test.exe", + data = ["BUILD"], env = { "TEST_ENV_VAR": "test_env_var_value", + "TEST_ENV_VAR_WITH_EXPANSION": "|$(rlocationpath BUILD)|", }, env_inherit = [ "HOME", # for POSIX diff --git a/tests/native_binary/assertenv.cc b/tests/native_binary/assertenv.cc index 84015ca6..df65ada9 100644 --- a/tests/native_binary/assertenv.cc +++ b/tests/native_binary/assertenv.cc @@ -8,24 +8,37 @@ #define OS_VAR "HOME" #endif +enum vars_to_be_found { + test_env_var = 0, + inherited, + test_env_var_with_expansion, + last, +}; + int main(int argc, char **argv, char **envp) { - bool test_env_found = false; - bool inherited_var_found = false; + const char* expected[last] = { + "TEST_ENV_VAR=test_env_var_value", + OS_VAR "=", + "TEST_ENV_VAR_WITH_EXPANSION=|_main/tests/native_binary/BUILD|", + }; for (char **env = envp; *env != NULL; ++env) { printf("%s\n", *env); - if (strcmp(*env, "TEST_ENV_VAR=test_env_var_value") == 0) { - test_env_found = true; + if (expected[test_env_var] && strcmp(*env, expected[test_env_var]) == 0) { + expected[test_env_var] = nullptr; } - if (strncasecmp(*env, OS_VAR "=", strlen(OS_VAR "=")) == 0) { - inherited_var_found = true; + if (expected[inherited] && strncasecmp(*env, expected[inherited], strlen(expected[inherited])) == 0) { + expected[inherited] = nullptr; + } + if (expected[test_env_var_with_expansion] && strcmp(*env, expected[test_env_var_with_expansion]) == 0) { + expected[test_env_var_with_expansion] = nullptr; } } - if (!test_env_found) { - fprintf(stderr, - "expected TEST_ENV_VAR=test_env_var_value in environment\n"); - } - if (!inherited_var_found) { - fprintf(stderr, "expected " OS_VAR " in environment\n"); + auto return_status = 0; + for (auto still_expected : expected) { + if (still_expected) { + fprintf(stderr, "expected %s\n", still_expected); + return_status = 1; + } } - return test_env_found && inherited_var_found ? 0 : 1; + return return_status; } From 798c1a78f867315f8eb066b838357f1ccf6090c0 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 13 Jun 2024 09:23:29 +0200 Subject: [PATCH 20/25] Update docs --- docs/native_binary_doc.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/native_binary_doc.md b/docs/native_binary_doc.md index e1d65104..3729e3bc 100755 --- a/docs/native_binary_doc.md +++ b/docs/native_binary_doc.md @@ -33,7 +33,7 @@ in genrule.tools for example. You can also augment the binary with runfiles. | src | path of the pre-built executable | Label | required | | | data | data dependencies. See https://bazel.build/reference/be/common-definitions#typical.data | List of labels | optional | `[]` | | out | An output name for the copy of the binary. Defaults to name.exe. (We add .exe to the name by default because it's required on Windows and tolerated on other platforms.) | String | optional | `""` | -| env | additional environment variables to set when the target is executed by `bazel`. Setting this requires bazel version 5.3.0 or later. | Dictionary: String -> String | optional | `{}` | +| env | additional environment variables to set when the target is executed by `bazel`. Setting this requires bazel version 5.3.0 or later. Values are subject to location expansion for labels in `data`. | Dictionary: String -> String | optional | `{}` | @@ -58,7 +58,7 @@ the binary with runfiles. | src | path of the pre-built executable | Label | required | | | data | data dependencies. See https://bazel.build/reference/be/common-definitions#typical.data | List of labels | optional | `[]` | | out | An output name for the copy of the binary. Defaults to name.exe. (We add .exe to the name by default because it's required on Windows and tolerated on other platforms.) | String | optional | `""` | -| env | additional environment variables to set when the target is executed by `bazel`. Setting this requires bazel version 5.3.0 or later. | Dictionary: String -> String | optional | `{}` | +| env | additional environment variables to set when the target is executed by `bazel`. Setting this requires bazel version 5.3.0 or later. Values are subject to location expansion for labels in `data`. | Dictionary: String -> String | optional | `{}` | | env_inherit | additional environment variables to inherit from the external environment when the test is executed by `bazel test`. Setting this requires bazel version 5.3.0 or later. | List of strings | optional | `[]` | From a7c141564da9f28b4c8b5c45ec2d614a28ad6609 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 13 Jun 2024 09:30:49 +0200 Subject: [PATCH 21/25] Fix `--noenable_bzlmod` checks --- WORKSPACE | 4 ++++ tests/native_binary/BUILD | 2 +- tests/native_binary/assertenv.cc | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index 3a4d21f5..47b3830d 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -4,6 +4,10 @@ load(":workspace.bzl", "bazel_skylib_workspace") bazel_skylib_workspace() +load("@bazel_features//:deps.bzl", "bazel_features_deps") + +bazel_features_deps() + ### INTERNAL ONLY - lines after this are not included in the release packaging. # Lines below are for tests, documentation generation, and distribution archive # generation only, and should thus not be included by dependencies on bazel-skylib. diff --git a/tests/native_binary/BUILD b/tests/native_binary/BUILD index d3f98f1e..114c83fb 100644 --- a/tests/native_binary/BUILD +++ b/tests/native_binary/BUILD @@ -143,7 +143,7 @@ native_test( data = ["BUILD"], env = { "TEST_ENV_VAR": "test_env_var_value", - "TEST_ENV_VAR_WITH_EXPANSION": "|$(rlocationpath BUILD)|", + "TEST_ENV_VAR_WITH_EXPANSION": "|$(rootpath BUILD)|", }, env_inherit = [ "HOME", # for POSIX diff --git a/tests/native_binary/assertenv.cc b/tests/native_binary/assertenv.cc index df65ada9..d4d7cf6f 100644 --- a/tests/native_binary/assertenv.cc +++ b/tests/native_binary/assertenv.cc @@ -19,7 +19,7 @@ int main(int argc, char **argv, char **envp) { const char* expected[last] = { "TEST_ENV_VAR=test_env_var_value", OS_VAR "=", - "TEST_ENV_VAR_WITH_EXPANSION=|_main/tests/native_binary/BUILD|", + "TEST_ENV_VAR_WITH_EXPANSION=|tests/native_binary/BUILD|", }; for (char **env = envp; *env != NULL; ++env) { printf("%s\n", *env); From b9cc025569f78a703afe7e7a0c7f19fb5dd3c325 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 26 Jun 2024 08:51:10 +0200 Subject: [PATCH 22/25] Remove unneeded backward compatibility code According to https://bazel.build/release#support-matrix, we can drop support for Bazel 4.x (so we can use `runfiles.merge_all`) and Bazel <5.3 (so we can use `RunEnvironmentInfo` unconditionally, which simplifies the change significantly). --- MODULE.bazel | 6 --- MODULE.bazel-remove-override.patch | 15 +++---- WORKSPACE | 4 -- docs/BUILD | 3 -- docs/maintainers_guide.md | 7 ---- docs/native_binary_doc.md | 10 ++--- docs/private/stardoc_with_diff_test.bzl | 6 +-- rules/native_binary.bzl | 53 ++++++++----------------- workspace.bzl | 7 ---- 9 files changed, 27 insertions(+), 84 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index a593bd6e..80f7028d 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -11,7 +11,6 @@ register_toolchains( ) bazel_dep(name = "platforms", version = "0.0.9") -bazel_dep(name = "bazel_features", version = "1.12.0") bazel_dep(name = "rules_license", version = "0.0.7") ### INTERNAL ONLY - lines after this are not included in the release packaging. @@ -30,11 +29,6 @@ local_path_override( path = "gazelle", ) -local_path_override( - module_name = "bazel_features", - path = "bazel_features_stub", -) - external_directory_tests_ext = use_extension("//tests/directory:external_directory_tests.bzl", "external_directory_tests_ext", dev_dependency = True) use_repo(external_directory_tests_ext, "external_directory_tests") diff --git a/MODULE.bazel-remove-override.patch b/MODULE.bazel-remove-override.patch index 51b8589f..0f307770 100644 --- a/MODULE.bazel-remove-override.patch +++ b/MODULE.bazel-remove-override.patch @@ -1,6 +1,6 @@ --- MODULE.bazel +++ MODULE.bazel -@@ -24,16 +24,6 @@ bazel_dep(name = "rules_testing", version = "0.6.0", dev_dependency = True) +@@ -22,8 +22,8 @@ # Needed for bazelci and for building distribution tarballs. # If using an unreleased version of bazel_skylib via git_override, apply # MODULE.bazel-remove-override.patch to remove the following lines: @@ -9,11 +9,8 @@ - module_name = "bazel_skylib_gazelle_plugin", - path = "gazelle", -) -- --local_path_override( -- module_name = "bazel_features", -- path = "bazel_features_stub", --) - - external_directory_tests_ext = use_extension("//tests/directory:external_directory_tests.bzl", "external_directory_tests_ext", dev_dependency = True) - use_repo(external_directory_tests_ext, "external_directory_tests") ++# bazel_dep(name = "bazel_skylib_gazelle_plugin", dev_dependency = True) ++# local_path_override( ++# module_name = "bazel_skylib_gazelle_plugin", ++# path = "gazelle", ++# ) diff --git a/WORKSPACE b/WORKSPACE index 47b3830d..3a4d21f5 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -4,10 +4,6 @@ load(":workspace.bzl", "bazel_skylib_workspace") bazel_skylib_workspace() -load("@bazel_features//:deps.bzl", "bazel_features_deps") - -bazel_features_deps() - ### INTERNAL ONLY - lines after this are not included in the release packaging. # Lines below are for tests, documentation generation, and distribution archive # generation only, and should thus not be included by dependencies on bazel-skylib. diff --git a/docs/BUILD b/docs/BUILD index ed2ae963..73ace3da 100644 --- a/docs/BUILD +++ b/docs/BUILD @@ -98,9 +98,6 @@ stardoc_with_diff_test( name = "native_binary", bzl_library_target = "//rules:native_binary", out_label = "//docs:native_binary_doc.md", - deps = [ - "@bazel_features//:features.bzl", - ], ) stardoc_with_diff_test( diff --git a/docs/maintainers_guide.md b/docs/maintainers_guide.md index 230b097b..9abdecfa 100644 --- a/docs/maintainers_guide.md +++ b/docs/maintainers_guide.md @@ -123,13 +123,6 @@ load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") bazel_skylib_workspace() ``` -***Additional WORKSPACE setup for `native_binary.bzl`*** - -```starlark -load("@bazel_features//:deps.bzl", "bazel_features_deps") -bazel_features_deps() -``` - ***Additional WORKSPACE setup for the Gazelle plugin*** ```starlark diff --git a/docs/native_binary_doc.md b/docs/native_binary_doc.md index 3729e3bc..e8d4ad23 100755 --- a/docs/native_binary_doc.md +++ b/docs/native_binary_doc.md @@ -7,10 +7,6 @@ and test rule respectively. They fulfill the same goal as sh_binary and sh_test do, but they run the wrapped binary directly, instead of through Bash, so they don't depend on Bash and work with --shell_executable="". -If `bazel_skylib` is loaded from `WORKSPACE` rather than with bzlmod, using -this library requires additional `WORKSPACE` setup as explained in the -[release page](https://github.com/bazelbuild/bazel-skylib/releases). - ## native_binary @@ -33,7 +29,7 @@ in genrule.tools for example. You can also augment the binary with runfiles. | src | path of the pre-built executable | Label | required | | | data | data dependencies. See https://bazel.build/reference/be/common-definitions#typical.data | List of labels | optional | `[]` | | out | An output name for the copy of the binary. Defaults to name.exe. (We add .exe to the name by default because it's required on Windows and tolerated on other platforms.) | String | optional | `""` | -| env | additional environment variables to set when the target is executed by `bazel`. Setting this requires bazel version 5.3.0 or later. Values are subject to location expansion for labels in `data`. | Dictionary: String -> String | optional | `{}` | +| env | additional environment variables to set when the target is executed by `bazel`. Values are subject to location expansion for labels in `src` and `data`. | Dictionary: String -> String | optional | `{}` | @@ -58,7 +54,7 @@ the binary with runfiles. | src | path of the pre-built executable | Label | required | | | data | data dependencies. See https://bazel.build/reference/be/common-definitions#typical.data | List of labels | optional | `[]` | | out | An output name for the copy of the binary. Defaults to name.exe. (We add .exe to the name by default because it's required on Windows and tolerated on other platforms.) | String | optional | `""` | -| env | additional environment variables to set when the target is executed by `bazel`. Setting this requires bazel version 5.3.0 or later. Values are subject to location expansion for labels in `data`. | Dictionary: String -> String | optional | `{}` | -| env_inherit | additional environment variables to inherit from the external environment when the test is executed by `bazel test`. Setting this requires bazel version 5.3.0 or later. | List of strings | optional | `[]` | +| env | additional environment variables to set when the target is executed by `bazel`. Values are subject to location expansion for labels in `src` and `data`. | Dictionary: String -> String | optional | `{}` | +| env_inherit | additional environment variables to inherit from the external environment when the test is executed by `bazel test`. | List of strings | optional | `[]` | diff --git a/docs/private/stardoc_with_diff_test.bzl b/docs/private/stardoc_with_diff_test.bzl index 96ee0679..32b471a7 100644 --- a/docs/private/stardoc_with_diff_test.bzl +++ b/docs/private/stardoc_with_diff_test.bzl @@ -30,8 +30,7 @@ load("@io_bazel_stardoc//stardoc:stardoc.bzl", "stardoc") def stardoc_with_diff_test( name, bzl_library_target, - out_label, - deps = None): + out_label): """Creates a stardoc target coupled with a `diff_test` for a given `bzl_library`. This is helpful for minimizing boilerplate in repos with lots of stardoc targets. @@ -40,7 +39,6 @@ def stardoc_with_diff_test( name: the stardoc target name bzl_library_target: the label of the `bzl_library` target to generate documentation for out_label: the label of the output MD file - deps: additional files loaded by the bazel library, if any """ out_file = out_label.replace("//", "").replace(":", "/") @@ -49,7 +47,7 @@ def stardoc_with_diff_test( name = name, out = out_file.replace(".md", "-docgen.md"), input = bzl_library_target + ".bzl", - deps = [bzl_library_target] + (deps or []), + deps = [bzl_library_target], ) # Ensure that the generated MD has been updated in the local source tree diff --git a/rules/native_binary.bzl b/rules/native_binary.bzl index 1c680855..3d826ca2 100644 --- a/rules/native_binary.bzl +++ b/rules/native_binary.bzl @@ -18,20 +18,9 @@ These rules let you wrap a pre-built binary or script in a conventional binary and test rule respectively. They fulfill the same goal as sh_binary and sh_test do, but they run the wrapped binary directly, instead of through Bash, so they don't depend on Bash and work with --shell_executable="". - -If `bazel_skylib` is loaded from `WORKSPACE` rather than with bzlmod, using -this library requires additional `WORKSPACE` setup as explained in the -[release page](https://github.com/bazelbuild/bazel-skylib/releases). """ -load("@bazel_features//:features.bzl", "bazel_features") - def _impl_rule(ctx): - if not bazel_features.globals.RunEnvironmentInfo: - for attr in ("env", "env_inherit"): - if getattr(ctx.attr, attr, None): - fail("Attribute %s specified for %s is only supported with bazel >= 5.3.0" % - (attr, ctx.label)) out = ctx.actions.declare_file(ctx.attr.out if (ctx.attr.out != "") else ctx.attr.name + ".exe") ctx.actions.symlink( target_file = ctx.executable.src, @@ -40,35 +29,26 @@ def _impl_rule(ctx): ) runfiles = ctx.runfiles(files = ctx.files.data) - # Bazel 4.x LTS does not support `merge_all`. - # TODO: remove `merge` branch once we drop support for Bazel 4.x. - if hasattr(runfiles, "merge_all"): - runfiles = runfiles.merge_all([ - d[DefaultInfo].default_runfiles - for d in ctx.attr.data + [ctx.attr.src] - ]) - else: - for d in ctx.attr.data: - runfiles = runfiles.merge(d[DefaultInfo].default_runfiles) - runfiles = runfiles.merge(ctx.attr.src[DefaultInfo].default_runfiles) + runfiles = runfiles.merge_all([ + d[DefaultInfo].default_runfiles + for d in ctx.attr.data + [ctx.attr.src] + ]) + - ret = [ + targets = [ctx.attr.src] + ctx.attr.data + env = {k: ctx.expand_location(v, targets) for k, v in ctx.attr.env.items()} + + return [ DefaultInfo( executable = out, files = depset([out]), runfiles = runfiles, ), + RunEnvironmentInfo( + environment = env, + inherited_environment = getattr(ctx.attr, "env_inherit", []), + ), ] - if bazel_features.globals.RunEnvironmentInfo: - targets = [ctx.attr.src] + ctx.attr.data - env = {k: ctx.expand_location(v, targets) for k, v in ctx.attr.env.items()} - ret.append( - bazel_features.globals.RunEnvironmentInfo( - environment = env, - inherited_environment = getattr(ctx.attr, "env_inherit", []), - ), - ) - return ret _ATTRS = { "src": attr.label( @@ -95,8 +75,8 @@ _ATTRS = { ), "env": attr.string_dict( doc = "additional environment variables to set when the target is executed by " + - "`bazel`. Setting this requires bazel version 5.3.0 or later. " + - "Values are subject to location expansion for labels in `data`.", + "`bazel`. Values are subject to location expansion for labels in `src` and " + + "`data`.", default = {}, ), } @@ -119,8 +99,7 @@ native_test = rule( _ATTRS, env_inherit = attr.string_list( doc = "additional environment variables to inherit from the external " + - "environment when the test is executed by `bazel test`. " + - "Setting this requires bazel version 5.3.0 or later.", + "environment when the test is executed by `bazel test`. ", default = [], ), ), diff --git a/workspace.bzl b/workspace.bzl index 158b3ad9..0997ec32 100644 --- a/workspace.bzl +++ b/workspace.bzl @@ -30,10 +30,3 @@ def bazel_skylib_workspace(): ], ) register_unittest_toolchains() - maybe( - http_archive, - name = "bazel_features", - sha256 = "b8789c83c893d7ef3041d3f2795774936b27ff61701a705df52fd41d6ddbf692", - strip_prefix = "bazel_features-1.2.0", - url = "https://github.com/bazel-contrib/bazel_features/releases/download/v1.2.0/bazel_features-v1.2.0.tar.gz", - ) From b8adf7f6affa6fb05c5c08a31ef047e820b10675 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 26 Jun 2024 08:56:32 +0200 Subject: [PATCH 23/25] Fix formatting --- rules/native_binary.bzl | 1 - 1 file changed, 1 deletion(-) diff --git a/rules/native_binary.bzl b/rules/native_binary.bzl index 3d826ca2..adaaa45b 100644 --- a/rules/native_binary.bzl +++ b/rules/native_binary.bzl @@ -34,7 +34,6 @@ def _impl_rule(ctx): for d in ctx.attr.data + [ctx.attr.src] ]) - targets = [ctx.attr.src] + ctx.attr.data env = {k: ctx.expand_location(v, targets) for k, v in ctx.attr.env.items()} From 1ca13a4b1e1a58774c577f7b1b7264eadb1b06b5 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 26 Jun 2024 08:58:53 +0200 Subject: [PATCH 24/25] Remove unneeded code --- bazel_features_stub/BUILD | 1 - bazel_features_stub/MODULE.bazel | 5 ----- bazel_features_stub/WORKSPACE | 0 bazel_features_stub/features.bzl | 13 ------------- 4 files changed, 19 deletions(-) delete mode 100644 bazel_features_stub/BUILD delete mode 100644 bazel_features_stub/MODULE.bazel delete mode 100644 bazel_features_stub/WORKSPACE delete mode 100644 bazel_features_stub/features.bzl diff --git a/bazel_features_stub/BUILD b/bazel_features_stub/BUILD deleted file mode 100644 index 24233e5b..00000000 --- a/bazel_features_stub/BUILD +++ /dev/null @@ -1 +0,0 @@ -exports_files(["features.bzl"]) diff --git a/bazel_features_stub/MODULE.bazel b/bazel_features_stub/MODULE.bazel deleted file mode 100644 index 9225ef96..00000000 --- a/bazel_features_stub/MODULE.bazel +++ /dev/null @@ -1,5 +0,0 @@ -module( - name = "bazel_features", - version = "0.0.0", - compatibility_level = 1, -) diff --git a/bazel_features_stub/WORKSPACE b/bazel_features_stub/WORKSPACE deleted file mode 100644 index e69de29b..00000000 diff --git a/bazel_features_stub/features.bzl b/bazel_features_stub/features.bzl deleted file mode 100644 index 022186ad..00000000 --- a/bazel_features_stub/features.bzl +++ /dev/null @@ -1,13 +0,0 @@ -""" -This is a stub for [bazel_features](https://github.com/bazel-contrib/bazel_features) used for -testing and updating docs. -""" - -bazel_features = struct( - globals = struct( - RunEnvironmentInfo = RunEnvironmentInfo, - ), - external_deps = struct( - extension_metadata_has_reproducible = False, - ), -) From 8f76bb66807f692f90e7e27c568d3b0266a35ac4 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 26 Aug 2024 09:09:27 +0200 Subject: [PATCH 25/25] Clean up test code --- tests/native_binary/assertenv.cc | 55 ++++++++++++-------------------- 1 file changed, 21 insertions(+), 34 deletions(-) diff --git a/tests/native_binary/assertenv.cc b/tests/native_binary/assertenv.cc index d4d7cf6f..0dd51f3c 100644 --- a/tests/native_binary/assertenv.cc +++ b/tests/native_binary/assertenv.cc @@ -1,44 +1,31 @@ #include +#include #include +bool check(const char *var, const char *expected = nullptr); + +int main() { + bool ok = true; + ok = ok && check("TEST_ENV_VAR", "test_env_var_value"); #ifdef _WIN32 -#define OS_VAR "APPDATA" -#define strncasecmp _strnicmp + ok = ok && check("APPDATA"); #else -#define OS_VAR "HOME" + ok = ok && check("HOME"); #endif + ok = + ok && check("TEST_ENV_VAR_WITH_EXPANSION", "|tests/native_binary/BUILD|"); + return ok ? 0 : 1; +} -enum vars_to_be_found { - test_env_var = 0, - inherited, - test_env_var_with_expansion, - last, -}; - -int main(int argc, char **argv, char **envp) { - const char* expected[last] = { - "TEST_ENV_VAR=test_env_var_value", - OS_VAR "=", - "TEST_ENV_VAR_WITH_EXPANSION=|tests/native_binary/BUILD|", - }; - for (char **env = envp; *env != NULL; ++env) { - printf("%s\n", *env); - if (expected[test_env_var] && strcmp(*env, expected[test_env_var]) == 0) { - expected[test_env_var] = nullptr; - } - if (expected[inherited] && strncasecmp(*env, expected[inherited], strlen(expected[inherited])) == 0) { - expected[inherited] = nullptr; - } - if (expected[test_env_var_with_expansion] && strcmp(*env, expected[test_env_var_with_expansion]) == 0) { - expected[test_env_var_with_expansion] = nullptr; - } +bool check(const char *var, const char *expected) { + const char *actual = getenv(var); + if (actual == nullptr) { + fprintf(stderr, "expected %s\n", var); + return false; } - auto return_status = 0; - for (auto still_expected : expected) { - if (still_expected) { - fprintf(stderr, "expected %s\n", still_expected); - return_status = 1; - } + if (expected && strcmp(actual, expected) != 0) { + fprintf(stderr, "expected %s=%s, got %s\n", var, expected, actual); + return false; } - return return_status; + return true; }