From f6cff647a4fe204b71365e225d14d14a6493ffee Mon Sep 17 00:00:00 2001 From: Alex Rodionov Date: Tue, 24 Dec 2024 13:49:16 -0800 Subject: [PATCH] feat: expose Ruby engine configuration (#185) --- docs/repository_rules.md | 16 ++++++++++++ examples/gem/spec/BUILD | 6 ++++- examples/gem/spec/env_spec.rb | 4 +++ ruby/private/download.bzl | 18 +++++++++++++ ruby/private/download/BUILD.engine.tpl | 36 ++++++++++++++++++++++++++ ruby/private/toolchain.bzl | 16 ++++++++++++ 6 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 ruby/private/download/BUILD.engine.tpl diff --git a/docs/repository_rules.md b/docs/repository_rules.md index a6b439b8..f76bed44 100644 --- a/docs/repository_rules.md +++ b/docs/repository_rules.md @@ -58,6 +58,22 @@ $ bazel run @ruby//:bundle -- update $ bazel run @ruby//:gem -- install rails ``` +You can also use Ruby engine targets to `select()` depending on installed Ruby interpreter: + +`BUILD`: +```bazel +rb_library( + name = "my_lib", + srcs = ["my_lib.rb"], + deps = select({ + "@ruby//engine:jruby": [":my_jruby_lib"], + "@ruby//engine:truffleruby": ["//:my_truffleruby_lib"], + "@ruby//engine:ruby": ["//:my__lib"], + "//conditions:default": [], + }), +) +``` + **PARAMETERS** diff --git a/examples/gem/spec/BUILD b/examples/gem/spec/BUILD index 3ebceb3c..11eb5bbe 100644 --- a/examples/gem/spec/BUILD +++ b/examples/gem/spec/BUILD @@ -38,7 +38,11 @@ rb_test( "LOCATION_SRC": "$(location :env_spec)", "LOCATION_DEP": "$(location //lib/gem:add)", "LOCATION_DATA": "$(location //spec/support:file)", - }, + } | select({ + "@ruby//engine:jruby": {"RUBY_ENGINE": "jruby"}, + "@ruby//engine:truffleruby": {"RUBY_ENGINE": "truffleruby"}, + "//conditions:default": {"RUBY_ENGINE": "ruby"}, + }), env_inherit = [ "USER", # POSIX "USERNAME", # Windows diff --git a/examples/gem/spec/env_spec.rb b/examples/gem/spec/env_spec.rb index 500ed5d0..c4b0daeb 100644 --- a/examples/gem/spec/env_spec.rb +++ b/examples/gem/spec/env_spec.rb @@ -20,4 +20,8 @@ expect(File).to exist(ENV.fetch('LOCATION_DATA')) expect(File).to exist(ENV.fetch('LOCATION_DEP')) end + + specify do + expect(ENV.fetch('RUBY_ENGINE')).to eq(RUBY_ENGINE) + end end diff --git a/ruby/private/download.bzl b/ruby/private/download.bzl index cea302cb..058044e8 100644 --- a/ruby/private/download.bzl +++ b/ruby/private/download.bzl @@ -99,11 +99,16 @@ def _rb_download_impl(repository_ctx): gem_binary_name = "gem" env = {} + engine = "ruby" if version.startswith("jruby"): + engine = "jruby" + # JRuby might fail with "Errno::EACCES: Permission denied - NUL" on Windows: # https://github.com/jruby/jruby/issues/7182#issuecomment-1112953015 env.update({"JAVA_OPTS": "-Djdk.io.File.enableADS=true"}) elif version.startswith("truffleruby"): + engine = "truffleruby" + # TruffleRuby needs explicit locale # https://www.graalvm.org/dev/reference-manual/ruby/UTF8Locale/ env.update({"LANG": "en_US.UTF-8"}) @@ -120,6 +125,15 @@ def _rb_download_impl(repository_ctx): }, ) + repository_ctx.template( + "engine/BUILD", + repository_ctx.attr._build_engine_tpl, + executable = False, + substitutions = { + "{ruby_engine}": engine, + }, + ) + def _read_version_from_file(repository_ctx): version = repository_ctx.read(repository_ctx.attr.version_file).strip("\r\n") if repository_ctx.attr.version_file.name == ".tool-versions": @@ -271,5 +285,9 @@ which isn't available in this ruby-build yet. allow_single_file = True, default = "@rules_ruby//:ruby/private/download/BUILD.tpl", ), + "_build_engine_tpl": attr.label( + allow_single_file = True, + default = "@rules_ruby//:ruby/private/download/BUILD.engine.tpl", + ), }, ) diff --git a/ruby/private/download/BUILD.engine.tpl b/ruby/private/download/BUILD.engine.tpl new file mode 100644 index 00000000..861ea126 --- /dev/null +++ b/ruby/private/download/BUILD.engine.tpl @@ -0,0 +1,36 @@ +load("@bazel_skylib//rules:common_settings.bzl", "string_flag") + +package(default_visibility = ["//visibility:public"]) + +string_flag( + name = "engine", + values = [ + "jruby", + "truffleruby", + "ruby", + ], + build_setting_default = "{ruby_engine}", +) + +config_setting( + name = "jruby", + flag_values = { + ":engine": "jruby", + }, +) + +config_setting( + name = "truffleruby", + flag_values = { + ":engine": "truffleruby", + }, +) + +config_setting( + name = "ruby", + flag_values = { + ":engine": "ruby", + }, +) + +# vim: ft=bzl diff --git a/ruby/private/toolchain.bzl b/ruby/private/toolchain.bzl index a4ff7418..f89beeb7 100644 --- a/ruby/private/toolchain.bzl +++ b/ruby/private/toolchain.bzl @@ -38,6 +38,22 @@ def rb_register_toolchains( $ bazel run @ruby//:gem -- install rails ``` + You can also use Ruby engine targets to `select()` depending on installed Ruby interpreter: + + `BUILD`: + ```bazel + rb_library( + name = "my_lib", + srcs = ["my_lib.rb"], + deps = select({ + "@ruby//engine:jruby": [":my_jruby_lib"], + "@ruby//engine:truffleruby": ["//:my_truffleruby_lib"], + "@ruby//engine:ruby": ["//:my__lib"], + "//conditions:default": [], + }), + ) + ``` + Args: name: base name of resulting repositories, by default "ruby" version: a semver version of MRI, or a string like [interpreter type]-[version], or "system"