diff --git a/README.md b/README.md index 65c2248cf..f07ec74f8 100755 --- a/README.md +++ b/README.md @@ -129,92 +129,58 @@ Keep in mind, that it takes some time for compilation to complete. On Windows, [RubyInstaller][6] is used to install MRI. -#### Fast Installation with rv-ruby +#### Fast Installation with Portable Ruby -For faster MRI installation on Linux and macOS, you can use prebuilt Ruby -binaries from [rv-ruby][19] instead of compiling from source. This significantly +For faster MRI installation on Linux and macOS, you can use portable Ruby +binaries from [jdx/ruby][19] instead of compiling from source. This significantly reduces installation time and ensures consistent, portable Ruby environments. -**Configure rv-ruby Downloads** - -To securely download and properly cache the Ruby binaries, the `ruby.toolchain` -declaration must be updated with the `rv_version` and `rv_checksums` attributes. - -We have provided the `generate_rv_checksums` utility to add/update these -attributes for you. The utility needs to know the `rv-ruby` version to use -(https://github.com/spinel-coop/rv-ruby/releases) and the version of Ruby to -download. By default, it will use the Ruby version specified in the -`.ruby-version` file. - -```bash -bazel run @rules_ruby//tools/generate_rv_checksums -- 20251225 -``` - -After running the utility, the toolchain declaration in your `MODULE.bazel` -should look something like the following: +To enable portable Ruby, set `portable_ruby = True` in your toolchain declaration: ```bazel ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby") ruby.toolchain( name = "ruby", + portable_ruby = True, version_file = "//:.ruby-version", - rv_version = "20251225", - rv_checksums = { - "linux-arm64": "0c08c35a99f10817643d548f98012268c5433ae25a737ab4d6751336108a941d", - "linux-x86_64": "f36cef10365d370e0867f0c3ac36e457a26ab04f3cfbbd7edb227a18e6e9b3c3", - "macos-arm64": "cd9d7a1428076bfcc6c2ca3c0eb69b8e671e9b48afb4c351fa4a84927841ffef", - "macos-x86_64": "e9da39082d1dd8502d322c850924d929bc45b7a1e35da593a5606c00673218d4", - }, ) ``` -**Configure Excluded Gems** +This ruleset ships with [default checksums][20] to securely download and properly cache +the Ruby binaries. If you want to use Ruby version not available with ruleset release, +you should use `portable_ruby_checksums` attribute. -When using `rv-ruby`, you must exclude _default_ gems with C extensions from -`bundle_fetch` as these are pre-compiled in the `rv-ruby` binary. You may see -compilation errors if you do not exclude these gems. - -We have provided the `generate_excluded_gems` utility to update the declaration -for you. +We have provided the `generate_portable_ruby_checksums` utility to add/update these +attributes for you. The utility needs to know the version of Ruby to download. +By default, it will use the Ruby version specified in the `.ruby-version` file. ```bash -bazel run @rules_ruby//tools/generate_excluded_gems +bazel run @rules_ruby//tools/generate_portable_ruby_checksums -- 3.4.8 ``` -The utility reads the Ruby version being used and checks -https://raw.githubusercontent.com/janlelis/stdgems/main/default_gems.json to -determine which gems should be excluded. The utility adds/updates the -`excluded_gems` attribute with the correct list of gems. The `bundle_fetch` -declaration will look something like the following: +After running the utility, the toolchain declaration in your `MODULE.bazel` +should look something like the following: ```bazel -ruby.bundle_fetch( - name = "bundle", - gemfile = "//:Gemfile", - gemfile_lock = "//:Gemfile.lock", - excluded_gems = [ - "date", "digest", "etc", "fcntl", "fiddle", - "io-console", "io-nonblock", "io-wait", "json", - "openssl", "pathname", "prism", "psych", - "stringio", "strscan", "zlib", - ], +ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby") +ruby.toolchain( + name = "ruby", + version_file = "//:.ruby-version", + portable_ruby = True, + portable_ruby_checksums = { + "ruby-3.4.8.x86_64_linux.tar.gz": "e1c5ed91dc8b05e516cb5386a695e5ffed7b585fd577b93880b7eb61d20092e7", + "ruby-3.4.8.macos.tar.gz": "46c48fceb34d11b848f1fd7456ac77df49406f355de4f7d5667f254ea9da2f84", + "ruby-3.4.8.arm64_linux.tar.gz": "fdf6833e7ebe0b9c26a151a6f7481d81e178372046ad2b3f54ae56d159da8b1e", + }, ) ``` -> [!NOTE] -> You can find an HTML-rendered list of the default gems for a Ruby version at -> https://stdgems.org/\ (e.g., https://stdgems.org/3.4.8 for Ruby -> 3.4.8). - **Notes:** -- `rv-ruby` is only supported on Linux and macOS (x86_64 and arm64). +- Portable Ruby is only supported on Linux (arm64, x86_64) and macOS (arm64). +- Setting `portable_ruby = True` has no effect on JRuby, TruffleRuby, or Windows. - On Windows, the toolchain automatically falls back to RubyInstaller. -- Find available `rv-ruby` releases at - https://github.com/spinel-coop/rv-ruby/releases -- The utilities support `--name` to target specific toolchains/bundles and - `--module-bazel` to specify a custom MODULE.bazel path. -- Run utilities with `--dry-run` to preview changes without modifying files. +- Find available portable Ruby releases at https://github.com/jdx/ruby/releases ### JRuby @@ -267,4 +233,5 @@ However, some are known not to work or work only partially (e.g. mRuby has no bu [16]: https://bazel.build/reference/command-line-reference#flag--experimental_inprocess_symlink_creation [17]: https://github.com/bazelbuild/bazel/issues/4327 [18]: docs/rails.md -[19]: https://github.com/spinel-coop/rv-ruby +[19]: https://github.com/jdx/ruby +[20]: ruby/private/portable_ruby_checksums.bzl diff --git a/docs/repository_rules.md b/docs/repository_rules.md index 23967110e..9f1c8e223 100644 --- a/docs/repository_rules.md +++ b/docs/repository_rules.md @@ -30,8 +30,8 @@ Wraps `rb_bundle_rule()` providing default toolchain name.
 load("@rules_ruby//ruby:deps.bzl", "rb_register_toolchains")
 
-rb_register_toolchains(name, version, version_file, msys2_packages, rv_version, rv_checksums,
-                       register, **kwargs)
+rb_register_toolchains(name, version, version_file, msys2_packages, portable_ruby,
+                       portable_ruby_checksums, register, **kwargs)
 
Register a Ruby toolchain and lazily download the Ruby Interpreter. @@ -40,7 +40,7 @@ Register a Ruby toolchain and lazily download the Ruby Interpreter. * _(For MRI on Windows)_ Installed using [RubyInstaller](https://rubyinstaller.org). * _(For JRuby on any OS)_ Downloaded and installed directly from [official website](https://www.jruby.org). * _(For TruffleRuby on Linux and macOS)_ Installed using [ruby-build](https://github.com/rbenv/ruby-build). -* _(For rv-ruby)_ Prebuilt Ruby downloaded from [rv-ruby](https://github.com/spinel-coop/rv-ruby). +* _(With portable_ruby)_ Portable Ruby downloaded from [jdx/ruby](https://github.com/jdx/ruby). * _(For "system")_ Ruby found on the PATH is used. Please note that builds are not hermetic in this case. `WORKSPACE`: @@ -86,8 +86,8 @@ rb_library( | version | a semver version of MRI, or a string like [interpreter type]-[version], or "system" | `None` | | version_file | .ruby-version or .tool-versions file to read version from | `None` | | msys2_packages | extra MSYS2 packages to install | `["libyaml"]` | -| rv_version | rv-ruby release version (e.g., "20251225"). When set, downloads prebuilt Ruby from rv-ruby instead of compiling via ruby-build. | `""` | -| rv_checksums | platform checksums for rv-ruby downloads. Keys: linux-x86_64, linux-arm64, macos-arm64, macos-x86_64. | `{}` | +| portable_ruby | when True, downloads portable Ruby from jdx/ruby instead of compiling via ruby-build. Has no effect on JRuby, TruffleRuby, or Windows. | `False` | +| portable_ruby_checksums | platform checksums for portable Ruby downloads, overriding built-in checksums. Keys: linux-x86_64, linux-arm64, macos-arm64, macos-x86_64. | `{}` | | register | whether to register the resulting toolchains, should be False under bzlmod | `True` | | kwargs | additional parameters to the downloader for this interpreter type | none | @@ -99,8 +99,8 @@ rb_library(
 load("@rules_ruby//ruby:deps.bzl", "rb_bundle_fetch")
 
-rb_bundle_fetch(name, srcs, auth_patterns, bundler_checksums, bundler_remote, env, excluded_gems,
-                gem_checksums, gemfile, gemfile_lock, jar_checksums, netrc, repo_mapping, ruby)
+rb_bundle_fetch(name, srcs, auth_patterns, bundler_checksums, bundler_remote, env, gem_checksums,
+                gemfile, gemfile_lock, jar_checksums, netrc, repo_mapping, ruby)
 
Fetches Bundler dependencies to be automatically installed by other targets. @@ -166,7 +166,6 @@ rb_test( | bundler_checksums | Custom map from Bundler version to its SHA-256 checksum. | Dictionary: String -> String | optional | `{}` | | bundler_remote | Remote to fetch the bundler gem from. | String | optional | `"https://rubygems.org/"` | | env | Environment variables to use during installation. | Dictionary: String -> String | optional | `{}` | -| excluded_gems | List of gem names to exclude from downloading. Useful for default gems bundled with Ruby (e.g., psych, stringio). | List of strings | optional | `[]` | | gem_checksums | SHA-256 checksums for remote gems. Keys are gem names (e.g. foobar-1.2.3), values are SHA-256 checksums. | Dictionary: String -> String | optional | `{}` | | gemfile | Gemfile to install dependencies from. | Label | required | | | gemfile_lock | Gemfile.lock to install dependencies from. | Label | required | | diff --git a/examples/deep_gem/MODULE.bazel b/examples/deep_gem/MODULE.bazel index 0a140c96a..571c4a31a 100644 --- a/examples/deep_gem/MODULE.bazel +++ b/examples/deep_gem/MODULE.bazel @@ -7,6 +7,7 @@ local_path_override( ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby") ruby.toolchain( name = "ruby", + portable_ruby = True, version_file = "//:.ruby-version", ) ruby.bundle_fetch( diff --git a/examples/gem/Gemfile b/examples/gem/Gemfile index 630f17beb..8ecd51b1b 100644 --- a/examples/gem/Gemfile +++ b/examples/gem/Gemfile @@ -4,9 +4,6 @@ source 'https://rubygems.org' gemspec gem 'debug', '>= 1.0.0', platforms: %i[mri mswin64] -# Gem with native extensions. -# Use 5.0.1 to test for Jars fetching on JRuby. -# https://github.com/bazel-contrib/rules_ruby/issues/218 -gem 'psych', '5.0.1' +gem 'psych', '~> 5.3' # native extensions gem 'rspec', '~> 3.0' gem 'rubocop', '~> 1.64' diff --git a/examples/gem/Gemfile.lock b/examples/gem/Gemfile.lock index ad1917095..af677df0b 100644 --- a/examples/gem/Gemfile.lock +++ b/examples/gem/Gemfile.lock @@ -10,6 +10,8 @@ GEM specs: ast (2.4.2) concurrent-ruby (1.3.5) + date (3.5.1) + date (3.5.1-java) debug (1.10.0) irb (~> 1.10) reline (>= 0.3.8) @@ -33,9 +35,11 @@ GEM pp (0.6.2) prettyprint prettyprint (0.2.0) - psych (5.0.1) + psych (5.3.1) + date stringio - psych (5.0.1-java) + psych (5.3.1-java) + date jar-dependencies (>= 0.1.7) racc (1.8.1) racc (1.8.1-java) @@ -78,21 +82,17 @@ GEM unicode-emoji (4.2.0) PLATFORMS - arm64-darwin-23 - arm64-darwin-24 + arm64-darwin java ruby + universal-java universal-java-1.8 - universal-java-11 - universal-java-17 - universal-java-18 - universal-java-21 x64-mingw32 DEPENDENCIES debug (>= 1.0.0) example! - psych (= 5.0.1) + psych (~> 5.3) rspec (~> 3.0) rubocop (~> 1.64) diff --git a/examples/gem/MODULE.bazel b/examples/gem/MODULE.bazel index 06b409fa0..7510b0fb6 100644 --- a/examples/gem/MODULE.bazel +++ b/examples/gem/MODULE.bazel @@ -13,6 +13,7 @@ local_path_override( ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby") ruby.toolchain( name = "ruby", + portable_ruby = True, version_file = "//:.ruby-version", ) use_repo(ruby, "ruby") @@ -29,6 +30,8 @@ ruby.bundle_fetch( gem_checksums = { "ast-2.4.2": "1e280232e6a33754cde542bc5ef85520b74db2aac73ec14acef453784447cc12", "concurrent-ruby-1.3.5": "813b3e37aca6df2a21a3b9f1d497f8cbab24a2b94cab325bffe65ee0f6cbebc6", + "date-3.5.1": "750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0", + "date-3.5.1-java": "12e09477dc932afe45bf768cd362bf73026804e0db1e6c314186d6cd0bee3344", "debug-1.10.0": "11e28ca74875979e612444104f3972bd5ffb9e79179907d7ad46dba44bd2e7a4", "diff-lcs-1.5.1": "273223dfb40685548436d32b4733aa67351769c7dea621da7d9dd4813e63ddfe", "i18n-1.14.7": "ceba573f8138ff2c0915427f1fc5bdf4aa3ab8ae88c8ce255eb3ecf0a11a5d0f", @@ -43,8 +46,8 @@ ruby.bundle_fetch( "parser-3.3.7.0": "7449011771e3e7881297859b849de26a6f4fccd515bece9520a87e7d2116119b", "pp-0.6.2": "947ec3120c6f92195f8ee8aa25a7b2c5297bb106d83b41baa02983686577b6ff", "prettyprint-0.2.0": "2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193", - "psych-5.0.1": "43264252cc33b8e626fb940cddc7379d00f7583500680da32c74a54bd9b000d0", - "psych-5.0.1-java": "c4a94895e325d326063f9d53f5e4f231a5df3a6e593ce9563d19b35fe11f800d", + "psych-5.3.1": "eb7a57cef10c9d70173ff74e739d843ac3b2c019a003de48447b2963d81b1974", + "psych-5.3.1-java": "20a4a81ad01479ef060f604ed75ba42fe673169e67d923b1bae5aa4e13cc5820", "racc-1.8.1": "4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f", "racc-1.8.1-java": "54f2e6d1e1b91c154013277d986f52a90e5ececbe91465d29172e49342732b98", "rainbow-3.1.1": "039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a", @@ -67,7 +70,7 @@ ruby.bundle_fetch( gemfile = "//:Gemfile", gemfile_lock = "//:Gemfile.lock", jar_checksums = { - "org.yaml:snakeyaml:1.33": "11ff459788f0a2d781f56a4a86d7e69202cebacd0273d5269c4ae9f02f3fd8f0", + "org.snakeyaml:snakeyaml-engine:2.10": "c99d9fd66c7c251d881a9cd95089b7c8044c29a1b02983d7036981bd4354ec37", }, ) use_repo(ruby, "bundle", "ruby_toolchains") diff --git a/examples/gem/WORKSPACE b/examples/gem/WORKSPACE index b7b4a8395..dd7266729 100644 --- a/examples/gem/WORKSPACE +++ b/examples/gem/WORKSPACE @@ -16,6 +16,7 @@ http_archive( load("@rules_ruby//ruby:deps.bzl", "rb_bundle_fetch", "rb_register_toolchains") rb_register_toolchains( + portable_ruby = True, version_file = "//:.ruby-version", ) diff --git a/examples/jekyll/MODULE.bazel b/examples/jekyll/MODULE.bazel index 845c43b42..d9eef34fe 100644 --- a/examples/jekyll/MODULE.bazel +++ b/examples/jekyll/MODULE.bazel @@ -13,6 +13,7 @@ local_path_override( ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby") ruby.toolchain( name = "ruby", + portable_ruby = True, version = "3.2.8", ) use_repo(ruby, "ruby") diff --git a/examples/native_ext/MODULE.bazel b/examples/native_ext/MODULE.bazel index e2c8edf8c..9de71fec1 100644 --- a/examples/native_ext/MODULE.bazel +++ b/examples/native_ext/MODULE.bazel @@ -12,6 +12,7 @@ local_path_override( ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby") ruby.toolchain( name = "ruby", + portable_ruby = True, version_file = "//:.ruby-version", ) use_repo(ruby, "ruby", "ruby_toolchains") diff --git a/examples/proto/MODULE.bazel b/examples/proto/MODULE.bazel index aedaebcf8..d1cbda38c 100644 --- a/examples/proto/MODULE.bazel +++ b/examples/proto/MODULE.bazel @@ -14,6 +14,7 @@ local_path_override( ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby") ruby.toolchain( name = "ruby", + portable_ruby = True, version_file = "//:.ruby-version", ) use_repo(ruby, "ruby", "ruby_toolchains") diff --git a/examples/rails/Gemfile b/examples/rails/Gemfile index e39c5ab56..8965c176b 100644 --- a/examples/rails/Gemfile +++ b/examples/rails/Gemfile @@ -4,27 +4,3 @@ source "https://rubygems.org" # Rails for generating and running the People Tracker Rails application gem "rails", "~> 8.0" - -# Pin default gems with C extensions to versions bundled with rv-ruby Ruby -# binaries. The list can be found at https://stdgems.org/ (e.g, -# https://stdgems.org/3.4.8 for Ruby 3.4.8). These gems should NOT be -# downloaded - they're pre-compiled in rv-ruby with portable dependencies. -# -# IMPORTANT: These gems must be listed in the excluded_gems list in the -# bundle_fetch configured in your MODULE.bazel file. -gem "date", "3.4.1" -gem "digest", "3.2.0" -gem "etc", "1.4.6" -gem "fcntl", "1.2.0" -gem "fiddle", "1.1.6" -gem "io-console", "0.8.1" -gem "io-nonblock", "0.3.2" -gem "io-wait", "0.3.2" -gem "json", "2.9.1" -gem "openssl", "3.3.1" -gem "pathname", "0.4.0" -gem "prism", "1.5.2" -gem "psych", "5.2.2" -gem "stringio", "3.1.2" -gem "strscan", "3.1.2" -gem "zlib", "3.2.1" diff --git a/examples/rails/Gemfile.lock b/examples/rails/Gemfile.lock index 17c59b0a0..fd8ad5b41 100644 --- a/examples/rails/Gemfile.lock +++ b/examples/rails/Gemfile.lock @@ -82,20 +82,14 @@ GEM connection_pool (3.0.2) crass (1.0.6) date (3.4.1) - digest (3.2.0) drb (2.2.3) erb (6.0.1) erubi (1.13.1) - etc (1.4.6) - fcntl (1.2.0) - fiddle (1.1.6) globalid (1.3.0) activesupport (>= 6.1) i18n (1.14.8) concurrent-ruby (~> 1.0) io-console (0.8.1) - io-nonblock (0.3.2) - io-wait (0.3.2) irb (1.16.0) pp (>= 0.6.0) rdoc (>= 4.0.0) @@ -141,8 +135,6 @@ GEM racc (~> 1.4) nokogiri (1.19.0-x86_64-linux-musl) racc (~> 1.4) - openssl (3.3.1) - pathname (0.4.0) pp (0.6.3) prettyprint prettyprint (0.2.0) @@ -198,7 +190,6 @@ GEM io-console (~> 0.5) securerandom (0.4.1) stringio (3.1.2) - strscan (3.1.2) thor (1.4.0) timeout (0.6.0) tsort (0.2.0) @@ -211,7 +202,6 @@ GEM websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) zeitwerk (2.7.4) - zlib (3.2.1) PLATFORMS aarch64-linux-gnu @@ -225,23 +215,7 @@ PLATFORMS x86_64-linux-musl DEPENDENCIES - date (= 3.4.1) - digest (= 3.2.0) - etc (= 1.4.6) - fcntl (= 1.2.0) - fiddle (= 1.1.6) - io-console (= 0.8.1) - io-nonblock (= 0.3.2) - io-wait (= 0.3.2) - json (= 2.9.1) - openssl (= 3.3.1) - pathname (= 0.4.0) - prism (= 1.5.2) - psych (= 5.2.2) rails (~> 8.0) - stringio (= 3.1.2) - strscan (= 3.1.2) - zlib (= 3.2.1) BUNDLED WITH 2.6.9 diff --git a/examples/rails/MODULE.bazel b/examples/rails/MODULE.bazel index f1b2d3e7c..3dcce4a2c 100644 --- a/examples/rails/MODULE.bazel +++ b/examples/rails/MODULE.bazel @@ -28,42 +28,11 @@ bazel_dep( ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby") ruby.toolchain( name = "ruby", - rv_checksums = { - "linux-arm64": "0c08c35a99f10817643d548f98012268c5433ae25a737ab4d6751336108a941d", - "linux-x86_64": "f36cef10365d370e0867f0c3ac36e457a26ab04f3cfbbd7edb227a18e6e9b3c3", - "macos-arm64": "cd9d7a1428076bfcc6c2ca3c0eb69b8e671e9b48afb4c351fa4a84927841ffef", - "macos-x86_64": "e9da39082d1dd8502d322c850924d929bc45b7a1e35da593a5606c00673218d4", - }, - rv_version = "20251225", + portable_ruby = True, version_file = "//:.ruby-version", ) ruby.bundle_fetch( name = "root_bundle", - # Exclude default gems with C extensions as listed at - # https://stdgems.org/ (e.g, https://stdgems.org/3.4.8 for - # Ruby 3.4.8) - these are pre-compiled in rv-ruby with portable - # dependencies. Bundled gems are NOT excluded because bundler needs to - # install them normally. - # - # IMPORTANT: These gems must be pinned in your Gemfile, as well. - excluded_gems = [ - "date", - "digest", - "etc", - "fcntl", - "fiddle", - "io-console", - "io-nonblock", - "io-wait", - "json", - "openssl", - "pathname", - "prism", - "psych", - "stringio", - "strscan", - "zlib", - ], gem_checksums = { "action_text-trix-2.1.16": "f645a2c21821b8449fd1d6770708f4031c91a2eedf9ef476e9be93c64e703a8a", "actioncable-8.1.1": "7262307e9693f09b299e281590110ce4b6ba7e4e4cee6da4b9d987eaf56f9139", @@ -83,12 +52,15 @@ ruby.bundle_fetch( "concurrent-ruby-1.3.6": "6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab", "connection_pool-3.0.2": "33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a", "crass-1.0.6": "dc516022a56e7b3b156099abc81b6d2b08ea1ed12676ac7a5657617f012bd45d", + "date-3.4.1": "bf268e14ef7158009bfeaec40b5fa3c7271906e88b196d958a89d4b408abe64f", "drb-2.2.3": "0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373", "erb-6.0.1": "28ecdd99c5472aebd5674d6061e3c6b0a45c049578b071e5a52c2a7f13c197e5", "erubi-1.13.1": "a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9", "globalid-1.3.0": "05c639ad6eb4594522a0b07983022f04aa7254626ab69445a0e493aa3786ff11", "i18n-1.14.8": "285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5", + "io-console-0.8.1": "1e15440a6b2f67b6ea496df7c474ed62c860ad11237f29b3bd187f054b925fcb", "irb-1.16.0": "2abe56c9ac947cdcb2f150572904ba798c1e93c890c256f8429981a7675b0806", + "json-2.9.1": "d2bdef4644052fad91c1785d48263756fe32fcac08b96a20bb15840e96550d11", "logger-1.7.0": "196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203", "loofah-2.25.0": "df5ed7ac3bac6a4ec802df3877ee5cc86d027299f8952e6243b3dac446b060e6", "mail-2.9.0": "6fa6673ecd71c60c2d996260f9ee3dd387d4673b8169b502134659ece6d34941", @@ -110,6 +82,8 @@ ruby.bundle_fetch( "nokogiri-1.19.0-x86_64-linux-musl": "1c4ca6b381622420073ce6043443af1d321e8ed93cc18b08e2666e5bd02ffae4", "pp-0.6.3": "2951d514450b93ccfeb1df7d021cae0da16e0a7f95ee1e2273719669d0ab9df6", "prettyprint-0.2.0": "2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193", + "prism-1.5.2": "192741663a55af1ac1b987caa1092deb666e4ff46a30c5064ad5456acd05df1d", + "psych-5.2.2": "a4a9477c85d3e858086c38cf64e7096abe40d1b1eed248b01020dec0ff9906ab", "racc-1.8.1": "4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f", "rack-3.2.4": "5d74b6f75082a643f43c1e76b419c40f0e5527fcfee1e669ac1e6b73c0ccb6f6", "rack-session-2.1.1": "0b6dc07dea7e4b583f58a48e8b806d4c9f1c6c9214ebc202ec94562cbea2e4e9", @@ -123,6 +97,7 @@ ruby.bundle_fetch( "rdoc-7.0.3": "dfe3d0981d19b7bba71d9dbaeb57c9f4e3a7a4103162148a559c4fc687ea81f9", "reline-0.6.3": "1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835", "securerandom-0.4.1": "cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1", + "stringio-3.1.2": "204f1828f85cdb39d57cac4abc6dc44b04505a223f131587f2e20ae3729ba131", "thor-1.4.0": "8763e822ccb0f1d7bee88cde131b19a65606657b847cc7b7b4b82e772bcd8a3d", "timeout-0.6.0": "6d722ad619f96ee383a0c557ec6eb8c4ecb08af3af62098a0be5057bf00de1af", "tsort-0.2.0": "9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f", @@ -138,31 +113,6 @@ ruby.bundle_fetch( ) ruby.bundle_fetch( name = "people_tracker_bundle", - # Exclude default gems with C extensions as listed at - # https://stdgems.org/ (e.g, https://stdgems.org/3.4.8 for - # Ruby 3.4.8) - these are pre-compiled in rv-ruby with portable - # dependencies. Bundled gems are NOT excluded because bundler needs to - # install them normally. - # - # IMPORTANT: These gems must be pinned in your Gemfile, as well. - excluded_gems = [ - "date", - "digest", - "etc", - "fcntl", - "fiddle", - "io-console", - "io-nonblock", - "io-wait", - "json", - "openssl", - "pathname", - "prism", - "psych", - "stringio", - "strscan", - "zlib", - ], gem_checksums = { "actioncable-8.0.4": "aadb2bf2977b666cfeaa7dee66fd50e147559f78a8d55f6169e913502475e09f", "actionmailbox-8.0.4": "ed0b634a502fb63d1ba01ae025772e9d0261b7ba12e66389c736fcf4635cd80f", @@ -191,6 +141,7 @@ ruby.bundle_fetch( "concurrent-ruby-1.3.6": "6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab", "connection_pool-3.0.2": "33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a", "crass-1.0.6": "dc516022a56e7b3b156099abc81b6d2b08ea1ed12676ac7a5657617f012bd45d", + "date-3.4.1": "bf268e14ef7158009bfeaec40b5fa3c7271906e88b196d958a89d4b408abe64f", "debug-1.11.1": "2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6", "devise-4.9.4": "920042fe5e704c548aa4eb65ebdd65980b83ffae67feb32c697206bfd975a7f8", "dotenv-3.2.0": "e375b83121ea7ca4ce20f214740076129ab8514cd81378161f11c03853fe619d", @@ -203,8 +154,10 @@ ruby.bundle_fetch( "globalid-1.3.0": "05c639ad6eb4594522a0b07983022f04aa7254626ab69445a0e493aa3786ff11", "i18n-1.14.8": "285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5", "importmap-rails-2.2.2": "729f5b1092f832780829ade1d0b46c7e53d91c556f06da7254da2977e93fe614", + "io-console-0.8.1": "1e15440a6b2f67b6ea496df7c474ed62c860ad11237f29b3bd187f054b925fcb", "irb-1.16.0": "2abe56c9ac947cdcb2f150572904ba798c1e93c890c256f8429981a7675b0806", "jbuilder-2.14.1": "4eb26376ff60ef100cb4fd6fd7533cd271f9998327e86adf20fd8c0e69fabb42", + "json-2.9.1": "d2bdef4644052fad91c1785d48263756fe32fcac08b96a20bb15840e96550d11", "kamal-2.10.1": "53b7ecb4c33dd83b1aedfc7aacd1c059f835993258a552d70d584c6ce32b6340", "language_server-protocol-3.17.0.5": "fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc", "lint_roller-1.1.0": "2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87", @@ -237,7 +190,9 @@ ruby.bundle_fetch( "parser-3.3.10.0": "ce3587fa5cc55a88c4ba5b2b37621b3329aadf5728f9eafa36bbd121462aabd6", "pp-0.6.3": "2951d514450b93ccfeb1df7d021cae0da16e0a7f95ee1e2273719669d0ab9df6", "prettyprint-0.2.0": "2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193", + "prism-1.5.2": "192741663a55af1ac1b987caa1092deb666e4ff46a30c5064ad5456acd05df1d", "propshaft-1.3.1": "9acc664ef67e819ffa3d95bd7ad4c3623ea799110c5f4dee67fa7e583e74c392", + "psych-5.2.2": "a4a9477c85d3e858086c38cf64e7096abe40d1b1eed248b01020dec0ff9906ab", "public_suffix-7.0.0": "f7090b5beb0e56f9f10d79eed4d5fbe551b3b425da65877e075dad47a6a1b095", "puma-7.1.0": "e45c10cb124f224d448c98db653a75499794edbecadc440ad616cf50f2fd49dd", "raabro-1.4.0": "d4fa9ff5172391edb92b242eed8be802d1934b1464061ae5e70d80962c5da882", @@ -278,6 +233,7 @@ ruby.bundle_fetch( "sqlite3-2.9.0-x86_64-linux-musl": "ef716ba7a66d7deb1ccc402ac3a6d7343da17fac862793b7f0be3d2917253c90", "sshkit-1.25.0": "c8c6543cdb60f91f1d277306d585dd11b6a064cb44eab0972827e4311ff96744", "stimulus-rails-1.3.4": "765676ffa1f33af64ce026d26b48e8ffb2e0b94e0f50e9119e11d6107d67cb06", + "stringio-3.1.2": "204f1828f85cdb39d57cac4abc6dc44b04505a223f131587f2e20ae3729ba131", "tailwindcss-rails-4.4.0": "efa2961351a52acebe616e645a81a30bb4f27fde46cc06ce7688d1cd1131e916", "tailwindcss-ruby-4.1.18": "b62fad5b00494e92987ee319dfb5c5ad272f0ed93649963d62f08d2ba0f03fa7", "tailwindcss-ruby-4.1.18-aarch64-linux-gnu": "e10f9560bccddbb4955fd535b3bcc8c7071a7df07404dd473a23fa791ec4e46b", diff --git a/examples/rails/people_tracker/Gemfile b/examples/rails/people_tracker/Gemfile index a7e892e73..b7b5f4c18 100644 --- a/examples/rails/people_tracker/Gemfile +++ b/examples/rails/people_tracker/Gemfile @@ -71,27 +71,3 @@ end gem "cancancan", "~> 3.6" gem "devise", "~> 4.9" - -# Pin default gems with C extensions to versions bundled with rv-ruby Ruby -# binaries. The list can be found at https://stdgems.org/ (e.g, -# https://stdgems.org/3.4.8 for Ruby 3.4.8). These gems should NOT be -# downloaded - they're pre-compiled in rv-ruby with portable dependencies. -# -# IMPORTANT: These gems must be listed in the excluded_gems list in the -# bundle_fetch configured in your MODULE.bazel file. -gem "date", "3.4.1" -gem "digest", "3.2.0" -gem "etc", "1.4.6" -gem "fcntl", "1.2.0" -gem "fiddle", "1.1.6" -gem "io-console", "0.8.1" -gem "io-nonblock", "0.3.2" -gem "io-wait", "0.3.2" -gem "json", "2.9.1" -gem "openssl", "3.3.1" -gem "pathname", "0.4.0" -gem "prism", "1.5.2" -gem "psych", "5.2.2" -gem "stringio", "3.1.2" -gem "strscan", "3.1.2" -gem "zlib", "3.2.1" diff --git a/examples/rails/people_tracker/Gemfile.lock b/examples/rails/people_tracker/Gemfile.lock index fa2827937..2471c9905 100644 --- a/examples/rails/people_tracker/Gemfile.lock +++ b/examples/rails/people_tracker/Gemfile.lock @@ -109,7 +109,6 @@ GEM railties (>= 4.1.0) responders warden (~> 1.2.3) - digest (3.2.0) dotenv (3.2.0) drb (2.2.3) ed25519 (1.4.0) @@ -117,9 +116,6 @@ GEM erubi (1.13.1) et-orbi (1.4.0) tzinfo - etc (1.4.6) - fcntl (1.2.0) - fiddle (1.1.6) fugit (1.12.1) et-orbi (~> 1.4) raabro (~> 1.4) @@ -132,8 +128,6 @@ GEM activesupport (>= 6.0.0) railties (>= 6.0.0) io-console (0.8.1) - io-nonblock (0.3.2) - io-wait (0.3.2) irb (1.16.0) pp (>= 0.6.0) rdoc (>= 4.0.0) @@ -199,14 +193,12 @@ GEM racc (~> 1.4) nokogiri (1.19.0-x86_64-linux-musl) racc (~> 1.4) - openssl (3.3.1) orm_adapter (0.5.0) ostruct (0.6.3) parallel (1.27.0) parser (3.3.10.0) ast (~> 2.4.1) racc - pathname (0.4.0) pp (0.6.3) prettyprint prettyprint (0.2.0) @@ -344,7 +336,6 @@ GEM stimulus-rails (1.3.4) railties (>= 6.0.0) stringio (3.1.2) - strscan (3.1.2) tailwindcss-rails (4.4.0) railties (>= 7.0.0) tailwindcss-ruby (~> 4.0) @@ -386,7 +377,6 @@ GEM xpath (3.2.0) nokogiri (~> 1.8) zeitwerk (2.7.4) - zlib (3.2.1) PLATFORMS aarch64-linux @@ -406,26 +396,13 @@ DEPENDENCIES brakeman cancancan (~> 3.6) capybara - date (= 3.4.1) debug devise (~> 4.9) - digest (= 3.2.0) - etc (= 1.4.6) - fcntl (= 1.2.0) - fiddle (= 1.1.6) importmap-rails - io-console (= 0.8.1) - io-nonblock (= 0.3.2) - io-wait (= 0.3.2) jbuilder - json (= 2.9.1) kamal minitest (~> 5.25) - openssl (= 3.3.1) - pathname (= 0.4.0) - prism (= 1.5.2) propshaft - psych (= 5.2.2) puma (>= 5.0) rails (~> 8.0.2, >= 8.0.2.1) rubocop-rails-omakase @@ -435,14 +412,11 @@ DEPENDENCIES solid_queue sqlite3 (>= 2.1) stimulus-rails - stringio (= 3.1.2) - strscan (= 3.1.2) tailwindcss-rails thruster turbo-rails tzinfo-data web-console - zlib (= 3.2.1) BUNDLED WITH 2.6.9 diff --git a/ruby/extensions.bzl b/ruby/extensions.bzl index 3e9d3e36f..98f9bde41 100644 --- a/ruby/extensions.bzl +++ b/ruby/extensions.bzl @@ -23,7 +23,6 @@ ruby_bundle_fetch = tag_class(attrs = { "jar_checksums": attr.string_dict(), "bundler_remote": attr.string(default = "https://rubygems.org/"), "bundler_checksums": attr.string_dict(), - "excluded_gems": attr.string_list(default = []), }) ruby_toolchain = tag_class(attrs = { @@ -32,17 +31,17 @@ ruby_toolchain = tag_class(attrs = { "version_file": attr.label(doc = "File to read Ruby version from."), "ruby_build_version": attr.string(doc = "Version of ruby-build to use.", default = RUBY_BUILD_VERSION), "msys2_packages": attr.string_list(doc = "Extra MSYS2 packages to install.", default = ["libyaml"]), - "rv_version": attr.string( + "portable_ruby": attr.bool( doc = """\ -rv-ruby release version (e.g., '20251225'). When set, downloads prebuilt Ruby \ -from rv-ruby instead of compiling via ruby-build.\ +When True, downloads portable Ruby from jdx/ruby instead of compiling via \ +ruby-build. Has no effect on JRuby, TruffleRuby, or Windows.\ """, - default = "", + default = False, ), - "rv_checksums": attr.string_dict( + "portable_ruby_checksums": attr.string_dict( doc = """\ -Platform checksums for rv-ruby downloads. Keys: linux-x86_64, linux-arm64, \ -macos-arm64, macos-x86_64.\ +Platform checksums for portable Ruby downloads, overriding built-in checksums. \ +Keys: linux-x86_64, linux-arm64, macos-arm64, macos-x86_64.\ """, default = {}, ), @@ -77,7 +76,6 @@ def _ruby_module_extension(module_ctx): jar_checksums = bundle_fetch.jar_checksums, bundler_remote = bundle_fetch.bundler_remote, bundler_checksums = bundle_fetch.bundler_checksums, - excluded_gems = bundle_fetch.excluded_gems, ) if module_ctx.is_dev_dependency(bundle_fetch): direct_dev_dep_names.append(bundle_fetch.name) @@ -106,8 +104,8 @@ def _ruby_module_extension(module_ctx): toolchain.version_file, toolchain.msys2_packages, toolchain.ruby_build_version, - toolchain.rv_version, - toolchain.rv_checksums, + toolchain.portable_ruby, + toolchain.portable_ruby_checksums, ) if module_ctx.is_dev_dependency(toolchain): direct_dev_dep_names.append(toolchain.name) @@ -122,8 +120,8 @@ def _ruby_module_extension(module_ctx): version_file, msys2_packages, ruby_build_version, - rv_version, - rv_checksums, + portable_ruby, + portable_ruby_checksums, ) = config rb_register_toolchains( name = name, @@ -131,8 +129,8 @@ def _ruby_module_extension(module_ctx): version_file = version_file, msys2_packages = msys2_packages, ruby_build_version = ruby_build_version, - rv_version = rv_version, - rv_checksums = rv_checksums, + portable_ruby = portable_ruby, + portable_ruby_checksums = portable_ruby_checksums, register = False, ) diff --git a/ruby/private/BUILD b/ruby/private/BUILD index 400e30dc9..2244417de 100644 --- a/ruby/private/BUILD +++ b/ruby/private/BUILD @@ -72,12 +72,6 @@ bzl_library( ], ) -bzl_library( - name = "bundler_checksums", - srcs = ["bundler_checksums.bzl"], - visibility = ["//ruby:__subpackages__"], -) - bzl_library( name = "bundle_fetch", srcs = ["bundle_fetch.bzl"], @@ -122,6 +116,13 @@ bzl_library( ], ) +bzl_library( + name = "download", + srcs = ["download.bzl"], + visibility = ["//ruby:__subpackages__"], + deps = [":portable_ruby_checksums"], +) + bzl_library( name = "bundle", srcs = ["bundle.bzl"], @@ -129,8 +130,14 @@ bzl_library( ) bzl_library( - name = "download", - srcs = ["download.bzl"], + name = "bundler_checksums", + srcs = ["bundler_checksums.bzl"], + visibility = ["//ruby:__subpackages__"], +) + +bzl_library( + name = "portable_ruby_checksums", + srcs = ["portable_ruby_checksums.bzl"], visibility = ["//ruby:__subpackages__"], ) diff --git a/ruby/private/bundle_fetch.bzl b/ruby/private/bundle_fetch.bzl index 1d077dad6..56e0d73f6 100644 --- a/ruby/private/bundle_fetch.bzl +++ b/ruby/private/bundle_fetch.bzl @@ -174,13 +174,7 @@ def _rb_bundle_fetch_impl(repository_ctx): repository_name = _normalize_bzlmod_repository_name(repository_ctx.name) # Fetch gems and expose them as `rb_gem()` targets. - # Skip gems that are in the excluded_gems list (e.g., default gems bundled with Ruby). - excluded_gems = {name: True for name in repository_ctx.attr.excluded_gems} - for gem in gemfile_lock.remote_packages: - if gem.name in excluded_gems: - # Skip downloading this gem - it's bundled with Ruby - continue gem_checksums[gem.full_name] = _download_gem( repository_ctx, gem, @@ -317,13 +311,6 @@ rb_bundle_fetch = repository_rule( default = {}, doc = "SHA-256 checksums for JAR dependencies. Keys are Maven coordinates (e.g. org.yaml:snakeyaml:1.33), values are SHA-256 checksums.", ), - "excluded_gems": attr.string_list( - default = [], - doc = """\ -List of gem names to exclude from downloading. Useful for default gems bundled \ -with Ruby (e.g., psych, stringio).\ -""", - ), "ruby": attr.label( doc = "Override Ruby toolchain to use for installation.", providers = [platform_common.ToolchainInfo], diff --git a/ruby/private/bundler_checksums.bzl b/ruby/private/bundler_checksums.bzl index 450e093c3..46598574b 100644 --- a/ruby/private/bundler_checksums.bzl +++ b/ruby/private/bundler_checksums.bzl @@ -4,6 +4,13 @@ # curl -sSf https://rubygems.org/api/v1/versions/bundler.json | jq 'map({key: .number, value: .sha}) | from_entries' | grep -vE '\.pre|\.rc|\.beta' BUNDLER_CHECKSUMS = { + "4.0.6": "4e43c13acf18c417926053d00f964a45c54f71721b33066336a0d7db5de73f08", + "4.0.5": "5d52254ae14057ad6b02b20615436bd585790a7ca5ee3ef7ac05799dc90723fd", + "4.0.4": "d0f94b7ba176666896318e419f9a0cc55b698874bffec64cc33537611c61bd16", + "4.0.3": "f06623d5edf4183e5fac847a953c1f1bd95e27aa766471525d3a9c70bdee9394", + "4.0.2": "9a13f770fff8ee2f27af4b833c10f254d104cc01db53a12adcdb3300841f79fb", + "4.0.1": "1d1a19f59f45ae0d9c0698ce0c50a58028963af65e28d755cd6ced017fe7bd39", + "4.0.0": "7d9461e65e813863ce9b710d5b2f3636d1b4904ea64595e54e957a25d721bd3d", "2.7.2": "1decaf9e2e1acb91b6586a2925c8f3f6da2334a82731a62ff2ded1b83c283871", "2.7.1": "0ad5a002a879776b2a98be652f557ac8731be3353612d63fa4ef1b2706dc1e0b", "2.7.0": "27c18e8c1593dd0cab39140265453001e3bd2b440e0873480104c6df347e15ab", diff --git a/ruby/private/download.bzl b/ruby/private/download.bzl index c483fe771..3e7a669f8 100644 --- a/ruby/private/download.bzl +++ b/ruby/private/download.bzl @@ -1,19 +1,14 @@ "Repository rule for fetching Ruby interpreters" +load("//ruby/private:portable_ruby_checksums.bzl", "PORTABLE_RUBY_CHECKSUMS") + RUBY_BUILD_VERSION = "20260114" _JRUBY_BINARY_URL = "https://repo1.maven.org/maven2/org/jruby/jruby-dist/{version}/jruby-dist-{version}-bin.tar.gz" _RUBY_BUILD_URL = "https://github.com/rbenv/ruby-build/archive/refs/tags/v{version}.tar.gz" _RUBY_INSTALLER_URL = "https://github.com/oneclick/rubyinstaller2/releases/download/RubyInstaller-{version}-1/rubyinstaller-devkit-{version}-1-x64.exe" -_RV_RUBY_URL = "https://github.com/spinel-coop/rv-ruby/releases/download/{release}/ruby-{version}.{platform}.tar.gz" - -# Map Bazel OS/arch to rv-ruby artifact naming -_RV_RUBY_PLATFORMS = { - "linux-x86_64": "x86_64_linux", - "linux-arm64": "arm64_linux", - "macos-arm64": "arm64_sonoma", - "macos-x86_64": "ventura", -} +_PORTABLE_RUBY_NAME = "ruby-{version}.{platform}.tar.gz" +_MISE_RUBY_URL = "https://github.com/jdx/ruby/releases/download/{release}/{name}" # Maintained JRuby versions integrity from https://repo1.maven.org/maven2/org/jruby/jruby-dist. # Run the following script to update the list: @@ -105,26 +100,7 @@ def _rb_download_impl(repository_ctx): ruby_binary_name = "ruby" gem_binary_name = "gem" - # Handle rv-ruby: only supported on Linux and macOS - use_rv_ruby = False - if repository_ctx.attr.rv_version: - if repository_ctx.os.name.startswith("windows"): - # buildifier: disable=print - print("""\ -WARNING: rv-ruby is not supported on Windows. Falling back to RubyInstaller \ -for Ruby %s.\ -""" % version) - else: - use_rv_ruby = True - - if use_rv_ruby: - _install_rv_ruby( - repository_ctx, - repository_ctx.attr.rv_version, - version, - repository_ctx.attr.rv_checksums, - ) - elif version.startswith("jruby"): + if version.startswith("jruby"): _install_jruby(repository_ctx, version) engine = "jruby" @@ -152,11 +128,25 @@ for Ruby %s.\ openssl_prefix = _execute_command(repository_ctx, ["dist/bin/ruby", "-rrbconfig", "-e", "puts ENV['OPENSSL_PREFIX']"]) if openssl_prefix: env.update({"OPENSSL_PREFIX": openssl_prefix}) - elif version == "system": engine = _symlink_system_ruby(repository_ctx) elif repository_ctx.os.name.startswith("windows"): _install_via_rubyinstaller(repository_ctx, version) + elif repository_ctx.attr.portable_ruby: + _install_portable_ruby( + repository_ctx, + version, + repository_ctx.attr.portable_ruby_checksums, + ) + + # Portable Ruby may ship with libyaml and openssl which are needed to compile the + # psych and openssl gems respectively when built with --incompatible_strict_action_env). + # TODO: This won't work on RBE. + dist_dir = str(repository_ctx.path("dist")) + if repository_ctx.path("dist/include/yaml.h").exists: + env.update({"BUNDLE_BUILD__PSYCH": "--with-libyaml-dir=" + dist_dir}) + if repository_ctx.path("dist/include/openssl").exists: + env.update({"BUNDLE_BUILD__OPENSSL": "--with-openssl-dir=" + dist_dir}) else: _install_via_ruby_build(repository_ctx, version) @@ -289,12 +279,11 @@ def _install_via_ruby_build(repository_ctx, version): repository_ctx.delete("ruby-build") -def _install_rv_ruby(repository_ctx, rv_version, ruby_version, checksums): - """Install prebuilt Ruby from rv-ruby project. +def _install_portable_ruby(repository_ctx, ruby_version, checksums): + """Install portable Ruby from jdx/ruby project. Args: repository_ctx: Repository context - rv_version: rv-ruby release version (e.g., "20251225") ruby_version: Ruby version (e.g., "3.4.8") checksums: Dict mapping platform keys to SHA256 checksums """ @@ -317,48 +306,39 @@ def _install_rv_ruby(repository_ctx, rv_version, ruby_version, checksums): else: arch_key = arch - platform_key = os_key + "-" + arch_key - - # Validate platform is supported by rv-ruby - if platform_key not in _RV_RUBY_PLATFORMS: - supported = ", ".join(sorted(_RV_RUBY_PLATFORMS.keys())) - fail(""" -rv-ruby does not support platform: {platform} -Detected OS: {os} ({os_raw}) -Detected architecture: {arch} ({arch_raw}) -Supported platforms: {supported} -""".format( - platform = platform_key, - os = os_key, - os_raw = os_name, - arch = arch_key, - arch_raw = arch, - supported = supported, - )) + if os_key == "macos" and arch_key == "x86_64": + print("Warning: Portable Ruby does not support macOS on x86_64, falling back to compiling from source.") # buildifier: disable=print + _install_via_ruby_build(repository_ctx, ruby_version) + return + + if os_key == "macos": + # Intel is not supported + platform_key = "macos" + else: + platform_key = arch_key + "_" + os_key - rv_platform = _RV_RUBY_PLATFORMS[platform_key] + artifact_name = _PORTABLE_RUBY_NAME.format( + version = ruby_version, + platform = platform_key, + ) # Get checksum if provided (Bazel will warn if not provided) kwargs = {} - if platform_key in checksums: - kwargs["sha256"] = checksums[platform_key] + if artifact_name in checksums: + kwargs["sha256"] = checksums[artifact_name] + elif artifact_name in PORTABLE_RUBY_CHECKSUMS: + kwargs["sha256"] = PORTABLE_RUBY_CHECKSUMS[artifact_name] repository_ctx.report_progress( - "Downloading rv-ruby %s for %s" % (ruby_version, platform_key), + "Downloading portable Ruby %s for %s" % (ruby_version, platform_key), ) - - # rv-ruby releases have a nested directory structure: - # rv-ruby@//bin/ruby - # rv-ruby@//lib/... - # Strip the outer directories to get the Ruby installation at dist/ repository_ctx.download_and_extract( - url = _RV_RUBY_URL.format( - release = rv_version, - version = ruby_version, - platform = rv_platform, + url = _MISE_RUBY_URL.format( + release = ruby_version, + name = artifact_name, ), output = "dist/", - stripPrefix = "rv-ruby@{v}/{v}".format(v = ruby_version), + stripPrefix = "ruby-{}".format(ruby_version), **kwargs ) @@ -416,21 +396,19 @@ to install. You normally don't need to change this, unless `version` you pass is which isn't available in this ruby-build yet. """, ), - "rv_version": attr.string( - default = "", + "portable_ruby": attr.bool( + default = False, doc = """ -rv-ruby release version (e.g., "20251225"). - -When set, downloads prebuilt Ruby from rv-ruby instead of compiling via ruby-build. -The Ruby version is still read from the `version` or `version_file` attribute. +When set to True, downloads portable Ruby from jdx/ruby instead of compiling via ruby-build. +Has no effect on JRuby, TruffleRuby, or Windows (which use their own installation methods). """, ), - "rv_checksums": attr.string_dict( + "portable_ruby_checksums": attr.string_dict( default = {}, doc = """ -Platform checksums for rv-ruby downloads. +Platform checksums for portable Ruby downloads, overriding built-in checksums. Can be generated by running `bazel run @rules_ruby//tools/generate_portable_ruby_checksums`. -Keys: linux-x86_64, linux-arm64, macos-arm64, macos-x86_64. +Keys: artifact names (e.g., ruby-3.4.8.x86_64_linux.tar.gz, ruby-3.4.8.macos.tar.gz). Values: SHA256 checksums for the corresponding platform. """, ), diff --git a/ruby/private/portable_ruby_checksums.bzl b/ruby/private/portable_ruby_checksums.bzl new file mode 100644 index 000000000..166436806 --- /dev/null +++ b/ruby/private/portable_ruby_checksums.bzl @@ -0,0 +1,112 @@ +"Provides checksums for portable Ruby versions from jdx/ruby." + +# Generated via: +# bazel run //tools/generate_portable_ruby_checksums -- --all + +PORTABLE_RUBY_CHECKSUMS = { + "ruby-4.0.1.x86_64_linux.tar.gz": "df9793cc730f782273fb17c70bc205f724fd2e127e95c0c059ae198705110b98", + "ruby-4.0.1.macos.tar.gz": "d5fd316eabcbe58e33be6b44125c7b22f87da90bae0d7e28ffc6be34abe1476e", + "ruby-4.0.1.arm64_linux.tar.gz": "59f6f03b5113afac408248c7b762a8a4d8bbe223917ef3cc56614d061e296f92", + "ruby-4.0.0.x86_64_linux.tar.gz": "4e08d47347c316a0715bc3091c2eaa057a7d9028330bd8f4a6f8a54afc2cdb4f", + "ruby-4.0.0.macos.tar.gz": "0acf7816bfe41553205191394b9fa913664a01b92a13093c96c8c0b751b07cce", + "ruby-4.0.0.arm64_linux.tar.gz": "383cfa9b1ddb4d67e16cceb8472e878662ff6cdf49922d642ca373d2ec5c17e0", + "ruby-4.0.0-preview3.x86_64_linux.tar.gz": "c58920d762c7802d138e62903ef04a0ab0f48c2721687a3048c692e13a07fd0a", + "ruby-4.0.0-preview3.macos.tar.gz": "61813baa7420f8408595f57cd3e134442235ecc2c4a6ad21aeb5bda34e1cce02", + "ruby-4.0.0-preview3.arm64_linux.tar.gz": "9d6a1d1dda2bae8b9aef0381f023fe59f093b0c7683815e596011912e58b6857", + "ruby-4.0.0-preview2.x86_64_linux.tar.gz": "230d73bc04eaf184d785b5d6beb8e7d2371a56fa5af66c57cfac5c51c9169dca", + "ruby-4.0.0-preview2.macos.tar.gz": "39a8728fed0386c5e2145163f5084a88bbad5fe144493c524ae26ae5c6a79bd8", + "ruby-4.0.0-preview2.arm64_linux.tar.gz": "b2ff3eaca2fe3495a8494553da2aa8dfbef535e45e390397c54aae1e16a6f3f9", + "ruby-3.5.0-preview1.x86_64_linux.tar.gz": "f02fa8f8c3aa92c24e0108db467134dcc8a2d4c82894ed019974d30246e3baa1", + "ruby-3.5.0-preview1.macos.tar.gz": "c90849af78a13d2e344baa7b7b58069027f3744a6af1996c0defa8b64fea1c3f", + "ruby-3.5.0-preview1.arm64_linux.tar.gz": "7adf7075a489147f94b277723989f083d830dacedf19b97617c3240ec2513e29", + "ruby-3.4.8.x86_64_linux.tar.gz": "e1c5ed91dc8b05e516cb5386a695e5ffed7b585fd577b93880b7eb61d20092e7", + "ruby-3.4.8.macos.tar.gz": "46c48fceb34d11b848f1fd7456ac77df49406f355de4f7d5667f254ea9da2f84", + "ruby-3.4.8.arm64_linux.tar.gz": "fdf6833e7ebe0b9c26a151a6f7481d81e178372046ad2b3f54ae56d159da8b1e", + "ruby-3.4.7.x86_64_linux.tar.gz": "ea1a3ac2c5301358e22371ca2b526f48e910fccbcbccdc5542d7c8cef4c5b9d0", + "ruby-3.4.7.macos.tar.gz": "cf0dc9f8f4d476860f24fc81d4b338317471cf1fffa0b09ce26d489407db511b", + "ruby-3.4.7.arm64_linux.tar.gz": "9e65819ba3ca56dd49f012692dca32efb6ae5142f6493bb50fd4ccaa766cc31c", + "ruby-3.4.6.x86_64_linux.tar.gz": "7439cab09b14c102978f2f05c9bfea48a44e84a90bf5d797fd69476c84ce9ee8", + "ruby-3.4.6.macos.tar.gz": "85c95717d2276c3de1fb488529c55cedba0daacce9b20bfd77649f267d8076b0", + "ruby-3.4.6.arm64_linux.tar.gz": "d212488ce3aec7c2a228e9d171598a8d3e1c1202c3140dfe7f1380cfebf501ee", + "ruby-3.4.5.x86_64_linux.tar.gz": "ce7f0a6347b4aaaac995ca2ce635874ae4f169619b39c8345b80dc78be628c90", + "ruby-3.4.5.macos.tar.gz": "49ba77f4ef04e2ced7f3a5a043e489b16bd29fee450d9f61b741ff752fb7dd3a", + "ruby-3.4.5.arm64_linux.tar.gz": "0b65653b42b8e7fc3eda4ddc56b415aafdb6428f25d9485bcbd4f445e0d237be", + "ruby-3.4.4.x86_64_linux.tar.gz": "0221eba0842d35cbcbf914ae1e92061a865c5aaa11fd32517318ad1691b043bd", + "ruby-3.4.4.macos.tar.gz": "3737e31d09dd1ef4309e1bc044e48ee78c236d9990ddeb113b495873e04a5457", + "ruby-3.4.4.arm64_linux.tar.gz": "5cd67b50c1b5ffc3135e14f07e1264cc3ac8a0ccb339a3b5f17c9c588bc1ff17", + "ruby-3.4.3.x86_64_linux.tar.gz": "b9631adc5ad33dd29fad47a04c43777162ce71141cd68131e30e0a7b902b6f67", + "ruby-3.4.3.macos.tar.gz": "9b5d7cd508a4173e8fd98ad3de6a315016f6ab3fd50db8654dea34643a3bb3b3", + "ruby-3.4.3.arm64_linux.tar.gz": "622cdb89ae42e3ba667131cd0cfd7503284ac8efc41db71753483b773250db0f", + "ruby-3.4.2.x86_64_linux.tar.gz": "9ad469e718293998c14a31b337aaddfaa5761fcf44e6d239755f99417832b770", + "ruby-3.4.2.macos.tar.gz": "fcef3a381f0e44abba5411e43ca064d60cd4919d9f0a22c99c820d1aa5584e21", + "ruby-3.4.2.arm64_linux.tar.gz": "6e12d9bb981328f435d6600b5991520db2121fd9ddb7ca0854b5c0d79523e2bb", + "ruby-3.4.1.x86_64_linux.tar.gz": "9b4ea357f6b82e0f53b7649dac6e5b2fe5ec9d5ba298a489a1d99e9890df95ef", + "ruby-3.4.1.macos.tar.gz": "18d95d7d8b9575e9b77ce3d35b635a71a7208ec282c25689375e84c1271449ca", + "ruby-3.4.1.arm64_linux.tar.gz": "d142ba8dde62490d5b09488d709ab5c7f014901cfc8085fa1498cb849df483f7", + "ruby-3.4.0.x86_64_linux.tar.gz": "6818ae6ae6e648d6e6ec35b12b6bc5179af4b269afec038f2c5ae181c59ae7e3", + "ruby-3.4.0.macos.tar.gz": "bac2dabc8fee3002b04962c09c64db8677d634644db369135a637e36b7dbac39", + "ruby-3.4.0.arm64_linux.tar.gz": "22033d237b028b2c07d19b43a59d54366ed112340fe313ac2a6e5b4f7e9a8d9e", + "ruby-3.3.9.x86_64_linux.tar.gz": "be04260f132844a67a2bb965260599ac54989f0d33c70859661671db7d4fb4cc", + "ruby-3.3.9.macos.tar.gz": "503b3a1d67ae804f97c8d22d6b27fb0246c8d21260ef69a6ed27dc2505583ef3", + "ruby-3.3.9.arm64_linux.tar.gz": "8566ca9c1db5a0e8d4e7ef9c31f744207bc4bd5769b795dff1e4fef4c39dd0b5", + "ruby-3.3.8.x86_64_linux.tar.gz": "bf95f450d49b2fb8d0b5a113be94135800f252d50bc1bf830c17caa6d2ab0756", + "ruby-3.3.8.macos.tar.gz": "a7e9764e7b2912455ed4065aea2ba4561ef309a0080c2cd7d6e5504f91818760", + "ruby-3.3.8.arm64_linux.tar.gz": "ae78b3b5982607dfe654dc7c41d37abccb7e45b5ee3abb999c269ff0e3d9ac80", + "ruby-3.3.7.x86_64_linux.tar.gz": "f8322097295b09cc5f26b0c44eff82ecb94af8415735216ba3362a5f7d5e3e03", + "ruby-3.3.7.macos.tar.gz": "20620b53d419c950ea44f1e0971b6e19194e0c72fd4f7954a38f2c70e5af41d0", + "ruby-3.3.7.arm64_linux.tar.gz": "10cf4670fbbf07a3a865da6afefe2a96d7039f665e3d3149fa602b245f78c021", + "ruby-3.3.6.x86_64_linux.tar.gz": "83729c2b68410c91758d6cd92a8b46fa99608dc1a4aaa913947e3abdf252aa76", + "ruby-3.3.6.macos.tar.gz": "3a766d133d9a3f03799bd96523571c55c7735624768a57c656cf1fc24de8407e", + "ruby-3.3.6.arm64_linux.tar.gz": "8a1730b277d3ad34e065495c4d5dcf2f9f4a72bbef19485fa77ec86aacc7962b", + "ruby-3.3.5.x86_64_linux.tar.gz": "3d4e85f5e3b3b5b5913ca2105764d90b62435fb8b658e71c7a457a8441e8b8ea", + "ruby-3.3.5.macos.tar.gz": "80d412a9b7de99f7afcb602e9a64d489b50393032cb825abe72b61378232ad60", + "ruby-3.3.5.arm64_linux.tar.gz": "57c70825b333b8339bef3aed8b4f9c254873020bc632e8c6232e45d1a0c57837", + "ruby-3.3.4.x86_64_linux.tar.gz": "74b8c3e4f92392a3a24530b9208b5dcfa7b194aa527af941d8c20946ecaad718", + "ruby-3.3.4.macos.tar.gz": "e36a4f4640ac8beacaf2137ee45e0b65b6bb25d42d04ceacf8d001e56ccd85b4", + "ruby-3.3.4.arm64_linux.tar.gz": "eae558722a9ab250ef57d737073263d46e2a99c42381019a965a9c578e10c017", + "ruby-3.3.3.x86_64_linux.tar.gz": "ca0f454eba2a985138e924839d8f49ded4c6ea64ad2e8540c41450bc17a707e4", + "ruby-3.3.3.macos.tar.gz": "f9187b97ad14a16a625c970f0cea42f84246b9899af87aa6cfb53ff1e0ab6ab4", + "ruby-3.3.3.arm64_linux.tar.gz": "bfb6f9f114b8a010472d1148c7d4b38241a19abe6a6c1595087e9ebbaae093c4", + "ruby-3.3.2.x86_64_linux.tar.gz": "5d02cc62a1618ab9e1cb00c5d807a257fcf3835a1234f77136427b577b387fec", + "ruby-3.3.2.macos.tar.gz": "a8105ec8bc425ea1d9aa9129f3ed498bb594efa83cb9195de0c8a2c5593f0866", + "ruby-3.3.2.arm64_linux.tar.gz": "b630cbddf8f19391c27fee5911439bcd740da2382a9bd1b9965012a7c65ba0aa", + "ruby-3.3.10.x86_64_linux.tar.gz": "864b2f58f33d88f2d3c8130b2d50f3289796c1a2a0e0cc945253abd2d329796e", + "ruby-3.3.10.macos.tar.gz": "bdbfeceee5981e29a64c0d515a29755fad723ef17c259317af7976aedca22098", + "ruby-3.3.10.arm64_linux.tar.gz": "0265cb5f0626dd6ef20ef7043ed8dfb9daa38984793b26cadc8170653cc082e8", + "ruby-3.3.1.x86_64_linux.tar.gz": "7f45190f2082d92f7ce364704978d5c08ae58ceedf840907288d3a458e710d43", + "ruby-3.3.1.macos.tar.gz": "86ee3826214e6aae96cf695719d06e0add93a69cf198a8e070cc2d6373075347", + "ruby-3.3.1.arm64_linux.tar.gz": "6eab9b363552e4e6f7d820ed7ac37951d930f90c0f5f3e5cb229d12ab796209c", + "ruby-3.3.0.x86_64_linux.tar.gz": "8a6fa8b1a78eba16d22e80e6286ebb52aa9ef73bb5d696f6432b25346836379c", + "ruby-3.3.0.macos.tar.gz": "279757e685c850a3bc836ab296ee667a176f923662fe4c738fd95f575a3518cb", + "ruby-3.3.0.arm64_linux.tar.gz": "51bc7a3178a9d676dfa43076d6e031f6749b00230b9801a29db4363bb449777d", + "ruby-3.2.9.x86_64_linux.tar.gz": "d646b2a3484b5fa6396608c40b01543d81c60d6bc2288ee36235bc35139529a0", + "ruby-3.2.9.macos.tar.gz": "4c3242afe861ef88213f92b88ae2f121c8adf74335b7092ecc07fd9e699c6ccc", + "ruby-3.2.9.arm64_linux.tar.gz": "33a9dbf2247bf474be7d713d6a9a0737fffef9170d726ba15e06cf2699e4df46", + "ruby-3.2.8.x86_64_linux.tar.gz": "3ed0ecb06ed8aaa409f891f4becde8f0f1523b5acbdfdcdbd81b5a0226c9eddb", + "ruby-3.2.8.macos.tar.gz": "d5d7d071183d8cd60ecf95cbdff1b166e64b4d79bd32d7a4e359e92a74b9a8e2", + "ruby-3.2.8.arm64_linux.tar.gz": "25ce1492a308f3dba01509fbc541be999d48d6c4f9fb01c9f16b28518c5e3320", + "ruby-3.2.7.x86_64_linux.tar.gz": "8dc113aca806ac23fa08562953ab0a9bb2bbfb7ea621166156774b6b52e63ddf", + "ruby-3.2.7.macos.tar.gz": "f418eba7bc7cf13e1ff08898df3f321002cc49c6382a4a26ae634c9317b41702", + "ruby-3.2.7.arm64_linux.tar.gz": "0f19d3eadc5203cd34696341c7e9503133832f0e5729e63286a57de3e8a30d73", + "ruby-3.2.6.x86_64_linux.tar.gz": "b31295cb4d023d576e08679511a2ab1c464d3f9f4b19663e5a40152645cd98ba", + "ruby-3.2.6.macos.tar.gz": "80de724860d24ff47c2b193051e7b0df99063d5cece8819664ef2e0398b7c7dd", + "ruby-3.2.6.arm64_linux.tar.gz": "33f353a09664b86b4e65a15f7a306b34a22ad4c2b562ca6b3a970f69b6f5944a", + "ruby-3.2.5.x86_64_linux.tar.gz": "a5d8ecd43deed0806f6b547505b22270522af562d89feed1f15abcfaeba71d30", + "ruby-3.2.5.macos.tar.gz": "ca53505a18a01164706b592ff324abdd8c7b37adeb12e6faa6894396aa4e07fe", + "ruby-3.2.5.arm64_linux.tar.gz": "36d9db634bdded83da414da63c06e849d89d344baaf8772b09e608d38d7e7b7b", + "ruby-3.2.4.x86_64_linux.tar.gz": "45ddaa50db174a8636c768dd13fb24da49408ac544c8d4b933afef92c9136edd", + "ruby-3.2.4.macos.tar.gz": "e56911eff21e9b0c0d57d5998628a9ab8a5e62f7d492617bd98886db98d17f00", + "ruby-3.2.4.arm64_linux.tar.gz": "9a033ab671b6c323a12eda0935938f85b42cf469506cd184ddc33fe1b5222e12", + "ruby-3.2.3.x86_64_linux.tar.gz": "8d66a935e875af7ab3a50ec8f99aa66c1567b603015fde80aaebf133d95bf9c8", + "ruby-3.2.3.macos.tar.gz": "375445c663d9c69fac68f9ab4107893e5f006771ae505f1e112a5d3679565d32", + "ruby-3.2.3.arm64_linux.tar.gz": "d21a1d83f1d76e2d54cc5be686391f9f7e7816e16dad90caca088e4d7069877f", + "ruby-3.2.2.x86_64_linux.tar.gz": "d1963b15781661aab878b0266d383cf46ba0b3c84e3c39500bc2121bb69dd1bc", + "ruby-3.2.2.macos.tar.gz": "a50886781ec0797a1d77a8af042facd0527530b8a0d2c836693258e9c2f6005f", + "ruby-3.2.2.arm64_linux.tar.gz": "a5b963775a08ee6c3ad1d89c97adfddc394ac77b38a4ee64ce0caeb4832aa3b7", + "ruby-3.2.10.x86_64_linux.tar.gz": "ba756ddc71b7f262440e038557541666bec147bff32c36086f99ccdc4ee327bf", + "ruby-3.2.10.macos.tar.gz": "0d3895528cc1e28dee0aa990da4cdf40201d09fb3f0ce416933e5a1abbc8a147", + "ruby-3.2.10.arm64_linux.tar.gz": "35127cdd1f57dd9603ea87e8a700a5b8ba840d57672935c444d04068439265a1", + "ruby-3.2.1.x86_64_linux.tar.gz": "b6b37f9282545bfa65882e1415e2c032b8577b5ea3579a1c913d1b1478a24420", + "ruby-3.2.1.macos.tar.gz": "e825a3c3336af0905f80657c7ace7571a1b685811bf98c38b24c49556355fa3e", + "ruby-3.2.1.arm64_linux.tar.gz": "b961ab1f0b78a98a3540ea6d48791b48c77ee88c1448cd8be54838d8706b0993", +} diff --git a/ruby/private/toolchain.bzl b/ruby/private/toolchain.bzl index 0206f2915..07bca732d 100644 --- a/ruby/private/toolchain.bzl +++ b/ruby/private/toolchain.bzl @@ -10,8 +10,8 @@ def rb_register_toolchains( version = None, version_file = None, msys2_packages = ["libyaml"], - rv_version = "", - rv_checksums = {}, + portable_ruby = False, + portable_ruby_checksums = {}, register = True, **kwargs): """ @@ -21,7 +21,7 @@ def rb_register_toolchains( * _(For MRI on Windows)_ Installed using [RubyInstaller](https://rubyinstaller.org). * _(For JRuby on any OS)_ Downloaded and installed directly from [official website](https://www.jruby.org). * _(For TruffleRuby on Linux and macOS)_ Installed using [ruby-build](https://github.com/rbenv/ruby-build). - * _(For rv-ruby)_ Prebuilt Ruby downloaded from [rv-ruby](https://github.com/spinel-coop/rv-ruby). + * _(With portable_ruby)_ Portable Ruby downloaded from [jdx/ruby](https://github.com/jdx/ruby). * _(For "system")_ Ruby found on the PATH is used. Please note that builds are not hermetic in this case. `WORKSPACE`: @@ -62,10 +62,10 @@ def rb_register_toolchains( version: a semver version of MRI, or a string like [interpreter type]-[version], or "system" version_file: .ruby-version or .tool-versions file to read version from msys2_packages: extra MSYS2 packages to install - rv_version: rv-ruby release version (e.g., "20251225"). When set, downloads prebuilt - Ruby from rv-ruby instead of compiling via ruby-build. - rv_checksums: platform checksums for rv-ruby downloads. - Keys: linux-x86_64, linux-arm64, macos-arm64, macos-x86_64. + portable_ruby: when True, downloads portable Ruby from jdx/ruby instead of compiling + via ruby-build. Has no effect on JRuby, TruffleRuby, or Windows. + portable_ruby_checksums: platform checksums for portable Ruby downloads, overriding + built-in checksums. Keys: linux-x86_64, linux-arm64, macos-arm64, macos-x86_64. register: whether to register the resulting toolchains, should be False under bzlmod **kwargs: additional parameters to the downloader for this interpreter type """ @@ -76,8 +76,8 @@ def rb_register_toolchains( version = version, version_file = version_file, msys2_packages = msys2_packages, - rv_version = rv_version, - rv_checksums = rv_checksums, + portable_ruby = portable_ruby, + portable_ruby_checksums = portable_ruby_checksums, **kwargs ) _rb_toolchain_repository_proxy( diff --git a/tools/generate_excluded_gems/BUILD.bazel b/tools/generate_excluded_gems/BUILD.bazel deleted file mode 100644 index 5a8331a4d..000000000 --- a/tools/generate_excluded_gems/BUILD.bazel +++ /dev/null @@ -1,48 +0,0 @@ -load("@rules_shell//shell:sh_binary.bzl", "sh_binary") -load("@rules_shell//shell:sh_test.bzl", "sh_test") - -sh_binary( - name = "generate_excluded_gems", - srcs = ["generate_excluded_gems.sh"], - data = [ - "@buildifier_prebuilt//buildozer", - ], - visibility = ["//visibility:public"], - deps = [ - "@cgrindel_bazel_starlib//shlib/lib:fail", - "@rules_shell//shell/runfiles", - ], -) - -sh_test( - name = "generate_excluded_gems_test", - srcs = ["generate_excluded_gems_test.sh"], - data = [ - "testdata/default_gems.json", - "testdata/expected_excluded_gems_output.txt", - ":generate_excluded_gems", - ], - deps = [ - "@cgrindel_bazel_starlib//shlib/lib:assertions", - "@rules_shell//shell/runfiles", - ], -) - -sh_test( - name = "generate_excluded_gems_integration_test", - srcs = ["generate_excluded_gems_integration_test.sh"], - data = [ - "testdata/default_gems.json", - ":generate_excluded_gems", - ], - deps = [ - "@cgrindel_bazel_starlib//shlib/lib:assertions", - "@rules_shell//shell/runfiles", - ], -) - -filegroup( - name = "all_files", - srcs = glob(["**/*"]), - visibility = ["//:__subpackages__"], -) diff --git a/tools/generate_excluded_gems/generate_excluded_gems.sh b/tools/generate_excluded_gems/generate_excluded_gems.sh deleted file mode 100755 index 5887529bb..000000000 --- a/tools/generate_excluded_gems/generate_excluded_gems.sh +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/env bash - -# Generates excluded_gems for ruby.bundle_fetch() and updates MODULE.bazel. - -# --- begin runfiles.bash initialization v3 --- -# Copy-pasted from the Bazel Bash runfiles library v3. -set -uo pipefail -set +e -f=bazel_tools/tools/bash/runfiles/runfiles.bash -# shellcheck disable=SC1090 -source "${RUNFILES_DIR:-/dev/null}/${f}" 2>/dev/null \ - || source "$(grep -sm1 "^${f} " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null \ - || source "$0.runfiles/${f}" 2>/dev/null \ - || source "$(grep -sm1 "^${f} " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null \ - || source "$(grep -sm1 "^${f} " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null \ - || { - echo >&2 "ERROR: ${BASH_SOURCE[0]} cannot find ${f}" - exit 1 - } -f= -set -e -# --- end runfiles.bash initialization v3 --- - -# MARK - Dependencies - -fail_sh_location=cgrindel_bazel_starlib/shlib/lib/fail.sh -fail_sh="$(rlocation "${fail_sh_location}")" \ - || (echo >&2 "Failed to locate ${fail_sh_location}" && exit 1) -# shellcheck disable=SC1090 -source "${fail_sh}" - -# Locate buildozer via runfiles -buildozer_location=buildifier_prebuilt/buildozer/buildozer -buildozer="$(rlocation "${buildozer_location}")" \ - || (echo >&2 "Failed to locate ${buildozer_location}" && exit 1) - -# MARK - Default Values - -# Default values -dry_run=false -name="bundle" -module_bazel="${BUILD_WORKSPACE_DIRECTORY:-.}/MODULE.bazel" -ruby_version="" - -# MARK - Functions - -# Read .ruby-version file -read_ruby_version() { - local version_file="${BUILD_WORKSPACE_DIRECTORY}/.ruby-version" - if [[ ! -f ${version_file} ]]; then - fail "Error: .ruby-version not found and --ruby-version not specified" - fi - tr -d '[:space:]' <"${version_file}" -} - -# Extract minor version from a Ruby version string (e.g., 3.4.8 -> 3.4) -# Ruby uses MAJOR.MINOR.PATCH versioning, and stdgems data is organized by -# minor version since default gems are typically consistent within a minor -# release series. -get_minor_version() { - local version="$1" - echo "${version}" | cut -d. -f1,2 -} - -# MARK - Argument Handling - -# Parse arguments -while (("$#")); do - case "${1}" in - --dry-run) - dry_run=true - shift - ;; - --ruby-version) - ruby_version="${2}" - shift 2 - ;; - --name) - name="${2}" - shift 2 - ;; - --module-bazel) - module_bazel="${2}" - shift 2 - ;; - -*) - fail "Error: Unknown option: ${1}" - ;; - *) - fail "Error: Unexpected argument: ${1}" - ;; - esac -done - -# Get Ruby version -if [[ -z ${ruby_version} ]]; then - ruby_version="$(read_ruby_version)" -fi - -# Get minor version -minor_version=$(get_minor_version "${ruby_version}") - -# MARK - Retrieve stdgems data - -# Fetch stdgems data -stdgems_url="${STDGEMS_URL:-https://raw.githubusercontent.com/janlelis/stdgems/main/default_gems.json}" -response=$(curl -sL --max-time 30 "${stdgems_url}") - -# Filter for native gems that exist for this Ruby version -# The jq query: -# 1. Select gems where native == true -# 2. Select gems where versions contains the minor version key -# 3. Extract the gem name -# 4. Sort -excluded_gems=$(echo "${response}" | jq -r --arg version "${minor_version}" \ - '.gems[] | select(.native == true) | select(.versions | has($version)) | .gem' \ - | sort) - -# Check if we found any gems -if [[ -z ${excluded_gems} ]]; then - fail <<-EOT -Error: No native gems found for Ruby ${ruby_version} (${minor_version}) -This Ruby version may not be supported in stdgems data -EOT -fi - -# MARK - Update MODULE.bazel - -# Generate output for dry-run or display -output="excluded_gems = [\n" -while IFS= read -r gem; do - output+=" \"${gem}\",\n" -done <<<"${excluded_gems}" -output+="]," - -if [[ ${dry_run} == "true" ]]; then - # Dry-run: just output the excluded gems - echo -e "${output}" - exit 0 -fi - -# Construct list of gems for buildozer 'add' command -# Convert newline-separated list to space-separated -gem_list="" -while IFS= read -r gem; do - gem_list+=" ${gem}" -done <<<"${excluded_gems}" - -# Update MODULE.bazel using buildozer -buildozer_cmd=( - "${buildozer}" - -types ruby.bundle_fetch - "remove excluded_gems" - "add excluded_gems${gem_list}" - "${module_bazel}:${name}" -) -if ! "${buildozer_cmd[@]}" 2>/dev/null; then - fail <<-EOT -Failed to update ${module_bazel} - -Buildozer command failed. This could mean: -- The file doesn't exist at ${module_bazel} -- No ruby.bundle_fetch() call was found with name="${name}" -- The file has syntax errors - -You can use --dry-run to see what would be updated: -$(echo -e "${output}") -EOT -fi - -echo "Successfully updated excluded_gems in ${module_bazel}" diff --git a/tools/generate_excluded_gems/generate_excluded_gems_integration_test.sh b/tools/generate_excluded_gems/generate_excluded_gems_integration_test.sh deleted file mode 100755 index 4f6f9875e..000000000 --- a/tools/generate_excluded_gems/generate_excluded_gems_integration_test.sh +++ /dev/null @@ -1,175 +0,0 @@ -#!/usr/bin/env bash - -# Integration tests for generate_excluded_gems.sh that verify buildozer -# updates work - -# --- begin runfiles.bash initialization v3 --- -# Copy-pasted from the Bazel Bash runfiles library v3. -set -uo pipefail -set +e -f=bazel_tools/tools/bash/runfiles/runfiles.bash -# shellcheck disable=SC1090 -source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null \ - || source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null \ - || source "$0.runfiles/$f" 2>/dev/null \ - || source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null \ - || source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null \ - || { - echo >&2 "ERROR: ${BASH_SOURCE[0]} cannot find $f" - exit 1 - } -f= -set -e -# --- end runfiles.bash initialization v3 --- - -# MARK - Locate Deps - -assertions_sh_location=cgrindel_bazel_starlib/shlib/lib/assertions.sh -assertions_sh="$(rlocation "${assertions_sh_location}")" \ - || (echo >&2 "Failed to locate ${assertions_sh_location}" && exit 1) -# shellcheck disable=SC1090 -source "${assertions_sh}" - -generate_excluded_gems_location=rules_ruby/tools/generate_excluded_gems/generate_excluded_gems.sh -generate_excluded_gems="$(rlocation "${generate_excluded_gems_location}")" - -mock_response_location=rules_ruby/tools/generate_excluded_gems/testdata/default_gems.json -mock_response="$(rlocation "${mock_response_location}")" - -# MARK - Cleanup - -# Collect temp directories for cleanup -temp_dirs=() -cleanup_temp_dirs() { - for dir in "${temp_dirs[@]:-}"; do - rm -rf "${dir}" - done -} -trap cleanup_temp_dirs EXIT - -# MARK - Tests - -# Test: Buildozer updates MODULE.bazel correctly -test_buildozer_updates() { - - local temp_dir - temp_dir="$(mktemp -d)" - temp_dirs+=("${temp_dir}") - - cd "${temp_dir}" - export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" - - # Create a minimal Bazel workspace - cat >WORKSPACE.bazel <<'EOF' -# Empty workspace for testing -EOF - - cat >MODULE.bazel <<'EOF' -module(name = "test_workspace") - -ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby") - -ruby.bundle_fetch( - name = "bundle", - gemfile = "//:Gemfile", - gemfile_lock = "//:Gemfile.lock", -) - -use_repo(ruby, "bundle") -EOF - - # Mock the stdgems response - export STDGEMS_URL="file://${mock_response}" - - # Run the script WITHOUT --dry-run - "${generate_excluded_gems}" --ruby-version 3.4.8 --module-bazel MODULE.bazel - - # Verify MODULE.bazel was updated - local module_content - module_content=$(cat MODULE.bazel) - - # Check excluded_gems was set with expected gems - assert_match "excluded_gems = \[" "${module_content}" \ - "MODULE.bazel should contain excluded_gems list" - assert_match '"date"' "${module_content}" \ - "MODULE.bazel should contain date gem" - assert_match '"digest"' "${module_content}" \ - "MODULE.bazel should contain digest gem" - assert_match '"json"' "${module_content}" \ - "MODULE.bazel should contain json gem" - assert_match '"psych"' "${module_content}" \ - "MODULE.bazel should contain psych gem" - - # Verify gemfile was NOT changed - assert_match 'gemfile = "//:Gemfile"' "${module_content}" \ - "MODULE.bazel should preserve existing gemfile" - -} - -# Test: Buildozer updates only target bundle by name -test_buildozer_name_filtering() { - - local temp_dir - temp_dir="$(mktemp -d)" - temp_dirs+=("${temp_dir}") - - cd "${temp_dir}" - export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" - - # Create workspace with multiple bundle_fetch calls - cat >WORKSPACE.bazel <<'EOF' -# Empty workspace for testing -EOF - - cat >MODULE.bazel <<'EOF' -module(name = "test_workspace") - -ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby") - -ruby.bundle_fetch( - name = "bundle", - gemfile = "//:Gemfile", - gemfile_lock = "//:Gemfile.lock", -) - -ruby.bundle_fetch( - name = "bundle_alt", - gemfile = "//alt:Gemfile", - gemfile_lock = "//alt:Gemfile.lock", -) - -use_repo(ruby, "bundle", "bundle_alt") -EOF - - # Mock the stdgems response - export STDGEMS_URL="file://${mock_response}" - - # Run the script for "bundle_alt" - "${generate_excluded_gems}" --ruby-version 3.4.8 --name bundle_alt \ - --module-bazel MODULE.bazel - - # Verify MODULE.bazel was updated - local module_content - module_content=$(cat MODULE.bazel) - - # Count how many excluded_gems assignments there are - local excluded_gems_count - excluded_gems_count=$(grep -c "excluded_gems = \[" MODULE.bazel || true) - - assert_equal "1" "${excluded_gems_count}" \ - 'Should have exactly one excluded_gems list (only in bundle_alt)' - - # Verify the first bundle_fetch (bundle) was NOT updated - # Check that there's still a bundle_fetch without excluded_gems before - # bundle_alt - if ! grep -B5 'name = "bundle_alt"' MODULE.bazel \ - | grep -q 'name = "bundle"'; then - fail "First bundle_fetch should still exist" - fi - -} - -# Run all tests -test_buildozer_updates -test_buildozer_name_filtering - diff --git a/tools/generate_excluded_gems/generate_excluded_gems_test.sh b/tools/generate_excluded_gems/generate_excluded_gems_test.sh deleted file mode 100755 index 2beb5ae74..000000000 --- a/tools/generate_excluded_gems/generate_excluded_gems_test.sh +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env bash - -# Tests for generate_excluded_gems.sh - -# --- begin runfiles.bash initialization v3 --- -# Copy-pasted from the Bazel Bash runfiles library v3. -set -uo pipefail -set +e -f=bazel_tools/tools/bash/runfiles/runfiles.bash -# shellcheck disable=SC1090 -source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null \ - || source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null \ - || source "$0.runfiles/$f" 2>/dev/null \ - || source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null \ - || source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null \ - || { - echo >&2 "ERROR: ${BASH_SOURCE[0]} cannot find $f" - exit 1 - } -f= -set -e -# --- end runfiles.bash initialization v3 --- - -# MARK - Locate Deps - -assertions_sh_location=cgrindel_bazel_starlib/shlib/lib/assertions.sh -assertions_sh="$(rlocation "${assertions_sh_location}")" \ - || (echo >&2 "Failed to locate ${assertions_sh_location}" && exit 1) -# shellcheck disable=SC1090 -source "${assertions_sh}" - -generate_excluded_gems_location=rules_ruby/tools/generate_excluded_gems/generate_excluded_gems.sh -generate_excluded_gems="$(rlocation "${generate_excluded_gems_location}")" - -mock_response_location=rules_ruby/tools/generate_excluded_gems/testdata/default_gems.json -mock_response="$(rlocation "${mock_response_location}")" - -expected_output_location=rules_ruby/tools/generate_excluded_gems/testdata/expected_excluded_gems_output.txt -expected_output="$(rlocation "${expected_output_location}")" - -# MARK - Cleanup - -# Collect temp directories for cleanup -temp_dirs=() -cleanup_temp_dirs() { - for dir in "${temp_dirs[@]:-}"; do - rm -rf "${dir}" - done -} -trap cleanup_temp_dirs EXIT - -# MARK - Tests - -# Test 1: Basic dry-run with .ruby-version -test_basic_dry_run() { - - local temp_dir - temp_dir="$(mktemp -d)" - temp_dirs+=("${temp_dir}") - - cd "${temp_dir}" - export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" - - # Setup .ruby-version - echo "3.4.8" >.ruby-version - - # Mock the stdgems response - export STDGEMS_URL="file://${mock_response}" - - # Run the script - local output - output=$("${generate_excluded_gems}" --dry-run) - - # Verify output matches expected - local expected - expected=$(cat "${expected_output}") - - assert_equal "${expected}" "${output}" \ - "Output should match expected excluded gems" - -} - -# Test 2: Explicit Ruby version -test_explicit_ruby_version() { - - local temp_dir - temp_dir="$(mktemp -d)" - temp_dirs+=("${temp_dir}") - - cd "${temp_dir}" - export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" - - # Mock the stdgems response - export STDGEMS_URL="file://${mock_response}" - - # Run the script with explicit version - local output - output=$("${generate_excluded_gems}" --ruby-version 3.4.8 --dry-run) - - # Verify output contains expected gems - assert_match "psych" "${output}" "Output should contain psych" - assert_match "json" "${output}" "Output should contain json" - - # Should NOT contain non-native gems - if echo "${output}" | grep -q "csv"; then - fail "Output should not contain csv (non-native gem)" - fi - -} - -# Test 3: Missing .ruby-version without --ruby-version -test_missing_ruby_version() { - - local temp_dir - temp_dir="$(mktemp -d)" - temp_dirs+=("${temp_dir}") - - cd "${temp_dir}" - export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" - - # Don't create .ruby-version file - - # Mock the stdgems response - export STDGEMS_URL="file://${mock_response}" - - # Run the script and expect failure - if "${generate_excluded_gems}" --dry-run 2>/dev/null; then - fail "Should have failed when .ruby-version is missing" - fi - -} - -# Test 4: Ruby version not in stdgems data -test_unsupported_ruby_version() { - - local temp_dir - temp_dir="$(mktemp -d)" - temp_dirs+=("${temp_dir}") - - cd "${temp_dir}" - export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" - - # Mock the stdgems response - export STDGEMS_URL="file://${mock_response}" - - # Run the script with unsupported version and expect failure - generate_excluded_gems_cmd=( - "${generate_excluded_gems}" --ruby-version 1.0.0 --dry-run - ) - if "${generate_excluded_gems_cmd[@]}" 2>/dev/null; then - fail "Should have failed for unsupported Ruby version" - fi - -} - -# Test 5: Ruby 3.3 version -test_ruby_33_version() { - - local temp_dir - temp_dir="$(mktemp -d)" - temp_dirs+=("${temp_dir}") - - cd "${temp_dir}" - export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" - - # Mock the stdgems response - export STDGEMS_URL="file://${mock_response}" - - # Run the script with 3.3.x version - local output - output=$("${generate_excluded_gems}" --ruby-version 3.3.0 --dry-run) - - # Verify output contains expected gems (same ones exist for 3.3) - assert_match "psych" "${output}" "Output should contain psych" - assert_match "json" "${output}" "Output should contain json" - -} - -# Run all tests -test_basic_dry_run -test_explicit_ruby_version -test_missing_ruby_version -test_unsupported_ruby_version -test_ruby_33_version - diff --git a/tools/generate_excluded_gems/testdata/default_gems.json b/tools/generate_excluded_gems/testdata/default_gems.json deleted file mode 100644 index 2cdcea036..000000000 --- a/tools/generate_excluded_gems/testdata/default_gems.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "version": "5.24.0", - "gems": [ - { - "gem": "date", - "native": true, - "versions": { - "3.4": "3.4.1", - "3.3": "3.3.4" - } - }, - { - "gem": "digest", - "native": true, - "versions": { - "3.4": "3.2.0", - "3.3": "3.1.1" - } - }, - { - "gem": "etc", - "native": true, - "versions": { - "3.4": "1.4.6", - "3.3": "1.4.3" - } - }, - { - "gem": "json", - "native": true, - "versions": { - "3.4": "2.9.1", - "3.3": "2.7.2" - } - }, - { - "gem": "psych", - "native": true, - "versions": { - "3.4": "5.2.2", - "3.3": "5.1.2" - } - }, - { - "gem": "stringio", - "native": true, - "versions": { - "3.4": "3.1.2", - "3.3": "3.1.0" - } - }, - { - "gem": "csv", - "native": false, - "versions": { - "3.4": "3.3.2", - "3.3": "3.2.8" - } - }, - { - "gem": "erb", - "native": false, - "versions": { - "3.4": "6.0.1", - "3.3": "4.0.4" - } - } - ] -} diff --git a/tools/generate_excluded_gems/testdata/expected_excluded_gems_output.txt b/tools/generate_excluded_gems/testdata/expected_excluded_gems_output.txt deleted file mode 100644 index b6c09b203..000000000 --- a/tools/generate_excluded_gems/testdata/expected_excluded_gems_output.txt +++ /dev/null @@ -1,8 +0,0 @@ -excluded_gems = [ - "date", - "digest", - "etc", - "json", - "psych", - "stringio", -], diff --git a/tools/generate_rv_checksums/BUILD.bazel b/tools/generate_portable_ruby_checksums/BUILD.bazel similarity index 55% rename from tools/generate_rv_checksums/BUILD.bazel rename to tools/generate_portable_ruby_checksums/BUILD.bazel index e2490d678..abaf83030 100644 --- a/tools/generate_rv_checksums/BUILD.bazel +++ b/tools/generate_portable_ruby_checksums/BUILD.bazel @@ -2,8 +2,8 @@ load("@rules_shell//shell:sh_binary.bzl", "sh_binary") load("@rules_shell//shell:sh_test.bzl", "sh_test") sh_binary( - name = "generate_rv_checksums", - srcs = ["generate_rv_checksums.sh"], + name = "generate_portable_ruby_checksums", + srcs = ["generate_portable_ruby_checksums.sh"], data = [ "@buildifier_prebuilt//buildozer", ], @@ -15,13 +15,14 @@ sh_binary( ) sh_test( - name = "generate_rv_checksums_test", - srcs = ["generate_rv_checksums_test.sh"], + name = "generate_portable_ruby_checksums_test", + srcs = ["generate_portable_ruby_checksums_test.sh"], data = [ - "testdata/20251225", + "testdata/3.4.8", "testdata/expected_checksums_output.txt", - "testdata/rv_ruby_release_response.json", - ":generate_rv_checksums", + "testdata/jdx_ruby_release_response.json", + "testdata/jdx_ruby_releases_list.json", + ":generate_portable_ruby_checksums", ], deps = [ "@cgrindel_bazel_starlib//shlib/lib:assertions", @@ -30,12 +31,12 @@ sh_test( ) sh_test( - name = "generate_rv_checksums_integration_test", - srcs = ["generate_rv_checksums_integration_test.sh"], + name = "generate_portable_ruby_checksums_integration_test", + srcs = ["generate_portable_ruby_checksums_integration_test.sh"], data = [ - "testdata/20251225", - "testdata/rv_ruby_release_response.json", - ":generate_rv_checksums", + "testdata/3.4.8", + "testdata/jdx_ruby_release_response.json", + ":generate_portable_ruby_checksums", ], deps = [ "@cgrindel_bazel_starlib//shlib/lib:assertions", diff --git a/tools/generate_rv_checksums/generate_rv_checksums.sh b/tools/generate_portable_ruby_checksums/generate_portable_ruby_checksums.sh similarity index 56% rename from tools/generate_rv_checksums/generate_rv_checksums.sh rename to tools/generate_portable_ruby_checksums/generate_portable_ruby_checksums.sh index b13311a61..28b515fab 100755 --- a/tools/generate_rv_checksums/generate_rv_checksums.sh +++ b/tools/generate_portable_ruby_checksums/generate_portable_ruby_checksums.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash -# Generates rv_checksums for ruby.toolchain() and updates MODULE.bazel. +# Generates portable_ruby_checksums for ruby.toolchain() and updates MODULE.bazel or +# ruby/private/portable_ruby_checksums.bzl (when --all is specified). # --- begin runfiles.bash initialization v3 --- # Copy-pasted from the Bazel Bash runfiles library v3. @@ -41,15 +42,11 @@ dry_run=false name="ruby" module_bazel="${BUILD_WORKSPACE_DIRECTORY:-.}/MODULE.bazel" ruby_version="" -rv_version="" - -# Map rv-ruby platform names to rules_ruby platform keys -declare -A PLATFORM_MAP=( - ["arm64_linux"]="linux-arm64" - ["x86_64_linux"]="linux-x86_64" - ["arm64_sonoma"]="macos-arm64" - ["ventura"]="macos-x86_64" -) +all_releases=false +checksums_bzl="${BUILD_WORKSPACE_DIRECTORY:-.}/ruby/private/portable_ruby_checksums.bzl" + +# jdx/ruby platform names (order matches portable_ruby_checksums.bzl) +PLATFORMS=("x86_64_linux" "macos" "arm64_linux") # MARK - Functions @@ -72,6 +69,10 @@ while (("$#")); do dry_run=true shift ;; + --all) + all_releases=true + shift + ;; --ruby-version) ruby_version="${2}" shift 2 @@ -84,6 +85,10 @@ while (("$#")); do module_bazel="${2}" shift 2 ;; + --checksums-bzl) + checksums_bzl="${2}" + shift 2 + ;; -*) fail "Error: Unknown option: ${1}" ;; @@ -94,36 +99,64 @@ while (("$#")); do esac done -# Check for required positional argument -if [[ ${#args[@]} -eq 0 ]]; then - fail <<-EOT -Error: rv_version is required -Usage: ${0} [OPTIONS] - -Options: - --ruby-version VERSION - --name NAME - --module-bazel PATH - --dry-run -EOT +# MARK - --all mode: update ruby/private/portable_ruby_checksums.bzl + +if [[ ${all_releases} == "true" ]]; then + # Verify we are running inside the rules_ruby repo + workspace_module_bazel="${BUILD_WORKSPACE_DIRECTORY:-.}/MODULE.bazel" + if ! grep -q 'name = "rules_ruby"' "${workspace_module_bazel}" 2>/dev/null; then + fail "Error: --all is only supported when run inside the rules_ruby repository" + fi + + # Fetch list of all releases with their assets + list_url="${RV_RUBY_LIST_API_URL:-https://api.github.com/repos/jdx/ruby/releases?per_page=100}" + all_response=$(curl -sL --max-time 60 "${list_url}") + + # Extract all checksums (excluding no_yjit), sorted by key in reverse order + entries=$(echo "${all_response}" | jq -r \ + '[.[].assets[] | select(.name | endswith(".tar.gz")) | select(.name | contains("no_yjit") | not) | {(.name): (.digest | ltrimstr("sha256:"))}] | add | to_entries | sort_by(.key) | reverse | .[] | " \"\(.key)\": \"\(.value)\","') + + if [[ -z ${entries} ]]; then + fail "Error: No checksums found in releases response" + fi + + # Build the bzl file content + bzl_content='"Provides checksums for portable Ruby versions from jdx/ruby." + +# Generated via: +# bazel run //tools/generate_portable_ruby_checksums -- --all + +PORTABLE_RUBY_CHECKSUMS = { +'"${entries}"' +} +' + + if [[ ${dry_run} == "true" ]]; then + printf "%s" "${bzl_content}" + exit 0 + fi + + printf "%s" "${bzl_content}" >"${checksums_bzl}" + echo "Successfully updated ${checksums_bzl}" + exit 0 fi -rv_version="${args[0]}" +# MARK - Single-version mode # Get Ruby version if [[ -z ${ruby_version} ]]; then ruby_version="$(read_ruby_version)" fi -# MARK - Retrieve rv-ruby release info +# MARK - Retrieve jdx/ruby release info # Fetch release data from GitHub API -api_url="${RV_RUBY_API_URL:-https://api.github.com/repos/spinel-coop/rv-ruby/releases/tags}/${rv_version}" +api_url="${RV_RUBY_API_URL:-https://api.github.com/repos/jdx/ruby/releases/tags}/${ruby_version}" response=$(curl -sL --max-time 30 "${api_url}") # Check if release was found if echo "${response}" | jq -e '.message == "Not Found"' >/dev/null 2>&1; then - fail "Error: rv-ruby release ${rv_version} not found" + fail "Error: jdx/ruby release for Ruby ${ruby_version} not found" fi # MARK - Extract checksums @@ -132,11 +165,9 @@ fi declare -A checksums found_ruby_version=false -for rv_platform in "${!PLATFORM_MAP[@]}"; do - platform_key="${PLATFORM_MAP[${rv_platform}]}" - +for platform in "${PLATFORMS[@]}"; do # Find asset for this Ruby version and platform - asset_name="ruby-${ruby_version}.${rv_platform}.tar.gz" + asset_name="ruby-${ruby_version}.${platform}.tar.gz" digest=$(echo "${response}" | jq -r --arg name "${asset_name}" \ '.assets[] | select(.name == $name) | .digest // ""') @@ -144,21 +175,20 @@ for rv_platform in "${!PLATFORM_MAP[@]}"; do found_ruby_version=true # Strip "sha256:" prefix if present checksum="${digest#sha256:}" - checksums["${platform_key}"]="${checksum}" + checksums["${platform}"]="${checksum}" fi done # Check if we found any assets for this Ruby version if [[ ${found_ruby_version} != "true" ]]; then fail <<-EOT -Error: Ruby version ${ruby_version} not found in rv-ruby release ${rv_version} +Error: Ruby version ${ruby_version} not found in jdx/ruby releases EOT fi # Check if we have all expected platforms -expected_platforms=("linux-arm64" "linux-x86_64" "macos-arm64" "macos-x86_64") missing_platforms=() -for platform in "${expected_platforms[@]}"; do +for platform in "${PLATFORMS[@]}"; do if [[ -z ${checksums[${platform}]:-} ]]; then missing_platforms+=("${platform}") fi @@ -171,37 +201,36 @@ fi # MARK - Update MODULE.bazel # Generate output for dry-run or display -output="rv_version = \"${rv_version}\",\n" -output+="rv_checksums = {\n" -for platform in "${expected_platforms[@]}"; do +output="portable_ruby_checksums = {\n" +for platform in "${PLATFORMS[@]}"; do if [[ -n ${checksums[${platform}]:-} ]]; then - output+=" \"${platform}\": \"${checksums[${platform}]}\",\n" + output+=" \"ruby-${ruby_version}.${platform}.tar.gz\": \"${checksums[${platform}]}\",\n" fi done output+="}," if [[ ${dry_run} == "true" ]]; then - # Dry-run: just output the version and checksums + # Dry-run: just output the checksums echo -e "${output}" exit 0 fi # Construct dict string for buildozer dict_str="" -for platform in "${expected_platforms[@]}"; do +for platform in "${PLATFORMS[@]}"; do if [[ -n ${checksums[${platform}]:-} ]]; then - dict_str+=" ${platform}:${checksums[${platform}]}" + dict_str+=" ruby-${ruby_version}.${platform}.tar.gz:${checksums[${platform}]}" fi done # Update MODULE.bazel using buildozer -# Set both rv_version and rv_checksums +# Set portable_ruby and portable_ruby_checksums buildozer_cmd=( "${buildozer}" -types ruby.toolchain - "set rv_version \"${rv_version}\"" - "remove rv_checksums" - "dict_set rv_checksums ${dict_str}" + "set portable_ruby True" + "remove portable_ruby_checksums" + "dict_set portable_ruby_checksums ${dict_str}" "${module_bazel}:${name}" ) if ! "${buildozer_cmd[@]}" 2>/dev/null; then @@ -218,4 +247,4 @@ $(echo -e "${output}") EOT fi -echo "Successfully updated rv_version and rv_checksums in ${module_bazel}" +echo "Successfully updated portable_ruby and portable_ruby_checksums in ${module_bazel}" diff --git a/tools/generate_rv_checksums/generate_rv_checksums_integration_test.sh b/tools/generate_portable_ruby_checksums/generate_portable_ruby_checksums_integration_test.sh similarity index 66% rename from tools/generate_rv_checksums/generate_rv_checksums_integration_test.sh rename to tools/generate_portable_ruby_checksums/generate_portable_ruby_checksums_integration_test.sh index 69a743ea4..f3c23aa62 100755 --- a/tools/generate_rv_checksums/generate_rv_checksums_integration_test.sh +++ b/tools/generate_portable_ruby_checksums/generate_portable_ruby_checksums_integration_test.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Integration tests for generate_rv_checksums.sh that verify buildozer updates +# Integration tests for generate_portable_ruby_checksums.sh that verify buildozer updates # work # --- begin runfiles.bash initialization v3 --- @@ -30,10 +30,10 @@ assertions_sh="$(rlocation "${assertions_sh_location}")" \ # shellcheck disable=SC1090 source "${assertions_sh}" -generate_rv_checksums_location=rules_ruby/tools/generate_rv_checksums/generate_rv_checksums.sh -generate_rv_checksums="$(rlocation "${generate_rv_checksums_location}")" +generate_portable_ruby_checksums_location=rules_ruby/tools/generate_portable_ruby_checksums/generate_portable_ruby_checksums.sh +generate_portable_ruby_checksums="$(rlocation "${generate_portable_ruby_checksums_location}")" -mock_response_location=rules_ruby/tools/generate_rv_checksums/testdata/rv_ruby_release_response.json +mock_response_location=rules_ruby/tools/generate_portable_ruby_checksums/testdata/jdx_ruby_release_response.json mock_response="$(rlocation "${mock_response_location}")" # MARK - Cleanup @@ -76,40 +76,36 @@ ruby.toolchain( use_repo(ruby, "ruby_toolchains") EOF - # Mock the API response + # Mock the API response (the release tag is the Ruby version) export RV_RUBY_API_URL="file://${mock_response%/*}" # Run the script WITHOUT --dry-run - "${generate_rv_checksums}" 20251225 --ruby-version 3.4.8 \ + "${generate_portable_ruby_checksums}" --ruby-version 3.4.8 \ --module-bazel MODULE.bazel # Verify MODULE.bazel was updated local module_content module_content=$(cat MODULE.bazel) - # Check rv_version was set - assert_match 'rv_version = "20251225"' "${module_content}" \ - "MODULE.bazel should contain rv_version" + # Check portable_ruby was set + assert_match 'portable_ruby = True' "${module_content}" \ + "MODULE.bazel should contain portable_ruby" - # Check rv_checksums was set with all platforms - assert_match "rv_checksums = \{" "${module_content}" \ - "MODULE.bazel should contain rv_checksums" - assert_match \ - '"linux-arm64": "0c08c35a99f10817643d548f98012268c5433ae25a737ab4d6751336108a941d"' \ - "${module_content}" \ - "MODULE.bazel should contain linux-arm64 checksum" + # Check portable_ruby_checksums was set with all platforms + assert_match "portable_ruby_checksums = \{" "${module_content}" \ + "MODULE.bazel should contain portable_ruby_checksums" assert_match \ - '"linux-x86_64": "f36cef10365d370e0867f0c3ac36e457a26ab04f3cfbbd7edb227a18e6e9b3c3"' \ + '"ruby-3.4.8.arm64_linux.tar.gz": "0c08c35a99f10817643d548f98012268c5433ae25a737ab4d6751336108a941d"' \ "${module_content}" \ - "MODULE.bazel should contain linux-x86_64 checksum" + "MODULE.bazel should contain arm64_linux checksum" assert_match \ - '"macos-arm64": "cd9d7a1428076bfcc6c2ca3c0eb69b8e671e9b48afb4c351fa4a84927841ffef"' \ + '"ruby-3.4.8.x86_64_linux.tar.gz": "f36cef10365d370e0867f0c3ac36e457a26ab04f3cfbbd7edb227a18e6e9b3c3"' \ "${module_content}" \ - "MODULE.bazel should contain macos-arm64 checksum" + "MODULE.bazel should contain x86_64_linux checksum" assert_match \ - '"macos-x86_64": "e9da39082d1dd8502d322c850924d929bc45b7a1e35da593a5606c00673218d4"' \ + '"ruby-3.4.8.macos.tar.gz": "cd9d7a1428076bfcc6c2ca3c0eb69b8e671e9b48afb4c351fa4a84927841ffef"' \ "${module_content}" \ - "MODULE.bazel should contain macos-x86_64 checksum" + "MODULE.bazel should contain macos checksum" # Verify ruby_version was NOT changed (we didn't update it) assert_match 'ruby_version = "3.3.0"' "${module_content}" \ @@ -152,22 +148,22 @@ EOF export RV_RUBY_API_URL="file://${mock_response%/*}" # Run the script for "ruby_alt" toolchain - "${generate_rv_checksums}" 20251225 --ruby-version 3.4.8 --name ruby_alt \ + "${generate_portable_ruby_checksums}" --ruby-version 3.4.8 --name ruby_alt \ --module-bazel MODULE.bazel # Verify MODULE.bazel was updated local module_content module_content=$(cat MODULE.bazel) - # Count how many rv_version assignments there are - local rv_version_count - rv_version_count=$(grep -c 'rv_version = "20251225"' MODULE.bazel || true) + # Count how many portable_ruby assignments there are + local portable_ruby_count + portable_ruby_count=$(grep -c 'portable_ruby = True' MODULE.bazel || true) - assert_equal "1" "${rv_version_count}" \ - 'Should have exactly one rv_version = "20251225" (only in ruby_alt)' + assert_equal "1" "${portable_ruby_count}" \ + 'Should have exactly one portable_ruby = True (only in ruby_alt)' # Verify the first toolchain (ruby) was NOT updated - # Check that there's still a toolchain without rv_version before ruby_alt + # Check that there's still a toolchain without portable_ruby before ruby_alt if ! grep -B5 'name = "ruby_alt"' MODULE.bazel | grep -q 'name = "ruby"'; then fail "First toolchain should still exist" fi diff --git a/tools/generate_portable_ruby_checksums/generate_portable_ruby_checksums_test.sh b/tools/generate_portable_ruby_checksums/generate_portable_ruby_checksums_test.sh new file mode 100755 index 000000000..58c029b60 --- /dev/null +++ b/tools/generate_portable_ruby_checksums/generate_portable_ruby_checksums_test.sh @@ -0,0 +1,260 @@ +#!/usr/bin/env bash + +# Tests for generate_portable_ruby_checksums.sh + +# --- begin runfiles.bash initialization v3 --- +# Copy-pasted from the Bazel Bash runfiles library v3. +set -uo pipefail +set +e +f=bazel_tools/tools/bash/runfiles/runfiles.bash +# shellcheck disable=SC1090 +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null \ + || source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null \ + || source "$0.runfiles/$f" 2>/dev/null \ + || source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null \ + || source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null \ + || { + echo >&2 "ERROR: ${BASH_SOURCE[0]} cannot find $f" + exit 1 + } +f= +set -e +# --- end runfiles.bash initialization v3 --- + +# MARK - Locate Deps + +assertions_sh_location=cgrindel_bazel_starlib/shlib/lib/assertions.sh +assertions_sh="$(rlocation "${assertions_sh_location}")" \ + || (echo >&2 "Failed to locate ${assertions_sh_location}" && exit 1) +# shellcheck disable=SC1090 +source "${assertions_sh}" + +generate_portable_ruby_checksums_location=rules_ruby/tools/generate_portable_ruby_checksums/generate_portable_ruby_checksums.sh +generate_portable_ruby_checksums="$(rlocation "${generate_portable_ruby_checksums_location}")" + +mock_response_location=rules_ruby/tools/generate_portable_ruby_checksums/testdata/jdx_ruby_release_response.json +mock_response="$(rlocation "${mock_response_location}")" + +expected_output_location=rules_ruby/tools/generate_portable_ruby_checksums/testdata/expected_checksums_output.txt +expected_output="$(rlocation "${expected_output_location}")" + +releases_list_location=rules_ruby/tools/generate_portable_ruby_checksums/testdata/jdx_ruby_releases_list.json +releases_list="$(rlocation "${releases_list_location}")" + +# MARK - Cleanup + +# Collect temp directories for cleanup +temp_dirs=() +cleanup_temp_dirs() { + for dir in "${temp_dirs[@]:-}"; do + rm -rf "${dir}" + done +} +trap cleanup_temp_dirs EXIT + +# MARK - Tests + +# Test 1: Basic dry-run with .ruby-version +test_basic_dry_run() { + + local temp_dir + temp_dir="$(mktemp -d)" + temp_dirs+=("${temp_dir}") + + cd "${temp_dir}" + export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" + + # Setup .ruby-version + echo "3.4.8" >.ruby-version + + # Mock the API response (the release tag is the Ruby version) + export RV_RUBY_API_URL="file://${mock_response%/*}" + + # Run the script + local output + output=$("${generate_portable_ruby_checksums}" --dry-run) + + # Verify output matches expected + local expected + expected=$(cat "${expected_output}") + + assert_equal "${expected}" "${output}" "Output should match expected checksums" + +} + +# Test 2: Explicit Ruby version +test_explicit_ruby_version() { + + local temp_dir + temp_dir="$(mktemp -d)" + temp_dirs+=("${temp_dir}") + + cd "${temp_dir}" + export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" + + # Mock the API response + export RV_RUBY_API_URL="file://${mock_response%/*}" + + # Run the script with explicit version + local output + output=$("${generate_portable_ruby_checksums}" --ruby-version 3.4.8 --dry-run) + + # Verify output contains expected checksums + assert_match "arm64_linux" "${output}" "Output should contain arm64_linux" + assert_match "0c08c35a99f10817643d548f98012268c5433ae25a737ab4d6751336108a941d" "${output}" \ + "Output should contain correct checksum" + +} + +# Test 3: Missing .ruby-version without --ruby-version +test_missing_ruby_version() { + + local temp_dir + temp_dir="$(mktemp -d)" + temp_dirs+=("${temp_dir}") + + cd "${temp_dir}" + export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" + + # Don't create .ruby-version file + + # Mock the API response + export RV_RUBY_API_URL="file://${mock_response%/*}" + + # Run the script and expect failure + if "${generate_portable_ruby_checksums}" --dry-run 2>/dev/null; then + fail "Should have failed when .ruby-version is missing" + fi + +} + +# Test 4: Invalid Ruby version (release not found) +test_invalid_ruby_version() { + + local temp_dir + temp_dir="$(mktemp -d)" + temp_dirs+=("${temp_dir}") + + cd "${temp_dir}" + export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" + + # Use a non-existent API URL to simulate 404 + export RV_RUBY_API_URL="file:///nonexistent" + + # Run the script and expect failure + if "${generate_portable_ruby_checksums}" --ruby-version 99.99.99 --dry-run 2>/dev/null; then + fail "Should have failed for invalid Ruby version" + fi + +} + +# Test 5: --all flag fails outside rules_ruby repo +test_all_requires_rules_ruby_repo() { + + local temp_dir + temp_dir="$(mktemp -d)" + temp_dirs+=("${temp_dir}") + + cd "${temp_dir}" + export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" + + # Create a MODULE.bazel with a different module name + cat >"${temp_dir}/MODULE.bazel" <<'EOF' +module(name = "some_other_repo") +EOF + + export RV_RUBY_LIST_API_URL="file://${releases_list}" + + # Should fail because module name is not rules_ruby + if "${generate_portable_ruby_checksums}" --all --dry-run 2>/dev/null; then + fail "Should have failed when not in rules_ruby repo" + fi + +} + +# Test 6: --all flag dry-run generates correct bzl content +test_all_dry_run() { + + local temp_dir + temp_dir="$(mktemp -d)" + temp_dirs+=("${temp_dir}") + + cd "${temp_dir}" + export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" + + # Satisfy the rules_ruby repo check + printf 'module(name = "rules_ruby")\n' >"${temp_dir}/MODULE.bazel" + + # Mock the releases list API response + export RV_RUBY_LIST_API_URL="file://${releases_list}" + + # Run the script with --all --dry-run + local output + output=$("${generate_portable_ruby_checksums}" --all --dry-run) + + # Verify output is a valid bzl file + assert_match 'PORTABLE_RUBY_CHECKSUMS =' "${output}" \ + "Output should contain PORTABLE_RUBY_CHECKSUMS dict" + + # Verify no_yjit entries are excluded + if echo "${output}" | grep -q "no_yjit"; then + fail "Output should not contain no_yjit entries" + fi + + # Verify both versions are present + assert_match "ruby-3.4.8" "${output}" "Output should contain 3.4.8 checksums" + assert_match "ruby-3.4.7" "${output}" "Output should contain 3.4.7 checksums" + + # Verify entries are sorted in reverse order (3.4.8 before 3.4.7) + local pos_348 pos_347 + pos_348=$(echo "${output}" | grep -n "ruby-3.4.8" | head -1 | cut -d: -f1) + pos_347=$(echo "${output}" | grep -n "ruby-3.4.7" | head -1 | cut -d: -f1) + if [[ ${pos_348} -gt ${pos_347} ]]; then + fail "Entries should be in reverse order (3.4.8 before 3.4.7)" + fi + +} + +# Test 7: --all flag writes bzl file +test_all_writes_bzl_file() { + + local temp_dir + temp_dir="$(mktemp -d)" + temp_dirs+=("${temp_dir}") + + cd "${temp_dir}" + export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" + + # Satisfy the rules_ruby repo check + printf 'module(name = "rules_ruby")\n' >"${temp_dir}/MODULE.bazel" + + # Mock the releases list API response + export RV_RUBY_LIST_API_URL="file://${releases_list}" + + # Run the script with --all and a custom output path + local output_file="${temp_dir}/checksums.bzl" + "${generate_portable_ruby_checksums}" --all --checksums-bzl "${output_file}" + + # Verify the file was written + if [[ ! -f ${output_file} ]]; then + fail "Checksums bzl file should have been written" + fi + + local content + content=$(cat "${output_file}") + + assert_match 'PORTABLE_RUBY_CHECKSUMS =' "${content}" \ + "File should contain PORTABLE_RUBY_CHECKSUMS dict" + assert_match "ruby-3.4.8.x86_64_linux.tar.gz" "${content}" \ + "File should contain x86_64_linux entry" + +} + +# Run all tests +test_basic_dry_run +test_explicit_ruby_version +test_missing_ruby_version +test_invalid_ruby_version +test_all_requires_rules_ruby_repo +test_all_dry_run +test_all_writes_bzl_file diff --git a/tools/generate_portable_ruby_checksums/testdata/3.4.8 b/tools/generate_portable_ruby_checksums/testdata/3.4.8 new file mode 120000 index 000000000..921a38d20 --- /dev/null +++ b/tools/generate_portable_ruby_checksums/testdata/3.4.8 @@ -0,0 +1 @@ +jdx_ruby_release_response.json \ No newline at end of file diff --git a/tools/generate_portable_ruby_checksums/testdata/expected_checksums_output.txt b/tools/generate_portable_ruby_checksums/testdata/expected_checksums_output.txt new file mode 100644 index 000000000..01d81cd15 --- /dev/null +++ b/tools/generate_portable_ruby_checksums/testdata/expected_checksums_output.txt @@ -0,0 +1,5 @@ +portable_ruby_checksums = { + "ruby-3.4.8.x86_64_linux.tar.gz": "f36cef10365d370e0867f0c3ac36e457a26ab04f3cfbbd7edb227a18e6e9b3c3", + "ruby-3.4.8.macos.tar.gz": "cd9d7a1428076bfcc6c2ca3c0eb69b8e671e9b48afb4c351fa4a84927841ffef", + "ruby-3.4.8.arm64_linux.tar.gz": "0c08c35a99f10817643d548f98012268c5433ae25a737ab4d6751336108a941d", +}, diff --git a/tools/generate_rv_checksums/testdata/rv_ruby_release_response.json b/tools/generate_portable_ruby_checksums/testdata/jdx_ruby_release_response.json similarity index 63% rename from tools/generate_rv_checksums/testdata/rv_ruby_release_response.json rename to tools/generate_portable_ruby_checksums/testdata/jdx_ruby_release_response.json index 6d9eb5adc..35902e970 100644 --- a/tools/generate_rv_checksums/testdata/rv_ruby_release_response.json +++ b/tools/generate_portable_ruby_checksums/testdata/jdx_ruby_release_response.json @@ -1,6 +1,6 @@ { - "tag_name": "20251225", - "name": "20251225", + "tag_name": "3.4.8", + "name": "3.4.8", "assets": [ { "name": "ruby-3.4.8.arm64_linux.tar.gz", @@ -11,12 +11,8 @@ "digest": "sha256:f36cef10365d370e0867f0c3ac36e457a26ab04f3cfbbd7edb227a18e6e9b3c3" }, { - "name": "ruby-3.4.8.arm64_sonoma.tar.gz", + "name": "ruby-3.4.8.macos.tar.gz", "digest": "sha256:cd9d7a1428076bfcc6c2ca3c0eb69b8e671e9b48afb4c351fa4a84927841ffef" - }, - { - "name": "ruby-3.4.8.ventura.tar.gz", - "digest": "sha256:e9da39082d1dd8502d322c850924d929bc45b7a1e35da593a5606c00673218d4" } ] } diff --git a/tools/generate_portable_ruby_checksums/testdata/jdx_ruby_releases_list.json b/tools/generate_portable_ruby_checksums/testdata/jdx_ruby_releases_list.json new file mode 100644 index 000000000..00b29449b --- /dev/null +++ b/tools/generate_portable_ruby_checksums/testdata/jdx_ruby_releases_list.json @@ -0,0 +1,42 @@ +[ + { + "tag_name": "3.4.8", + "name": "3.4.8", + "assets": [ + { + "name": "ruby-3.4.8.arm64_linux.tar.gz", + "digest": "sha256:0c08c35a99f10817643d548f98012268c5433ae25a737ab4d6751336108a941d" + }, + { + "name": "ruby-3.4.8.x86_64_linux.tar.gz", + "digest": "sha256:f36cef10365d370e0867f0c3ac36e457a26ab04f3cfbbd7edb227a18e6e9b3c3" + }, + { + "name": "ruby-3.4.8.macos.tar.gz", + "digest": "sha256:cd9d7a1428076bfcc6c2ca3c0eb69b8e671e9b48afb4c351fa4a84927841ffef" + }, + { + "name": "ruby-3.4.8.arm64_linux.no_yjit.tar.gz", + "digest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + } + ] + }, + { + "tag_name": "3.4.7", + "name": "3.4.7", + "assets": [ + { + "name": "ruby-3.4.7.arm64_linux.tar.gz", + "digest": "sha256:9e65819ba3ca56dd49f012692dca32efb6ae5142f6493bb50fd4ccaa766cc31c" + }, + { + "name": "ruby-3.4.7.x86_64_linux.tar.gz", + "digest": "sha256:ea1a3ac2c5301358e22371ca2b526f48e910fccbcbccdc5542d7c8cef4c5b9d0" + }, + { + "name": "ruby-3.4.7.macos.tar.gz", + "digest": "sha256:cf0dc9f8f4d476860f24fc81d4b338317471cf1fffa0b09ce26d489407db511b" + } + ] + } +] diff --git a/tools/generate_rv_checksums/generate_rv_checksums_test.sh b/tools/generate_rv_checksums/generate_rv_checksums_test.sh deleted file mode 100755 index fe206c684..000000000 --- a/tools/generate_rv_checksums/generate_rv_checksums_test.sh +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/env bash - -# Tests for generate_rv_checksums.sh - -# --- begin runfiles.bash initialization v3 --- -# Copy-pasted from the Bazel Bash runfiles library v3. -set -uo pipefail -set +e -f=bazel_tools/tools/bash/runfiles/runfiles.bash -# shellcheck disable=SC1090 -source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null \ - || source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null \ - || source "$0.runfiles/$f" 2>/dev/null \ - || source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null \ - || source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null \ - || { - echo >&2 "ERROR: ${BASH_SOURCE[0]} cannot find $f" - exit 1 - } -f= -set -e -# --- end runfiles.bash initialization v3 --- - -# MARK - Locate Deps - -assertions_sh_location=cgrindel_bazel_starlib/shlib/lib/assertions.sh -assertions_sh="$(rlocation "${assertions_sh_location}")" \ - || (echo >&2 "Failed to locate ${assertions_sh_location}" && exit 1) -# shellcheck disable=SC1090 -source "${assertions_sh}" - -generate_rv_checksums_location=rules_ruby/tools/generate_rv_checksums/generate_rv_checksums.sh -generate_rv_checksums="$(rlocation "${generate_rv_checksums_location}")" - -mock_response_location=rules_ruby/tools/generate_rv_checksums/testdata/rv_ruby_release_response.json -mock_response="$(rlocation "${mock_response_location}")" - -expected_output_location=rules_ruby/tools/generate_rv_checksums/testdata/expected_checksums_output.txt -expected_output="$(rlocation "${expected_output_location}")" - -# MARK - Cleanup - -# Collect temp directories for cleanup -temp_dirs=() -cleanup_temp_dirs() { - for dir in "${temp_dirs[@]:-}"; do - rm -rf "${dir}" - done -} -trap cleanup_temp_dirs EXIT - -# MARK - Tests - -# Test 1: Basic dry-run with .ruby-version -test_basic_dry_run() { - - local temp_dir - temp_dir="$(mktemp -d)" - temp_dirs+=("${temp_dir}") - - cd "${temp_dir}" - export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" - - # Setup .ruby-version - echo "3.4.8" >.ruby-version - - # Mock the API response - export RV_RUBY_API_URL="file://${mock_response%/*}" - - # Run the script - local output - output=$("${generate_rv_checksums}" 20251225 --dry-run) - - # Verify output matches expected - local expected - expected=$(cat "${expected_output}") - - assert_equal "${expected}" "${output}" "Output should match expected checksums" - -} - -# Test 2: Explicit Ruby version -test_explicit_ruby_version() { - - local temp_dir - temp_dir="$(mktemp -d)" - temp_dirs+=("${temp_dir}") - - cd "${temp_dir}" - export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" - - # Mock the API response - export RV_RUBY_API_URL="file://${mock_response%/*}" - - # Run the script with explicit version - local output - output=$("${generate_rv_checksums}" 20251225 --ruby-version 3.4.8 --dry-run) - - # Verify output contains expected checksums - assert_match "linux-arm64" "${output}" "Output should contain linux-arm64" - assert_match "0c08c35a99f10817643d548f98012268c5433ae25a737ab4d6751336108a941d" "${output}" \ - "Output should contain correct checksum" - -} - -# Test 3: Missing .ruby-version without --ruby-version -test_missing_ruby_version() { - - local temp_dir - temp_dir="$(mktemp -d)" - temp_dirs+=("${temp_dir}") - - cd "${temp_dir}" - export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" - - # Don't create .ruby-version file - - # Mock the API response - export RV_RUBY_API_URL="file://${mock_response%/*}" - - # Run the script and expect failure - if "${generate_rv_checksums}" 20251225 --dry-run 2>/dev/null; then - fail "Should have failed when .ruby-version is missing" - fi - -} - -# Test 4: Invalid rv_version -test_invalid_rv_version() { - - local temp_dir - temp_dir="$(mktemp -d)" - temp_dirs+=("${temp_dir}") - - cd "${temp_dir}" - export BUILD_WORKSPACE_DIRECTORY="${temp_dir}" - - # Use a non-existent API URL to simulate 404 - export RV_RUBY_API_URL="file:///nonexistent" - - # Run the script and expect failure - if "${generate_rv_checksums}" 99999999 --ruby-version 3.4.8 --dry-run 2>/dev/null; then - fail "Should have failed for invalid rv_version" - fi - -} - -# Run all tests -test_basic_dry_run -test_explicit_ruby_version -test_missing_ruby_version -test_invalid_rv_version - diff --git a/tools/generate_rv_checksums/testdata/20251225 b/tools/generate_rv_checksums/testdata/20251225 deleted file mode 120000 index ba22c8526..000000000 --- a/tools/generate_rv_checksums/testdata/20251225 +++ /dev/null @@ -1 +0,0 @@ -rv_ruby_release_response.json \ No newline at end of file diff --git a/tools/generate_rv_checksums/testdata/expected_checksums_output.txt b/tools/generate_rv_checksums/testdata/expected_checksums_output.txt deleted file mode 100644 index d52745ba4..000000000 --- a/tools/generate_rv_checksums/testdata/expected_checksums_output.txt +++ /dev/null @@ -1,7 +0,0 @@ -rv_version = "20251225", -rv_checksums = { - "linux-arm64": "0c08c35a99f10817643d548f98012268c5433ae25a737ab4d6751336108a941d", - "linux-x86_64": "f36cef10365d370e0867f0c3ac36e457a26ab04f3cfbbd7edb227a18e6e9b3c3", - "macos-arm64": "cd9d7a1428076bfcc6c2ca3c0eb69b8e671e9b48afb4c351fa4a84927841ffef", - "macos-x86_64": "e9da39082d1dd8502d322c850924d929bc45b7a1e35da593a5606c00673218d4", -},