From 3f9e47737f838744ac5bed90c0a5582a4d6c0635 Mon Sep 17 00:00:00 2001 From: Andres Cecilia Luque Date: Tue, 27 Oct 2026 17:35:25 +0400 Subject: [PATCH] feat: support env from a bzl file in bundle_fetch The `env` tag attribute only accepts static strings, and `load()` is not allowed in MODULE.bazel, so machine-resolved values (e.g. a toolchain selected via a generated repository) cannot reach the generated rb_bundle_install action. Add an optional `env_bzl` label whose exported `bundle_env` dict is loaded into the generated BUILD and merged with `env`, resolved at BUILD-evaluation time so values participate in the action cache key. Upstream: https://github.com/bazel-contrib/rules_ruby/pull/432 --- ruby/extensions.bzl | 7 +++++++ ruby/private/bundle_fetch.bzl | 17 ++++++++++++++++- ruby/private/bundle_fetch/BUILD.tpl | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/ruby/extensions.bzl b/ruby/extensions.bzl index 59e7f143..5e912f37 100644 --- a/ruby/extensions.bzl +++ b/ruby/extensions.bzl @@ -30,6 +30,12 @@ ruby_bundle_fetch = tag_class(attrs = { "name": attr.string(doc = "Resulting repository name for the bundle"), "srcs": attr.label_list(), "env": attr.string_dict(), + "env_bzl": attr.label(doc = """\ +Optional .bzl file exporting a dict named `bundle_env`, merged into the generated \ +rb_bundle_install `env`. Unlike `env` (static strings), values are resolved at \ +BUILD-evaluation time, so they can come from generated repositories (e.g. a \ +machine-resolved toolchain path).\ +""",), "extra_args": attr.string_list(doc = "Extra arguments appended to `bundle install`. Supports `$(location ...)` against `data`."), "data": attr.label_list(doc = "Files referenced from `extra_args` via `$(location ...)`."), "binstubs": attr.bool(default = True, doc = "Run `bundle binstubs --all` after install. Set False for cross-platform bundles."), @@ -81,6 +87,7 @@ def _ruby_module_extension(module_ctx): name = bundle_fetch.name, srcs = bundle_fetch.srcs, env = bundle_fetch.env, + env_bzl = bundle_fetch.env_bzl, extra_args = bundle_fetch.extra_args, data = [str(label) for label in bundle_fetch.data], binstubs = bundle_fetch.binstubs, diff --git a/ruby/private/bundle_fetch.bzl b/ruby/private/bundle_fetch.bzl index d9ab31c5..4d5f27dd 100644 --- a/ruby/private/bundle_fetch.bzl +++ b/ruby/private/bundle_fetch.bzl @@ -233,6 +233,15 @@ def _rb_bundle_fetch_impl(repository_ctx): }, ) + if repository_ctx.attr.env_bzl: + env_load = 'load("{}", "bundle_env")'.format(str(repository_ctx.attr.env_bzl)) + env_value = "bundle_env" + if repository_ctx.attr.env: + env_value = "bundle_env | {}".format(repr(repository_ctx.attr.env)) + else: + env_load = "" + env_value = repr(repository_ctx.attr.env) + repository_ctx.template( "BUILD", repository_ctx.attr._build_tpl, @@ -246,7 +255,8 @@ def _rb_bundle_fetch_impl(repository_ctx): "{gems}": _join_and_indent(gem_full_names), "{gem_fragments}": "".join(gem_fragments), "{gem_install_fragments}": "".join(gem_install_fragments), - "{env}": repr(repository_ctx.attr.env), + "{env_load}": env_load, + "{env}": env_value, "{extra_args}": repr(repository_ctx.attr.extra_args), "{data}": _join_and_indent(repository_ctx.attr.data), "{binstubs}": repr(repository_ctx.attr.binstubs), @@ -309,6 +319,11 @@ rb_bundle_fetch = repository_rule( "`$(location ...)` expansion against `data` (forwarded to the " + "generated rb_bundle_install `env`).", ), + "env_bzl": attr.label( + doc = "Optional .bzl file exporting `bundle_env` (dict), merged into the " + + "generated rb_bundle_install `env`. Values are resolved at " + + "BUILD-evaluation time, so they can come from generated repositories.", + ), "extra_args": attr.string_list( doc = "Extra arguments appended to the `bundle install` command line " + "run by the generated rb_bundle_install target. Supports " + diff --git a/ruby/private/bundle_fetch/BUILD.tpl b/ruby/private/bundle_fetch/BUILD.tpl index 9537cf29..a61e5c74 100644 --- a/ruby/private/bundle_fetch/BUILD.tpl +++ b/ruby/private/bundle_fetch/BUILD.tpl @@ -1,6 +1,7 @@ """@generated by @rules_ruby//:ruby/private/bundle_fetch.bzl""" load("@rules_ruby//ruby:defs.bzl", "rb_bundle_install", "rb_gem", "rb_gem_install") +{env_load} package(default_visibility = ["//visibility:public"])