Skip to content

feat: add generated_srcs to rb_bundle_fetch - #421

Open
titusfortner wants to merge 1 commit into
bazel-contrib:mainfrom
titusfortner:c/rules-ruby-lazy-bundle-srcs-full
Open

titusfortner wants to merge 1 commit into
bazel-contrib:mainfrom
titusfortner:c/rules-ruby-lazy-bundle-srcs-full

Conversation

@titusfortner

Copy link
Copy Markdown
Contributor

This allows Bazel to dynamically generate version files so that just bumping the version does not invalidate test result cache.

Today rb_bundle_fetch copies the gemspec and the version file it requires at fetch time, so the version file must be checked in, and that copy plus Gemfile.lock sit in the runfiles of every target that depends on the bundle.

What

  • Adds generated_srcs to rb_bundle_fetch and ruby.bundle_fetch: files the Gemfile needs that the build produces, such as a version.rb from expand_template
  • When generated_srcs is set, the bundle's copy of Gemfile.lock gets its path gem versions rewritten to match their gemspecs, so the checked-in lock keeps the real version while unstamped builds use another
  • Adds examples/stamped_gem, a gem whose version lives in Starlark and is stamped only under --stamp, with a Linux CI job

Notes

  • Bundles without generated_srcs take exactly today's path: no staging, no lock rewrite, and Bundler's deployment-mode check still applies.
  • Inputs are staged by copy, not symlink, because gemspecs that use __dir__ or File.realpath would otherwise resolve to the gemspec's original directory, which doesn't contain the generated file.
  • BUNDLE_CACHE_PATH keeps forward slashes on Windows, unlike the other Bundler paths, because Bundler globs it and Ruby globs treat backslashes as escapes.
  • The lock rewrite is its own action, so a byte-identical result keeps bundle install and every test cached across a bump; the rewrite only touches path gem entries, and a miss fails loudly with Bundler's "gemspecs for path gems changed".
  • Alternatives considered:
    • Detecting generated files by whether they exist on disk: a gitignored local copy would be fetched silently instead.
    • An install_gemfile_lock hook: every consumer would maintain its own lock rewrite in sync with its version source.

Considerations

  • rules_ruby now edits Gemfile.lock text, limited to path gem version strings.
  • The unstamped version must still satisfy any requirement other gems in the bundle place on the path gem, because the rewrite changes versions, not requirements.
  • The example exercises the generated version and stamping end to end, and its CI job reruns the tests with a CRLF copy of the lock; the rewrite reads and writes raw bytes, so CRLF handling doesn't depend on the OS.
  • Nothing in the repo tests the rewrite against glob: sources or nested gemspecs.
  • Staging generated_srcs could land as its own PR, but alone it only helps a project whose checked-in lock already records the unstamped version, so it would not remove the need for the lock rewrite.

Selenium is trying this out as a patch in SeleniumHQ/selenium#18164, where its Ruby smoke tests pass on Linux, macOS and Windows.

titusfortner added a commit to titusfortner/selenium that referenced this pull request Oct 13, 2026
titusfortner added a commit to SeleniumHQ/selenium that referenced this pull request Oct 13, 2026
…ad the version (#18164)

* [rb] generate version.rb from the root version.bzl so tests do not read the version

* [rb] write version.rb before Bundler reads the source tree gemspecs

* [rb] point the rules_ruby generated_srcs patch comment at bazel-contrib/rules_ruby#421 and how to back it out
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