Skip to content

Capture Ruby Version information directly from the Gemfile.lock #1603

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
May 27, 2025

Conversation

schneems
Copy link
Contributor

@schneems schneems commented May 22, 2025

Add a custom class GemfileLock that parses a lockfile to return information that can build a RubyVersion. We then compare that information to the current method of using bundle platform --ruby output to gauge correctness from production data before we make any behavior changes.

Commits are are focused (if not entirely small) and ordered.

Context of this work

Today, the order of operations for running the buildpack looks like this:

  • Install bootstrap (buildpack) ruby version
  • Detect and install a limited number of "blessed" bundler versions (from S3)
  • Use that version with the bootstrap Ruby to run bundle platform --ruby to detect the application Ruby version.

Moving into the future, an eventual goal is to be able to avoid running bundle platform --ruby with the bootstrap version of ruby (used by the buildpack). This execution exposes incompatibilities between the bootstrap ruby version and versions of bundler. Instead, the order will eventually be:

  • Install bootstrap ruby version
  • Read and parse the Gemfile.lock to determine Ruby version and install it
  • Install the arbitrary bundler version found in Gemfile.lock (from gem install bundler -v <version>)

To support this, I want to populate RubyVersion from different sources at the same time so I can compare them, instrument them, and ensure consistent platform behavior.

Worth noting that the proposed future goal is the same order of execution as the CNB (without the need to install a bootstrap ruby as the CNB is written in Rust).

GUS-W-18627780

@schneems schneems force-pushed the schneems/parse-ruby-version-from-gemfile-lock branch 6 times, most recently from 9d29dd5 to d9c3921 Compare May 22, 2025 21:00
@schneems schneems marked this pull request as ready for review May 22, 2025 21:22
@schneems schneems requested a review from a team as a code owner May 22, 2025 21:22
@schneems schneems enabled auto-merge (squash) May 23, 2025 13:29
@schneems schneems disabled auto-merge May 23, 2025 13:29
schneems added 10 commits May 23, 2025 08:30
This class parses a Gemfile.lock for the purposes of extracting information about the Ruby version and Bundler version. Tests cases are pulled from `ruby_version_spec.rb` and from the Ruby CNB https://github.com/heroku/buildpacks-ruby/blob/e249a8bcbc75f7e5322f02bb4e32aaed50724355/commons/src/gemfile_lock.rs.
I didn't notice before, but vscode silently removed the extra space when I indented this code. There should be three spaces before the version i.e. `   2.3.25`. Apparently `bundle platform --ruby` is not as strict and will accept two spaces. I'm unsure if there are customers relying on this behavior, running both approaches and recording metrics will answer that question.
The current code uses the output of `bundle platform --ruby` to produce a RubyVersion via `RubyVersion.bundle_platform_ruby` this adds `RubyVersion.from_gemfile_lock` that allows us to build the same value class from the raw `Gemfile.lock` file on disk (don't have to execute any Ruby code).

This behavior is validated by running both modes in the `ruby_version_spec.rb` tests.
This move allows us to inject the information into language packs (not yet wired up).
Manipulating classes as variables is common, but they're usually annotated to indicate they're a class.
The dead_end gem is renamed into syntax_suggest and now comes with Ruby 3.2 (I maintain it!).
@schneems schneems force-pushed the schneems/parse-ruby-version-from-gemfile-lock branch from d9c3921 to 0595ea3 Compare May 23, 2025 13:30
@schneems schneems merged commit 7e58e63 into main May 27, 2025
4 checks passed
@schneems schneems deleted the schneems/parse-ruby-version-from-gemfile-lock branch May 27, 2025 13:53
@heroku-linguist heroku-linguist bot mentioned this pull request May 27, 2025
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.

2 participants