Skip to content

Commit 5a94c47

Browse files
committed
feat: allow to read version from .ruby-version or .tool-versions file
fixes #23
1 parent 957579f commit 5a94c47

File tree

10 files changed

+70
-54
lines changed

10 files changed

+70
-54
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,32 +53,15 @@ jobs:
5353
# TruffleRuby doesn't work on Windows.
5454
- os: windows
5555
ruby: truffleruby-23.1.1
56-
# https://github.com/bazel-contrib/rules_ruby/issues/23
57-
- mode: bzlmod
58-
ruby: system
59-
- mode: bzlmod
60-
ruby: 3.0.6
61-
- mode: bzlmod
62-
ruby: 3.1.4
63-
- mode: bzlmod
64-
ruby: 3.2.2
65-
- mode: bzlmod
66-
ruby: 3.3.0-preview3
67-
- mode: bzlmod
68-
ruby: 3.0.6
69-
- mode: bzlmod
70-
ruby: truffleruby-23.1.1
7156
defaults:
7257
run:
7358
working-directory: examples/gem
7459
steps:
7560
- uses: actions/checkout@v4
7661
- uses: p0deje/setup-bazel@0.3.2
7762
with:
78-
bazelrc: |
79-
common --announce_rc --color=yes
80-
${{ matrix.mode == 'bzlmod' && 'common --enable_bzlmod' || '' }}
81-
- run: echo 'RUBY_VERSION = "${{ matrix.ruby }}"' > ruby_version.bzl
63+
bazelrc: common --announce_rc --color=yes ${{ matrix.mode == 'bzlmod' && '--enable_bzlmod' || '' }}
64+
- run: echo ${{ matrix.ruby }} > .ruby-version
8265
- if: matrix.ruby == 'system'
8366
uses: ruby/setup-ruby@v1
8467
with:

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ The ruleset is known to work with:
2121
load("@rules_ruby//ruby:deps.bzl", "rb_register_toolchains")
2222

2323
rb_register_toolchains(
24-
version = "3.0.6"
24+
version = "3.0.6",
25+
# alternatively, load version from .ruby-version file
26+
# version_file = "//:.ruby-version",
2527
)
2628
```
2729

@@ -50,7 +52,9 @@ rb_bundle(
5052
ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby")
5153
ruby.toolchain(
5254
name = "rules_ruby",
53-
version = "3.0.6"
55+
version = "3.0.6",
56+
# alternatively, load version from .ruby-version file
57+
# version_file = "//:.ruby-version",
5458
)
5559
use_repo(ruby, "rules_ruby_dist")
5660
```
@@ -92,7 +96,7 @@ The following toolchains are known to work and tested on CI.
9296

9397
| Ruby | Linux | macOS | Windows |
9498
|-------------------|-------|-------|---------|
95-
| MRI 3.3 (preview) | 🟩 | 🟩 | 🟩 |
99+
| MRI 3.3 (preview) | 🟩 | 🟩 | 🟥 |
96100
| MRI 3.2 | 🟩 | 🟩 | 🟩 |
97101
| MRI 3.1 | 🟩 | 🟩 | 🟩 |
98102
| MRI 3.0 | 🟩 | 🟩 | 🟩 |

docs/repository_rules.md

Lines changed: 4 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/gem/.ruby-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.0.6

examples/gem/MODULE.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ local_path_override(
1010
ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby")
1111
ruby.toolchain(
1212
name = "rules_ruby",
13-
version = "jruby-9.4.5.0",
13+
version_file = "//:.ruby-version",
1414
)
1515
use_repo(ruby, "rules_ruby_dist")
1616
ruby.bundle(

examples/gem/WORKSPACE

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@ http_archive(
1414
)
1515

1616
load("@rules_ruby//ruby:deps.bzl", "rb_bundle", "rb_register_toolchains")
17-
load("ruby_version.bzl", "RUBY_VERSION")
1817

1918
rb_register_toolchains(
20-
version = RUBY_VERSION,
19+
version_file = "//:.ruby-version",
2120
)
2221

2322
rb_bundle(

examples/gem/ruby_version.bzl

Lines changed: 0 additions & 2 deletions
This file was deleted.

ruby/extensions.bzl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ ruby_bundle = tag_class(attrs = {
1414
ruby_toolchain = tag_class(attrs = {
1515
"name": attr.string(doc = "Base name for generated repositories, allowing multiple to be registered."),
1616
"version": attr.string(doc = "Explicit version of ruby."),
17+
"version_file": attr.label(doc = "File to read Ruby version from."),
1718
})
1819

1920
def _ruby_module_extension(module_ctx):
@@ -40,15 +41,17 @@ def _ruby_module_extension(module_ctx):
4041
fail("Multiple conflicting toolchains declared for name {} ({} and {}".format(
4142
toolchain.name,
4243
toolchain.version,
44+
toolchain.version_file,
4345
registrations[toolchain.name],
4446
))
4547
else:
46-
registrations[toolchain.name] = toolchain.version
48+
registrations[toolchain.name] = (toolchain.version, toolchain.version_file)
4749

48-
for name, version in registrations.items():
50+
for name, (version, version_file) in registrations.items():
4951
rb_register_toolchains(
5052
name = name,
5153
version = version,
54+
version_file = version_file,
5255
register = False,
5356
)
5457

ruby/private/download.bzl

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
11
"Repository rule for fetching Ruby interpreters"
2+
23
_JRUBY_BINARY_URL = "https://repo1.maven.org/maven2/org/jruby/jruby-dist/{version}/jruby-dist-{version}-bin.tar.gz"
34
_RUBY_BUILD_URL = "https://github.com/rbenv/ruby-build/archive/refs/tags/v{version}.tar.gz"
45
_RUBY_INSTALLER_URL = "https://github.com/oneclick/rubyinstaller2/releases/download/RubyInstaller-{version}-1/rubyinstaller-devkit-{version}-1-x64.exe"
56

67
def _rb_download_impl(repository_ctx):
7-
if repository_ctx.attr.version.startswith("jruby"):
8-
_install_jruby(repository_ctx)
9-
elif repository_ctx.attr.version == "system":
8+
if repository_ctx.attr.version and not repository_ctx.attr.version_file:
9+
version = repository_ctx.attr.version
10+
elif repository_ctx.attr.version_file and not repository_ctx.attr.version:
11+
version = _read_version_from_file(repository_ctx)
12+
elif repository_ctx.attr.version_file and repository_ctx.attr.version:
13+
fail("only one of mandatory attributes 'version' or 'version_file' is allowed")
14+
else:
15+
fail("missing value for one of mandatory attributes 'version' or 'version_file'")
16+
17+
if version.startswith("jruby"):
18+
_install_jruby(repository_ctx, version)
19+
elif version == "system":
1020
_symlink_system_ruby(repository_ctx)
1121
elif repository_ctx.os.name.startswith("windows"):
12-
_install_via_rubyinstaller(repository_ctx)
22+
_install_via_rubyinstaller(repository_ctx, version)
1323
else:
14-
_install_via_ruby_build(repository_ctx)
24+
_install_via_ruby_build(repository_ctx, version)
1525

16-
if repository_ctx.attr.version.startswith("jruby"):
26+
if version.startswith("jruby"):
1727
ruby_binary_name = "jruby"
1828
gem_binary_name = "jgem"
1929
else:
@@ -26,14 +36,28 @@ def _rb_download_impl(repository_ctx):
2636
executable = False,
2737
substitutions = {
2838
"{bindir}": repr(repository_ctx.path("dist/bin")),
29-
"{version}": repository_ctx.attr.version,
39+
"{version}": version,
3040
"{ruby_binary_name}": ruby_binary_name,
3141
"{gem_binary_name}": gem_binary_name,
3242
},
3343
)
3444

35-
def _install_jruby(repository_ctx):
36-
version = repository_ctx.attr.version.removeprefix("jruby-")
45+
def _read_version_from_file(repository_ctx):
46+
version = repository_ctx.read(repository_ctx.attr.version_file).strip("\r\n")
47+
if repository_ctx.attr.version_file.name == ".tool-versions":
48+
return _parse_version_from_tool_versions(version)
49+
else:
50+
return version
51+
52+
def _parse_version_from_tool_versions(file):
53+
for line in file.splitlines():
54+
if line.startswith("ruby"):
55+
version = line.partition(" ")[-1]
56+
return version
57+
return None
58+
59+
def _install_jruby(repository_ctx, version):
60+
version = version.removeprefix("jruby-")
3761
repository_ctx.report_progress("Downloading JRuby %s" % version)
3862
repository_ctx.download_and_extract(
3963
url = _JRUBY_BINARY_URL.format(version = version),
@@ -45,14 +69,14 @@ def _install_jruby(repository_ctx):
4569
repository_ctx.symlink("dist/bin/bundle.bat", "dist/bin/bundle.cmd")
4670

4771
# https://github.com/oneclick/rubyinstaller2/wiki/FAQ#q-how-do-i-perform-a-silentunattended-install-with-the-rubyinstaller
48-
def _install_via_rubyinstaller(repository_ctx):
72+
def _install_via_rubyinstaller(repository_ctx, version):
4973
repository_ctx.report_progress("Downloading RubyInstaller")
5074
repository_ctx.download(
51-
url = _RUBY_INSTALLER_URL.format(version = repository_ctx.attr.version),
75+
url = _RUBY_INSTALLER_URL.format(version = version),
5276
output = "ruby-installer.exe",
5377
)
5478

55-
repository_ctx.report_progress("Installing Ruby %s" % repository_ctx.attr.version)
79+
repository_ctx.report_progress("Installing Ruby %s" % version)
5680
result = repository_ctx.execute([
5781
"./ruby-installer.exe",
5882
"/components=ruby,msys2",
@@ -76,17 +100,17 @@ def _install_via_rubyinstaller(repository_ctx):
76100
"{}/bundle.cmd".format(binpath),
77101
)
78102

79-
def _install_via_ruby_build(repository_ctx):
103+
def _install_via_ruby_build(repository_ctx, version):
80104
repository_ctx.report_progress("Downloading ruby-build %s" % repository_ctx.attr.ruby_build_version)
81105
repository_ctx.download_and_extract(
82106
url = _RUBY_BUILD_URL.format(version = repository_ctx.attr.ruby_build_version),
83107
output = "ruby-build",
84108
stripPrefix = "ruby-build-%s" % repository_ctx.attr.ruby_build_version,
85109
)
86110

87-
repository_ctx.report_progress("Installing Ruby %s" % repository_ctx.attr.version)
111+
repository_ctx.report_progress("Installing Ruby %s" % version)
88112
result = repository_ctx.execute(
89-
["ruby-build/bin/ruby-build", "--verbose", repository_ctx.attr.version, "dist"],
113+
["ruby-build/bin/ruby-build", "--verbose", version, "dist"],
90114
timeout = 1200,
91115
quiet = not repository_ctx.os.environ.get("RUBY_RULES_DEBUG", default = False),
92116
)
@@ -106,10 +130,11 @@ rb_download = repository_rule(
106130
implementation = _rb_download_impl,
107131
attrs = {
108132
"version": attr.string(
109-
mandatory = True,
110-
doc = """
111-
Ruby version to install.
112-
""",
133+
doc = "Ruby version to install.",
134+
),
135+
"version_file": attr.label(
136+
allow_single_file = [".ruby-version"],
137+
doc = "File to read Ruby version from.",
113138
),
114139
"ruby_build_version": attr.string(
115140
default = "20231114",

ruby/private/toolchain.bzl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ load("//ruby/private/toolchain:repository_proxy.bzl", _rb_toolchain_repository_p
55

66
DEFAULT_RUBY_REPOSITORY = "rules_ruby"
77

8-
def rb_register_toolchains(name = DEFAULT_RUBY_REPOSITORY, version = None, register = True, **kwargs):
8+
def rb_register_toolchains(name = DEFAULT_RUBY_REPOSITORY, version = None, version_file = None, register = True, **kwargs):
99
"""
1010
Register a Ruby toolchain and lazily download the Ruby Interpreter.
1111
@@ -20,13 +20,14 @@ def rb_register_toolchains(name = DEFAULT_RUBY_REPOSITORY, version = None, regis
2020
load("@rules_ruby//ruby:deps.bzl", "rb_register_toolchains")
2121
2222
rb_register_toolchains(
23-
version = "2.7.5"
23+
version = "3.0.6"
2424
)
2525
```
2626
2727
Args:
2828
name: base name of resulting repositories, by default "rules_ruby"
29-
version: a semver version of Matz Ruby Interpreter, or a string like [interpreter type]-[version], or "system"
29+
version: a semver version of MRI, or a string like [interpreter type]-[version], or "system"
30+
version_file: .ruby-version or .tool-versions file to read version from
3031
register: whether to register the resulting toolchains, should be False under bzlmod
3132
**kwargs: additional parameters to the downloader for this interpreter type
3233
"""
@@ -36,6 +37,7 @@ def rb_register_toolchains(name = DEFAULT_RUBY_REPOSITORY, version = None, regis
3637
_rb_download(
3738
name = repo_name,
3839
version = version,
40+
version_file = version_file,
3941
**kwargs
4042
)
4143
_rb_toolchain_repository_proxy(

0 commit comments

Comments
 (0)