Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ On Windows, [RubyInstaller][6] is used to install MRI.
#### Fast Installation with Portable Ruby

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
binaries from [bazel-contrib/portable-ruby][19] instead of compiling from source. This significantly
reduces installation time and ensures consistent, portable Ruby environments.

To enable portable Ruby, set `portable_ruby = True` in your toolchain declaration:
Expand All @@ -147,7 +147,7 @@ ruby.toolchain(

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.
you should use `portable_ruby_release_suffix` and `portable_ruby_checksums` attribute.

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.
Expand All @@ -166,10 +166,12 @@ ruby.toolchain(
name = "ruby",
version_file = "//:.ruby-version",
portable_ruby = True,
portable_ruby_release_suffix = "2", # default is 1
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",
"ruby-3.2.8.arm64_darwin.tar.gz": "4b5343a5513523409b4cc1b285ebaeb75356c758080e45d99f506a827492a8fb",
"ruby-3.4.8.arm64_linux.tar.gz": "8348296d8148acbc6e5a170861810b693fb6ea72e1d59cc7b82f0369bffa9870",
"ruby-3.2.8.x86_64_darwin.tar.gz": "75b72e64e42bb36a80e3382751c74bfe379efcf28880ed3c4c86657cac9d8462",
"ruby-3.2.8.x86_64_linux.tar.gz": "2a2f40774634abed8eb32b762b8f440f85c6add74b5c14f28e70b42f49537464",
},
)
```
Expand All @@ -179,7 +181,7 @@ ruby.toolchain(
- 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 portable Ruby releases at https://github.com/jdx/ruby/releases
- Find available portable Ruby releases at https://github.com/bazel-contrib/portable-ruby/releases

### JRuby

Expand Down Expand Up @@ -263,7 +265,7 @@ rb_test(
[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/jdx/ruby
[19]: https://github.com/bazel-contrib/portable-ruby
[20]: ruby/private/portable_ruby_checksums.bzl
[21]: https://github.com/simplecov-ruby/simplecov
[22]: https://github.com/fortissimo1997/simplecov-lcov
9 changes: 5 additions & 4 deletions docs/repository_rules.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 12 additions & 1 deletion ruby/extensions.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,19 @@ ruby_toolchain = tag_class(attrs = {
"msys2_packages": attr.string_list(doc = "Extra MSYS2 packages to install.", default = ["libyaml"]),
"portable_ruby": attr.bool(
doc = """\
When True, downloads portable Ruby from jdx/ruby instead of compiling via \
When True, downloads portable Ruby from bazel-contrib/portable-ruby instead of compiling via \
ruby-build. Has no effect on JRuby, TruffleRuby, or Windows.\
""",
default = False,
),
"portable_ruby_release_suffix": attr.string(
doc = """\
Release suffix for portable Ruby downloads. When empty (default), uses the built-in \
PORTABLE_RUBY_DEFAULT_SUFFIXES mapping. Set explicitly to pin to a specific rebuild, \
e.g. "2" downloads version X.Y.Z-2.\
""",
default = "",
),
"portable_ruby_checksums": attr.string_dict(
doc = """\
Platform checksums for portable Ruby downloads, overriding built-in checksums. \
Expand Down Expand Up @@ -105,6 +113,7 @@ def _ruby_module_extension(module_ctx):
toolchain.msys2_packages,
toolchain.ruby_build_version,
toolchain.portable_ruby,
toolchain.portable_ruby_release_suffix,
toolchain.portable_ruby_checksums,
)
if module_ctx.is_dev_dependency(toolchain):
Expand All @@ -121,6 +130,7 @@ def _ruby_module_extension(module_ctx):
msys2_packages,
ruby_build_version,
portable_ruby,
portable_ruby_release_suffix,
portable_ruby_checksums,
) = config
rb_register_toolchains(
Expand All @@ -130,6 +140,7 @@ def _ruby_module_extension(module_ctx):
msys2_packages = msys2_packages,
ruby_build_version = ruby_build_version,
portable_ruby = portable_ruby,
portable_ruby_release_suffix = portable_ruby_release_suffix,
portable_ruby_checksums = portable_ruby_checksums,
register = False,
)
Expand Down
46 changes: 26 additions & 20 deletions ruby/private/download.bzl
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
"Repository rule for fetching Ruby interpreters"

load("//ruby/private:portable_ruby_checksums.bzl", "PORTABLE_RUBY_CHECKSUMS")
load("//ruby/private:portable_ruby_checksums.bzl", "PORTABLE_RUBY_CHECKSUMS", "PORTABLE_RUBY_DEFAULT_SUFFIXES")

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"
_PORTABLE_RUBY_NAME = "ruby-{version}.{platform}.tar.gz"
_MISE_RUBY_URL = "https://github.com/jdx/ruby/releases/download/{release}/{name}"
_PORTABLE_RUBY_URL = "https://github.com/bazel-contrib/portable-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:
Expand Down Expand Up @@ -280,7 +280,7 @@ def _install_via_ruby_build(repository_ctx, version):
repository_ctx.delete("ruby-build")

def _install_portable_ruby(repository_ctx, ruby_version, checksums):
"""Install portable Ruby from jdx/ruby project.
"""Install portable Ruby from bazel-contrib/portable-ruby project.

Args:
repository_ctx: Repository context
Expand All @@ -291,7 +291,7 @@ def _install_portable_ruby(repository_ctx, ruby_version, checksums):
# Detect platform
os_name = repository_ctx.os.name
if os_name.startswith("mac"):
os_key = "macos"
os_key = "darwin"
elif os_name.startswith("linux"):
os_key = "linux"
else:
Expand All @@ -306,16 +306,13 @@ def _install_portable_ruby(repository_ctx, ruby_version, checksums):
else:
arch_key = arch

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
# Combine to form platform key
platform_key = arch_key + "_" + os_key

if os_key == "macos":
# Intel is not supported
platform_key = "macos"
else:
platform_key = arch_key + "_" + os_key
# Determine release suffix: explicit attr overrides built-in default
suffix = repository_ctx.attr.portable_ruby_release_suffix
if not suffix:
suffix = PORTABLE_RUBY_DEFAULT_SUFFIXES.get(ruby_version, "1")

artifact_name = _PORTABLE_RUBY_NAME.format(
version = ruby_version,
Expand All @@ -326,15 +323,15 @@ def _install_portable_ruby(repository_ctx, ruby_version, checksums):
kwargs = {}
if artifact_name in checksums:
kwargs["sha256"] = checksums[artifact_name]
elif artifact_name in PORTABLE_RUBY_CHECKSUMS:
kwargs["sha256"] = PORTABLE_RUBY_CHECKSUMS[artifact_name]
elif suffix in PORTABLE_RUBY_CHECKSUMS and artifact_name in PORTABLE_RUBY_CHECKSUMS[suffix]:
kwargs["sha256"] = PORTABLE_RUBY_CHECKSUMS[suffix][artifact_name]

repository_ctx.report_progress(
"Downloading portable Ruby %s for %s" % (ruby_version, platform_key),
"Downloading portable Ruby %s-%s for %s" % (ruby_version, suffix, platform_key),
)
repository_ctx.download_and_extract(
url = _MISE_RUBY_URL.format(
release = ruby_version,
url = _PORTABLE_RUBY_URL.format(
release = ruby_version + "-" + suffix,
name = artifact_name,
),
output = "dist/",
Expand Down Expand Up @@ -399,16 +396,25 @@ which isn't available in this ruby-build yet.
"portable_ruby": attr.bool(
default = False,
doc = """
When set to True, downloads portable Ruby from jdx/ruby instead of compiling via ruby-build.
When set to True, downloads portable Ruby from bazel-contrib/portable-ruby instead of compiling via ruby-build.
Has no effect on JRuby, TruffleRuby, or Windows (which use their own installation methods).
""",
),
"portable_ruby_release_suffix": attr.string(
default = "",
doc = """
Release suffix for portable Ruby downloads from bazel-contrib/portable-ruby.
The release tag is constructed as `{version}-{suffix}` (e.g. `4.0.2-1`).
When empty (default), the built-in PORTABLE_RUBY_DEFAULT_SUFFIXES mapping is used.
Set explicitly to pin to a specific rebuild (e.g. `"2"` for `4.0.2-2`).
""",
),
"portable_ruby_checksums": attr.string_dict(
default = {},
doc = """
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: artifact names (e.g., ruby-3.4.8.x86_64_linux.tar.gz, ruby-3.4.8.macos.tar.gz).
Keys: artifact names (e.g., ruby-3.4.8.x86_64_linux.tar.gz, ruby-3.4.8.arm64_darwin.tar.gz).
Values: SHA256 checksums for the corresponding platform.
""",
),
Expand Down
Loading
Loading