Skip to content

feat: add extra_args passthrough to bundle install - #394

Open
DhashS wants to merge 4 commits into
bazel-contrib:mainfrom
DhashS:feat/bundle-install-extra-args
Open

feat: add extra_args passthrough to bundle install#394
DhashS wants to merge 4 commits into
bazel-contrib:mainfrom
DhashS:feat/bundle-install-extra-args

Conversation

@DhashS

@DhashS DhashS commented Aug 5, 2026

Copy link
Copy Markdown

What

Adds an extra_args attribute that appends extra command-line arguments to the bundle install invocation, plumbed through all three entry points:

  • the ruby.bundle_fetch bzlmod tag (extensions.bzl)
  • the rb_bundle_fetch repo rule (bundle_fetch.bzl, used by both bzlmod and WORKSPACE)
  • the rb_bundle_install rule (bundle_install.bzl)

Why

Cross-platform bundles. Bundler 2.6 / RubyGems 3.4 added bundle install --target-rbconfig=<rbconfig.rb> (Gem::TargetRbConfig), which lets the host Ruby install a different platform's precompiled gems. There's currently no way to pass that (or any other) flag through rb_bundle_install — the command is hardcoded to install --standalone --local, the env attr isn't consulted by bundler for --target-rbconfig (it's a Thor CLI option, not a Bundler::Settings key), and BUNDLE_IGNORE_CONFIG=1 rules out .bundle/config.

With extra_args, an arm64-darwin host can assemble an x86_64-linux vendor/bundle for a container image layer without a Linux executor:

ruby.bundle_fetch(
    name = "bundle",
    gemfile = "//:Gemfile",
    gemfile_lock = "//:Gemfile.lock",
    extra_args = ["--target-rbconfig", "/path/to/linux/rbconfig.rb"],
)

(Today the documented cross-platform story is RBE via the multi-platform toolchains from #377 — this offers a complementary, executor-free path for precompiled gems.)

Verified

Threaded end-to-end: with extra_args set, the generated @bundle//:BUILD carries extra_args = [...] and the generated install script runs:

bundle install --standalone --local --target-rbconfig /…/rbconfig.rb

Notes / open questions

  • extra_args is a verbatim string_list. For file-valued flags like --target-rbconfig, a natural follow-up is $(location) expansion + threading the file as an action input (hermetic). Happy to add that here or in a follow-up — whichever you prefer.
  • Windows .cmd template updated symmetrically.
  • Can add an example/e2e test under examples/ if you'd like — guidance welcome on the preferred shape.

🤖 Generated with Claude Code

DhashS added 4 commits August 5, 2026 14:03
Threads extra command-line arguments to `bundle install` from the
`ruby.bundle_fetch` bzlmod tag / `rb_bundle_fetch` repo rule / `rb_bundle_install`
rule down onto the install command line.

Primary use case: cross-platform bundles. With bundler's `--target-rbconfig`
(RubyGems 3.4+ / Gem::TargetRbConfig), the host ruby can install a DIFFERENT
platform's precompiled gems — e.g. assembling an x86_64-linux vendor/bundle on
an arm64-darwin host for a container image layer, without a linux executor:

    ruby.bundle_fetch(
        name = "bundle",
        gemfile = "//:Gemfile",
        gemfile_lock = "//:Gemfile.lock",
        extra_args = ["--target-rbconfig", "/path/to/linux/rbconfig.rb"],
    )

Covers both the bzlmod and WORKSPACE paths (shared rb_bundle_fetch repo rule)
and the standalone rb_bundle_install rule.
extra_args now supports $(location)/$(rootpath)/$(execpath) make-variable
expansion (built-in ctx.expand_location) against a new `data` label_list, which
is also threaded as inputs to the bundle install action. This lets a file-valued
flag reference a target instead of a raw path:

    ruby.bundle_fetch(
        name = "bundle_linux_amd64",
        gemfile = "//:Gemfile",
        gemfile_lock = "//:Gemfile.lock",
        data = ["//image:x86_64-linux-rbconfig.rb"],
        extra_args = ["--target-rbconfig", "$(location //image:x86_64-linux-rbconfig.rb)"],
    )

Threaded through the bzlmod tag, repo rule, generated BUILD, and install rule.
Adds a public dist_files filegroup (glob dist/**/*) to each per-platform ruby
repo, aliased on the @ruby hub. Lets you package the interpreter into a
container image (portable-ruby is relocatable), e.g.:

    pkg_tar(name = "ruby_runtime", srcs = ["@ruby//:dist_files"],
            package_dir = "/usr/local", strip_prefix = "dist")
Adds the pieces needed to install a bundle for a FOREIGN platform (e.g. build a
linux gems layer from a macOS host via --target-rbconfig) and package it into a
container image:

* env values now support $(location ...)/$(execpath ...) expansion against
  `data` (mirrors extra_args) — lets an env var reference a build artifact,
  e.g. prepend a generated cross-compiler wrapper dir onto PATH.
* new `rbconfig` filegroup on the ruby dist (+ hub alias): the interpreter's
  own relocatable rbconfig.rb, for `gem install --target-rbconfig` cross-builds.
* `binstubs` attr (default True): skip `bundle binstubs --all` for
  cross-platform bundles, where the host ruby can't validate the target's
  native extensions; the (empty) binstubs dir is still materialized.
* `gems` output group: just the vendor/bundle tree (no Gemfile/binstubs), so
  consumers can lay the gems into a container BUNDLE_PATH with a clean
  strip_prefix.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant