├── WORKSPACE
├── .bazelversion
├── .bazelignore
├── examples
├── rails
│ ├── .ruby-version
│ ├── people_tracker
│ │ ├── script
│ │ │ └── .keep
│ │ ├── vendor
│ │ │ └── .keep
│ │ ├── lib
│ │ │ └── tasks
│ │ │ │ └── .keep
│ │ ├── test
│ │ │ ├── mailers
│ │ │ │ └── .keep
│ │ │ ├── integration
│ │ │ │ └── .keep
│ │ │ ├── fixtures
│ │ │ │ ├── files
│ │ │ │ │ └── .keep
│ │ │ │ ├── BUILD.bazel
│ │ │ │ └── people.yml
│ │ │ ├── models
│ │ │ │ ├── BUILD.bazel
│ │ │ │ └── person_test.rb
│ │ │ ├── system
│ │ │ │ ├── BUILD.bazel
│ │ │ │ └── people_test.rb
│ │ │ ├── controllers
│ │ │ │ ├── BUILD.bazel
│ │ │ │ └── people_controller_test.rb
│ │ │ ├── application_system_test_case.rb
│ │ │ ├── rails_test.bzl
│ │ │ ├── BUILD.bazel
│ │ │ └── test_helper.rb
│ │ ├── app
│ │ │ ├── assets
│ │ │ │ ├── images
│ │ │ │ │ └── .keep
│ │ │ │ ├── tailwind
│ │ │ │ │ └── application.css
│ │ │ │ ├── BUILD.bazel
│ │ │ │ └── stylesheets
│ │ │ │ │ └── application.css
│ │ │ ├── views
│ │ │ │ ├── layouts
│ │ │ │ │ ├── mailer.text.erb
│ │ │ │ │ ├── BUILD.bazel
│ │ │ │ │ ├── mailer.html.erb
│ │ │ │ │ └── application.html.erb
│ │ │ │ ├── people
│ │ │ │ │ ├── show.json.jbuilder
│ │ │ │ │ ├── index.json.jbuilder
│ │ │ │ │ ├── BUILD.bazel
│ │ │ │ │ ├── _person.json.jbuilder
│ │ │ │ │ ├── _person.html.erb
│ │ │ │ │ ├── new.html.erb
│ │ │ │ │ ├── edit.html.erb
│ │ │ │ │ ├── show.html.erb
│ │ │ │ │ ├── _form.html.erb
│ │ │ │ │ └── index.html.erb
│ │ │ │ ├── pwa
│ │ │ │ │ ├── BUILD.bazel
│ │ │ │ │ ├── manifest.json.erb
│ │ │ │ │ └── service-worker.js
│ │ │ │ └── BUILD.bazel
│ │ │ ├── models
│ │ │ │ ├── concerns
│ │ │ │ │ └── BUILD.bazel
│ │ │ │ ├── application_record.rb
│ │ │ │ ├── BUILD.bazel
│ │ │ │ └── person.rb
│ │ │ ├── controllers
│ │ │ │ ├── concerns
│ │ │ │ │ └── BUILD.bazel
│ │ │ │ ├── BUILD.bazel
│ │ │ │ ├── application_controller.rb
│ │ │ │ └── people_controller.rb
│ │ │ ├── helpers
│ │ │ │ ├── people_helper.rb
│ │ │ │ ├── application_helper.rb
│ │ │ │ └── BUILD.bazel
│ │ │ ├── mailers
│ │ │ │ ├── application_mailer.rb
│ │ │ │ └── BUILD.bazel
│ │ │ ├── javascript
│ │ │ │ ├── BUILD.bazel
│ │ │ │ ├── application.js
│ │ │ │ └── controllers
│ │ │ │ │ ├── application.js
│ │ │ │ │ └── index.js
│ │ │ ├── jobs
│ │ │ │ ├── BUILD.bazel
│ │ │ │ └── application_job.rb
│ │ │ └── BUILD.bazel
│ │ ├── config
│ │ │ ├── master.key
│ │ │ ├── environment.rb
│ │ │ ├── locales
│ │ │ │ ├── BUILD.bazel
│ │ │ │ └── en.yml
│ │ │ ├── boot.rb
│ │ │ ├── environments
│ │ │ │ ├── BUILD.bazel
│ │ │ │ ├── test.rb
│ │ │ │ ├── development.rb
│ │ │ │ └── production.rb
│ │ │ ├── initializers
│ │ │ │ ├── BUILD.bazel
│ │ │ │ ├── assets.rb
│ │ │ │ ├── filter_parameter_logging.rb
│ │ │ │ ├── inflections.rb
│ │ │ │ ├── bazel_ruby_patches.rb
│ │ │ │ └── content_security_policy.rb
│ │ │ ├── cable.yml
│ │ │ ├── importmap.rb
│ │ │ ├── credentials.yml.enc
│ │ │ ├── BUILD.bazel
│ │ │ ├── routes.rb
│ │ │ ├── storage.yml
│ │ │ ├── database.yml
│ │ │ ├── application.rb
│ │ │ ├── puma.rb
│ │ │ └── deploy.yml
│ │ ├── Procfile.dev
│ │ ├── bin
│ │ │ ├── rake
│ │ │ ├── thrust
│ │ │ ├── rails
│ │ │ ├── brakeman
│ │ │ ├── rubocop
│ │ │ ├── BUILD.bazel
│ │ │ ├── dev
│ │ │ ├── docker-entrypoint
│ │ │ └── setup
│ │ ├── public
│ │ │ ├── icon.png
│ │ │ ├── robots.txt
│ │ │ └── icon.svg
│ │ ├── config.ru
│ │ ├── db
│ │ │ ├── migrate
│ │ │ │ ├── BUILD.bazel
│ │ │ │ └── 20250821215024_create_people.rb
│ │ │ ├── BUILD.bazel
│ │ │ ├── seeds.rb
│ │ │ └── schema.rb
│ │ ├── Rakefile
│ │ ├── .rubocop.yml
│ │ ├── BUILD.bazel
│ │ ├── .dockerignore
│ │ ├── .envrc
│ │ ├── Dockerfile
│ │ └── Gemfile
│ ├── .standard.yml
│ ├── Gemfile
│ ├── do_test
│ ├── .envrc
│ ├── .bazelrc
│ ├── BUILD.bazel
│ └── README.md
├── gem
│ ├── .bazelversion
│ ├── .ruby-version
│ ├── spec
│ │ ├── support
│ │ │ ├── file.txt
│ │ │ └── BUILD
│ │ ├── spec_helper.rb
│ │ ├── support_spec.rb
│ │ ├── add_spec.rb
│ │ ├── subtract_spec.rb
│ │ ├── env_spec.rb
│ │ └── BUILD
│ ├── Rakefile
│ ├── lib
│ │ ├── gem.rb
│ │ ├── gem
│ │ │ ├── subtract.rb
│ │ │ ├── version.rb
│ │ │ ├── add.rb
│ │ │ └── BUILD
│ │ └── BUILD
│ ├── WORKSPACE.bzlmod
│ ├── Gemfile
│ ├── .rubocop.yml
│ ├── wrapper.tpl.sh
│ ├── gem.gemspec
│ ├── .bazelrc
│ ├── BUILD
│ ├── Gemfile.lock
│ ├── WORKSPACE
│ └── MODULE.bazel
├── jekyll
│ ├── .bazelversion
│ ├── .gitignore
│ ├── index.md
│ ├── 404.html
│ ├── about.md
│ ├── _posts
│ │ └── 2024-02-03-welcome-to-jekyll.markdown
│ ├── Gemfile
│ ├── _config.yml
│ ├── BUILD
│ ├── Gemfile.lock
│ └── MODULE.bazel
├── deep_gem
│ ├── .bazelversion
│ ├── .ruby-version
│ ├── BUILD
│ ├── hello_world
│ │ ├── BUILD.bazel
│ │ ├── .rspec
│ │ ├── lib
│ │ │ ├── hello_world
│ │ │ │ ├── version.rb
│ │ │ │ ├── speaker.rb
│ │ │ │ └── BUILD.bazel
│ │ │ ├── hello_world.rb
│ │ │ └── BUILD.bazel
│ │ ├── Gemfile
│ │ ├── spec
│ │ │ ├── hello_world_spec.rb
│ │ │ ├── spec_helper.rb
│ │ │ ├── BUILD.bazel
│ │ │ └── speaker_spec.rb
│ │ ├── hello_world.gemspec
│ │ ├── Gemfile.lock
│ │ └── .bazelrc
│ ├── do_test
│ ├── .bazelrc
│ ├── MODULE.bazel
│ └── README.md
└── native_ext
│ ├── .bazelversion
│ ├── .ruby-version
│ ├── ext
│ ├── c
│ │ ├── native_ext.h
│ │ └── native_ext.c
│ └── java
│ │ └── Dummy.java
│ ├── .bazelrc
│ ├── MODULE.bazel
│ └── BUILD
├── ruby
├── private
│ ├── gem_build
│ │ ├── BUILD
│ │ └── gem_builder.rb.tpl
│ ├── binary
│ │ ├── BUILD
│ │ ├── binary.cmd.tpl
│ │ └── binary.sh.tpl
│ ├── gem_install
│ │ ├── BUILD
│ │ ├── gem_install.cmd.tpl
│ │ └── gem_install.sh.tpl
│ ├── bundle_install
│ │ ├── BUILD
│ │ ├── bundle_install.cmd.tpl
│ │ └── bundle_install.sh.tpl
│ ├── toolchain
│ │ ├── repository_proxy
│ │ │ └── BUILD.tpl
│ │ ├── BUILD
│ │ └── repository_proxy.bzl
│ ├── bundle_fetch
│ │ ├── BUILD
│ │ ├── bin
│ │ │ └── BUILD.tpl
│ │ └── BUILD.tpl
│ ├── bundle
│ │ └── BUILD.tpl
│ ├── download
│ │ ├── BUILD.engine.tpl
│ │ └── BUILD.tpl
│ ├── gem.bzl
│ ├── BUILD
│ ├── toolchain.bzl
│ ├── gem_push.bzl
│ ├── test.bzl
│ ├── providers.bzl
│ ├── library.bzl
│ └── gem_install.bzl
├── tests
│ ├── BUILD
│ └── utils_tests.bzl
├── deps.bzl
├── defs.bzl
├── toolchain.bzl
└── BUILD
├── .gitattributes
├── rails
├── rails_test_factory.bzl
├── private
│ └── BUILD.bazel
└── BUILD.bazel
├── .gitignore
├── .bazelrc
├── CONTRIBUTING.md
├── renovate.json
├── .bcr
├── source.template.json
├── metadata.template.json
├── config.yml
├── README.md
└── presubmit.yml
├── .github
└── workflows
│ ├── ci.bazelrc
│ └── release_prep.sh
├── BUILD
├── docs
├── BUILD
└── rails.md
├── .pre-commit-config.yaml
└── MODULE.bazel
/WORKSPACE:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.bazelversion:
--------------------------------------------------------------------------------
1 | 8.4.2
2 |
--------------------------------------------------------------------------------
/.bazelignore:
--------------------------------------------------------------------------------
1 | examples
2 |
--------------------------------------------------------------------------------
/examples/rails/.ruby-version:
--------------------------------------------------------------------------------
1 | 3.4.5
2 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/script/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/vendor/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/gem/.bazelversion:
--------------------------------------------------------------------------------
1 | ../../.bazelversion
--------------------------------------------------------------------------------
/examples/gem/.ruby-version:
--------------------------------------------------------------------------------
1 | jruby-10.0.2.0
2 |
--------------------------------------------------------------------------------
/examples/gem/spec/support/file.txt:
--------------------------------------------------------------------------------
1 | File!
2 |
--------------------------------------------------------------------------------
/examples/jekyll/.bazelversion:
--------------------------------------------------------------------------------
1 | ../../.bazelversion
--------------------------------------------------------------------------------
/examples/rails/people_tracker/lib/tasks/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/test/mailers/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/deep_gem/.bazelversion:
--------------------------------------------------------------------------------
1 | ../../.bazelversion
--------------------------------------------------------------------------------
/examples/deep_gem/.ruby-version:
--------------------------------------------------------------------------------
1 | jruby-10.0.2.0
2 |
--------------------------------------------------------------------------------
/examples/deep_gem/BUILD:
--------------------------------------------------------------------------------
1 | # Intentionally blank
2 |
--------------------------------------------------------------------------------
/examples/native_ext/.bazelversion:
--------------------------------------------------------------------------------
1 | ../../.bazelversion
--------------------------------------------------------------------------------
/examples/native_ext/.ruby-version:
--------------------------------------------------------------------------------
1 | jruby-10.0.2.0
2 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/assets/images/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/test/integration/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/test/fixtures/files/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/jekyll/.gitignore:
--------------------------------------------------------------------------------
1 | bazel-*
2 | MODULE.bazel.lock
3 |
--------------------------------------------------------------------------------
/examples/rails/.standard.yml:
--------------------------------------------------------------------------------
1 | # Config file for Standardrb
2 |
--------------------------------------------------------------------------------
/examples/deep_gem/hello_world/BUILD.bazel:
--------------------------------------------------------------------------------
1 | # Intentionally blank
2 |
--------------------------------------------------------------------------------
/ruby/private/gem_build/BUILD:
--------------------------------------------------------------------------------
1 | exports_files(["gem_builder.rb.tpl"])
2 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/layouts/mailer.text.erb:
--------------------------------------------------------------------------------
1 | <%= yield %>
2 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/master.key:
--------------------------------------------------------------------------------
1 | 7a77b7a551c74939a2d64605d80d07a8
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/models/concerns/BUILD.bazel:
--------------------------------------------------------------------------------
1 | # Intentionally empty
2 |
--------------------------------------------------------------------------------
/examples/gem/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'gem'
4 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/assets/tailwind/application.css:
--------------------------------------------------------------------------------
1 | @import "tailwindcss";
2 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/controllers/concerns/BUILD.bazel:
--------------------------------------------------------------------------------
1 | # Intentionally blank
2 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/helpers/people_helper.rb:
--------------------------------------------------------------------------------
1 | module PeopleHelper
2 | end
3 |
--------------------------------------------------------------------------------
/ruby/tests/BUILD:
--------------------------------------------------------------------------------
1 | load(":utils_tests.bzl", "utils_test_suite")
2 |
3 | utils_test_suite()
4 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # In code review, collapse generated files
2 | docs/*.md linguist-generated=true
3 |
--------------------------------------------------------------------------------
/examples/deep_gem/hello_world/.rspec:
--------------------------------------------------------------------------------
1 | --format documentation
2 | --color
3 | --require spec_helper
4 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/helpers/application_helper.rb:
--------------------------------------------------------------------------------
1 | module ApplicationHelper
2 | end
3 |
--------------------------------------------------------------------------------
/ruby/private/binary/BUILD:
--------------------------------------------------------------------------------
1 | exports_files([
2 | "binary.cmd.tpl",
3 | "binary.sh.tpl",
4 | ])
5 |
--------------------------------------------------------------------------------
/examples/gem/Rakefile:
--------------------------------------------------------------------------------
1 | desc "say goodnight to bash"
2 | task "goodnight" do
3 | puts "exit 0"
4 | end
5 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/Procfile.dev:
--------------------------------------------------------------------------------
1 | web: bin/rails server
2 | css: bin/rails tailwindcss:watch
3 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/people/show.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.partial! "people/person", person: @person
2 |
--------------------------------------------------------------------------------
/ruby/private/gem_install/BUILD:
--------------------------------------------------------------------------------
1 | exports_files([
2 | "gem_install.cmd.tpl",
3 | "gem_install.sh.tpl",
4 | ])
5 |
--------------------------------------------------------------------------------
/ruby/private/bundle_install/BUILD:
--------------------------------------------------------------------------------
1 | exports_files([
2 | "bundle_install.cmd.tpl",
3 | "bundle_install.sh.tpl",
4 | ])
5 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/people/index.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.array! @people, partial: "people/person", as: :person
2 |
--------------------------------------------------------------------------------
/examples/gem/lib/gem.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'gem/add'
4 | require 'gem/subtract'
5 | require 'gem/version'
6 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/models/application_record.rb:
--------------------------------------------------------------------------------
1 | class ApplicationRecord < ActiveRecord::Base
2 | primary_abstract_class
3 | end
4 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require_relative "../config/boot"
3 | require "rake"
4 | Rake.application.run
5 |
--------------------------------------------------------------------------------
/examples/deep_gem/hello_world/lib/hello_world/version.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module HelloWorld
4 | VERSION = "0.0.0"
5 | end
6 |
--------------------------------------------------------------------------------
/examples/native_ext/ext/c/native_ext.h:
--------------------------------------------------------------------------------
1 | #ifndef NATIVE_EXT_H
2 | #define NATIVE_EXT_H 1
3 |
4 | #include "ruby.h"
5 |
6 | #endif /* NATIVE_EXT_H */
7 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/public/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bazel-contrib/rules_ruby/HEAD/examples/rails/people_tracker/public/icon.png
--------------------------------------------------------------------------------
/examples/rails/people_tracker/public/robots.txt:
--------------------------------------------------------------------------------
1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
2 |
--------------------------------------------------------------------------------
/examples/gem/WORKSPACE.bzlmod:
--------------------------------------------------------------------------------
1 | # Marker file that this is the root of a Bazel workspace.
2 | # This file replaces WORKSPACE.bazel under --enable_bzlmod.
3 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/bin/thrust:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require "rubygems"
3 | require "bundler/setup"
4 |
5 | load Gem.bin_path("thruster", "thrust")
6 |
--------------------------------------------------------------------------------
/examples/deep_gem/hello_world/lib/hello_world.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require_relative "hello_world/version"
4 | require_relative "hello_world/speaker"
5 |
--------------------------------------------------------------------------------
/examples/gem/spec/support/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//spec:__subpackages__"])
2 |
3 | filegroup(
4 | name = "file",
5 | srcs = ["file.txt"],
6 | )
7 |
--------------------------------------------------------------------------------
/ruby/private/bundle_install/bundle_install.cmd.tpl:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | {env}
4 |
5 | {ruby_path} {bundler_exe} install --standalone --local
6 |
7 | :: vim: ft=dosbatch
8 |
--------------------------------------------------------------------------------
/ruby/private/bundle_install/bundle_install.sh.tpl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | {env}
4 |
5 | {ruby_path} {bundler_exe} install --standalone --local
6 |
7 | # vim: ft=bash
8 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/mailers/application_mailer.rb:
--------------------------------------------------------------------------------
1 | class ApplicationMailer < ActionMailer::Base
2 | default from: "from@example.com"
3 | layout "mailer"
4 | end
5 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/public/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/examples/deep_gem/hello_world/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source "https://rubygems.org"
4 |
5 | # Specify your gem's dependencies in hello_world.gemspec
6 | gemspec
7 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/pwa/BUILD.bazel:
--------------------------------------------------------------------------------
1 | filegroup(
2 | name = "files",
3 | srcs = glob(["*"]),
4 | visibility = ["//people_tracker:__subpackages__"],
5 | )
6 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/assets/BUILD.bazel:
--------------------------------------------------------------------------------
1 | filegroup(
2 | name = "files",
3 | srcs = glob(["**/*.css"]),
4 | visibility = ["//people_tracker:__subpackages__"],
5 | )
6 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/people/BUILD.bazel:
--------------------------------------------------------------------------------
1 | filegroup(
2 | name = "files",
3 | srcs = glob(["*"]),
4 | visibility = ["//people_tracker:__subpackages__"],
5 | )
6 |
--------------------------------------------------------------------------------
/examples/rails/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source "https://rubygems.org"
4 |
5 | # Rails for generating and running the People Tracker Rails application
6 | gem "rails", "~> 8.0"
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/javascript/BUILD.bazel:
--------------------------------------------------------------------------------
1 | filegroup(
2 | name = "files",
3 | srcs = glob(["**/*.js"]),
4 | visibility = ["//people_tracker:__subpackages__"],
5 | )
6 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/layouts/BUILD.bazel:
--------------------------------------------------------------------------------
1 | filegroup(
2 | name = "files",
3 | srcs = glob(["*.erb"]),
4 | visibility = ["//people_tracker:__subpackages__"],
5 | )
6 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/people/_person.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.extract! person, :id, :first_name, :last_name, :created_at, :updated_at
2 | json.url person_url(person, format: :json)
3 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | APP_PATH = File.expand_path("../config/application", __dir__)
3 | require_relative "../config/boot"
4 | require "rails/commands"
5 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/test/fixtures/BUILD.bazel:
--------------------------------------------------------------------------------
1 | filegroup(
2 | name = "files",
3 | srcs = glob(["*.yml"]),
4 | visibility = ["//people_tracker/test:__subpackages__"],
5 | )
6 |
--------------------------------------------------------------------------------
/examples/native_ext/ext/java/Dummy.java:
--------------------------------------------------------------------------------
1 | import org.jruby.*;
2 | import org.jruby.anno.JRubyClass;
3 |
4 | @JRubyClass(name = "Dummy")
5 | public class Dummy {
6 | public Dummy() {
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the Rails application.
2 | require_relative "application"
3 |
4 | # Initialize the Rails application.
5 | Rails.application.initialize!
6 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/locales/BUILD.bazel:
--------------------------------------------------------------------------------
1 | filegroup(
2 | name = "files",
3 | srcs = glob(["*.yml"]),
4 | visibility = ["//people_tracker/config:__subpackages__"],
5 | )
6 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/test/models/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("//people_tracker/test:rails_test.bzl", "rails_test")
2 |
3 | rails_test(
4 | name = "person_test",
5 | src = "person_test.rb",
6 | )
7 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/bin/brakeman:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require "rubygems"
3 | require "bundler/setup"
4 |
5 | ARGV.unshift("--ensure-latest")
6 |
7 | load Gem.bin_path("brakeman", "brakeman")
8 |
--------------------------------------------------------------------------------
/examples/jekyll/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | # Feel free to add content and custom Front Matter to this file.
3 | # To modify the layout, see https://jekyllrb.com/docs/themes/#overriding-theme-defaults
4 |
5 | layout: home
6 | ---
7 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config.ru:
--------------------------------------------------------------------------------
1 | # This file is used by Rack-based servers to start the application.
2 |
3 | require_relative "config/environment"
4 |
5 | run Rails.application
6 | Rails.application.load_server
7 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/test/system/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("//people_tracker/test:rails_test.bzl", "rails_system_test")
2 |
3 | rails_system_test(
4 | name = "people_test",
5 | src = "people_test.rb",
6 | )
7 |
--------------------------------------------------------------------------------
/ruby/private/toolchain/repository_proxy/BUILD.tpl:
--------------------------------------------------------------------------------
1 | toolchain(
2 | name = "{name}",
3 | toolchain = "{toolchain}",
4 | toolchain_type = "{toolchain_type}",
5 | visibility = ["//visibility:public"],
6 | )
7 |
--------------------------------------------------------------------------------
/examples/native_ext/ext/c/native_ext.c:
--------------------------------------------------------------------------------
1 | #include "native_ext.h"
2 |
3 | VALUE rb_mNativeExt;
4 |
5 | RUBY_FUNC_EXPORTED void
6 | Init_native_ext(void)
7 | {
8 | rb_mNativeExt = rb_define_module("NativeExt");
9 | }
10 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/javascript/application.js:
--------------------------------------------------------------------------------
1 | // Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
2 | import "@hotwired/turbo-rails";
3 | import "controllers";
4 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/test/controllers/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("//people_tracker/test:rails_test.bzl", "rails_test")
2 |
3 | rails_test(
4 | name = "people_controller_test",
5 | src = "people_controller_test.rb",
6 | )
7 |
--------------------------------------------------------------------------------
/ruby/private/toolchain/BUILD:
--------------------------------------------------------------------------------
1 | load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
2 |
3 | bzl_library(
4 | name = "repository_proxy",
5 | srcs = ["repository_proxy.bzl"],
6 | visibility = ["//ruby:__subpackages__"],
7 | )
8 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/jobs/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
2 |
3 | rb_library(
4 | name = "jobs",
5 | srcs = glob(["*.rb"]),
6 | visibility = ["//people_tracker/app:__subpackages__"],
7 | )
8 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/helpers/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
2 |
3 | rb_library(
4 | name = "helpers",
5 | srcs = glob(["*.rb"]),
6 | visibility = ["//people_tracker/app:__subpackages__"],
7 | )
8 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/mailers/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
2 |
3 | rb_library(
4 | name = "mailers",
5 | srcs = glob(["*.rb"]),
6 | visibility = ["//people_tracker/app:__subpackages__"],
7 | )
8 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/models/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
2 |
3 | rb_library(
4 | name = "models",
5 | srcs = glob(["*.rb"]),
6 | visibility = ["//people_tracker/app:__subpackages__"],
7 | )
8 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/db/migrate/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
2 |
3 | rb_library(
4 | name = "migrate",
5 | srcs = glob(["*.rb"]),
6 | visibility = ["//people_tracker/db:__subpackages__"],
7 | )
8 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/test/application_system_test_case.rb:
--------------------------------------------------------------------------------
1 | require "test_helper"
2 |
3 | class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
4 | driven_by :selenium, using: :headless_chrome, screen_size: [1400, 1400]
5 | end
6 |
--------------------------------------------------------------------------------
/ruby/private/bundle_fetch/BUILD:
--------------------------------------------------------------------------------
1 | load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
2 |
3 | bzl_library(
4 | name = "gemfile_lock_parser",
5 | srcs = ["gemfile_lock_parser.bzl"],
6 | visibility = ["//ruby:__subpackages__"],
7 | )
8 |
--------------------------------------------------------------------------------
/examples/gem/spec/support_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require_relative 'spec_helper'
4 |
5 | RSpec.describe File do
6 | specify do
7 | expect(File.read('spec/support/file.txt').chomp).to eq('File!')
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/rails/rails_test_factory.bzl:
--------------------------------------------------------------------------------
1 | """Public definition for `rails_test_factory`."""
2 |
3 | load(
4 | "//rails/private:rails_test_factory.bzl",
5 | _rails_test_factory = "rails_test_factory",
6 | )
7 |
8 | rails_test_factory = _rails_test_factory
9 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/controllers/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
2 |
3 | rb_library(
4 | name = "controllers",
5 | srcs = glob(["*.rb"]),
6 | visibility = ["//people_tracker/app:__subpackages__"],
7 | )
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore all Bazel symlinks
2 | bazel-*
3 |
4 | # Ignore Bazel lock file.
5 | MODULE.bazel.lock
6 |
7 |
8 | examples/rails/people_tracker/log/**
9 | examples/rails/people_tracker/storage/**
10 | examples/rails/people_tracker/tmp/***
11 |
12 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/boot.rb:
--------------------------------------------------------------------------------
1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
2 |
3 | require "bundler/setup" # Set up gems listed in the Gemfile.
4 | require "bootsnap/setup" # Speed up boot time by caching expensive operations.
5 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/environments/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
2 |
3 | rb_library(
4 | name = "environments",
5 | srcs = glob(["*.rb"]),
6 | visibility = ["//people_tracker/config:__subpackages__"],
7 | )
8 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/initializers/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
2 |
3 | rb_library(
4 | name = "initializers",
5 | srcs = glob(["*.rb"]),
6 | visibility = ["//people_tracker/config:__subpackages__"],
7 | )
8 |
--------------------------------------------------------------------------------
/rails/private/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
2 |
3 | bzl_library(
4 | name = "rails_test_factory",
5 | srcs = ["rails_test_factory.bzl"],
6 | visibility = ["//rails:__subpackages__"],
7 | deps = ["//ruby:defs"],
8 | )
9 |
--------------------------------------------------------------------------------
/examples/gem/spec/add_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require_relative 'spec_helper'
4 |
5 | RSpec.describe GEM::Add do
6 | describe '#result' do
7 | specify do
8 | expect(GEM::Add.new(2, 2).result).to eq(4)
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/examples/gem/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source 'https://rubygems.org'
4 | gemspec
5 |
6 | gem 'debug', '>= 1.0.0', platforms: %i[mri mswin64]
7 | gem 'psych', '~> 5.1' # Gem with native extensions.
8 | gem 'rspec', '~> 3.0'
9 | gem 'rubocop', '~> 1.64'
10 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/Rakefile:
--------------------------------------------------------------------------------
1 | # Add your own tasks in files placed in lib/tasks ending in .rake,
2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3 |
4 | require_relative "config/application"
5 |
6 | Rails.application.load_tasks
7 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | class ApplicationController < ActionController::Base
2 | # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has.
3 | allow_browser versions: :modern
4 | end
5 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/cable.yml:
--------------------------------------------------------------------------------
1 | development:
2 | adapter: async
3 |
4 | test:
5 | adapter: test
6 |
7 | production:
8 | adapter: redis
9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
10 | channel_prefix: people_tracker_production
11 |
--------------------------------------------------------------------------------
/ruby/private/bundle_fetch/bin/BUILD.tpl:
--------------------------------------------------------------------------------
1 | """@generated by @rules_ruby//:ruby/private/bundle_fetch.bzl"""
2 |
3 | load("@rules_ruby//ruby:defs.bzl", "rb_binary")
4 |
5 | package(default_visibility = ["//visibility:public"])
6 |
7 | {gem_binary_fragments}
8 |
9 | # vim: ft=bzl
10 |
--------------------------------------------------------------------------------
/.bazelrc:
--------------------------------------------------------------------------------
1 | # This file contains Bazel settings to apply on Release only.
2 | # It is referenced with a --bazelrc option in the call to bazel in release.yaml
3 | #
4 | # Not ready for the MODULE.lock file yet, as of Bazel 7.0.0 there are still some stability issues.
5 | common --lockfile_mode=off
6 |
--------------------------------------------------------------------------------
/examples/gem/spec/subtract_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require_relative 'spec_helper'
4 |
5 | RSpec.describe GEM::Subtract do
6 | describe '#result' do
7 | specify do
8 | expect(GEM::Subtract.new(2, 2).result).to eq(0)
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to Contribute
2 |
3 | TODO
4 |
5 | ## Releasing
6 |
7 | To perform a release, simply tag the commit you wish to release, for example:
8 |
9 | ```
10 | rules_ruby$ git fetch
11 | rules_ruby$ git tag v1.2.3 origin/main
12 | rules_ruby$ git push origin v1.2.3
13 | ```
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "config:recommended"
5 | ],
6 | "ignoreDeps": [
7 | "bazel_features",
8 | "bazel_skylib",
9 | "platforms",
10 | "rules_cc",
11 | "rules_java"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/db/migrate/20250821215024_create_people.rb:
--------------------------------------------------------------------------------
1 | class CreatePeople < ActiveRecord::Migration[8.0]
2 | def change
3 | create_table :people do |t|
4 | t.string :first_name
5 | t.string :last_name
6 |
7 | t.timestamps
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/db/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
2 |
3 | rb_library(
4 | name = "db",
5 | srcs = glob(["*.rb"]),
6 | visibility = ["//people_tracker:__subpackages__"],
7 | deps = [
8 | "//people_tracker/db/migrate",
9 | ],
10 | )
11 |
--------------------------------------------------------------------------------
/.bcr/source.template.json:
--------------------------------------------------------------------------------
1 | {
2 | "integrity": "**leave this alone**",
3 | "strip_prefix": "{REPO}-{VERSION}",
4 | "docs_url": "https://github.com/{OWNER}/{REPO}/releases/download/{TAG}/{REPO}-{TAG}.docs.tar.gz",
5 | "url": "https://github.com/{OWNER}/{REPO}/releases/download/{TAG}/{REPO}-{TAG}.tar.gz"
6 | }
7 |
--------------------------------------------------------------------------------
/examples/deep_gem/do_test:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -o errexit -o nounset -o pipefail
4 |
5 | # Use the Bazel binary specified by the integration test. Otherise, fall back
6 | # to bazel.
7 | bazel="${BIT_BAZEL_BINARY:-bazel}"
8 |
9 | # Ensure that it builds and tests pass
10 | "${bazel}" test //...
11 |
--------------------------------------------------------------------------------
/examples/deep_gem/hello_world/spec/hello_world_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require_relative "spec_helper"
4 | require_relative "../lib/hello_world"
5 |
6 | RSpec.describe HelloWorld do
7 | it "has a version number" do
8 | expect(HelloWorld::VERSION).not_to be nil
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/examples/rails/do_test:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -o errexit -o nounset -o pipefail
4 |
5 | # Use the Bazel binary specified by the integration test. Otherise, fall back
6 | # to bazel.
7 | bazel="${BIT_BAZEL_BINARY:-bazel}"
8 |
9 | # Ensure that it builds and tests pass
10 | "${bazel}" test //...
11 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/.rubocop.yml:
--------------------------------------------------------------------------------
1 | # Omakase Ruby styling for Rails
2 | inherit_gem: {rubocop-rails-omakase: rubocop.yml}
3 |
4 | # Overwrite or add rules to create your own house style
5 | #
6 | # # Use `[a, [b, c]]` not `[ a, [ b, c ] ]`
7 | # Layout/SpaceInsideArrayLiteralBrackets:
8 | # Enabled: false
9 |
--------------------------------------------------------------------------------
/examples/gem/lib/gem/subtract.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module GEM
4 | class Subtract # :nodoc:
5 | def initialize(a, b) # rubocop:disable Naming/MethodParameterName
6 | @a = a
7 | @b = b
8 | end
9 |
10 | def result
11 | @a - @b
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/models/person.rb:
--------------------------------------------------------------------------------
1 | class Person < ApplicationRecord
2 | after_commit -> { broadcast_refresh_later_to "people" }
3 |
4 | validates :first_name, :last_name, presence: true
5 |
6 | def full_name
7 | [first_name, last_name].select(&:present?).join(" ")
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/examples/rails/.envrc:
--------------------------------------------------------------------------------
1 | bazel_env_dir="bazel-out/bazel_env-opt/bin/bazel_env/bin"
2 |
3 | watch_file "${bazel_env_dir}"
4 | PATH_add "${bazel_env_dir}"
5 |
6 | if [ ! -d "${bazel_env_dir}" ]; then
7 | log_error "ERROR[bazel_env.bzl]: Run 'bazel run //:bazel_env' to" \
8 | "regenerate ${bazel_env_dir}"
9 | fi
10 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/javascript/controllers/application.js:
--------------------------------------------------------------------------------
1 | import { Application } from "@hotwired/stimulus";
2 |
3 | const application = Application.start();
4 |
5 | // Configure Stimulus development experience
6 | application.debug = false;
7 | window.Stimulus = application;
8 |
9 | export { application };
10 |
--------------------------------------------------------------------------------
/.bcr/metadata.template.json:
--------------------------------------------------------------------------------
1 | {
2 | "homepage": "https://github.com/bazel-contrib/rules_ruby",
3 | "maintainers": [
4 | {
5 | "github": "p0deje",
6 | "name": "Alex Rodionov"
7 | }
8 | ],
9 | "repository": ["github:bazel-contrib/rules_ruby"],
10 | "versions": [],
11 | "yanked_versions": {}
12 | }
13 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/bin/rubocop:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require "rubygems"
3 | require "bundler/setup"
4 |
5 | # explicit rubocop config increases performance slightly while avoiding config confusion.
6 | ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__))
7 |
8 | load Gem.bin_path("rubocop", "rubocop")
9 |
--------------------------------------------------------------------------------
/.bcr/config.yml:
--------------------------------------------------------------------------------
1 | # See https://github.com/bazel-contrib/publish-to-bcr#a-note-on-release-automation
2 | # Our releases are created by github actions based on pushing a tag, so they don't have an author.
3 | # This person's fork of BCR will be used to originate pull requests.
4 | fixedReleaser:
5 | login: alexeagle
6 | email: alex@aspect.dev
7 |
--------------------------------------------------------------------------------
/examples/gem/lib/BUILD:
--------------------------------------------------------------------------------
1 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
2 |
3 | package(default_visibility = ["//:__subpackages__"])
4 |
5 | rb_library(
6 | name = "gem",
7 | srcs = ["gem.rb"],
8 | deps = [
9 | "//lib/gem:add",
10 | "//lib/gem:subtract",
11 | "//lib/gem:version",
12 | ],
13 | )
14 |
--------------------------------------------------------------------------------
/examples/native_ext/.bazelrc:
--------------------------------------------------------------------------------
1 | # Not ready for the MODULE.lock file yet, as of Bazel 7.0.0 there are still some stability issues.
2 | common --lockfile_mode=off
3 |
4 | # Allow to run Bazel without pre-installed JDK.
5 | # Docs: https://bazel.build/reference/command-line-reference#flag--java_runtime_version
6 | build --java_runtime_version=remotejdk_21
7 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/jobs/application_job.rb:
--------------------------------------------------------------------------------
1 | class ApplicationJob < ActiveJob::Base
2 | # Automatically retry jobs that encountered a deadlock
3 | # retry_on ActiveRecord::Deadlocked
4 |
5 | # Most jobs are safe to ignore if the underlying records are no longer available
6 | # discard_on ActiveJob::DeserializationError
7 | end
8 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/layouts/mailer.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
11 | <%= yield %>
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/importmap.rb:
--------------------------------------------------------------------------------
1 | # Pin npm packages by running ./bin/importmap
2 |
3 | pin "application"
4 | pin "@hotwired/turbo-rails", to: "turbo.min.js"
5 | pin "@hotwired/stimulus", to: "stimulus.min.js"
6 | pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
7 | pin_all_from "app/javascript/controllers", under: "controllers"
--------------------------------------------------------------------------------
/ruby/private/gem_install/gem_install.cmd.tpl:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | {env}
4 |
5 | {gem_binary} ^
6 | install ^
7 | {gem} ^
8 | --wrappers ^
9 | --ignore-dependencies ^
10 | --local ^
11 | --no-document ^
12 | --no-env-shebang ^
13 | --install-dir {install_dir} ^
14 | --bindir {install_dir}/bin
15 |
16 | :: vim: ft=dosbatch
17 |
--------------------------------------------------------------------------------
/ruby/private/gem_install/gem_install.sh.tpl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | {env}
4 |
5 | {gem_binary} \
6 | install \
7 | {gem} \
8 | --wrappers \
9 | --ignore-dependencies \
10 | --local \
11 | --no-document \
12 | --no-env-shebang \
13 | --install-dir {install_dir} \
14 | --bindir {install_dir}/bin
15 |
16 | # vim: ft=bash
17 |
--------------------------------------------------------------------------------
/examples/gem/lib/gem/version.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module GEM
4 | VERSION = '0.1.0'
5 | end
6 |
7 | if __FILE__ == $PROGRAM_NAME
8 | puts "Ruby is: #{RUBY_ENGINE}/#{RUBY_VERSION}"
9 | puts "Java version is: #{ENV_JAVA['java.version']}" if Object.const_defined?(:ENV_JAVA)
10 | puts "Version is: #{GEM::VERSION}"
11 | end
12 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/BUILD.bazel:
--------------------------------------------------------------------------------
1 | filegroup(
2 | name = "files",
3 | srcs = [
4 | "//people_tracker/app/views/layouts:files",
5 | "//people_tracker/app/views/people:files",
6 | "//people_tracker/app/views/pwa:files",
7 | ],
8 | visibility = ["//people_tracker/app:__subpackages__"],
9 | )
10 |
--------------------------------------------------------------------------------
/examples/gem/.rubocop.yml:
--------------------------------------------------------------------------------
1 | AllCops:
2 | NewCops: enable
3 | SuggestExtensions: false
4 | TargetRubyVersion: 3.0
5 | Exclude:
6 | - 'external/**/*'
7 |
8 | # There is a difference in line endings between
9 | # GitHub Actions and Bazel CI.
10 | # https://github.com/bazel-contrib/rules_ruby/issues/27
11 | Layout/EndOfLine:
12 | Enabled: false
13 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/bin/BUILD.bazel:
--------------------------------------------------------------------------------
1 | filegroup(
2 | name = "files",
3 | srcs = [
4 | "brakeman",
5 | "dev",
6 | "docker-entrypoint",
7 | "rails",
8 | "rake",
9 | "rubocop",
10 | "setup",
11 | "thrust",
12 | ],
13 | visibility = ["//people_tracker:__subpackages__"],
14 | )
15 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/initializers/assets.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Version of your assets, change this if you want to expire all your assets.
4 | Rails.application.config.assets.version = "1.0"
5 |
6 | # Add additional assets to the asset load path.
7 | # Rails.application.config.assets.paths << Emoji.images_path
8 |
--------------------------------------------------------------------------------
/examples/deep_gem/hello_world/lib/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
2 |
3 | rb_library(
4 | name = "hello_world",
5 | srcs = ["hello_world.rb"],
6 | visibility = ["//hello_world:__subpackages__"],
7 | deps = [
8 | "//hello_world/lib/hello_world:speaker",
9 | "//hello_world/lib/hello_world:version",
10 | ],
11 | )
12 |
--------------------------------------------------------------------------------
/examples/deep_gem/hello_world/lib/hello_world/speaker.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module HelloWorld
4 | class Speaker
5 | attr_reader :name
6 |
7 | def initialize(name = "world")
8 | @name = name
9 | end
10 |
11 | def message
12 | "Hello, #{@name}"
13 | end
14 |
15 | def hi
16 | puts message
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/examples/deep_gem/hello_world/lib/hello_world/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
2 |
3 | rb_library(
4 | name = "version",
5 | srcs = ["version.rb"],
6 | visibility = ["//hello_world:__subpackages__"],
7 | )
8 |
9 | rb_library(
10 | name = "speaker",
11 | srcs = ["speaker.rb"],
12 | visibility = ["//hello_world:__subpackages__"],
13 | )
14 |
--------------------------------------------------------------------------------
/ruby/private/bundle/BUILD.tpl:
--------------------------------------------------------------------------------
1 | """@generated by @rules_ruby//:ruby/private/binary.bzl"""
2 |
3 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
4 | load("//:defs.bzl", "BUNDLE_ENV")
5 |
6 | package(default_visibility = ["//visibility:public"])
7 |
8 | rb_library(
9 | name = "bundle",
10 | bundle_env = BUNDLE_ENV,
11 | data = glob(["**/*"]),
12 | )
13 |
14 | # vim: ft=bzl
15 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/people/_person.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | First name:
4 | <%= person.first_name %>
5 |
6 |
7 | Last name:
8 | <%= person.last_name %>
9 |
10 |
11 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/test/rails_test.bzl:
--------------------------------------------------------------------------------
1 | """Module for app-specific rails helpers and macros."""
2 |
3 | load("@rules_ruby//rails:rails_test_factory.bzl", "rails_test_factory")
4 |
5 | _TEST_PKG = "people_tracker/test"
6 |
7 | rails_test = rails_test_factory.new_test(test_package = _TEST_PKG)
8 |
9 | rails_system_test = rails_test_factory.new_system_test(test_package = _TEST_PKG)
10 |
--------------------------------------------------------------------------------
/.bcr/README.md:
--------------------------------------------------------------------------------
1 | # Bazel Central Registry
2 |
3 | When the ruleset is released, we want it to be published to the
4 | Bazel Central Registry automatically:
5 |
6 |
7 | This folder contains configuration files to automate the publish step.
8 | See
9 | for authoritative documentation about these files.
10 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/test/fixtures/people.yml:
--------------------------------------------------------------------------------
1 | # Read about fixtures at
2 | # https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
3 |
4 | john_doe:
5 | first_name: John
6 | last_name: Doe
7 |
8 | jane_smith:
9 | first_name: Jane
10 | last_name: Smith
11 |
12 | bob_johnson:
13 | first_name: Bob
14 | last_name: Johnson
15 |
16 | alice_brown:
17 | first_name: Alice
18 | last_name: Brown
19 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/javascript/controllers/index.js:
--------------------------------------------------------------------------------
1 | // Import and register all your controllers from the importmap via controllers/**/*_controller
2 | import { application } from "controllers/application";
3 |
4 | // Eager load all controllers defined in the import map under controllers/**/*_controller
5 | import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading";
6 | eagerLoadControllersFrom("controllers", application);
7 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/people/new.html.erb:
--------------------------------------------------------------------------------
1 | <% content_for :title, "New person" %>
2 |
3 |
4 |
New person
5 |
6 | <%= render "form", person: @person %>
7 |
8 | <%= link_to "Back to people", people_path, class: "w-full sm:w-auto text-center mt-2 sm:mt-0 sm:ml-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
9 |
10 |
--------------------------------------------------------------------------------
/examples/deep_gem/hello_world/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | RSpec.configure do |config|
4 | # Enable flags like --only-failures and --next-failure
5 | config.example_status_persistence_file_path = ".rspec_status"
6 |
7 | # Disable RSpec exposing methods globally on `Module` and `main`
8 | config.disable_monkey_patching!
9 |
10 | config.expect_with :rspec do |c|
11 | c.syntax = :expect
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/bin/dev:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | if ! gem list foreman -i --silent; then
4 | echo "Installing foreman..."
5 | gem install foreman
6 | fi
7 |
8 | # Default to port 3000 if not specified
9 | export PORT="${PORT:-3000}"
10 |
11 | # Let the debug gem allow remote connections,
12 | # but avoid loading until `debugger` is called
13 | export RUBY_DEBUG_OPEN="true"
14 | export RUBY_DEBUG_LAZY="true"
15 |
16 | exec foreman start -f Procfile.dev "$@"
17 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/bin/docker-entrypoint:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 |
3 | # Enable jemalloc for reduced memory usage and latency.
4 | if [ -z "${LD_PRELOAD+x}" ]; then
5 | LD_PRELOAD=$(find /usr/lib -name libjemalloc.so.2 -print -quit)
6 | export LD_PRELOAD
7 | fi
8 |
9 | # If running the rails server then create or migrate existing database
10 | if [ "${@: -2:1}" == "./bin/rails" ] && [ "${@: -1:1}" == "server" ]; then
11 | ./bin/rails db:prepare
12 | fi
13 |
14 | exec "${@}"
15 |
--------------------------------------------------------------------------------
/.github/workflows/ci.bazelrc:
--------------------------------------------------------------------------------
1 | # This file contains Bazel settings to apply on Release only.
2 | # It is referenced with a --bazelrc option in the call to bazel in release.yaml
3 |
4 | # Debug where options came from
5 | build --announce_rc
6 | # Don't rely on test logs being easily accessible from the test runner,
7 | # though it makes the log noisier.
8 | test --test_output=errors
9 | # Allows tests to run bazelisk-in-bazel, since this is the cache folder used
10 | test --test_env=XDG_CACHE_HOME
11 |
--------------------------------------------------------------------------------
/BUILD:
--------------------------------------------------------------------------------
1 | load("@buildifier_prebuilt//:rules.bzl", "buildifier")
2 | load("@gazelle//:def.bzl", "gazelle", "gazelle_binary")
3 |
4 | gazelle_binary(
5 | name = "gazelle_bin",
6 | languages = ["@bazel_skylib_gazelle_plugin//bzl"],
7 | )
8 |
9 | gazelle(
10 | name = "gazelle",
11 | gazelle = "gazelle_bin",
12 | )
13 |
14 | buildifier(
15 | name = "buildifier.check",
16 | diff_command = "diff -u",
17 | exclude_patterns = ["./.git/*"],
18 | lint_mode = "warn",
19 | mode = "diff",
20 | )
21 |
--------------------------------------------------------------------------------
/examples/gem/wrapper.tpl.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | @@rlocation_lib@@
4 |
5 | set -euo pipefail
6 |
7 | rake_binary_expansion=(@@rake_binary@@)
8 |
9 | echo "calling the rake binary"
10 | rake="$(rlocation @@rake_binary@@)"
11 | rakefile="$(rlocation @@rakefile@@)"
12 | "$rake" -f "$rakefile" goodnight
13 | set -x
14 | eval "$("$rake" -f "$rakefile" goodnight)"
15 | set +x
16 |
17 | echo "rake failed to fail"
18 | echo "rlocationpaths for rake binary:"
19 | printf ' %s\n' "${rake_binary_expansion[@]}"
20 | exit 1
21 |
--------------------------------------------------------------------------------
/examples/jekyll/404.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 |
5 |
18 |
19 |
20 |
404
21 |
22 |
Page not found :(
23 |
The requested page could not be found.
24 |
25 |
--------------------------------------------------------------------------------
/rails/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
2 |
3 | exports_files(["rails_test_factory.bzl"])
4 |
5 | bzl_library(
6 | name = "rails_test_factory",
7 | srcs = ["rails_test_factory.bzl"],
8 | visibility = ["//visibility:public"],
9 | deps = [
10 | "//rails/private:rails_test_factory",
11 | ],
12 | )
13 |
14 | starlark_doc_extract(
15 | name = "rails_test_factory.doc_extract",
16 | src = "rails_test_factory.bzl",
17 | deps = [":rails_test_factory"],
18 | )
19 |
--------------------------------------------------------------------------------
/examples/rails/.bazelrc:
--------------------------------------------------------------------------------
1 | # Verbose Failures
2 | build --verbose_failures
3 |
4 | # Test output information
5 | test --test_output=errors --test_summary=detailed
6 |
7 | # Strict PATH. Helps prevent build cache invalidation due to PATH differences.
8 | build --incompatible_strict_action_env=true
9 |
10 | # Don't allow empty glob patterns by default
11 | build --incompatible_disallow_empty_glob
12 |
13 | # Enable bzlmod
14 | common --enable_bzlmod
15 |
16 | # Download the JDK to run Bazel
17 | build --java_runtime_version=remotejdk_11
18 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/initializers/filter_parameter_logging.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file.
4 | # Use this to limit dissemination of sensitive information.
5 | # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.
6 | Rails.application.config.filter_parameters += [
7 | :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn, :cvv, :cvc
8 | ]
9 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/pwa/manifest.json.erb:
--------------------------------------------------------------------------------
1 | {
2 | "name": "PeopleTracker",
3 | "icons": [
4 | {
5 | "src": "/icon.png",
6 | "type": "image/png",
7 | "sizes": "512x512"
8 | },
9 | {
10 | "src": "/icon.png",
11 | "type": "image/png",
12 | "sizes": "512x512",
13 | "purpose": "maskable"
14 | }
15 | ],
16 | "start_url": "/",
17 | "display": "standalone",
18 | "scope": "/",
19 | "description": "People Tracker.",
20 | "theme_color": "red",
21 | "background_color": "red"
22 | }
23 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/db/seeds.rb:
--------------------------------------------------------------------------------
1 | # This file should ensure the existence of records required to run the application in every environment (production,
2 | # development, test). The code here should be idempotent so that it can be executed at any point in every environment.
3 | # The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup).
4 | #
5 | # Example:
6 | #
7 | # ["Action", "Comedy", "Drama", "Horror"].each do |genre_name|
8 | # MovieGenre.find_or_create_by!(name: genre_name)
9 | # end
10 |
--------------------------------------------------------------------------------
/ruby/private/bundle_fetch/BUILD.tpl:
--------------------------------------------------------------------------------
1 | """@generated by @rules_ruby//:ruby/private/bundle_fetch.bzl"""
2 |
3 | load("@rules_ruby//ruby:defs.bzl", "rb_bundle_install", "rb_gem", "rb_gem_install")
4 |
5 | package(default_visibility = ["//visibility:public"])
6 |
7 | rb_bundle_install(
8 | name = "{name}",
9 | srcs = {srcs},
10 | env = {env},
11 | gemfile = "{gemfile_path}",
12 | gemfile_lock = "{gemfile_lock_path}",
13 | gems = {gems},
14 | ruby = {ruby},
15 | )
16 |
17 | {gem_fragments}
18 |
19 | {gem_install_fragments}
20 |
21 | # vim: ft=bzl
22 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/credentials.yml.enc:
--------------------------------------------------------------------------------
1 | PqmOA8TR9Gz0FHOtrpuxYnAcDkoD6JDBjedD4uIrTyM3Q+ve2QgCHRin45b3vySwJ4Ao437LiMYyCYuqGBHhc047AAGkxdmbbNkal5rmojfdgQ3HAgUfP0QZcKcUOQYtehN21MKXVXsrTzOLQjtktGADUpUI94+7g6GZzI/KRMW23c5MT9t5C5+umH3lFuk5shEDwkkwETezL4e5Bxl/QZmF3Eft0GWtSVQvWsN09Lls1w1hbvJ99PMs+5I+towYDt0bmbh4SArg87gcChupyCWHT5S43B/nD64Z0llyBnGtmmcHwLX6poeWtFNMx7wbJNWlSrJJGVkA0ypa/JMOK/Py9V9pIezHWRYfziHFCd0azLLdIgJTd03p2H+a+doXrNDvJSfeIDgw+HU6UCvnlFw0iGsANCJUFHYIDjPp93FsCTLqPmlyKZQHmvapaZ8Bhn0MUo/eozASLdgj0Xj99OV/axmLepdU8BmNUR8dnxs6NzlkrfY7/oBA--BSW+HirppL4YcBWZ--chud7xgdM5nvnYFjLmI5Vw==
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/assets/stylesheets/application.css:
--------------------------------------------------------------------------------
1 | /*
2 | * This is a manifest file that'll be compiled into application.css.
3 | *
4 | * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
5 | * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
6 | * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
7 | * depending on specificity.
8 | *
9 | * Consider organizing styles into separate files for maintainability.
10 | */
11 |
--------------------------------------------------------------------------------
/.bcr/presubmit.yml:
--------------------------------------------------------------------------------
1 | # https://github.com/bazel-contrib/publish-to-bcr/tree/main/templates#presubmityml
2 | bcr_test_module:
3 | module_path: "examples/gem"
4 | matrix:
5 | bazel: ["8.x", "7.x", "6.x"]
6 | # NB: Windows is removed due to https://github.com/bazel-contrib/rules_ruby/issues/64
7 | platform: ["debian10", "macos", "ubuntu2004"]
8 | tasks:
9 | run_tests:
10 | name: "Run test module"
11 | platform: ${{ platform }}
12 | bazel: ${{ bazel }}
13 | test_flags:
14 | - "--test_tag_filters=-bcr-presubmit-failure"
15 | test_targets:
16 | - "//..."
17 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
2 |
3 | rb_library(
4 | name = "app",
5 | data = [
6 | "//people_tracker/app/assets:files",
7 | "//people_tracker/app/javascript:files",
8 | "//people_tracker/app/views:files",
9 | ],
10 | visibility = ["//people_tracker:__subpackages__"],
11 | deps = [
12 | "//people_tracker/app/controllers",
13 | "//people_tracker/app/helpers",
14 | "//people_tracker/app/jobs",
15 | "//people_tracker/app/mailers",
16 | "//people_tracker/app/models",
17 | ],
18 | )
19 |
--------------------------------------------------------------------------------
/docs/BUILD:
--------------------------------------------------------------------------------
1 | # This load statement must be in the docs/ package rather than anything users depend on
2 | # so that the dependency on stardoc doesn't leak to them.
3 | load("@aspect_bazel_lib//lib:docs.bzl", "stardoc_with_diff_test", "update_docs")
4 |
5 | stardoc_with_diff_test(
6 | name = "rules",
7 | bzl_library_target = "//ruby:defs",
8 | )
9 |
10 | stardoc_with_diff_test(
11 | name = "repository_rules",
12 | bzl_library_target = "//ruby:deps",
13 | )
14 |
15 | stardoc_with_diff_test(
16 | name = "rails",
17 | bzl_library_target = "//rails:rails_test_factory",
18 | )
19 |
20 | update_docs(name = "update")
21 |
--------------------------------------------------------------------------------
/examples/jekyll/about.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: About
4 | permalink: /about/
5 | ---
6 |
7 | This is the base Jekyll theme. You can find out more info about customizing your Jekyll theme, as well as basic Jekyll usage documentation at [jekyllrb.com](https://jekyllrb.com/)
8 |
9 | You can find the source code for Minima at GitHub:
10 | [jekyll][jekyll-organization] /
11 | [minima](https://github.com/jekyll/minima)
12 |
13 | You can find the source code for Jekyll at GitHub:
14 | [jekyll][jekyll-organization] /
15 | [jekyll](https://github.com/jekyll/jekyll)
16 |
17 |
18 | [jekyll-organization]: https://github.com/jekyll
19 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/people/edit.html.erb:
--------------------------------------------------------------------------------
1 | <% content_for :title, "Editing person" %>
2 |
3 |
4 |
Editing person
5 |
6 | <%= render "form", person: @person %>
7 |
8 | <%= link_to "Show this person", @person, class: "w-full sm:w-auto text-center mt-2 sm:mt-0 sm:ml-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
9 | <%= link_to "Back to people", people_path, class: "w-full sm:w-auto text-center mt-2 sm:mt-0 sm:ml-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
10 |
11 |
--------------------------------------------------------------------------------
/examples/gem/lib/gem/add.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | require 'i18n'
5 |
6 | module GEM
7 | class Add # :nodoc:
8 | def initialize(a, b) # rubocop:disable Naming/MethodParameterName
9 | @a = a
10 | @b = b
11 | end
12 |
13 | def result
14 | @a + @b
15 | end
16 | end
17 | end
18 |
19 | if __FILE__ == $PROGRAM_NAME
20 | raise "Pass two numbers to sum: #{ARGV}" if ARGV.size < 2
21 |
22 | one, two, output = *ARGV
23 | result = GEM::Add.new(Integer(one), Integer(two)).result
24 | if output
25 | File.write(output, result)
26 | else
27 | puts result
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | # See CONTRIBUTING.md for instructions.
2 | # See https://pre-commit.com for more information
3 | # See https://pre-commit.com/hooks.html for more hooks
4 |
5 | repos:
6 | # Check formatting and lint for starlark code
7 | - repo: https://github.com/keith/pre-commit-buildifier
8 | rev: 8.2.0
9 | hooks:
10 | - id: buildifier
11 | - id: buildifier-lint
12 | # Check that commit messages follow https://www.conventionalcommits.org
13 | - repo: https://github.com/compilerla/conventional-pre-commit
14 | rev: v3.0.0
15 | hooks:
16 | - id: conventional-pre-commit
17 | stages:
18 | - commit-msg
19 | args: []
20 |
--------------------------------------------------------------------------------
/examples/gem/spec/env_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require_relative 'spec_helper'
4 |
5 | RSpec.describe ENV do
6 | specify do
7 | expect(ENV.fetch('EXAMPLE')).to eq('ENV')
8 | end
9 |
10 | specify do
11 | expect(ENV).to have_key('USER').or have_key('USERNAME')
12 | end
13 |
14 | specify do
15 | expect(ENV.fetch('BUNDLE_BUILD__FOO')).to eq('bar')
16 | end
17 |
18 | specify do
19 | expect(File).to exist(ENV.fetch('LOCATION_SRC'))
20 | expect(File).to exist(ENV.fetch('LOCATION_DATA'))
21 | expect(File).to exist(ENV.fetch('LOCATION_DEP'))
22 | end
23 |
24 | specify do
25 | expect(ENV.fetch('RUBY_ENGINE')).to eq(RUBY_ENGINE)
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/examples/deep_gem/hello_world/hello_world.gemspec:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require_relative "lib/hello_world/version"
4 |
5 | Gem::Specification.new do |s|
6 | s.name = "hello_world"
7 | s.version = HelloWorld::VERSION
8 |
9 | s.authors = ["Foo Bar"]
10 | s.email = ["foobar@gmail.com"]
11 | s.homepage = "http://rubygems.org"
12 | s.license = "MIT"
13 | s.metadata["rubygems_mfa_required"] = "true"
14 |
15 | s.summary = "Example"
16 | s.description = "Example gem"
17 | s.files = Dir["lib/**/*"]
18 |
19 | s.require_paths = ["lib"]
20 | s.required_ruby_version = Gem::Requirement.new(">= 2.6")
21 |
22 | s.add_dependency "irb"
23 | s.add_dependency "rspec", "~> 3.0"
24 | end
25 |
--------------------------------------------------------------------------------
/examples/native_ext/MODULE.bazel:
--------------------------------------------------------------------------------
1 | "Bazel dependencies"
2 |
3 | bazel_dep(name = "platforms", version = "0.0.10", dev_dependency = True)
4 | bazel_dep(name = "rules_cc", version = "0.1.1", dev_dependency = True)
5 | bazel_dep(name = "rules_java", version = "8.7.1", dev_dependency = True)
6 | bazel_dep(name = "rules_ruby", version = "0.0.0", dev_dependency = True)
7 | local_path_override(
8 | module_name = "rules_ruby",
9 | path = "../..",
10 | )
11 |
12 | ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby")
13 | ruby.toolchain(
14 | name = "ruby",
15 | version_file = "//:.ruby-version",
16 | )
17 | use_repo(ruby, "ruby", "ruby_toolchains")
18 |
19 | register_toolchains("@ruby_toolchains//:all")
20 |
--------------------------------------------------------------------------------
/examples/native_ext/BUILD:
--------------------------------------------------------------------------------
1 | load("@rules_cc//cc:defs.bzl", "cc_library")
2 | load("@rules_java//java:defs.bzl", "java_library")
3 |
4 | cc_library(
5 | name = "ext_c",
6 | srcs = glob([
7 | "ext/**/*.c",
8 | "ext/**/*.h",
9 | ]),
10 | target_compatible_with = select({
11 | "@ruby//engine:ruby": [],
12 | "//conditions:default": ["@platforms//:incompatible"],
13 | }),
14 | deps = ["@ruby//:headers"],
15 | )
16 |
17 | java_library(
18 | name = "ext_java",
19 | srcs = glob(["ext/**/*.java"]),
20 | target_compatible_with = select({
21 | "@ruby//engine:jruby": [],
22 | "//conditions:default": ["@platforms//:incompatible"],
23 | }),
24 | deps = ["@ruby//:jars"],
25 | )
26 |
--------------------------------------------------------------------------------
/examples/gem/gem.gemspec:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | root = File.expand_path(__dir__)
4 | $LOAD_PATH.push(File.expand_path('lib', root))
5 | require 'gem/version'
6 |
7 | Gem::Specification.new do |s|
8 | s.name = 'example'
9 | s.version = GEM::VERSION
10 |
11 | s.authors = ['Foo Bar']
12 | s.email = ['foobar@gmail.com']
13 | s.homepage = 'http://rubygems.org'
14 | s.license = 'MIT'
15 | s.metadata['rubygems_mfa_required'] = 'true'
16 |
17 | s.summary = 'Example'
18 | s.description = 'Example gem'
19 | s.files = Dir['lib/**/*']
20 |
21 | s.require_paths = ['lib']
22 | s.required_ruby_version = Gem::Requirement.new('>= 2.6')
23 |
24 | s.add_dependency 'i18n', '~> 1.14'
25 | s.add_dependency 'rake', '~> 13'
26 | end
27 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
2 |
3 | package(default_visibility = ["//people_tracker:__subpackages__"])
4 |
5 | rb_library(
6 | name = "config",
7 | srcs = glob(["*.rb"]),
8 | data = [
9 | ":files",
10 | "//people_tracker/config/locales:files",
11 | ],
12 | deps = [
13 | "//people_tracker/app",
14 | "//people_tracker/config/environments",
15 | "//people_tracker/config/initializers",
16 | "//people_tracker/db",
17 | "@people_tracker_bundle",
18 | ],
19 | )
20 |
21 | filegroup(
22 | name = "files",
23 | srcs = glob(
24 | [
25 | "*",
26 | ],
27 | exclude = ["*.rb"],
28 | ),
29 | )
30 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format. Inflections
4 | # are locale specific, and you may define rules for as many different
5 | # locales as you wish. All of these examples are active by default:
6 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
7 | # inflect.plural /^(ox)$/i, "\\1en"
8 | # inflect.singular /^(ox)en/i, "\\1"
9 | # inflect.irregular "person", "people"
10 | # inflect.uncountable %w( fish sheep )
11 | # end
12 |
13 | # These inflection rules are supported but not enabled by default:
14 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
15 | # inflect.acronym "RESTful"
16 | # end
17 |
--------------------------------------------------------------------------------
/ruby/private/download/BUILD.engine.tpl:
--------------------------------------------------------------------------------
1 | load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
2 |
3 | package(default_visibility = ["//visibility:public"])
4 |
5 | string_flag(
6 | name = "engine",
7 | values = [
8 | "jruby",
9 | "truffleruby",
10 | "ruby",
11 | ],
12 | build_setting_default = "{ruby_engine}",
13 | )
14 |
15 | config_setting(
16 | name = "jruby",
17 | flag_values = {
18 | ":engine": "jruby",
19 | },
20 | )
21 |
22 | config_setting(
23 | name = "truffleruby",
24 | flag_values = {
25 | ":engine": "truffleruby",
26 | },
27 | )
28 |
29 | config_setting(
30 | name = "ruby",
31 | flag_values = {
32 | ":engine": "ruby",
33 | },
34 | )
35 |
36 | # vim: ft=bzl
37 |
--------------------------------------------------------------------------------
/ruby/deps.bzl:
--------------------------------------------------------------------------------
1 | "Public API for repository rules"
2 |
3 | load("//ruby/private:bundle.bzl", _rb_bundle = "rb_bundle")
4 | load("//ruby/private:bundle_fetch.bzl", _rb_bundle_fetch = "rb_bundle_fetch")
5 | load("//ruby/private:toolchain.bzl", _rb_register_toolchains = "rb_register_toolchains")
6 |
7 | def rb_bundle(toolchain = "@ruby//:BUILD", **kwargs):
8 | """
9 | Wraps `rb_bundle_rule()` providing default toolchain name.
10 |
11 | Args:
12 | toolchain: default Ruby toolchain BUILD
13 | **kwargs: underlying attrs passed to rb_bundle_rule()
14 | """
15 | _rb_bundle(
16 | toolchain = toolchain,
17 | **kwargs
18 | )
19 |
20 | rb_register_toolchains = _rb_register_toolchains
21 | rb_bundle_fetch = _rb_bundle_fetch
22 | rb_bundle_rule = _rb_bundle
23 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/routes.rb:
--------------------------------------------------------------------------------
1 | Rails.application.routes.draw do
2 | resources :people
3 | # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
4 |
5 | # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500.
6 | # Can be used by load balancers and uptime monitors to verify that the app is live.
7 | get "up" => "rails/health#show", :as => :rails_health_check
8 |
9 | # Render dynamic PWA files from app/views/pwa/* (remember to link manifest in application.html.erb)
10 | # get "manifest" => "rails/pwa#manifest", as: :pwa_manifest
11 | # get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker
12 |
13 | # Defines the root path route ("/")
14 | # root "posts#index"
15 | end
16 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/test/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
2 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
3 |
4 | rb_library(
5 | name = "test_helper",
6 | srcs = ["test_helper.rb"],
7 | visibility = ["//people_tracker/test:__subpackages__"],
8 | deps = [
9 | "//people_tracker/config",
10 | ],
11 | )
12 |
13 | rb_library(
14 | name = "application_system_test_case",
15 | srcs = ["application_system_test_case.rb"],
16 | visibility = ["//people_tracker/test:__subpackages__"],
17 | deps = [
18 | ":test_helper",
19 | ],
20 | )
21 |
22 | bzl_library(
23 | name = "rails_test",
24 | srcs = ["rails_test.bzl"],
25 | visibility = ["//visibility:public"],
26 | deps = ["@rules_ruby//rails:rails_test_factory"],
27 | )
28 |
--------------------------------------------------------------------------------
/examples/deep_gem/hello_world/spec/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@rules_ruby//ruby:defs.bzl", "rb_library", "rb_test")
2 |
3 | rb_library(
4 | name = "spec_helper",
5 | srcs = ["spec_helper.rb"],
6 | deps = [
7 | "@bundle",
8 | ],
9 | )
10 |
11 | rb_test(
12 | name = "hello_world_spec",
13 | srcs = ["hello_world_spec.rb"],
14 | args = ["hello_world/spec/hello_world_spec.rb"],
15 | main = "@bundle//bin:rspec",
16 | deps = [
17 | ":spec_helper",
18 | "//hello_world/lib:hello_world",
19 | ],
20 | )
21 |
22 | rb_test(
23 | name = "speaker_spec",
24 | srcs = ["speaker_spec.rb"],
25 | args = ["hello_world/spec/speaker_spec.rb"],
26 | main = "@bundle//bin:rspec",
27 | deps = [
28 | ":spec_helper",
29 | "//hello_world/lib:hello_world",
30 | ],
31 | )
32 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | require_relative "../config/initializers/bazel_ruby_patches"
2 |
3 | ENV["RAILS_ENV"] ||= "test"
4 | require_relative "../config/environment"
5 | require "rails/test_help"
6 |
7 | # Load schema once for in-memory database before fixtures
8 | ActiveRecord::Tasks::DatabaseTasks.load_schema_current
9 |
10 | module ActiveSupport
11 | class TestCase
12 | # Run tests in parallel with specified workers
13 | parallelize(workers: :number_of_processors)
14 |
15 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
16 | fixtures :all
17 |
18 | # Use transactional tests for automatic rollback (this is the default)
19 | self.use_transactional_tests = true
20 |
21 | # Add more helper methods to be used by all tests here...
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/ruby/defs.bzl:
--------------------------------------------------------------------------------
1 | "Public API for rules"
2 |
3 | load("//ruby/private:binary.bzl", _rb_binary = "rb_binary")
4 | load("//ruby/private:bundle_install.bzl", _rb_bundle_install = "rb_bundle_install")
5 | load("//ruby/private:gem.bzl", _rb_gem = "rb_gem")
6 | load("//ruby/private:gem_build.bzl", _rb_gem_build = "rb_gem_build")
7 | load("//ruby/private:gem_install.bzl", _rb_gem_install = "rb_gem_install")
8 | load("//ruby/private:gem_push.bzl", _rb_gem_push = "rb_gem_push")
9 | load("//ruby/private:library.bzl", _rb_library = "rb_library")
10 | load("//ruby/private:test.bzl", _rb_test = "rb_test")
11 |
12 | rb_binary = _rb_binary
13 | rb_bundle_install = _rb_bundle_install
14 | rb_gem = _rb_gem
15 | rb_gem_build = _rb_gem_build
16 | rb_gem_install = _rb_gem_install
17 | rb_gem_push = _rb_gem_push
18 | rb_library = _rb_library
19 | rb_test = _rb_test
20 |
--------------------------------------------------------------------------------
/ruby/private/gem.bzl:
--------------------------------------------------------------------------------
1 | "Implementation details for rb_gem"
2 |
3 | load("//ruby/private:providers.bzl", "GemInfo")
4 |
5 | def _rb_gem_impl(ctx):
6 | gem = ctx.file.gem
7 | name, _, version = ctx.attr.name.rpartition("-")
8 |
9 | return [
10 | DefaultInfo(files = depset([gem])),
11 | GemInfo(
12 | name = name,
13 | version = version,
14 | ),
15 | ]
16 |
17 | rb_gem = rule(
18 | _rb_gem_impl,
19 | attrs = {
20 | "gem": attr.label(
21 | allow_single_file = [".gem"],
22 | mandatory = True,
23 | doc = "Gem file.",
24 | ),
25 | },
26 | doc = """
27 | Exposes a Ruby gem file.
28 |
29 | You normally don't need to call this rule directly as it's an internal one
30 | used by `rb_bundle_fetch()`.
31 | """,
32 | )
33 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@bazel_env.bzl", "bazel_env")
2 | load("@bazel_skylib//rules:build_test.bzl", "build_test")
3 | load("@cgrindel_bazel_starlib//bzltidy:defs.bzl", "tidy")
4 |
5 | # This is a runnable target that is used to configure direnv to make the listed
6 | # tools available at the command-line.
7 | bazel_env(
8 | name = "bazel_env",
9 | tools = {
10 | "rails": "@people_tracker_bundle//bin:rails",
11 | },
12 | )
13 |
14 | tidy(
15 | name = "all_bazel_env",
16 | targets = [
17 | # Use fully-qualified labels here. There may be a bug in tidy that does
18 | # not resolve relative labels properly.
19 | "//:bazel_env",
20 | "//people_tracker:bazel_env",
21 | ],
22 | )
23 |
24 | build_test(
25 | name = "bazel_env_build_test",
26 | targets = [
27 | ":bazel_env",
28 | ],
29 | )
30 |
--------------------------------------------------------------------------------
/ruby/tests/utils_tests.bzl:
--------------------------------------------------------------------------------
1 | """Unit tests for utils."""
2 |
3 | load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest")
4 | load(
5 | "//ruby/private:utils.bzl",
6 | _normalize_bzlmod_repository_name = "normalize_bzlmod_repository_name",
7 | )
8 |
9 | def _normalize_bzlmod_repository_name_test_impl(ctx):
10 | env = unittest.begin(ctx)
11 | asserts.equals(env, _normalize_bzlmod_repository_name("bundle"), "bundle")
12 | asserts.equals(env, _normalize_bzlmod_repository_name("rules_ruby+override+ruby+bundle"), "bundle")
13 | asserts.equals(env, _normalize_bzlmod_repository_name("rules_ruby~override~ruby~bundle"), "bundle")
14 | return unittest.end(env)
15 |
16 | normalize_bzlmod_repository_name_test = unittest.make(_normalize_bzlmod_repository_name_test_impl)
17 |
18 | def utils_test_suite():
19 | unittest.suite("utils_tests", normalize_bzlmod_repository_name_test)
20 |
--------------------------------------------------------------------------------
/examples/rails/BUILD.bazel:
--------------------------------------------------------------------------------
1 | load("@bazel_env.bzl", "bazel_env")
2 | load("@bazel_skylib//rules:build_test.bzl", "build_test")
3 |
4 | # MARK: - bazel_env
5 |
6 | _RUBY_BINARIES = [
7 | "bundle",
8 | "bundler",
9 | "erb",
10 | "gem",
11 | "irb",
12 | "racc",
13 | "rake",
14 | "rbs",
15 | "rdbg",
16 | "rdoc",
17 | "ri",
18 | "ruby",
19 | ]
20 |
21 | # This is a runnable target that is used to configure direnv to make the listed
22 | # tools available at the command-line.
23 | bazel_env(
24 | name = "bazel_env",
25 | tools = {
26 | "buildifier": "@buildifier_prebuilt//:buildifier",
27 | "rails": "@root_bundle//bin:rails",
28 | } | {
29 | rbin: "@ruby//:{}".format(rbin)
30 | for rbin in _RUBY_BINARIES
31 | },
32 | visibility = ["//:__subpackages__"],
33 | )
34 |
35 | build_test(
36 | name = "bazel_env_build_test",
37 | targets = [
38 | ":bazel_env",
39 | ],
40 | )
41 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/pwa/service-worker.js:
--------------------------------------------------------------------------------
1 | // Add a service worker for processing Web Push notifications:
2 | //
3 | // self.addEventListener("push", async (event) => {
4 | // const { title, options } = await event.data.json()
5 | // event.waitUntil(self.registration.showNotification(title, options))
6 | // })
7 | //
8 | // self.addEventListener("notificationclick", function(event) {
9 | // event.notification.close()
10 | // event.waitUntil(
11 | // clients.matchAll({ type: "window" }).then((clientList) => {
12 | // for (let i = 0; i < clientList.length; i++) {
13 | // let client = clientList[i]
14 | // let clientPath = (new URL(client.url)).pathname
15 | //
16 | // if (clientPath == event.notification.data.path && "focus" in client) {
17 | // return client.focus()
18 | // }
19 | // }
20 | //
21 | // if (clients.openWindow) {
22 | // return clients.openWindow(event.notification.data.path)
23 | // }
24 | // })
25 | // )
26 | // })
27 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/people/show.html.erb:
--------------------------------------------------------------------------------
1 | <% content_for :title, "Showing person" %>
2 |
3 |
4 | <% if notice.present? %>
5 |
<%= notice %>
6 | <% end %>
7 |
8 |
Showing person
9 |
10 | <%= render @person %>
11 |
12 | <%= link_to "Edit this person", edit_person_path(@person), class: "w-full sm:w-auto text-center rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
13 | <%= link_to "Back to people", people_path, class: "w-full sm:w-auto text-center mt-2 sm:mt-0 sm:ml-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
14 | <%= button_to "Destroy this person", @person, method: :delete, form_class: "sm:inline-block mt-2 sm:mt-0 sm:ml-2", class: "w-full rounded-md px-3.5 py-2.5 text-white bg-red-600 hover:bg-red-500 font-medium cursor-pointer", data: { turbo_confirm: "Are you sure?" } %>
15 |
16 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/db/schema.rb:
--------------------------------------------------------------------------------
1 | # This file is auto-generated from the current state of the database. Instead
2 | # of editing this file, please use the migrations feature of Active Record to
3 | # incrementally modify your database, and then regenerate this schema definition.
4 | #
5 | # This file is the source Rails uses to define your schema when running `bin/rails
6 | # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
7 | # be faster and is potentially less error prone than running all of your
8 | # migrations from scratch. Old migrations may fail to apply correctly if those
9 | # migrations use external dependencies or application code.
10 | #
11 | # It's strongly recommended that you check this file into your version control system.
12 |
13 | ActiveRecord::Schema[8.0].define(version: 2025_09_05_170124) do
14 | create_table "people", force: :cascade do |t|
15 | t.string "first_name"
16 | t.string "last_name"
17 | t.datetime "created_at", null: false
18 | t.datetime "updated_at", null: false
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/examples/gem/lib/gem/BUILD:
--------------------------------------------------------------------------------
1 | load("@bazel_skylib//rules:run_binary.bzl", "run_binary")
2 | load("@rules_ruby//ruby:defs.bzl", "rb_binary", "rb_library")
3 |
4 | package(default_visibility = ["//:__subpackages__"])
5 |
6 | rb_library(
7 | name = "add",
8 | srcs = ["add.rb"],
9 | )
10 |
11 | rb_library(
12 | name = "subtract",
13 | srcs = ["subtract.rb"],
14 | )
15 |
16 | rb_library(
17 | name = "version",
18 | srcs = ["version.rb"],
19 | )
20 |
21 | rb_binary(
22 | name = "add-numbers",
23 | args = ["1"], # pass 1 argument here and 1 extra in CI
24 | main = "add.rb",
25 | deps = [
26 | ":add",
27 | "@bundle",
28 | ],
29 | )
30 |
31 | rb_binary(
32 | name = "print-version",
33 | args = ["lib/gem/version.rb"],
34 | deps = [":version"],
35 | )
36 |
37 | run_binary(
38 | name = "perform-addition",
39 | srcs = [":add"],
40 | outs = ["addition-result"],
41 | args = [
42 | "1",
43 | "2",
44 | "$(location :addition-result)",
45 | ],
46 | tool = ":add-numbers",
47 | )
48 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # Files in the config/locales directory are used for internationalization and
2 | # are automatically loaded by Rails. If you want to use locales other than
3 | # English, add the necessary files in this directory.
4 | #
5 | # To use the locales, use `I18n.t`:
6 | #
7 | # I18n.t "hello"
8 | #
9 | # In views, this is aliased to just `t`:
10 | #
11 | # <%= t("hello") %>
12 | #
13 | # To use a different locale, set it with `I18n.locale`:
14 | #
15 | # I18n.locale = :es
16 | #
17 | # This would use the information in config/locales/es.yml.
18 | #
19 | # To learn more about the API, please read the Rails Internationalization guide
20 | # at https://guides.rubyonrails.org/i18n.html.
21 | #
22 | # Be aware that YAML interprets the following case-insensitive strings as
23 | # booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings
24 | # must be quoted to be interpreted as strings. For example:
25 | #
26 | # en:
27 | # "yes": yup
28 | # enabled: "ON"
29 |
30 | en:
31 | hello: "Hello world"
32 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/initializers/bazel_ruby_patches.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Bazel Ruby patches for Rails tests
4 | #
5 | # These patches fix issues with require_relative and __dir__ in Bazel's
6 | # sandboxed environment. Without these patches, require_relative bypasses
7 | # the sandbox by reading files directly from the source tree instead of
8 | # the runfiles tree.
9 | #
10 | # See: https://github.com/bazel-contrib/rules_ruby/issues/225
11 |
12 | module Kernel
13 | unless respond_to?(:bazel_ruby_patches_applied?)
14 | def bazel_ruby_patches_applied?
15 | true
16 | end
17 |
18 | alias_method :brp_original_require_relative, :require_relative
19 | alias_method :brp_original___dir__, :__dir__
20 |
21 | def require_relative(path)
22 | base = caller_locations(1..1).first&.path
23 | base = "" if base.nil?
24 | base_directory = File.dirname(base)
25 | require File.expand_path(path, base_directory)
26 | end
27 |
28 | def __dir__
29 | File.dirname(caller_locations(1..1).first&.path)
30 | end
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/.dockerignore:
--------------------------------------------------------------------------------
1 | # See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files.
2 |
3 | # Ignore git directory.
4 | /.git/
5 | /.gitignore
6 |
7 | # Ignore bundler config.
8 | /.bundle
9 |
10 | # Ignore all environment files.
11 | /.env*
12 |
13 | # Ignore all default key files.
14 | /config/master.key
15 | /config/credentials/*.key
16 |
17 | # Ignore all logfiles and tempfiles.
18 | /log/*
19 | /tmp/*
20 | !/log/.keep
21 | !/tmp/.keep
22 |
23 | # Ignore pidfiles, but keep the directory.
24 | /tmp/pids/*
25 | !/tmp/pids/.keep
26 |
27 | # Ignore storage (uploaded files in development and any SQLite databases).
28 | /storage/*
29 | !/storage/.keep
30 | /tmp/storage/*
31 | !/tmp/storage/.keep
32 |
33 | # Ignore assets.
34 | /node_modules/
35 | /app/assets/builds/*
36 | !/app/assets/builds/.keep
37 | /public/assets
38 |
39 | # Ignore CI service files.
40 | /.github
41 |
42 | # Ignore Kamal files.
43 | /config/deploy*.yml
44 | /.kamal
45 |
46 | # Ignore development files
47 | /.devcontainer
48 |
49 | # Ignore Docker-related files
50 | /.dockerignore
51 | /Dockerfile*
52 |
--------------------------------------------------------------------------------
/ruby/private/toolchain/repository_proxy.bzl:
--------------------------------------------------------------------------------
1 | "Repository rule for proxying registering Ruby interpreters"
2 |
3 | def _rb_toolchain_repository_proxy_impl(repository_ctx):
4 | repository_ctx.template(
5 | "BUILD",
6 | repository_ctx.attr._build_tpl,
7 | substitutions = {
8 | "{name}": repository_ctx.attr.name,
9 | "{toolchain}": repository_ctx.attr.toolchain,
10 | "{toolchain_type}": repository_ctx.attr.toolchain_type,
11 | },
12 | executable = False,
13 | )
14 |
15 | rb_toolchain_repository_proxy = repository_rule(
16 | implementation = _rb_toolchain_repository_proxy_impl,
17 | attrs = {
18 | "toolchain": attr.string(mandatory = True),
19 | "toolchain_type": attr.string(mandatory = True),
20 | "_build_tpl": attr.label(
21 | allow_single_file = True,
22 | default = "@rules_ruby//:ruby/private/toolchain/repository_proxy/BUILD.tpl",
23 | ),
24 | },
25 | doc = """
26 | A proxy repository that contains the toolchain declaration; this indirection
27 | allows the Ruby toolchain to be downloaded lazily.
28 | """,
29 | )
30 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/layouts/application.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= content_for(:title) || "People Tracker" %>
5 |
6 |
7 |
8 | <%= csrf_meta_tags %>
9 | <%= csp_meta_tag %>
10 |
11 | <%= yield :head %>
12 |
13 | <%# Enable PWA manifest for installable apps (make sure to enable in config/routes.rb too!) %>
14 | <%#= tag.link rel: "manifest", href: pwa_manifest_path(format: :json) %>
15 |
16 |
17 |
18 |
19 |
20 | <%# Includes all stylesheet files in app/assets/stylesheets %>
21 | <%= stylesheet_link_tag :app, "data-turbo-track": "reload" %>
22 | <%= javascript_importmap_tags %>
23 |
24 |
25 |
26 |
27 | <%= yield %>
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require "fileutils"
3 |
4 | APP_ROOT = File.expand_path("..", __dir__)
5 |
6 | def system!(*args)
7 | system(*args, exception: true)
8 | end
9 |
10 | FileUtils.chdir APP_ROOT do
11 | # This script is a way to set up or update your development environment automatically.
12 | # This script is idempotent, so that you can run it at any time and get an expectable outcome.
13 | # Add necessary setup steps to this file.
14 |
15 | puts "== Installing dependencies =="
16 | system("bundle check") || system!("bundle install")
17 |
18 | # puts "\n== Copying sample files =="
19 | # unless File.exist?("config/database.yml")
20 | # FileUtils.cp "config/database.yml.sample", "config/database.yml"
21 | # end
22 |
23 | puts "\n== Preparing database =="
24 | system! "bin/rails db:prepare"
25 |
26 | puts "\n== Removing old logs and tempfiles =="
27 | system! "bin/rails log:clear tmp:clear"
28 |
29 | unless ARGV.include?("--skip-server")
30 | puts "\n== Starting development server =="
31 | STDOUT.flush # flush the output before exec(2) so that it displays
32 | exec "bin/dev"
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/initializers/content_security_policy.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Define an application-wide content security policy.
4 | # See the Securing Rails Applications Guide for more information:
5 | # https://guides.rubyonrails.org/security.html#content-security-policy-header
6 |
7 | # Rails.application.configure do
8 | # config.content_security_policy do |policy|
9 | # policy.default_src :self, :https
10 | # policy.font_src :self, :https, :data
11 | # policy.img_src :self, :https, :data
12 | # policy.object_src :none
13 | # policy.script_src :self, :https
14 | # policy.style_src :self, :https
15 | # # Specify URI for violation reports
16 | # # policy.report_uri "/csp-violation-report-endpoint"
17 | # end
18 | #
19 | # # Generate session nonces for permitted importmap, inline scripts, and inline styles.
20 | # config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s }
21 | # config.content_security_policy_nonce_directives = %w(script-src style-src)
22 | #
23 | # # Report violations without enforcing the policy.
24 | # # config.content_security_policy_report_only = true
25 | # end
26 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/test/system/people_test.rb:
--------------------------------------------------------------------------------
1 | require "application_system_test_case"
2 |
3 | class PeopleTest < ApplicationSystemTestCase
4 | setup do
5 | @john_doe = people(:john_doe)
6 | end
7 |
8 | test "visiting the index" do
9 | visit people_url
10 | assert_selector "h1", text: "People"
11 | end
12 |
13 | test "should create person" do
14 | visit people_url
15 | click_on "New person"
16 |
17 | fill_in "First name", with: "Bob"
18 | fill_in "Last name", with: "Smith"
19 | click_on "Create Person"
20 |
21 | assert_text "Person was successfully created"
22 | click_on "Back"
23 | end
24 |
25 | test "should update Person" do
26 | visit person_url(@john_doe)
27 | click_on "Edit this person", match: :first
28 |
29 | fill_in "First name", with: @john_doe.first_name + "Suffix"
30 | fill_in "Last name", with: @john_doe.last_name + "Another"
31 | click_on "Update Person"
32 |
33 | assert_text "Person was successfully updated"
34 | click_on "Back"
35 | end
36 |
37 | test "should destroy Person" do
38 | visit person_url(@john_doe)
39 | accept_confirm { click_on "Destroy this person", match: :first }
40 |
41 | assert_text "Person was successfully destroyed"
42 | end
43 | end
44 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/storage.yml:
--------------------------------------------------------------------------------
1 | test:
2 | service: Disk
3 | root: <%= Rails.root.join("tmp/storage") %>
4 |
5 | local:
6 | service: Disk
7 | root: <%= Rails.root.join("storage") %>
8 |
9 | # Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
10 | # amazon:
11 | # service: S3
12 | # access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
13 | # secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
14 | # region: us-east-1
15 | # bucket: your_own_bucket-<%= Rails.env %>
16 |
17 | # Remember not to checkin your GCS keyfile to a repository
18 | # google:
19 | # service: GCS
20 | # project: your_project
21 | # credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
22 | # bucket: your_own_bucket-<%= Rails.env %>
23 |
24 | # Use bin/rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
25 | # microsoft:
26 | # service: AzureStorage
27 | # storage_account_name: your_account_name
28 | # storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
29 | # container: your_container_name-<%= Rails.env %>
30 |
31 | # mirror:
32 | # service: Mirror
33 | # primary: local
34 | # mirrors: [ amazon, google, microsoft ]
35 |
--------------------------------------------------------------------------------
/examples/jekyll/_posts/2024-02-03-welcome-to-jekyll.markdown:
--------------------------------------------------------------------------------
1 | ---
2 | layout: post
3 | title: "Welcome to Jekyll!"
4 | date: 2024-02-03 12:49:25 -0800
5 | categories: jekyll update
6 | ---
7 | You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated.
8 |
9 | To add new posts, simply add a file in the `_posts` directory that follows the convention `YYYY-MM-DD-name-of-post.ext` and includes the necessary front matter. Take a look at the source for this post to get an idea about how it works.
10 |
11 | Jekyll also offers powerful support for code snippets:
12 |
13 | {% highlight ruby %}
14 | def print_hi(name)
15 | puts "Hi, #{name}"
16 | end
17 | print_hi('Tom')
18 | #=> prints 'Hi, Tom' to STDOUT.
19 | {% endhighlight %}
20 |
21 | Check out the [Jekyll docs][jekyll-docs] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll’s GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll Talk][jekyll-talk].
22 |
23 | [jekyll-docs]: https://jekyllrb.com/docs/home
24 | [jekyll-gh]: https://github.com/jekyll/jekyll
25 | [jekyll-talk]: https://talk.jekyllrb.com/
26 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/database.yml:
--------------------------------------------------------------------------------
1 | # SQLite. Versions 3.8.0 and up are supported.
2 | # gem install sqlite3
3 | #
4 | # Ensure the SQLite 3 gem is defined in your Gemfile
5 | # gem "sqlite3"
6 | #
7 | default: &default
8 | adapter: sqlite3
9 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
10 | timeout: 5000
11 |
12 | development:
13 | !!merge <<: *default
14 | database: storage/development.sqlite3
15 |
16 | # Warning: The database defined as "test" will be erased and
17 | # re-generated from your development database when you run "rake".
18 | # Do not set this db to the same as development or production.
19 | test:
20 | !!merge <<: *default
21 | database: ":memory:"
22 |
23 | # Store production database in the storage/ directory, which by default
24 | # is mounted as a persistent Docker volume in config/deploy.yml.
25 | production:
26 | primary:
27 | !!merge <<: *default
28 | database: storage/production.sqlite3
29 | cache:
30 | !!merge <<: *default
31 | database: storage/production_cache.sqlite3
32 | migrations_paths: db/cache_migrate
33 | queue:
34 | !!merge <<: *default
35 | database: storage/production_queue.sqlite3
36 | migrations_paths: db/queue_migrate
37 | cable:
38 | !!merge <<: *default
39 | database: storage/production_cable.sqlite3
40 | migrations_paths: db/cable_migrate
41 |
--------------------------------------------------------------------------------
/ruby/private/binary/binary.cmd.tpl:
--------------------------------------------------------------------------------
1 | @echo off
2 | setlocal enableextensions enabledelayedexpansion
3 |
4 | set RUNFILES_MANIFEST_ONLY=1
5 | {rlocation_function}
6 |
7 | :: Find location of Ruby in runfiles.
8 | call :rlocation {ruby} ruby
9 | for %%a in ("!ruby!\..") do set PATH=%%~fa;%PATH%
10 |
11 | :: Find location of JAVA_HOME in runfiles.
12 | if "{java_bin}" neq "" (
13 | call :rlocation {java_bin} java_bin
14 | for %%a in ("!java_bin!\..\..") do set JAVA_HOME=%%~fa
15 | )
16 |
17 | :: Bundler expects the %HOME% directory to be writable and produces misleading
18 | :: warnings if it isn't. This isn't the case in every situation (e.g. remote
19 | :: execution) and Bazel recommends using %TEST_TMPDIR% when it's available:
20 | :: https://bazel.build/reference/test-encyclopedia#initial-conditions
21 | ::
22 | :: We set %HOME% prior to setting environment variables from the target itself
23 | :: so that users can override this behavior if they desire.
24 | if defined TEST_TMPDIR (
25 | set "HOME=%TEST_TMPDIR%"
26 | )
27 |
28 | :: Set environment variables.
29 | {env}
30 |
31 | :: Find location of Bundle path in runfiles.
32 | if "{bundler_command}" neq "" (
33 | call :rlocation "!BUNDLE_GEMFILE!" BUNDLE_GEMFILE
34 | call :rlocation "!BUNDLE_PATH!" BUNDLE_PATH
35 | )
36 |
37 | {bundler_command} {ruby_binary_name} {binary} {args} %*
38 |
39 | :: vim: ft=dosbatch
40 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/test/controllers/people_controller_test.rb:
--------------------------------------------------------------------------------
1 | require "test_helper"
2 |
3 | class PeopleControllerTest < ActionDispatch::IntegrationTest
4 | setup do
5 | @person = people(:john_doe)
6 | end
7 |
8 | test "should get index" do
9 | get people_url
10 | assert_response :success
11 | end
12 |
13 | test "should get new" do
14 | get new_person_url
15 | assert_response :success
16 | end
17 |
18 | test "should create person" do
19 | assert_difference("Person.count") do
20 | post people_url, params: {
21 | person: {first_name: @person.first_name, last_name: @person.last_name}
22 | }
23 | end
24 |
25 | assert_redirected_to person_url(Person.last)
26 | end
27 |
28 | test "should show person" do
29 | get person_url(@person)
30 | assert_response :success
31 | end
32 |
33 | test "should get edit" do
34 | get edit_person_url(@person)
35 | assert_response :success
36 | end
37 |
38 | test "should update person" do
39 | patch person_url(@person), params: {
40 | person: {first_name: @person.first_name, last_name: @person.last_name}
41 | }
42 | assert_redirected_to person_url(@person)
43 | end
44 |
45 | test "should destroy person" do
46 | assert_difference("Person.count", -1) do
47 | delete person_url(@person)
48 | end
49 |
50 | assert_redirected_to people_url
51 | end
52 | end
53 |
--------------------------------------------------------------------------------
/ruby/private/gem_build/gem_builder.rb.tpl:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'fileutils'
4 | require 'json'
5 | require 'rubygems/package'
6 | require 'tmpdir'
7 |
8 | gemspec_path = '{gemspec}'
9 | packaged_gem_path = File.expand_path('{gem_filename}', '{bazel_out_dir}')
10 | inputs = JSON.parse('{inputs_manifest}')
11 |
12 | # We need to check if there are inputs which are directories.
13 | # For such cases, we are going to check the contents of the directories
14 | # and add the file to the inputs manifest.
15 | inputs.dup.each do |src, dst|
16 | next unless File.directory?(src)
17 |
18 | inputs.delete(src)
19 | Dir.chdir(src) do
20 | Dir['**/*'].each do |file|
21 | inputs[File.join(src, file)] = File.join(dst, file)
22 | end
23 | end
24 | end
25 |
26 | Dir.mktmpdir do |tmpdir|
27 | inputs.each do |src, dst|
28 | dst = File.join(tmpdir, dst)
29 | FileUtils.mkdir_p(File.dirname(dst))
30 | FileUtils.cp(src, dst)
31 | end
32 |
33 | Dir.chdir(tmpdir) do
34 | gemspec_dir = File.dirname(gemspec_path)
35 | gemspec_file = File.basename(gemspec_path)
36 | gemspec_code = File.read(gemspec_path)
37 |
38 | Dir.chdir(gemspec_dir) do
39 | spec = binding.eval(gemspec_code, gemspec_file, __LINE__) # rubocop:disable Security/Eval
40 | file = Gem::Package.build(spec)
41 | FileUtils.mv(file, packaged_gem_path)
42 | end
43 | end
44 | end
45 |
46 | # vim: ft=ruby
47 |
--------------------------------------------------------------------------------
/ruby/toolchain.bzl:
--------------------------------------------------------------------------------
1 | "Define a Bazel toolchain for a Ruby interpreter"
2 |
3 | def _rb_toolchain_impl(ctx):
4 | return platform_common.ToolchainInfo(
5 | ruby = ctx.executable.ruby,
6 | bundle = ctx.executable.bundle,
7 | gem = ctx.executable.gem,
8 | version = ctx.attr.version,
9 | env = ctx.attr.env,
10 | files = ctx.files.files,
11 | )
12 |
13 | rb_toolchain = rule(
14 | implementation = _rb_toolchain_impl,
15 | attrs = {
16 | "ruby": attr.label(
17 | doc = "`ruby` binary to execute",
18 | allow_files = True,
19 | executable = True,
20 | cfg = "exec",
21 | ),
22 | "bundle": attr.label(
23 | doc = "`bundle` to execute",
24 | allow_files = True,
25 | executable = True,
26 | cfg = "exec",
27 | ),
28 | "gem": attr.label(
29 | doc = "`gem` to execute",
30 | allow_files = True,
31 | executable = True,
32 | cfg = "exec",
33 | ),
34 | "version": attr.string(
35 | doc = "Ruby version",
36 | ),
37 | "env": attr.string_dict(
38 | doc = "Environment variables required by an interpreter",
39 | ),
40 | "files": attr.label_list(
41 | allow_files = True,
42 | doc = "All files necessary for toolchain",
43 | ),
44 | },
45 | )
46 |
--------------------------------------------------------------------------------
/MODULE.bazel:
--------------------------------------------------------------------------------
1 | "Define the Bazel module published to the Bazel Central Registry"
2 |
3 | module(
4 | name = "rules_ruby",
5 | # NB: this version will be replaced after a release by the Publish to BCR app
6 | version = "0.0.0",
7 | compatibility_level = 1,
8 | )
9 |
10 | # Lower-bound dependency versions.
11 | # These should NOT be increased unless needed, as bumping our lower-bound may change
12 | # the versions resolved in users repositories.
13 | bazel_dep(name = "bazel_features", version = "1.9.0")
14 | bazel_dep(name = "bazel_skylib", version = "1.3.0")
15 | bazel_dep(name = "platforms", version = "0.0.5")
16 | bazel_dep(name = "rules_cc", version = "0.0.9")
17 | bazel_dep(name = "rules_java", version = "7.2.0")
18 |
19 | # Ruleset development dependencies.
20 | bazel_dep(name = "aspect_bazel_lib", version = "2.22.0", dev_dependency = True)
21 | bazel_dep(name = "bazel_skylib_gazelle_plugin", version = "1.8.2", dev_dependency = True)
22 | bazel_dep(name = "buildifier_prebuilt", version = "8.2.1.1", dev_dependency = True)
23 | bazel_dep(name = "gazelle", version = "0.47.0", dev_dependency = True)
24 | bazel_dep(name = "rules_go", version = "0.59.0", dev_dependency = True)
25 | bazel_dep(name = "stardoc", version = "0.8.0", dev_dependency = True)
26 |
27 | go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk", dev_dependency = True)
28 | go_sdk.download(version = "1.23.1")
29 |
30 | # TODO: should we register any toolchain by default?
31 |
--------------------------------------------------------------------------------
/examples/deep_gem/hello_world/Gemfile.lock:
--------------------------------------------------------------------------------
1 | PATH
2 | remote: .
3 | specs:
4 | hello_world (0.0.0)
5 | irb
6 | rspec (~> 3.0)
7 |
8 | GEM
9 | remote: https://rubygems.org/
10 | specs:
11 | date (3.4.1-java)
12 | diff-lcs (1.6.2)
13 | erb (5.0.2-java)
14 | io-console (0.8.1-java)
15 | irb (1.15.2)
16 | pp (>= 0.6.0)
17 | rdoc (>= 4.0.0)
18 | reline (>= 0.4.2)
19 | jar-dependencies (0.5.5)
20 | pp (0.6.2)
21 | prettyprint
22 | prettyprint (0.2.0)
23 | psych (5.2.6-java)
24 | date
25 | jar-dependencies (>= 0.1.7)
26 | rdoc (6.14.2)
27 | erb
28 | psych (>= 4.0.0)
29 | reline (0.6.2)
30 | io-console (~> 0.5)
31 | rspec (3.13.1)
32 | rspec-core (~> 3.13.0)
33 | rspec-expectations (~> 3.13.0)
34 | rspec-mocks (~> 3.13.0)
35 | rspec-core (3.13.5)
36 | rspec-support (~> 3.13.0)
37 | rspec-expectations (3.13.5)
38 | diff-lcs (>= 1.2.0, < 2.0)
39 | rspec-support (~> 3.13.0)
40 | rspec-mocks (3.13.5)
41 | diff-lcs (>= 1.2.0, < 2.0)
42 | rspec-support (~> 3.13.0)
43 | rspec-support (3.13.4)
44 |
45 | PLATFORMS
46 | arm64-darwin-23
47 | arm64-darwin-24
48 | java
49 | ruby
50 | universal-java-1.8
51 | universal-java-11
52 | universal-java-17
53 | universal-java-18
54 | universal-java-21
55 | x64-mingw32
56 |
57 | DEPENDENCIES
58 | hello_world!
59 |
60 | BUNDLED WITH
61 | 2.3.3
62 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/people/_form.html.erb:
--------------------------------------------------------------------------------
1 | <%= form_with(model: person, class: "contents") do |form| %>
2 | <% if person.errors.any? %>
3 |
4 |
<%= pluralize(person.errors.count, "error") %> prohibited this person from being saved:
5 |
6 |
7 | <% person.errors.each do |error| %>
8 | <%= error.full_message %>
9 | <% end %>
10 |
11 |
12 | <% end %>
13 |
14 |
15 | <%= form.label :first_name %>
16 | <%= form.text_field :first_name, class: ["block shadow-sm rounded-md border px-3 py-2 mt-2 w-full", {"border-gray-400 focus:outline-blue-600": person.errors[:first_name].none?, "border-red-400 focus:outline-red-600": person.errors[:first_name].any?}] %>
17 |
18 |
19 |
20 | <%= form.label :last_name %>
21 | <%= form.text_field :last_name, class: ["block shadow-sm rounded-md border px-3 py-2 mt-2 w-full", {"border-gray-400 focus:outline-blue-600": person.errors[:last_name].none?, "border-red-400 focus:outline-red-600": person.errors[:last_name].any?}] %>
22 |
23 |
24 |
25 | <%= form.submit class: "w-full sm:w-auto rounded-md px-3.5 py-2.5 bg-blue-600 hover:bg-blue-500 text-white inline-block font-medium cursor-pointer" %>
26 |
27 | <% end %>
28 |
--------------------------------------------------------------------------------
/ruby/BUILD:
--------------------------------------------------------------------------------
1 | load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
2 |
3 | package(default_visibility = ["//visibility:public"])
4 |
5 | exports_files(glob(["*.bzl"]))
6 |
7 | toolchain_type(
8 | name = "toolchain_type",
9 | visibility = ["//visibility:public"],
10 | )
11 |
12 | bzl_library(
13 | name = "defs",
14 | srcs = ["defs.bzl"],
15 | deps = [
16 | "//ruby/private:binary",
17 | "//ruby/private:bundle_install",
18 | "//ruby/private:gem",
19 | "//ruby/private:gem_build",
20 | "//ruby/private:gem_install",
21 | "//ruby/private:gem_push",
22 | "//ruby/private:library",
23 | "//ruby/private:test",
24 | ],
25 | )
26 |
27 | starlark_doc_extract(
28 | name = "defs.doc_extract",
29 | src = "defs.bzl",
30 | deps = [":defs"],
31 | )
32 |
33 | bzl_library(
34 | name = "deps",
35 | srcs = ["deps.bzl"],
36 | deps = [
37 | "//ruby/private:bundle",
38 | "//ruby/private:bundle_fetch",
39 | "//ruby/private:toolchain",
40 | ],
41 | )
42 |
43 | starlark_doc_extract(
44 | name = "deps.doc_extract",
45 | src = "deps.bzl",
46 | deps = [":deps"],
47 | )
48 |
49 | bzl_library(
50 | name = "extensions",
51 | srcs = ["extensions.bzl"],
52 | deps = [
53 | ":deps",
54 | "//ruby/private:download",
55 | "//ruby/private:toolchain",
56 | ],
57 | )
58 |
59 | bzl_library(
60 | name = "toolchain",
61 | srcs = ["toolchain.bzl"],
62 | )
63 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/test/models/person_test.rb:
--------------------------------------------------------------------------------
1 | require "test_helper"
2 |
3 | class PersonTest < ActiveSupport::TestCase
4 | test "should be valid with valid attributes" do
5 | person = Person.new(first_name: "John", last_name: "Doe")
6 | assert person.valid?
7 | end
8 |
9 | test "full_name returns concatenated first and last name" do
10 | person = people(:john_doe)
11 | assert_equal "John Doe", person.full_name
12 | end
13 |
14 | test "full_name handles nil first_name" do
15 | person = Person.new(first_name: nil, last_name: "Doe")
16 | assert_equal "Doe", person.full_name
17 | end
18 |
19 | test "full_name handles nil last_name" do
20 | person = Person.new(first_name: "John", last_name: nil)
21 | assert_equal "John", person.full_name
22 | end
23 |
24 | test "full_name handles both names being nil" do
25 | person = Person.new(first_name: nil, last_name: nil)
26 | assert_equal "", person.full_name
27 | end
28 |
29 | test "full_name handles empty strings" do
30 | person = Person.new(first_name: "", last_name: "")
31 | assert_equal "", person.full_name
32 | end
33 |
34 | test "should have timestamps" do
35 | person = people(:john_doe)
36 | assert_not_nil person.created_at
37 | assert_not_nil person.updated_at
38 | end
39 |
40 | test "can create person with minimal attributes" do
41 | person = Person.create(first_name: "Test", last_name: "User")
42 | assert_not_nil person.id
43 | assert_equal "Test", person.first_name
44 | assert_equal "User", person.last_name
45 | end
46 | end
47 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/application.rb:
--------------------------------------------------------------------------------
1 | require_relative "boot"
2 |
3 | require "rails/all"
4 |
5 | # Prevent pending migration checks from happening when running tests. We use
6 | # in-memory SQLite databases for our tests. The default pending migration check
7 | # fails if you run `rails test`.
8 | if ENV["RAILS_ENV"] == "test"
9 | module ActiveRecord
10 | class Migration
11 | class << self
12 | def check_pending_migrations
13 | # Do nothing.
14 | end
15 | end
16 | end
17 | end
18 | end
19 |
20 | # Require the gems listed in Gemfile, including any gems
21 | # you've limited to :test, :development, or :production.
22 | Bundler.require(*Rails.groups)
23 |
24 | module PeopleTracker
25 | class Application < Rails::Application
26 | # Initialize configuration defaults for originally generated Rails version.
27 | config.load_defaults 8.0
28 |
29 | # Please, add to the `ignore` list any other `lib` subdirectories that do
30 | # not contain `.rb` files, or that should not be reloaded or eager loaded.
31 | # Common ones are `templates`, `generators`, or `middleware`, for example.
32 | config.autoload_lib(ignore: %w[assets tasks])
33 |
34 | # Configuration for the application, engines, and railties goes here.
35 | #
36 | # These settings can be overridden in specific environments using the files
37 | # in config/environments, which are processed later.
38 | #
39 | # config.time_zone = "Central Time (US & Canada)"
40 | # config.eager_load_paths << Rails.root.join("extras")
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/examples/jekyll/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | # Hello! This is where you manage which Jekyll version is used to run.
4 | # When you want to use a different version, change it below, save the
5 | # file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
6 | #
7 | # bundle exec jekyll serve
8 | #
9 | # This will help ensure the proper Jekyll version is running.
10 | # Happy Jekylling!
11 | gem "jekyll", "~> 3.9.3"
12 |
13 | # This is the default theme for new Jekyll sites. You may change this to anything you like.
14 | gem "minima", "~> 2.0"
15 |
16 | # If you want to use GitHub Pages, remove the "gem "jekyll"" above and
17 | # uncomment the line below. To upgrade, run `bundle update github-pages`.
18 | # gem "github-pages", group: :jekyll_plugins
19 |
20 | # If you have any plugins, put them here!
21 | group :jekyll_plugins do
22 | gem "jekyll-feed", "~> 0.6"
23 | end
24 |
25 | # Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
26 | # and associated library.
27 | platforms :mingw, :x64_mingw, :mswin, :jruby do
28 | gem "tzinfo", ">= 1", "< 3"
29 | gem "tzinfo-data"
30 | end
31 |
32 | # Performance-booster for watching directories on Windows
33 | gem "wdm", "~> 0.1.0", :install_if => Gem.win_platform?
34 |
35 | # kramdown v2 ships without the gfm parser by default. If you're using
36 | # kramdown v1, comment out this line.
37 | gem "kramdown-parser-gfm"
38 |
39 | # Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem
40 | # do not have a Java counterpart.
41 | gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]
42 |
43 | # `webrick` is a missing dependency needed to run `jekyll serve`
44 | gem "webrick", "~> 1.8"
45 |
--------------------------------------------------------------------------------
/examples/deep_gem/hello_world/spec/speaker_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require_relative "spec_helper"
4 | require_relative "../lib/hello_world"
5 |
6 | RSpec.describe HelloWorld::Speaker do
7 | describe "#name" do
8 | context "when no name is provided" do
9 | it "defaults to 'world'" do
10 | speaker = HelloWorld::Speaker.new
11 | expect(speaker.name).to eq("world")
12 | end
13 | end
14 |
15 | context "when a name is provided" do
16 | it "returns the provided name" do
17 | name = "Jimmy"
18 | speaker = HelloWorld::Speaker.new(name)
19 | expect(speaker.name).to eq(name)
20 | end
21 | end
22 | end
23 |
24 | describe "#message" do
25 | context "when using default name" do
26 | it "returns a greeting with the default name" do
27 | speaker = HelloWorld::Speaker.new
28 | expect(speaker.message).to eq("Hello, world")
29 | end
30 | end
31 |
32 | context "when using custom name" do
33 | it "returns a greeting with the custom name" do
34 | speaker = HelloWorld::Speaker.new("Alice")
35 | expect(speaker.message).to eq("Hello, Alice")
36 | end
37 | end
38 | end
39 |
40 | describe "#hi" do
41 | context "when using default name" do
42 | it "outputs the greeting message to stdout" do
43 | speaker = HelloWorld::Speaker.new
44 | expect { speaker.hi }.to output("Hello, world\n").to_stdout
45 | end
46 | end
47 |
48 | context "when using custom name" do
49 | it "outputs the greeting message with custom name to stdout" do
50 | speaker = HelloWorld::Speaker.new("Bob")
51 | expect { speaker.hi }.to output("Hello, Bob\n").to_stdout
52 | end
53 | end
54 | end
55 | end
56 |
--------------------------------------------------------------------------------
/examples/gem/.bazelrc:
--------------------------------------------------------------------------------
1 | # Enable runfiles on all platforms. Runfiles are on by default on Linux and MacOS but off on
2 | # Windows.
3 | #
4 | # If you are developing on Windows, you must either run bazel with administrator privileges or
5 | # enable developer mode. If you do not you may hit this error on Windows:
6 | #
7 | # Bazel needs to create symlinks to build the runfiles tree.
8 | # Creating symlinks on Windows requires one of the following:
9 | # 1. Bazel is run with administrator privileges.
10 | # 2. The system version is Windows 10 Creators Update (1703) or later
11 | # and developer mode is enabled.
12 | #
13 | # Docs: https://bazel.build/reference/command-line-reference#flag--windows_enable_symlinks
14 | # Docs: https://bazel.build/reference/command-line-reference#flag--enable_runfiles
15 | startup --windows_enable_symlinks
16 | build --enable_runfiles
17 |
18 | # Allow to run Bazel without pre-installed JDK.
19 | # Docs: https://bazel.build/reference/command-line-reference#flag--java_runtime_version
20 | build --java_runtime_version=remotejdk_21 --tool_java_runtime_version=remotejdk_21
21 |
22 | # Not ready for the MODULE.lock file yet, as of Bazel 7.0.0 there are still some stability issues.
23 | common --lockfile_mode=off
24 |
25 | # Ignore timeout different between JRuby and MRI.
26 | test --test_verbose_timeout_warnings=false
27 |
28 | # JRuby needs $HOME for File#expand_path to work: https://github.com/jruby/jruby/issues/5661.
29 | # TruffleRuby needs $HOME too: https://github.com/oracle/truffleruby/issues/2784.
30 | build --action_env=HOME
31 | test --test_env=HOME
32 |
33 | # Allows to run tests with rdbg bundled with Ruby 3.1:
34 | # 1. Add breakpoint with `debugger`.
35 | # 2. Run tests: `bazel test --config debug spec:add`.
36 | # 3. Connect to debugger: `bazel-gem/external/ruby/dist/bin/rdbg -A`.
37 | test:debug --run_under="@ruby//:rdbg --nonstop --open --command"
38 |
--------------------------------------------------------------------------------
/examples/deep_gem/.bazelrc:
--------------------------------------------------------------------------------
1 | # Enable runfiles on all platforms. Runfiles are on by default on Linux and MacOS but off on
2 | # Windows.
3 | #
4 | # If you are developing on Windows, you must either run bazel with administrator privileges or
5 | # enable developer mode. If you do not you may hit this error on Windows:
6 | #
7 | # Bazel needs to create symlinks to build the runfiles tree.
8 | # Creating symlinks on Windows requires one of the following:
9 | # 1. Bazel is run with administrator privileges.
10 | # 2. The system version is Windows 10 Creators Update (1703) or later
11 | # and developer mode is enabled.
12 | #
13 | # Docs: https://bazel.build/reference/command-line-reference#flag--windows_enable_symlinks
14 | # Docs: https://bazel.build/reference/command-line-reference#flag--enable_runfiles
15 | startup --windows_enable_symlinks
16 | build --enable_runfiles
17 |
18 | # Allow to run Bazel without pre-installed JDK.
19 | # Docs: https://bazel.build/reference/command-line-reference#flag--java_runtime_version
20 | build --java_runtime_version=remotejdk_21 --tool_java_runtime_version=remotejdk_21
21 |
22 | # Not ready for the MODULE.lock file yet, as of Bazel 7.0.0 there are still some stability issues.
23 | common --lockfile_mode=off
24 |
25 | # Ignore timeout different between JRuby and MRI.
26 | test --test_verbose_timeout_warnings=false
27 |
28 | # JRuby needs $HOME for File#expand_path to work: https://github.com/jruby/jruby/issues/5661.
29 | # TruffleRuby needs $HOME too: https://github.com/oracle/truffleruby/issues/2784.
30 | build --action_env=HOME
31 | test --test_env=HOME
32 |
33 | # Allows to run tests with rdbg bundled with Ruby 3.1:
34 | # 1. Add breakpoint with `debugger`.
35 | # 2. Run tests: `bazel test --config debug spec:add`.
36 | # 3. Connect to debugger: `bazel-gem/external/ruby/dist/bin/rdbg -A`.
37 | test:debug --run_under="@ruby//:rdbg --nonstop --open --command"
38 |
--------------------------------------------------------------------------------
/examples/deep_gem/hello_world/.bazelrc:
--------------------------------------------------------------------------------
1 | # Enable runfiles on all platforms. Runfiles are on by default on Linux and MacOS but off on
2 | # Windows.
3 | #
4 | # If you are developing on Windows, you must either run bazel with administrator privileges or
5 | # enable developer mode. If you do not you may hit this error on Windows:
6 | #
7 | # Bazel needs to create symlinks to build the runfiles tree.
8 | # Creating symlinks on Windows requires one of the following:
9 | # 1. Bazel is run with administrator privileges.
10 | # 2. The system version is Windows 10 Creators Update (1703) or later
11 | # and developer mode is enabled.
12 | #
13 | # Docs: https://bazel.build/reference/command-line-reference#flag--windows_enable_symlinks
14 | # Docs: https://bazel.build/reference/command-line-reference#flag--enable_runfiles
15 | startup --windows_enable_symlinks
16 | build --enable_runfiles
17 |
18 | # Allow to run Bazel without pre-installed JDK.
19 | # Docs: https://bazel.build/reference/command-line-reference#flag--java_runtime_version
20 | build --java_runtime_version=remotejdk_21 --tool_java_runtime_version=remotejdk_21
21 |
22 | # Not ready for the MODULE.lock file yet, as of Bazel 7.0.0 there are still some stability issues.
23 | common --lockfile_mode=off
24 |
25 | # Ignore timeout different between JRuby and MRI.
26 | test --test_verbose_timeout_warnings=false
27 |
28 | # JRuby needs $HOME for File#expand_path to work: https://github.com/jruby/jruby/issues/5661.
29 | # TruffleRuby needs $HOME too: https://github.com/oracle/truffleruby/issues/2784.
30 | build --action_env=HOME
31 | test --test_env=HOME
32 |
33 | # Allows to run tests with rdbg bundled with Ruby 3.1:
34 | # 1. Add breakpoint with `debugger`.
35 | # 2. Run tests: `bazel test --config debug spec:add`.
36 | # 3. Connect to debugger: `bazel-gem/external/ruby/dist/bin/rdbg -A`.
37 | test:debug --run_under="@ruby//:rdbg --nonstop --open --command"
38 |
--------------------------------------------------------------------------------
/examples/jekyll/_config.yml:
--------------------------------------------------------------------------------
1 | # Welcome to Jekyll!
2 | #
3 | # This config file is meant for settings that affect your whole blog, values
4 | # which you are expected to set up once and rarely edit after that. If you find
5 | # yourself editing this file very often, consider using Jekyll's data files
6 | # feature for the data you need to update frequently.
7 | #
8 | # For technical reasons, this file is *NOT* reloaded automatically when you use
9 | # 'bundle exec jekyll serve'. If you change this file, please restart the server process.
10 |
11 | # Site settings
12 | # These are used to personalize your new site. If you look in the HTML files,
13 | # you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
14 | # You can create any custom variable you would like, and they will be accessible
15 | # in the templates via {{ site.myvariable }}.
16 | title: Your awesome title
17 | email: your-email@example.com
18 | description: >- # this means to ignore newlines until "baseurl:"
19 | Write an awesome description for your new site here. You can edit this
20 | line in _config.yml. It will appear in your document head meta (for
21 | Google search results) and in your feed.xml site description.
22 | baseurl: "" # the subpath of your site, e.g. /blog
23 | url: "" # the base hostname & protocol for your site, e.g. http://example.com
24 | twitter_username: jekyllrb
25 | github_username: jekyll
26 |
27 | # Build settings
28 | markdown: kramdown
29 | theme: minima
30 | plugins:
31 | - jekyll-feed
32 |
33 | # Exclude from processing.
34 | # The following items will not be processed, by default. Create a custom list
35 | # to override the default setting.
36 | exclude:
37 | - Gemfile
38 | - Gemfile.lock
39 | - bazel-out/
40 | - external/
41 | - BUILD
42 | - MODULE.bazel
43 | - MODULE.bazel.lock
44 | - README.md
45 | # - node_modules
46 | # - vendor/bundle/
47 | # - vendor/cache/
48 | # - vendor/gems/
49 | # - vendor/ruby/
50 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/.envrc:
--------------------------------------------------------------------------------
1 | # NOTE: This file was written to work with bash and zsh. It uses features like
2 | # arrays which POSIX does not support.
3 |
4 | source_up .envrc
5 |
6 | module_bazel="$(find_up "MODULE.bazel")"
7 | wksp_root_dir="$(dirname "${module_bazel}")"
8 |
9 | # MARK - bazel_env Tools
10 |
11 | # Add binaries and toolchains defined in //people_tracker:bazel_env.
12 | bazel_env_dir="${wksp_root_dir}/bazel-out/bazel_env-opt/bin/people_tracker/bazel_env/bin"
13 | watch_file "${bazel_env_dir}"
14 | PATH_add "${bazel_env_dir}"
15 | if [ ! -d "${bazel_env_dir}" ]; then
16 | log_error "ERROR[bazel_env.bzl]: Run 'bazel run //people_tracker:all_bazel_env' to" \
17 | "regenerate ${bazel_env_dir} and its parent envrcs."
18 | fi
19 |
20 | # MARK - Ruby Gems
21 |
22 | # We configure the environment to use the Gemfile in this directory
23 | # (BUNDLE_GEMFILE) and the Gems installed by Bazel (BUNDLE_PATH).
24 | bundle_repo_name="people_tracker_bundle"
25 |
26 | BUNDLE_GEMFILE="$(expand_path Gemfile)"
27 | export BUNDLE_GEMFILE
28 |
29 | # Look for the bundle path, if we see the convenience symlinks at the root of
30 | # the Bazel workspace. We want to avoid running long-running commands (e.g.
31 | # cquery) if the workspace has not been built. This is not a perfect test but
32 | # should be good enough for most situations.
33 | if [[ -L "${wksp_root_dir}/bazel-out" ]]; then
34 | bundle_files=()
35 | while IFS=$'\n' read -r line; do bundle_files+=("$line"); done < <(
36 | bazel cquery "@${bundle_repo_name}" --output files 2>/dev/null
37 | )
38 | for file in "${bundle_files[@]}"; do
39 | if [[ "${file}" =~ vendor/bundle$ ]]; then
40 | export BUNDLE_PATH="${wksp_root_dir}/${file}"
41 | break
42 | fi
43 | done
44 | fi
45 | if [[ -z "${BUNDLE_PATH:-}" ]] || [[ ! -e "${BUNDLE_PATH}" ]]; then
46 | log_error "ERROR[bazel_env.bzl]: Run 'bazel run //people_tracker:all_bazel_env' to" \
47 | "install the gems for this Ruby project."
48 | fi
49 |
--------------------------------------------------------------------------------
/examples/jekyll/BUILD:
--------------------------------------------------------------------------------
1 | load("@aspect_bazel_lib//lib:run_binary.bzl", "run_binary")
2 | load("@bazel_skylib//rules:write_file.bzl", "write_file")
3 | load("@rules_shell//shell:sh_binary.bzl", "sh_binary")
4 |
5 | package(default_visibility = ["//visibility:public"])
6 |
7 | filegroup(
8 | name = "sources",
9 | srcs = glob(
10 | [
11 | "_posts/**/*",
12 | "_layouts/**/*",
13 | ],
14 | allow_empty = True,
15 | ) + [
16 | "404.html",
17 | "about.md",
18 | "index.md",
19 | ],
20 | )
21 |
22 | run_binary(
23 | name = "site_build",
24 | srcs = [
25 | ":_config.yml",
26 | ":sources",
27 | ],
28 | args = [
29 | "build",
30 | "--destination",
31 | "$(GENDIR)/_site",
32 | "--config",
33 | "$(location :_config.yml)",
34 | ],
35 | env = {
36 | "LC_ALL": "C.UTF-8",
37 | "LANG": "en_US.UTF-8",
38 | "LANGUAGE": "en_US.UTF-8",
39 | },
40 | execution_requirements = {"no-sandbox": "1"},
41 | mnemonic = "JekyllBuild",
42 | out_dirs = [
43 | "_site",
44 | ],
45 | tool = "@bundle//bin:jekyll",
46 | )
47 |
48 | write_file(
49 | name = "site_serve_file",
50 | out = "site_serve_file.sh",
51 | content = [
52 | "#!/bin/bash",
53 | # rules_ruby needs RUNFILES_DIR to be set
54 | "export RUNFILES_DIR=$(readlink -f ../)",
55 | "EXEC_ROOT=$(pwd)",
56 | "$EXEC_ROOT/$1 ${@:2}",
57 | ],
58 | )
59 |
60 | sh_binary(
61 | name = "site_serve",
62 | srcs = [
63 | ":site_serve_file",
64 | ],
65 | args = [
66 | "$(location @bundle//bin:jekyll)",
67 | "serve",
68 | "--destination",
69 | "_site",
70 | "--skip-initial-build",
71 | "--config",
72 | "$(location :_config.yml)",
73 | ],
74 | data = [
75 | ":_config.yml",
76 | ":site_build",
77 | "@bundle//bin:jekyll",
78 | ],
79 | )
80 |
--------------------------------------------------------------------------------
/ruby/private/download/BUILD.tpl:
--------------------------------------------------------------------------------
1 | load("@rules_cc//cc:defs.bzl", "cc_library")
2 | load("@rules_java//java:defs.bzl", "java_import")
3 | load("@rules_ruby//ruby:defs.bzl", "rb_binary")
4 | load("@rules_ruby//ruby:toolchain.bzl", "rb_toolchain")
5 |
6 | package(default_visibility = ["//visibility:public"])
7 |
8 | filegroup(
9 | name = "ruby_file",
10 | srcs = select({
11 | "@platforms//os:windows": ["dist/bin/{ruby_binary_name}.exe"],
12 | "//conditions:default": ["dist/bin/{ruby_binary_name}"],
13 | }),
14 | )
15 |
16 | rb_binary(
17 | name = "ruby",
18 | main = ":ruby_file",
19 | )
20 |
21 | cc_library(
22 | name = "headers",
23 | hdrs = glob(
24 | ["dist/include/**/*.h"],
25 | allow_empty = True,
26 | ),
27 | includes = {includes},
28 | )
29 |
30 | java_import(
31 | name = "jars",
32 | jars = glob(
33 | ["dist/lib/**/*.jar"],
34 | allow_empty = True,
35 | ),
36 | neverlink = True,
37 | )
38 |
39 | rb_toolchain(
40 | name = "toolchain",
41 | bundle = select({
42 | "@platforms//os:windows": "dist/bin/bundle.cmd",
43 | "//conditions:default": "dist/bin/bundle",
44 | }),
45 | env = {env},
46 | files = glob(["dist/**/*"]),
47 | gem = select({
48 | "@platforms//os:windows": "dist/bin/{gem_binary_name}.cmd",
49 | "//conditions:default": "dist/bin/{gem_binary_name}",
50 | }),
51 | ruby = ":ruby_file",
52 | version = "{version}",
53 | )
54 |
55 | [
56 | rb_binary(
57 | name = file.removeprefix("dist/bin/"),
58 | main = file,
59 | )
60 | for file in glob(
61 | ["dist/bin/*"],
62 | exclude = [
63 | "dist/bin/ruby",
64 | "dist/bin/jruby",
65 | ] + glob([
66 | "dist/bin/*.exe",
67 | ], allow_empty = True) + glob([
68 | "dist/bin/*.cmd",
69 | ], allow_empty = True) + glob([
70 | "dist/bin/*.bat",
71 | ], allow_empty = True),
72 | )
73 | ]
74 |
75 | # vim: ft=bzl
76 |
--------------------------------------------------------------------------------
/examples/gem/BUILD:
--------------------------------------------------------------------------------
1 | load("@aspect_bazel_lib//lib:expand_template.bzl", "expand_template")
2 | load("@aspect_bazel_lib//lib:paths.bzl", "BASH_RLOCATION_FUNCTION")
3 | load(
4 | "@rules_ruby//ruby:defs.bzl",
5 | "rb_binary",
6 | "rb_gem_build",
7 | "rb_gem_install",
8 | "rb_gem_push",
9 | "rb_test",
10 | )
11 | load("@rules_shell//shell:sh_test.bzl", "sh_test")
12 |
13 | package(default_visibility = ["//:__subpackages__"])
14 |
15 | expand_template(
16 | name = "shell_wrapper",
17 | out = "wrapper.sh",
18 | data = [
19 | ":Rakefile",
20 | ":rake",
21 | ],
22 | substitutions = {
23 | "@@rlocation_lib@@": BASH_RLOCATION_FUNCTION.replace("$", "$$"),
24 | "@@rake_binary@@": "$(rlocationpaths :rake)",
25 | "@@rakefile@@": "$(rlocationpaths :Rakefile)",
26 | },
27 | template = "wrapper.tpl.sh",
28 | )
29 |
30 | sh_test(
31 | name = "shell_wrapper_test",
32 | srcs = [":shell_wrapper"],
33 | data = [
34 | ":Rakefile",
35 | ":rake",
36 | ],
37 | tags = ["bcr-presubmit-failure"],
38 | deps = ["@bazel_tools//tools/bash/runfiles"],
39 | )
40 |
41 | rb_binary(
42 | name = "rake",
43 | main = "@bundle//bin:rake",
44 | deps = [
45 | "//lib:gem",
46 | "@bundle",
47 | ],
48 | )
49 |
50 | rb_test(
51 | name = "rubocop",
52 | size = "small",
53 | timeout = "moderate", # JRuby startup can be slow
54 | data = [
55 | ".rubocop.yml",
56 | "Gemfile",
57 | ],
58 | main = "@bundle//bin:rubocop",
59 | tags = ["no-sandbox"],
60 | deps = [
61 | "//lib:gem",
62 | "//spec:add",
63 | "//spec:env",
64 | "//spec:subtract",
65 | "//spec:support",
66 | "@bundle",
67 | ],
68 | )
69 |
70 | rb_gem_build(
71 | name = "gem-build",
72 | gemspec = "gem.gemspec",
73 | deps = ["//lib:gem"],
74 | )
75 |
76 | rb_gem_install(
77 | name = "gem-install",
78 | gem = ":gem-build",
79 | )
80 |
81 | rb_gem_push(
82 | name = "gem-release",
83 | gem = ":gem-build",
84 | )
85 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/views/people/index.html.erb:
--------------------------------------------------------------------------------
1 | <%= turbo_stream_from "people" %>
2 | <%= turbo_refreshes_with method: :morph, scroll: :preserve %>
3 |
4 |
5 | <% if notice.present? %>
6 |
8 | <%= notice %>
9 |
10 | <% end %>
11 |
12 |
13 |
People
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | <%= link_to 'New person',
22 | new_person_path,
23 | class: "inline rounded-lg py-3 px-5 bg-green-600
24 | text-white block font-medium" %>
25 |
26 |
27 |
28 |
29 |
30 |
31 | <% @people.each do |person| %>
32 |
33 |
34 |
35 | <%= person.full_name %>
36 |
37 |
38 |
39 |
40 |
41 | <%= link_to 'Show',
42 | person,
43 | class: 'hover:underline' %>
44 |
45 |
46 | <%= link_to 'Edit',
47 | edit_person_path(person),
48 | class: 'hover:underline' %>
49 |
50 |
51 |
52 | <%= button_to 'Destroy',
53 | person,
54 | method: :delete,
55 | class: 'hover:underline',
56 | data: { turbo_confirm: "Are you sure?" } %>
57 |
58 |
59 |
60 |
61 | <% end %>
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/puma.rb:
--------------------------------------------------------------------------------
1 | # This configuration file will be evaluated by Puma. The top-level methods that
2 | # are invoked here are part of Puma's configuration DSL. For more information
3 | # about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html.
4 | #
5 | # Puma starts a configurable number of processes (workers) and each process
6 | # serves each request in a thread from an internal thread pool.
7 | #
8 | # You can control the number of workers using ENV["WEB_CONCURRENCY"]. You
9 | # should only set this value when you want to run 2 or more workers. The
10 | # default is already 1.
11 | #
12 | # The ideal number of threads per worker depends both on how much time the
13 | # application spends waiting for IO operations and on how much you wish to
14 | # prioritize throughput over latency.
15 | #
16 | # As a rule of thumb, increasing the number of threads will increase how much
17 | # traffic a given process can handle (throughput), but due to CRuby's
18 | # Global VM Lock (GVL) it has diminishing returns and will degrade the
19 | # response time (latency) of the application.
20 | #
21 | # The default is set to 3 threads as it's deemed a decent compromise between
22 | # throughput and latency for the average Rails application.
23 | #
24 | # Any libraries that use a connection pool or another resource pool should
25 | # be configured to provide at least as many connections as the number of
26 | # threads. This includes Active Record's `pool` parameter in `database.yml`.
27 | threads_count = ENV.fetch("RAILS_MAX_THREADS", 3)
28 | threads threads_count, threads_count
29 |
30 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
31 | port ENV.fetch("PORT", 3000)
32 |
33 | # Allow puma to be restarted by `bin/rails restart` command.
34 | plugin :tmp_restart
35 |
36 | # Run the Solid Queue supervisor inside of Puma for single-server deployments
37 | plugin :solid_queue if ENV["SOLID_QUEUE_IN_PUMA"]
38 |
39 | # Specify the PID file. Defaults to tmp/pids/server.pid in development.
40 | # In other environments, only set the PID file if requested.
41 | pidfile ENV["PIDFILE"] if ENV["PIDFILE"]
42 |
--------------------------------------------------------------------------------
/examples/gem/spec/BUILD:
--------------------------------------------------------------------------------
1 | load("@rules_ruby//ruby:defs.bzl", "rb_library", "rb_test")
2 |
3 | package(default_visibility = ["//:__pkg__"])
4 |
5 | rb_library(
6 | name = "spec_helper",
7 | srcs = ["spec_helper.rb"],
8 | deps = [
9 | "//lib:gem",
10 | "@bundle",
11 | ],
12 | )
13 |
14 | rb_test(
15 | name = "add",
16 | size = "small",
17 | timeout = "moderate", # JRuby startup can be slow
18 | srcs = ["add_spec.rb"],
19 | args = ["spec/add_spec.rb"],
20 | main = "@bundle//bin:rspec",
21 | deps = [":spec_helper"],
22 | )
23 |
24 | rb_library(
25 | name = "env_spec",
26 | srcs = ["env_spec.rb"],
27 | )
28 |
29 | rb_test(
30 | name = "env",
31 | size = "small",
32 | timeout = "moderate", # JRuby startup can be slow
33 | srcs = [":env_spec"],
34 | args = ["spec/env_spec.rb"],
35 | data = ["//spec/support:file"],
36 | env = {
37 | "EXAMPLE": "ENV",
38 | "LOCATION_SRC": "$(location :env_spec)",
39 | "LOCATION_DEP": "$(location //lib/gem:add)",
40 | "LOCATION_DATA": "$(location //spec/support:file)",
41 | } | select({
42 | "@ruby//engine:jruby": {"RUBY_ENGINE": "jruby"},
43 | "@ruby//engine:truffleruby": {"RUBY_ENGINE": "truffleruby"},
44 | "//conditions:default": {"RUBY_ENGINE": "ruby"},
45 | }),
46 | env_inherit = [
47 | "USER", # POSIX
48 | "USERNAME", # Windows
49 | ],
50 | main = "@bundle//bin:rspec",
51 | deps = [
52 | ":spec_helper",
53 | "//lib/gem:add",
54 | ],
55 | )
56 |
57 | rb_test(
58 | name = "support",
59 | size = "small",
60 | timeout = "moderate", # JRuby startup can be slow
61 | srcs = ["support_spec.rb"],
62 | args = ["spec/support_spec.rb"],
63 | data = ["//spec/support:file"],
64 | main = "@bundle//bin:rspec",
65 | deps = [":spec_helper"],
66 | )
67 |
68 | rb_test(
69 | name = "subtract",
70 | size = "small",
71 | timeout = "moderate", # JRuby startup can be slow
72 | srcs = ["subtract_spec.rb"],
73 | args = ["spec/subtract_spec.rb"],
74 | main = "@bundle//bin:rspec",
75 | deps = [":spec_helper"],
76 | )
77 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/app/controllers/people_controller.rb:
--------------------------------------------------------------------------------
1 | class PeopleController < ApplicationController
2 | before_action :set_person, only: %i[show edit update destroy]
3 |
4 | # GET /people or /people.json
5 | def index
6 | @people = Person.all
7 | end
8 |
9 | # GET /people/1 or /people/1.json
10 | def show
11 | end
12 |
13 | # GET /people/new
14 | def new
15 | @person = Person.new
16 | end
17 |
18 | # GET /people/1/edit
19 | def edit
20 | end
21 |
22 | # POST /people or /people.json
23 | def create
24 | @person = Person.new(person_params)
25 |
26 | respond_to do |format|
27 | if @person.save
28 | format.html { redirect_to @person, notice: "Person was successfully created." }
29 | format.json { render :show, status: :created, location: @person }
30 | else
31 | format.html { render :new, status: :unprocessable_entity }
32 | format.json { render json: @person.errors, status: :unprocessable_entity }
33 | end
34 | end
35 | end
36 |
37 | # PATCH/PUT /people/1 or /people/1.json
38 | def update
39 | respond_to do |format|
40 | if @person.update(person_params)
41 | format.html { redirect_to @person, notice: "Person was successfully updated.", status: :see_other }
42 | format.json { render :show, status: :ok, location: @person }
43 | else
44 | format.html { render :edit, status: :unprocessable_entity }
45 | format.json { render json: @person.errors, status: :unprocessable_entity }
46 | end
47 | end
48 | end
49 |
50 | # DELETE /people/1 or /people/1.json
51 | def destroy
52 | @person.destroy!
53 |
54 | respond_to do |format|
55 | format.html { redirect_to people_path, notice: "Person was successfully destroyed.", status: :see_other }
56 | format.json { head :no_content }
57 | end
58 | end
59 |
60 | private
61 |
62 | # Use callbacks to share common setup or constraints between actions.
63 | def set_person
64 | @person = Person.find(params.expect(:id))
65 | end
66 |
67 | # Only allow a list of trusted parameters through.
68 | def person_params
69 | params.expect(person: [:first_name, :last_name])
70 | end
71 | end
72 |
--------------------------------------------------------------------------------
/ruby/private/binary/binary.sh.tpl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | {rlocation_function}
4 |
5 | warn() {
6 | if [[ "${#}" -gt 0 ]]; then
7 | echo >&2 "${@}"
8 | else
9 | cat >&2
10 | fi
11 | }
12 |
13 | # shellcheck disable=SC2120
14 | fail() {
15 | local cmd=(warn)
16 | if [[ "${#}" -gt 0 ]]; then
17 | cmd+=("${@}")
18 | fi
19 | "${cmd[@]}"
20 | exit 1
21 | }
22 |
23 | # Provide a realpath implementation for macOS.
24 | realpath() (
25 | OURPWD=$PWD
26 | cd "$(dirname "$1")"
27 | LINK=$(readlink "$(basename "$1")")
28 | while [ "$LINK" ]; do
29 | cd "$(dirname "$LINK")"
30 | LINK=$(readlink "$(basename "$1")")
31 | done
32 | REALPATH="$PWD/$(basename "$1")"
33 | cd "$OURPWD"
34 | echo "$REALPATH"
35 | )
36 |
37 | export RUNFILES_DIR="$(realpath "${RUNFILES_DIR:-$0.runfiles}")"
38 |
39 | # Find location of Ruby in runfiles.
40 | export PATH=$(dirname $(rlocation {ruby})):$PATH
41 |
42 | # Find location of JAVA_HOME in runfiles.
43 | if [ -n "{java_bin}" ]; then
44 | export JAVA_HOME=$(dirname $(dirname $(rlocation "{java_bin}")))
45 | fi
46 |
47 | # Bundler expects the $HOME directory to be writable and produces misleading
48 | # warnings if it isn't. This isn't the case in every situation (e.g. remote
49 | # execution) and Bazel recommends using $TEST_TMPDIR when it's available:
50 | # https://bazel.build/reference/test-encyclopedia#initial-conditions
51 | #
52 | # We set $HOME prior to setting environment variables from the target itself so
53 | # that users can override this behavior if they desire.
54 | if [ -n "${TEST_TMPDIR:-}" ]; then
55 | export HOME=$TEST_TMPDIR
56 | fi
57 |
58 | # Set environment variables.
59 | {env}
60 |
61 | # Find location of Bundle path in runfiles.
62 | if [ -n "{bundler_command}" ]; then
63 | export BUNDLE_GEMFILE=$(rlocation $BUNDLE_GEMFILE)
64 | export BUNDLE_PATH=$(rlocation $BUNDLE_PATH)
65 | fi
66 |
67 | if [ -n "{locate_binary_in_runfiles}" ]; then
68 | binary="$(rlocation "{binary}")" \
69 | || (fail "Failed to locate {binary} in the runfiles." \
70 | "Did you forget to add the binary to the deps?")
71 | else
72 | binary="{binary}"
73 | fi
74 |
75 | exec {bundler_command} {ruby_binary_name} $binary {args} "$@"
76 |
77 | # vim: ft=bash
78 |
--------------------------------------------------------------------------------
/examples/jekyll/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | addressable (2.8.6)
5 | public_suffix (>= 2.0.2, < 6.0)
6 | colorator (1.1.0)
7 | concurrent-ruby (1.2.3)
8 | em-websocket (0.5.3)
9 | eventmachine (>= 0.12.9)
10 | http_parser.rb (~> 0)
11 | eventmachine (1.2.7)
12 | ffi (1.16.3)
13 | forwardable-extended (2.6.0)
14 | http_parser.rb (0.8.0)
15 | i18n (1.14.1)
16 | concurrent-ruby (~> 1.0)
17 | jekyll (3.9.4)
18 | addressable (~> 2.4)
19 | colorator (~> 1.0)
20 | em-websocket (~> 0.5)
21 | i18n (>= 0.7, < 2)
22 | jekyll-sass-converter (~> 1.0)
23 | jekyll-watch (~> 2.0)
24 | kramdown (>= 1.17, < 3)
25 | liquid (~> 4.0)
26 | mercenary (~> 0.3.3)
27 | pathutil (~> 0.9)
28 | rouge (>= 1.7, < 4)
29 | safe_yaml (~> 1.0)
30 | jekyll-feed (0.17.0)
31 | jekyll (>= 3.7, < 5.0)
32 | jekyll-sass-converter (1.5.2)
33 | sass (~> 3.4)
34 | jekyll-seo-tag (2.8.0)
35 | jekyll (>= 3.8, < 5.0)
36 | jekyll-watch (2.2.1)
37 | listen (~> 3.0)
38 | kramdown (2.4.0)
39 | rexml
40 | kramdown-parser-gfm (1.1.0)
41 | kramdown (~> 2.0)
42 | liquid (4.0.4)
43 | listen (3.8.0)
44 | rb-fsevent (~> 0.10, >= 0.10.3)
45 | rb-inotify (~> 0.9, >= 0.9.10)
46 | mercenary (0.3.6)
47 | minima (2.5.1)
48 | jekyll (>= 3.5, < 5.0)
49 | jekyll-feed (~> 0.9)
50 | jekyll-seo-tag (~> 2.1)
51 | pathutil (0.16.2)
52 | forwardable-extended (~> 2.6)
53 | public_suffix (5.0.4)
54 | rb-fsevent (0.11.2)
55 | rb-inotify (0.10.1)
56 | ffi (~> 1.0)
57 | rexml (3.2.6)
58 | rouge (3.30.0)
59 | safe_yaml (1.0.5)
60 | sass (3.7.4)
61 | sass-listen (~> 4.0.0)
62 | sass-listen (4.0.0)
63 | rb-fsevent (~> 0.9, >= 0.9.4)
64 | rb-inotify (~> 0.9, >= 0.9.7)
65 | wdm (0.1.1)
66 | webrick (1.8.1)
67 |
68 | PLATFORMS
69 | arm64-darwin-23
70 | arm64-darwin-24
71 | x86_64-darwin-21
72 | x86_64-linux
73 |
74 | DEPENDENCIES
75 | http_parser.rb (~> 0.6.0)
76 | jekyll (~> 3.9.3)
77 | jekyll-feed (~> 0.6)
78 | kramdown-parser-gfm
79 | minima (~> 2.0)
80 | tzinfo (>= 1, < 3)
81 | tzinfo-data
82 | wdm (~> 0.1.0)
83 | webrick (~> 1.8)
84 |
85 | BUNDLED WITH
86 | 2.3.3
87 |
--------------------------------------------------------------------------------
/examples/deep_gem/MODULE.bazel:
--------------------------------------------------------------------------------
1 | bazel_dep(name = "rules_ruby", version = "0.0.0", dev_dependency = True)
2 | local_path_override(
3 | module_name = "rules_ruby",
4 | path = "../..",
5 | )
6 |
7 | ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby")
8 | ruby.toolchain(
9 | name = "ruby",
10 | version_file = "//:.ruby-version",
11 | )
12 | ruby.bundle_fetch(
13 | name = "bundle",
14 | # List the gemspec and any files that it requires. We cannot use an
15 | # rb_library to tidy this up because bundle fetch is executed during the
16 | # loading phase.
17 | srcs = [
18 | "//hello_world:hello_world.gemspec",
19 | "//hello_world/lib/hello_world:version.rb",
20 | ],
21 | gem_checksums = {
22 | "date-3.4.1-java": "74740d914c65a922a15657c25ff0e203c16f1d0f7aa910a9ebed712afe9819c4",
23 | "diff-lcs-1.6.2": "9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962",
24 | "erb-5.0.2-java": "d000d963afebc166ec7f2499b2b3198d526790cf962c37514d7a85843a60423c",
25 | "io-console-0.8.1-java": "9457a61a7b23aab11e9e9ff67f71ae81d7f1a6a2e582bb5d65d754cbb546c06f",
26 | "irb-1.15.2": "222f32952e278da34b58ffe45e8634bf4afc2dc7aa9da23fed67e581aa50fdba",
27 | "jar-dependencies-0.5.5": "2972b9fcba4b014e6446a84b5c09674a3e8648b95b71768e729f0e8e40568059",
28 | "pp-0.6.2": "947ec3120c6f92195f8ee8aa25a7b2c5297bb106d83b41baa02983686577b6ff",
29 | "prettyprint-0.2.0": "2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193",
30 | "psych-5.2.6-java": "0a5f65d47ed1ae3475d062b254e7b2035a259eac578038016d62172dd4cfbd91",
31 | "rdoc-6.14.2": "9fdd44df130f856ae70cc9a264dfd659b9b40de369b16581f4ab746e42439226",
32 | "reline-0.6.2": "1dad26a6008872d59c8e05244b119347c9f2ddaf4a53dce97856cd5f30a02846",
33 | "rspec-3.13.1": "b9f9a58fa915b8d94a1d6b3195fe6dd28c4c34836a6097015142c4a9ace72140",
34 | "rspec-core-3.13.5": "ab3f682897c6131c67f9a17cfee5022a597f283aebe654d329a565f9937a4fa3",
35 | "rspec-expectations-3.13.5": "33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836",
36 | "rspec-mocks-3.13.5": "e4338a6f285ada9fe56f5893f5457783af8194f5d08884d17a87321d5195ea81",
37 | "rspec-support-3.13.4": "184b1814f6a968102b57df631892c7f1990a91c9a3b9e80ef892a0fc2a71a3f7",
38 | },
39 | gemfile = "//hello_world:Gemfile",
40 | gemfile_lock = "//hello_world:Gemfile.lock",
41 | )
42 | use_repo(ruby, "bundle", "ruby", "ruby_toolchains")
43 |
44 | register_toolchains("@ruby_toolchains//:all")
45 |
--------------------------------------------------------------------------------
/.github/workflows/release_prep.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -o errexit -o nounset -o pipefail
4 |
5 | # Set by GH actions, see
6 | # https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables
7 | TAG=${GITHUB_REF_NAME}
8 | # The prefix is chosen to match what GitHub generates for source archives
9 | PREFIX="rules_ruby-${TAG:1}"
10 | ARCHIVE="rules_ruby-$TAG.tar.gz"
11 |
12 | # NB: configuration for 'git archive' is in /.gitattributes
13 | git archive --format=tar --prefix=${PREFIX}/ ${TAG} | gzip > $ARCHIVE
14 | SHA=$(shasum -a 256 $ARCHIVE | awk '{print $1}')
15 |
16 | # Add generated API docs to the release, see https://github.com/bazelbuild/bazel-central-registry/issues/5593
17 | docs="$(mktemp -d)"; targets="$(mktemp)"
18 | bazel --output_base="$docs" query --output=label --output_file="$targets" 'kind("starlark_doc_extract rule", //rails:all //ruby:all)'
19 | bazel --output_base="$docs" build --target_pattern_file="$targets"
20 | tar --create --auto-compress \
21 | --directory "$(bazel --output_base="$docs" info bazel-bin)" \
22 | --file "$GITHUB_WORKSPACE/${ARCHIVE%.tar.gz}.docs.tar.gz" .
23 |
24 | # The stdout of this program will be used as the top of the release notes for this release.
25 | cat << EOF
26 | ## Using Bzlmod with Bazel 7-8
27 |
28 | 1. Add to your \`MODULE.bazel\` file:
29 |
30 | \`\`\`starlark
31 | bazel_dep(name = "rules_ruby", version = "${TAG:1}")
32 | \`\`\`
33 |
34 | ## Using Bzlmod with Bazel 6
35 |
36 | 1. Enable with \`common --enable_bzlmod\` in \`.bazelrc\`.
37 | 2. Add to your \`MODULE.bazel\` file:
38 |
39 | \`\`\`starlark
40 | bazel_dep(name = "rules_ruby", version = "${TAG:1}")
41 | \`\`\`
42 |
43 | ## Using WORKSPACE
44 |
45 | Paste this snippet into your \`WORKSPACE.bazel\` file:
46 |
47 | \`\`\`starlark
48 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
49 |
50 | # Skylib is a dependency, remove if you already have it.
51 | http_archive(
52 | name = "bazel_skylib",
53 | sha256 = "74d544d96f4a5bb630d465ca8bbcfe231e3594e5aae57e1edbf17a6eb3ca2506",
54 | urls = [
55 | "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz",
56 | "https://github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz",
57 | ],
58 | )
59 |
60 | http_archive(
61 | name = "rules_ruby",
62 | sha256 = "${SHA}",
63 | strip_prefix = "${PREFIX}",
64 | url = "https://github.com/bazel-contrib/rules_ruby/releases/download/${TAG}/${ARCHIVE}",
65 | )
66 | \`\`\`
67 | EOF
68 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/Dockerfile:
--------------------------------------------------------------------------------
1 | # syntax=docker/dockerfile:1
2 | # check=error=true
3 |
4 | # This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand:
5 | # docker build -t people_tracker .
6 | # docker run -d -p 80:80 -e RAILS_MASTER_KEY= --name people_tracker people_tracker
7 |
8 | # For a containerized dev environment, see Dev Containers: https://guides.rubyonrails.org/getting_started_with_devcontainer.html
9 |
10 | # Make sure RUBY_VERSION matches the Ruby version in .ruby-version
11 | ARG RUBY_VERSION=3.4.5
12 | FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base
13 |
14 | # Rails app lives here
15 | WORKDIR /rails
16 |
17 | # Install base packages
18 | RUN apt-get update -qq && \
19 | apt-get install --no-install-recommends -y curl libjemalloc2 libvips sqlite3 && \
20 | rm -rf /var/lib/apt/lists /var/cache/apt/archives
21 |
22 | # Set production environment
23 | ENV RAILS_ENV="production" \
24 | BUNDLE_DEPLOYMENT="1" \
25 | BUNDLE_PATH="/usr/local/bundle" \
26 | BUNDLE_WITHOUT="development"
27 |
28 | # Throw-away build stage to reduce size of final image
29 | FROM base AS build
30 |
31 | # Install packages needed to build gems
32 | RUN apt-get update -qq && \
33 | apt-get install --no-install-recommends -y build-essential git libyaml-dev pkg-config && \
34 | rm -rf /var/lib/apt/lists /var/cache/apt/archives
35 |
36 | # Install application gems
37 | COPY Gemfile Gemfile.lock ./
38 | RUN bundle install && \
39 | rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
40 | bundle exec bootsnap precompile --gemfile
41 |
42 | # Copy application code
43 | COPY . .
44 |
45 | # Precompile bootsnap code for faster boot times
46 | RUN bundle exec bootsnap precompile app/ lib/
47 |
48 | # Precompiling assets for production without requiring secret RAILS_MASTER_KEY
49 | RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile
50 |
51 |
52 |
53 |
54 | # Final stage for app image
55 | FROM base
56 |
57 | # Copy built artifacts: gems, application
58 | COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
59 | COPY --from=build /rails /rails
60 |
61 | # Run and own only the runtime files as a non-root user for security
62 | RUN groupadd --system --gid 1000 rails && \
63 | useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
64 | chown -R rails:rails db log storage tmp
65 | USER 1000:1000
66 |
67 | # Entrypoint prepares the database.
68 | ENTRYPOINT ["/rails/bin/docker-entrypoint"]
69 |
70 | # Start server via Thruster by default, this can be overwritten at runtime
71 | EXPOSE 80
72 | CMD ["./bin/thrust", "./bin/rails", "server"]
73 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | # The test environment is used exclusively to run your application's
2 | # test suite. You never need to work with it otherwise. Remember that
3 | # your test database is "scratch space" for the test suite and is wiped
4 | # and recreated between test runs. Don't rely on the data there!
5 |
6 | Rails.application.configure do
7 | # Settings specified here will take precedence over those in config/application.rb.
8 |
9 | # While tests run files are not watched, reloading is not necessary.
10 | config.enable_reloading = false
11 |
12 | # Eager loading loads your entire application. When running a single test locally,
13 | # this is usually not necessary, and can slow down your test suite. However, it's
14 | # recommended that you enable it in continuous integration systems to ensure eager
15 | # loading is working properly before deploying your code.
16 | config.eager_load = ENV["CI"].present?
17 |
18 | # Configure public file server for tests with cache-control for performance.
19 | config.public_file_server.headers = {"cache-control" => "public, max-age=3600"}
20 |
21 | # Show full error reports.
22 | config.consider_all_requests_local = true
23 | config.cache_store = :null_store
24 |
25 | # Render exception templates for rescuable exceptions and raise for other exceptions.
26 | config.action_dispatch.show_exceptions = :rescuable
27 |
28 | # Disable request forgery protection in test environment.
29 | config.action_controller.allow_forgery_protection = false
30 |
31 | # Store uploaded files on the local file system in a temporary directory.
32 | config.active_storage.service = :test
33 |
34 | # Tell Action Mailer not to deliver emails to the real world.
35 | # The :test delivery method accumulates sent emails in the
36 | # ActionMailer::Base.deliveries array.
37 | config.action_mailer.delivery_method = :test
38 |
39 | # Set host to be used by links generated in mailer templates.
40 | config.action_mailer.default_url_options = {host: "example.com"}
41 |
42 | # Print deprecation notices to the stderr.
43 | config.active_support.deprecation = :stderr
44 |
45 | # Configure logging to stderr for Bazel sandboxed environment
46 | config.logger = ActiveSupport::Logger.new($stderr)
47 | config.log_level = :warn
48 |
49 | # Raises error for missing translations.
50 | # config.i18n.raise_on_missing_translations = true
51 |
52 | # Annotate rendered view with file names.
53 | # config.action_view.annotate_rendered_view_with_filenames = true
54 |
55 | # Raise error when a before_action's only/except options reference missing actions.
56 | config.action_controller.raise_on_missing_callback_actions = true
57 | end
58 |
--------------------------------------------------------------------------------
/examples/gem/Gemfile.lock:
--------------------------------------------------------------------------------
1 | PATH
2 | remote: .
3 | specs:
4 | example (0.1.0)
5 | i18n (~> 1.14)
6 | rake (~> 13)
7 |
8 | GEM
9 | remote: https://rubygems.org/
10 | specs:
11 | ast (2.4.2)
12 | concurrent-ruby (1.3.5)
13 | date (3.4.1)
14 | date (3.4.1-java)
15 | debug (1.10.0)
16 | irb (~> 1.10)
17 | reline (>= 0.3.8)
18 | diff-lcs (1.5.1)
19 | i18n (1.14.7)
20 | concurrent-ruby (~> 1.0)
21 | io-console (0.8.0)
22 | io-console (0.8.0-java)
23 | irb (1.15.1)
24 | pp (>= 0.6.0)
25 | rdoc (>= 4.0.0)
26 | reline (>= 0.4.2)
27 | jar-dependencies (0.5.3)
28 | json (2.9.1)
29 | json (2.9.1-java)
30 | language_server-protocol (3.17.0.3)
31 | parallel (1.26.3)
32 | parser (3.3.7.0)
33 | ast (~> 2.4.1)
34 | racc
35 | pp (0.6.2)
36 | prettyprint
37 | prettyprint (0.2.0)
38 | psych (5.2.3)
39 | date
40 | stringio
41 | psych (5.2.3-java)
42 | date
43 | jar-dependencies (>= 0.1.7)
44 | racc (1.8.1)
45 | racc (1.8.1-java)
46 | rainbow (3.1.1)
47 | rake (13.2.1)
48 | rdoc (6.11.0)
49 | psych (>= 4.0.0)
50 | regexp_parser (2.10.0)
51 | reline (0.6.0)
52 | io-console (~> 0.5)
53 | rspec (3.13.0)
54 | rspec-core (~> 3.13.0)
55 | rspec-expectations (~> 3.13.0)
56 | rspec-mocks (~> 3.13.0)
57 | rspec-core (3.13.2)
58 | rspec-support (~> 3.13.0)
59 | rspec-expectations (3.13.3)
60 | diff-lcs (>= 1.2.0, < 2.0)
61 | rspec-support (~> 3.13.0)
62 | rspec-mocks (3.13.2)
63 | diff-lcs (>= 1.2.0, < 2.0)
64 | rspec-support (~> 3.13.0)
65 | rspec-support (3.13.2)
66 | rubocop (1.71.0)
67 | json (~> 2.3)
68 | language_server-protocol (>= 3.17.0)
69 | parallel (~> 1.10)
70 | parser (>= 3.3.0.2)
71 | rainbow (>= 2.2.2, < 4.0)
72 | regexp_parser (>= 2.9.3, < 3.0)
73 | rubocop-ast (>= 1.36.2, < 2.0)
74 | ruby-progressbar (~> 1.7)
75 | unicode-display_width (>= 2.4.0, < 4.0)
76 | rubocop-ast (1.37.0)
77 | parser (>= 3.3.1.0)
78 | ruby-progressbar (1.13.0)
79 | stringio (3.1.2)
80 | unicode-display_width (3.1.4)
81 | unicode-emoji (~> 4.0, >= 4.0.4)
82 | unicode-emoji (4.0.4)
83 |
84 | PLATFORMS
85 | arm64-darwin-23
86 | arm64-darwin-24
87 | java
88 | ruby
89 | universal-java-1.8
90 | universal-java-11
91 | universal-java-17
92 | universal-java-18
93 | universal-java-21
94 | x64-mingw32
95 |
96 | DEPENDENCIES
97 | debug (>= 1.0.0)
98 | example!
99 | psych (~> 5.1)
100 | rspec (~> 3.0)
101 | rubocop (~> 1.64)
102 |
103 | BUNDLED WITH
104 | 2.3.3
105 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
4 | gem "rails", "~> 8.0.2", ">= 8.0.2.1"
5 | # The modern asset pipeline for Rails [https://github.com/rails/propshaft]
6 | gem "propshaft"
7 | # Use sqlite3 as the database for Active Record
8 | gem "sqlite3", ">= 2.1"
9 | # Use the Puma web server [https://github.com/puma/puma]
10 | gem "puma", ">= 5.0"
11 | # Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails]
12 | gem "importmap-rails"
13 | # Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev]
14 | gem "turbo-rails"
15 | # Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev]
16 | gem "stimulus-rails"
17 | # Use Tailwind CSS [https://github.com/rails/tailwindcss-rails]
18 | gem "tailwindcss-rails"
19 | # Build JSON APIs with ease [https://github.com/rails/jbuilder]
20 | gem "jbuilder"
21 |
22 | # Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword]
23 | # gem "bcrypt", "~> 3.1.7"
24 |
25 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
26 | gem "tzinfo-data", platforms: %i[ windows jruby ]
27 |
28 | # Use the database-backed adapters for Rails.cache, Active Job, and Action Cable
29 | gem "solid_cache"
30 | gem "solid_queue"
31 | gem "solid_cable"
32 |
33 | # Reduces boot times through caching; required in config/boot.rb
34 | gem "bootsnap", require: false
35 |
36 | # Deploy this application anywhere as a Docker container [https://kamal-deploy.org]
37 | gem "kamal", require: false
38 |
39 | # Add HTTP asset caching/compression and X-Sendfile acceleration to Puma [https://github.com/basecamp/thruster/]
40 | gem "thruster", require: false
41 |
42 | # Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
43 | # gem "image_processing", "~> 1.2"
44 |
45 | group :development, :test do
46 | # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
47 | gem "debug", platforms: %i[ mri windows ], require: "debug/prelude"
48 |
49 | # Static analysis for security vulnerabilities [https://brakemanscanner.org/]
50 | gem "brakeman", require: false
51 |
52 | # Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/]
53 | gem "rubocop-rails-omakase", require: false
54 | end
55 |
56 | group :development do
57 | # Use console on exceptions pages [https://github.com/rails/web-console]
58 | gem "web-console"
59 | end
60 |
61 | group :test do
62 | # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
63 | gem "capybara"
64 | gem "selenium-webdriver"
65 | end
66 |
67 | gem "cancancan", "~> 3.6"
68 |
69 | gem "devise", "~> 4.9"
70 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | require "active_support/core_ext/integer/time"
2 |
3 | Rails.application.configure do
4 | # Settings specified here will take precedence over those in config/application.rb.
5 |
6 | # Make code changes take effect immediately without server restart.
7 | config.enable_reloading = true
8 |
9 | # Do not eager load code on boot.
10 | config.eager_load = false
11 |
12 | # Show full error reports.
13 | config.consider_all_requests_local = true
14 |
15 | # Enable server timing.
16 | config.server_timing = true
17 |
18 | # Enable/disable Action Controller caching. By default Action Controller caching is disabled.
19 | # Run rails dev:cache to toggle Action Controller caching.
20 | if Rails.root.join("tmp/caching-dev.txt").exist?
21 | config.action_controller.perform_caching = true
22 | config.action_controller.enable_fragment_cache_logging = true
23 | config.public_file_server.headers = { "cache-control" => "public, max-age=#{2.days.to_i}" }
24 | else
25 | config.action_controller.perform_caching = false
26 | end
27 |
28 | # Change to :null_store to avoid any caching.
29 | config.cache_store = :memory_store
30 |
31 | # Store uploaded files on the local file system (see config/storage.yml for options).
32 | config.active_storage.service = :local
33 |
34 | # Don't care if the mailer can't send.
35 | config.action_mailer.raise_delivery_errors = false
36 |
37 | # Make template changes take effect immediately.
38 | config.action_mailer.perform_caching = false
39 |
40 | # Set localhost to be used by links generated in mailer templates.
41 | config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
42 |
43 | # Print deprecation notices to the Rails logger.
44 | config.active_support.deprecation = :log
45 |
46 | # Raise an error on page load if there are pending migrations.
47 | config.active_record.migration_error = :page_load
48 |
49 | # Highlight code that triggered database queries in logs.
50 | config.active_record.verbose_query_logs = true
51 |
52 | # Append comments with runtime information tags to SQL queries in logs.
53 | config.active_record.query_log_tags_enabled = true
54 |
55 | # Highlight code that enqueued background job in logs.
56 | config.active_job.verbose_enqueue_logs = true
57 |
58 | # Raises error for missing translations.
59 | # config.i18n.raise_on_missing_translations = true
60 |
61 | # Annotate rendered view with file names.
62 | config.action_view.annotate_rendered_view_with_filenames = true
63 |
64 | # Uncomment if you wish to allow Action Cable access from any origin.
65 | # config.action_cable.disable_request_forgery_protection = true
66 |
67 | # Raise error when a before_action's only/except options reference missing actions.
68 | config.action_controller.raise_on_missing_callback_actions = true
69 |
70 | # Apply autocorrection by RuboCop to files generated by `bin/rails generate`.
71 | # config.generators.apply_rubocop_autocorrect_after_generate!
72 | end
73 |
--------------------------------------------------------------------------------
/ruby/private/BUILD:
--------------------------------------------------------------------------------
1 | load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
2 |
3 | bzl_library(
4 | name = "binary",
5 | srcs = ["binary.bzl"],
6 | visibility = ["//ruby:__subpackages__"],
7 | deps = [
8 | ":library",
9 | ":providers",
10 | ":utils",
11 | ],
12 | )
13 |
14 | bzl_library(
15 | name = "gem_build",
16 | srcs = ["gem_build.bzl"],
17 | visibility = ["//ruby:__subpackages__"],
18 | deps = [
19 | ":library",
20 | ":providers",
21 | ":utils",
22 | ],
23 | )
24 |
25 | bzl_library(
26 | name = "gem_push",
27 | srcs = ["gem_push.bzl"],
28 | visibility = ["//ruby:__subpackages__"],
29 | deps = [
30 | ":binary",
31 | ":library",
32 | ],
33 | )
34 |
35 | bzl_library(
36 | name = "library",
37 | srcs = ["library.bzl"],
38 | visibility = ["//ruby:__subpackages__"],
39 | deps = [":providers"],
40 | )
41 |
42 | bzl_library(
43 | name = "test",
44 | srcs = ["test.bzl"],
45 | visibility = ["//ruby:__subpackages__"],
46 | deps = [
47 | ":binary",
48 | ":library",
49 | ],
50 | )
51 |
52 | bzl_library(
53 | name = "toolchain",
54 | srcs = ["toolchain.bzl"],
55 | visibility = ["//ruby:__subpackages__"],
56 | deps = [
57 | ":download",
58 | "//ruby/private/toolchain:repository_proxy",
59 | ],
60 | )
61 |
62 | bzl_library(
63 | name = "bundler_checksums",
64 | srcs = ["bundler_checksums.bzl"],
65 | visibility = ["//ruby:__subpackages__"],
66 | )
67 |
68 | bzl_library(
69 | name = "bundle_fetch",
70 | srcs = ["bundle_fetch.bzl"],
71 | visibility = ["//ruby:__subpackages__"],
72 | deps = [
73 | ":bundler_checksums",
74 | ":utils",
75 | "//ruby/private/bundle_fetch:gemfile_lock_parser",
76 | "@bazel_skylib//lib:paths",
77 | "@bazel_skylib//lib:versions",
78 | "@bazel_tools//tools/build_defs/repo:utils.bzl",
79 | ],
80 | )
81 |
82 | bzl_library(
83 | name = "bundle_install",
84 | srcs = ["bundle_install.bzl"],
85 | visibility = ["//ruby:__subpackages__"],
86 | deps = [
87 | ":bundle_fetch",
88 | ":gem_install",
89 | ":providers",
90 | ":utils",
91 | ],
92 | )
93 |
94 | bzl_library(
95 | name = "gem",
96 | srcs = ["gem.bzl"],
97 | visibility = ["//ruby:__subpackages__"],
98 | deps = [":providers"],
99 | )
100 |
101 | bzl_library(
102 | name = "gem_install",
103 | srcs = ["gem_install.bzl"],
104 | visibility = ["//ruby:__subpackages__"],
105 | deps = [
106 | ":providers",
107 | ":utils",
108 | ],
109 | )
110 |
111 | bzl_library(
112 | name = "bundle",
113 | srcs = ["bundle.bzl"],
114 | visibility = ["//ruby:__subpackages__"],
115 | )
116 |
117 | bzl_library(
118 | name = "download",
119 | srcs = ["download.bzl"],
120 | visibility = ["//ruby:__subpackages__"],
121 | )
122 |
123 | bzl_library(
124 | name = "providers",
125 | srcs = ["providers.bzl"],
126 | visibility = ["//ruby:__subpackages__"],
127 | )
128 |
129 | bzl_library(
130 | name = "utils",
131 | srcs = ["utils.bzl"],
132 | visibility = ["//ruby:__subpackages__"],
133 | )
134 |
--------------------------------------------------------------------------------
/examples/rails/README.md:
--------------------------------------------------------------------------------
1 | # Rails Example
2 |
3 | This example demonstrates how to use Bazel and rules_ruby to build and test a
4 | Ruby on Rails application. The actual Rails application lives under the
5 | `people_tracker` directory.
6 |
7 | ## Development Workflow
8 |
9 | ### Bazel Testing
10 |
11 | ```bash
12 | bazel test //...
13 | ```
14 |
15 | ### Direnv Setup
16 |
17 | This project uses [direnv](https://direnv.net/) to provide access to `rails`
18 | and other related binaries on the command-line. Make sure you have direnv
19 | installed and allow the `.envrc` file:
20 |
21 | ```bash
22 | direnv allow
23 | ```
24 |
25 | #### Rails Command
26 |
27 | Once direnv is configured, change into the `people_tracker/` directory and run
28 | `rails` commands directly for development tasks instead of using
29 | `people_tracker/bin/rails`:
30 |
31 | ```bash
32 | cd people_tracker/
33 | rails test
34 | rails generate scaffold Foo
35 | rails server
36 | ```
37 |
38 | The `rails` command will automatically use the Ruby gems installed by Bazel,
39 | so there is no need to run `bundle install` separately.
40 |
41 | ## Implementation Notes
42 |
43 | ### Rails Test Setup
44 |
45 | To run Rails tests with Bazel, you need to create test macros that configure the
46 | Rails test environment. Create a file at `people_tracker/test/rails_test.bzl`:
47 |
48 | ```starlark
49 | """Module for app-specific rails helpers and macros."""
50 |
51 | load("@rules_ruby//rails:rails_test_factory.bzl", "rails_test_factory")
52 |
53 | # This is the directory in the Bazel workspace where the test helpers reside.
54 | # This is used to generate the test helper labels and appropriate includes.
55 | _TEST_PKG = "people_tracker/test"
56 |
57 | # The rails_test macro is used to define Bazel test targets for Rails model and
58 | # controller tests. See examples in people_tracker/test/models/BUILD.bazel.
59 | rails_test = rails_test_factory.new_test(test_package = _TEST_PKG)
60 |
61 | # The rails_system_test macro is used to define Bazel test targets for Rails
62 | # system tests. See examples in people_tracker/test/system/BUILD.bazel.
63 | rails_system_test = rails_test_factory.new_system_test(test_package = _TEST_PKG)
64 | ```
65 |
66 | These macros (`rails_test` and `rails_system_test`) can then be used in your
67 | `BUILD.bazel` files to define test targets for your Rails application.
68 |
69 | The tests are configured to use a SQLite in-memory database for fast, isolated
70 | test execution.
71 |
72 | ### Patches
73 |
74 | To prevent Ruby from escaping the sandbox, Ruby requires patches to `Kernel`
75 | functions. This example implements the patches to
76 | `people_tracker/config/initializers/bazel_ruby_patches.rb`. Being included in
77 | the `config/initializers` directory for a Rails app ensures that it is applied
78 | early in the Rails load process. However, we need to apply it earlier in the
79 | load process for tests. So, we add it to the top of the
80 | `people_tracker/test/test_helper.rb`.
81 |
82 | ### Direnv - Using rails from the command-line
83 |
84 | If you install [direnv](https://direnv.net/) and allow it to load the
85 | environment defined in the `.envrc` files, you can run `rails` commands using
86 | the Ruby and Rails installed by Bazel. The `rails` command will automatically
87 | use the Ruby gems installed by Bazel, so there is no need to run `bundle
88 | install` separately.
89 |
--------------------------------------------------------------------------------
/ruby/private/toolchain.bzl:
--------------------------------------------------------------------------------
1 | "Repository rule for registering Ruby interpreters"
2 |
3 | load("//ruby/private:download.bzl", _rb_download = "rb_download")
4 | load("//ruby/private/toolchain:repository_proxy.bzl", _rb_toolchain_repository_proxy = "rb_toolchain_repository_proxy")
5 |
6 | DEFAULT_RUBY_REPOSITORY = "ruby"
7 |
8 | def rb_register_toolchains(
9 | name = DEFAULT_RUBY_REPOSITORY,
10 | version = None,
11 | version_file = None,
12 | msys2_packages = ["libyaml"],
13 | register = True,
14 | **kwargs):
15 | """
16 | Register a Ruby toolchain and lazily download the Ruby Interpreter.
17 |
18 | * _(For MRI on Linux and macOS)_ Installed using [ruby-build](https://github.com/rbenv/ruby-build).
19 | * _(For MRI on Windows)_ Installed using [RubyInstaller](https://rubyinstaller.org).
20 | * _(For JRuby on any OS)_ Downloaded and installed directly from [official website](https://www.jruby.org).
21 | * _(For TruffleRuby on Linux and macOS)_ Installed using [ruby-build](https://github.com/rbenv/ruby-build).
22 | * _(For "system")_ Ruby found on the PATH is used. Please note that builds are not hermetic in this case.
23 |
24 | `WORKSPACE`:
25 | ```bazel
26 | load("@rules_ruby//ruby:deps.bzl", "rb_register_toolchains")
27 |
28 | rb_register_toolchains(
29 | version = "3.0.6"
30 | )
31 | ```
32 |
33 | Once registered, you can use the toolchain directly as it provides all the binaries:
34 |
35 | ```output
36 | $ bazel run @ruby -- -e "puts RUBY_VERSION"
37 | $ bazel run @ruby//:bundle -- update
38 | $ bazel run @ruby//:gem -- install rails
39 | ```
40 |
41 | You can also use Ruby engine targets to `select()` depending on installed Ruby interpreter:
42 |
43 | `BUILD`:
44 | ```bazel
45 | rb_library(
46 | name = "my_lib",
47 | srcs = ["my_lib.rb"],
48 | deps = select({
49 | "@ruby//engine:jruby": [":my_jruby_lib"],
50 | "@ruby//engine:truffleruby": ["//:my_truffleruby_lib"],
51 | "@ruby//engine:ruby": ["//:my__lib"],
52 | "//conditions:default": [],
53 | }),
54 | )
55 | ```
56 |
57 | Args:
58 | name: base name of resulting repositories, by default "ruby"
59 | version: a semver version of MRI, or a string like [interpreter type]-[version], or "system"
60 | version_file: .ruby-version or .tool-versions file to read version from
61 | msys2_packages: extra MSYS2 packages to install
62 | register: whether to register the resulting toolchains, should be False under bzlmod
63 | **kwargs: additional parameters to the downloader for this interpreter type
64 | """
65 | proxy_repo_name = name + "_toolchains"
66 | if name not in native.existing_rules().values():
67 | _rb_download(
68 | name = name,
69 | version = version,
70 | version_file = version_file,
71 | msys2_packages = msys2_packages,
72 | **kwargs
73 | )
74 | _rb_toolchain_repository_proxy(
75 | name = proxy_repo_name,
76 | toolchain = "@{}//:toolchain".format(name),
77 | toolchain_type = "@rules_ruby//ruby:toolchain_type",
78 | )
79 | if register:
80 | native.register_toolchains("@{}//:all".format(proxy_repo_name))
81 |
--------------------------------------------------------------------------------
/ruby/private/gem_push.bzl:
--------------------------------------------------------------------------------
1 | "Implementation details for rb_gem_push"
2 |
3 | load("//ruby/private:binary.bzl", "generate_rb_binary_script", BINARY_ATTRS = "ATTRS")
4 | load("//ruby/private:library.bzl", LIBRARY_ATTRS = "ATTRS")
5 |
6 | def _rb_gem_push_impl(ctx):
7 | env = {}
8 | java_toolchain = ctx.toolchains["@bazel_tools//tools/jdk:runtime_toolchain_type"]
9 | ruby_toolchain = ctx.toolchains["@rules_ruby//ruby:toolchain_type"]
10 | if ctx.attr.ruby != None:
11 | ruby_toolchain = ctx.attr.ruby[platform_common.ToolchainInfo]
12 | srcs = [ctx.file.gem]
13 | tools = [ruby_toolchain.gem]
14 |
15 | if ruby_toolchain.version.startswith("jruby"):
16 | env["JAVA_HOME"] = java_toolchain.java_runtime.java_home
17 | tools.extend(java_toolchain.java_runtime.files.to_list())
18 |
19 | script = generate_rb_binary_script(
20 | ctx,
21 | binary = ruby_toolchain.gem,
22 | bundler = False,
23 | args = ["push", ctx.file.gem.short_path],
24 | )
25 |
26 | runfiles = ctx.runfiles(srcs + tools)
27 | runfiles = runfiles.merge(ctx.attr._runfiles_library[DefaultInfo].default_runfiles)
28 | env.update(ctx.attr.env)
29 |
30 | return [
31 | DefaultInfo(
32 | executable = script,
33 | runfiles = runfiles,
34 | ),
35 | RunEnvironmentInfo(
36 | environment = env,
37 | inherited_environment = ctx.attr.env_inherit,
38 | ),
39 | ]
40 |
41 | rb_gem_push = rule(
42 | _rb_gem_push_impl,
43 | executable = True,
44 | attrs = dict(
45 | LIBRARY_ATTRS,
46 | gem = attr.label(
47 | allow_single_file = [".gem"],
48 | mandatory = True,
49 | doc = """
50 | Gem file to push to RubyGems. You would usually use an output of `rb_gem_build()` target here.
51 | """,
52 | ),
53 | env = BINARY_ATTRS["env"],
54 | env_inherit = BINARY_ATTRS["env_inherit"],
55 | ruby = BINARY_ATTRS["ruby"],
56 | _binary_cmd_tpl = BINARY_ATTRS["_binary_cmd_tpl"],
57 | _binary_sh_tpl = BINARY_ATTRS["_binary_sh_tpl"],
58 | _windows_constraint = BINARY_ATTRS["_windows_constraint"],
59 | _runfiles_library = BINARY_ATTRS["_runfiles_library"],
60 | ),
61 | toolchains = [
62 | "@rules_ruby//ruby:toolchain_type",
63 | "@bazel_tools//tools/jdk:runtime_toolchain_type",
64 | ],
65 | doc = """
66 | Pushes a built Ruby gem.
67 |
68 | Suppose you have the following Ruby gem, where `rb_library()` is used
69 | in `BUILD` files to define the packages for the gem and `rb_gem_build()` is used
70 | to build a Ruby gem package from the sources.
71 |
72 | ```output
73 | |-- BUILD
74 | |-- Gemfile
75 | |-- WORKSPACE
76 | |-- gem.gemspec
77 | `-- lib
78 | |-- BUILD
79 | |-- gem
80 | | |-- BUILD
81 | | |-- add.rb
82 | | |-- subtract.rb
83 | | `-- version.rb
84 | `-- gem.rb
85 | ```
86 |
87 | You can now release the built `.gem` file to RubyGems by defining a target:
88 |
89 | `BUILD`:
90 | ```bazel
91 | load("@rules_ruby//ruby:defs.bzl", "rb_gem_build", "rb_gem_push")
92 |
93 | package(default_visibility = ["//:__subpackages__"])
94 |
95 | rb_gem_build(
96 | name = "gem-build",
97 | gemspec = "gem.gemspec",
98 | deps = ["//lib:gem"],
99 | )
100 |
101 | rb_gem_push(
102 | name = "gem-release",
103 | gem = ":gem-build",
104 | )
105 | ```
106 |
107 | ```output
108 | $ bazel run :gem-release
109 | ...
110 | Pushing gem to https://rubygems.org...
111 | Successfully registered gem: example (0.1.0)
112 | ```
113 | """,
114 | )
115 |
--------------------------------------------------------------------------------
/examples/deep_gem/README.md:
--------------------------------------------------------------------------------
1 | # Deep Gem Example
2 |
3 | This example demonstrates how to define a Ruby gem that does not reside at the root of the
4 | Bazel workspace and how to reference files using standard Bazel package notation in the
5 | `MODULE.bazel` file.
6 |
7 | ## Overview
8 |
9 | Unlike typical Ruby gems that live at the workspace root, this example shows how to
10 | structure a gem in a subdirectory (`hello_world/`) while still being able to reference its
11 | files using Bazel's standard package notation.
12 |
13 | ## Key Features
14 |
15 | - **Non-root gem location**: The gem is located in `hello_world/` subdirectory, not at the
16 | workspace root
17 | - **Standard Bazel package notation**: Files are referenced using standard Bazel labels like
18 | `//hello_world/lib/hello_world:version.rb`
19 | - **Proper dependency management**: Demonstrates how to configure `bundle_fetch` with deep
20 | gem structure
21 |
22 | ## Project Structure
23 |
24 | ```
25 | examples/deep_gem/
26 | ├── MODULE.bazel # Workspace configuration with deep gem references
27 | ├── hello_world/ # Gem directory (not at root)
28 | │ ├── hello_world.gemspec
29 | │ ├── Gemfile
30 | │ ├── Gemfile.lock
31 | │ ├── lib/
32 | │ │ ├── hello_world.rb
33 | │ │ └── hello_world/
34 | │ │ ├── speaker.rb
35 | │ │ └── version.rb # Referenced as //hello_world/lib/hello_world:version.rb
36 | │ └── spec/
37 | │ ├── BUILD.bazel
38 | │ ├── hello_world_spec.rb
39 | │ ├── speaker_spec.rb
40 | │ └── spec_helper.rb
41 | ```
42 |
43 | ## Bazel Package Notation
44 |
45 | The key insight of this example is how to reference gem files using standard Bazel package
46 | notation in `MODULE.bazel`:
47 |
48 | ```starlark
49 | ruby.bundle_fetch(
50 | name = "bundle",
51 | srcs = [
52 | "//hello_world:hello_world.gemspec", # Gemspec in subdirectory
53 | "//hello_world/lib/hello_world:version.rb", # Version file in nested structure
54 | ],
55 | gemfile = "//hello_world:Gemfile",
56 | gemfile_lock = "//hello_world:Gemfile.lock",
57 | )
58 | ```
59 |
60 | ### Package Reference Examples
61 |
62 | - `//hello_world:hello_world.gemspec` - References the gemspec file in the hello_world directory
63 | - `//hello_world/lib/hello_world:version.rb` - References the version.rb file in the nested
64 | lib/hello_world directory
65 | - `//hello_world:Gemfile` - References the Gemfile in the hello_world directory
66 |
67 | ## Running Tests
68 |
69 | The example includes comprehensive RSpec tests organized with proper separation of concerns:
70 |
71 | ```bash
72 | # Run all tests
73 | bazel test //...
74 |
75 | # Run specific test suites
76 | bazel test //hello_world/spec:hello_world_spec
77 | bazel test //hello_world/spec:speaker_spec
78 |
79 | # Run all spec tests
80 | bazel test //hello_world/spec:all
81 | ```
82 |
83 | ## Benefits
84 |
85 | This approach provides several advantages:
86 |
87 | 1. **Workspace Organization**: Allows gems to be organized in subdirectories for better
88 | project structure
89 | 2. **Standard Bazel Conventions**: Uses familiar Bazel package notation for file references
90 | 3. **Scalability**: Enables multiple gems within a single workspace without conflicts
91 | 4. **Maintainability**: Clear separation of concerns with proper directory structure
92 |
93 | ## Usage
94 |
95 | This example serves as a template for projects that need to:
96 |
97 | - Define gems in subdirectories rather than at the workspace root
98 | - Reference gem files using standard Bazel package notation
99 | - Maintain proper dependency management with complex directory structures
100 | - Organize multiple gems within a single Bazel workspace
101 |
--------------------------------------------------------------------------------
/ruby/private/test.bzl:
--------------------------------------------------------------------------------
1 | "Implementation details for rb_test"
2 |
3 | load("//ruby/private:binary.bzl", "ATTRS", "rb_binary_impl")
4 | load("//ruby/private:library.bzl", LIBRARY_ATTRS = "ATTRS")
5 |
6 | rb_test = rule(
7 | implementation = rb_binary_impl,
8 | executable = True,
9 | test = True,
10 | attrs = dict(
11 | ATTRS,
12 | srcs = LIBRARY_ATTRS["srcs"],
13 | data = LIBRARY_ATTRS["data"],
14 | deps = LIBRARY_ATTRS["deps"],
15 | ),
16 | toolchains = [
17 | "@rules_ruby//ruby:toolchain_type",
18 | "@bazel_tools//tools/jdk:runtime_toolchain_type",
19 | ],
20 | doc = """
21 | Runs a Ruby test.
22 |
23 | Suppose you have the following Ruby gem, where `rb_library()` is used
24 | in `BUILD` files to define the packages for the gem.
25 |
26 | ```output
27 | |-- BUILD
28 | |-- Gemfile
29 | |-- WORKSPACE
30 | |-- gem.gemspec
31 | |-- lib
32 | | |-- BUILD
33 | | |-- gem
34 | | | |-- BUILD
35 | | | |-- add.rb
36 | | | |-- subtract.rb
37 | | | `-- version.rb
38 | | `-- gem.rb
39 | `-- spec
40 | |-- BUILD
41 | |-- add_spec.rb
42 | |-- spec_helper.rb
43 | `-- subtract_spec.rb
44 | ```
45 |
46 | You can run all tests inside `spec/` by defining individual targets:
47 |
48 | `spec/BUILD`:
49 | ```bazel
50 | load("@rules_ruby//ruby:defs.bzl", "rb_library", "rb_test")
51 |
52 | rb_library(
53 | name = "spec_helper",
54 | srcs = ["spec_helper.rb"],
55 | )
56 |
57 | rb_test(
58 | name = "add",
59 | srcs = ["add_spec.rb"],
60 | args = ["spec/add_spec.rb"],
61 | main = "@bundle//bin:rspec",
62 | deps = [
63 | ":spec_helper",
64 | "@bundle",
65 | ],
66 | )
67 |
68 | rb_test(
69 | name = "subtract",
70 | srcs = ["subtract_spec.rb"],
71 | args = ["spec/subtract_spec.rb"],
72 | main = "@bundle//bin:rspec",
73 | deps = [
74 | ":spec_helper",
75 | "@bundle",
76 | ],
77 | )
78 | ```
79 |
80 | ```output
81 | $ bazel test spec/...
82 | ...
83 | //spec:add PASSED in 0.4s
84 | //spec:subtract PASSED in 0.4s
85 |
86 | Executed 2 out of 2 tests: 2 tests pass.
87 | ```
88 |
89 | Since `rb_test()` is a wrapper around `rb_binary()`, you can also use it to run
90 | a Ruby binary script available in Gemfile dependencies, by passing `main`
91 | argument with a path to a Bundler binary stub.
92 |
93 | `BUILD`:
94 | ```bazel
95 | load("@rules_ruby//ruby:defs.bzl", "rb_test")
96 |
97 | package(default_visibility = ["//:__subpackages__"])
98 |
99 | rb_test(
100 | name = "rubocop",
101 | args = ["lib/"],
102 | main = "@bundle//bin:rubocop",
103 | tags = ["no-sandbox"],
104 | deps = [
105 | "//lib:gem",
106 | "@bundle",
107 | ],
108 | )
109 | ```
110 |
111 | ```output
112 | $ bazel test :rubocop
113 | ...
114 | //:rubocop PASSED in 0.8s
115 |
116 | Executed 1 out of 1 test: 1 test passes.
117 | ```
118 |
119 | Note that you can also `run` every test target passing extra arguments to
120 | the Ruby script. For example, you can re-use `:rubocop` target to perform autocorrect:
121 |
122 | ```output
123 | $ bazel run :rubocop -- --autocorrect-all
124 | ...
125 | Inspecting 11 files
126 | .C.........
127 |
128 | Offenses:
129 |
130 | gem.gemspec:1:1: C: [Corrected] Style/FrozenStringLiteralComment: Missing frozen string literal comment.
131 | root = File.expand_path(__dir__)
132 | ^
133 | gem.gemspec:2:1: C: [Corrected] Layout/EmptyLineAfterMagicComment: Add an empty line after magic comments.
134 | root = File.expand_path(__dir__)
135 | ^
136 |
137 | 11 files inspected, 2 offenses detected, 2 offenses corrected
138 | ```
139 | """,
140 | )
141 |
--------------------------------------------------------------------------------
/examples/jekyll/MODULE.bazel:
--------------------------------------------------------------------------------
1 | "Bazel dependencies"
2 |
3 | bazel_dep(name = "bazel_skylib", version = "1.7.1", dev_dependency = True)
4 | bazel_dep(name = "aspect_bazel_lib", version = "2.9.4", dev_dependency = True)
5 | bazel_dep(name = "rules_ruby", version = "0.0.0", dev_dependency = True)
6 | bazel_dep(name = "rules_shell", version = "0.5.0", dev_dependency = True)
7 |
8 | local_path_override(
9 | module_name = "rules_ruby",
10 | path = "../..",
11 | )
12 |
13 | ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby")
14 | ruby.toolchain(
15 | name = "ruby",
16 | version = "3.2.8",
17 | )
18 | use_repo(ruby, "ruby")
19 |
20 | ruby.bundle_fetch(
21 | name = "bundle",
22 | gem_checksums = {
23 | "addressable-2.8.6": "798f6af3556641a7619bad1dce04cdb6eb44b0216a991b0396ea7339276f2b47",
24 | "colorator-1.1.0": "e2f85daf57af47d740db2a32191d1bdfb0f6503a0dfbc8327d0c9154d5ddfc38",
25 | "concurrent-ruby-1.2.3": "82fdd3f8a0816e28d513e637bb2b90a45d7b982bdf4f3a0511722d2e495801e2",
26 | "em-websocket-0.5.3": "f56a92bde4e6cb879256d58ee31f124181f68f8887bd14d53d5d9a292758c6a8",
27 | "eventmachine-1.2.7": "994016e42aa041477ba9cff45cbe50de2047f25dd418eba003e84f0d16560972",
28 | "ffi-1.16.3": "6d3242ff10c87271b0675c58d68d3f10148fabc2ad6da52a18123f06078871fb",
29 | "forwardable-extended-2.6.0": "1bec948c469bbddfadeb3bd90eb8c85f6e627a412a3e852acfd7eaedbac3ec97",
30 | "http_parser.rb-0.8.0": "5a0932f1fa82ce08a8516a2685d5a86031c000560f89946913c555a0697544be",
31 | "i18n-1.14.1": "9d03698903547c060928e70a9bc8b6b87fda674453cda918fc7ab80235ae4a61",
32 | "jekyll-3.9.4": "5d5e0b931c203ce129a16b2d2d5094a905a088749d24452fa8d82e1078315eff",
33 | "jekyll-feed-0.17.0": "689aab16c877949bb9e7a5c436de6278318a51ecb974792232fd94d8b3acfcc3",
34 | "jekyll-sass-converter-1.5.2": "53773669e414dc3bb070113befacb808576025a28cfa4a4accc682e90a9c1101",
35 | "jekyll-seo-tag-2.8.0": "3f2ed1916d56f14ebfa38e24acde9b7c946df70cb183af2cb5f0598f21ae6818",
36 | "jekyll-watch-2.2.1": "bc44ed43f5e0a552836245a54dbff3ea7421ecc2856707e8a1ee203a8387a7e1",
37 | "kramdown-2.4.0": "b62e5bcbd6ea20c7a6730ebbb2a107237856e14f29cebf5b10c876cc1a2481c5",
38 | "kramdown-parser-gfm-1.1.0": "fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729",
39 | "liquid-4.0.4": "4fcfebb1a045e47918388dbb7a0925e7c3893e58d2bd6c3b3c73ec17a2d8fdb3",
40 | "listen-3.8.0": "9679040ac6e7845ad9f19cf59ecde60861c78e2fae57a5c20fe35e94959b2f8f",
41 | "mercenary-0.3.6": "2a084b18f5692c86a633e185d5311ba6d11fc46c802eb414ae05368178078a82",
42 | "minima-2.5.1": "520e52bc631fb16cbb8100660f6caa44f97859e2fa7e397d508deb18739567be",
43 | "pathutil-0.16.2": "e43b74365631cab4f6d5e4228f812927efc9cb2c71e62976edcb252ee948d589",
44 | "public_suffix-5.0.4": "35cd648e0d21d06b8dce9331d19619538d1d898ba6d56a6f2258409d2526d1ae",
45 | "rb-fsevent-0.11.2": "43900b972e7301d6570f64b850a5aa67833ee7d87b458ee92805d56b7318aefe",
46 | "rb-inotify-0.10.1": "050062d4f31d307cca52c3f6a7f4b946df8de25fc4bd373e1a5142e41034a7ca",
47 | "rexml-3.2.6": "e0669a2d4e9f109951cb1fde723d8acd285425d81594a2ea929304af50282816",
48 | "rouge-3.30.0": "a3d353222aa72e49e2c86726c0bcfd719f82592f57d494474655f48e669eceb6",
49 | "safe_yaml-1.0.5": "a6ac2d64b7eb027bdeeca1851fe7e7af0d668e133e8a88066a0c6f7087d9f848",
50 | "sass-3.7.4": "808b0d39053aa69068df939e24671fe84fd5a9d3314486e1a1457d0934a4255d",
51 | "sass-listen-4.0.0": "ae9dcb76dd3e234329e5ba6e213f48e532c5a3e7b0b4d8a87f13aaca0cc18377",
52 | "wdm-0.1.1": "28406f5f236796019bea5b2a85e37cbcd229ec928c8b68261947a44eec15b474",
53 | "webrick-1.8.1": "19411ec6912911fd3df13559110127ea2badd0c035f7762873f58afc803e158f",
54 | },
55 | gemfile = "//:Gemfile",
56 | gemfile_lock = "//:Gemfile.lock",
57 | )
58 | use_repo(ruby, "bundle", "ruby_toolchains")
59 |
60 | register_toolchains("@ruby_toolchains//:all")
61 |
--------------------------------------------------------------------------------
/ruby/private/providers.bzl:
--------------------------------------------------------------------------------
1 | "Providers for interoperability between rules"
2 |
3 | RubyFilesInfo = provider(
4 | "Provider for Ruby files",
5 | fields = {
6 | "binary": "Main Ruby script.",
7 | "transitive_data": "Transitive data files to add to runfiles.",
8 | "transitive_deps": "Transitive dependencies to get files from.",
9 | "transitive_srcs": "Transitive Ruby files.",
10 | "bundle_env": "Bundle environment variables (deprecated)",
11 | },
12 | )
13 |
14 | BundlerInfo = provider(
15 | "Provider for Bundler installation",
16 | fields = {
17 | "bin": "Binstubs path (BUNDLE_BIN).",
18 | "gemfile": "Gemfile path (BUNDLE_GEMFILE).",
19 | "path": "Bundle path (BUNDLE_PATH).",
20 | "env": "Bundle environment variables.",
21 | },
22 | )
23 |
24 | GemInfo = provider(
25 | "Provider for a packed Ruby gem",
26 | fields = {
27 | "name": "Gem name.",
28 | "version": "Gem version.",
29 | },
30 | )
31 |
32 | # https://bazel.build/rules/depsets
33 |
34 | def get_transitive_srcs(srcs, deps):
35 | """Obtain the source files for a target and its transitive dependencies.
36 |
37 | Args:
38 | srcs: a list of source files
39 | deps: a list of targets that are direct dependencies
40 | Returns:
41 | a collection of the transitive sources
42 | """
43 | return depset(
44 | srcs,
45 | transitive = [dep[RubyFilesInfo].transitive_srcs for dep in deps],
46 | )
47 |
48 | def get_transitive_data(data, deps):
49 | """Obtain the data files for a target and its transitive dependencies.
50 |
51 | Args:
52 | data: a list of data files
53 | deps: a list of targets that are direct dependencies
54 | Returns:
55 | a collection of the transitive data files
56 | """
57 | return depset(
58 | data,
59 | transitive = [dep[RubyFilesInfo].transitive_data for dep in deps],
60 | )
61 |
62 | def get_transitive_deps(deps):
63 | """Obtain the dependencies for a target and its transitive dependencies.
64 |
65 | Args:
66 | deps: a list of targets that are direct dependencies
67 | Returns:
68 | a collection of the transitive dependencies
69 | """
70 | return depset(
71 | deps,
72 | transitive = [dep[RubyFilesInfo].transitive_deps for dep in deps],
73 | )
74 |
75 | # https://bazel.build/extending/rules#runfiles
76 | def get_transitive_runfiles(runfiles, srcs, data, deps):
77 | """Obtain the runfiles for a target, its transitive data files and dependencies.
78 |
79 | Args:
80 | runfiles: the runfiles
81 | srcs: a list of source files
82 | data: a list of data files
83 | deps: a list of targets that are direct dependencies
84 | Returns:
85 | the runfiles
86 | """
87 | transitive_runfiles = []
88 | for targets in (srcs, data, deps):
89 | for target in targets:
90 | transitive_runfiles.append(target[DefaultInfo].default_runfiles)
91 | return runfiles.merge_all(transitive_runfiles)
92 |
93 | def get_bundle_env(envs, deps):
94 | """Obtain the BUNDLE_* environment variables for a target and its transitive dependencies.
95 |
96 | Args:
97 | envs: a list of environment variables
98 | deps: a list of targets that are direct dependencies
99 | Returns:
100 | a collection of the transitive environment variables
101 | """
102 | bundle_env = {}
103 |
104 | transitive_deps = get_transitive_deps(deps).to_list()
105 | for dep in transitive_deps:
106 | bundle_env.update(dep[RubyFilesInfo].bundle_env)
107 | if BundlerInfo in dep:
108 | bundle_env.update(dep[BundlerInfo].env)
109 |
110 | for env in envs:
111 | if env.startswith("BUNDLE_"):
112 | bundle_env[env] = envs[env]
113 | return bundle_env
114 |
--------------------------------------------------------------------------------
/docs/rails.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | Public definition for `rails_test_factory`.
4 |
5 |
6 |
7 | ## rails_test_factory.new_system_test
8 |
9 |
10 | load("@rules_ruby//rails:rails_test_factory.bzl", "rails_test_factory")
11 |
12 | rails_test_factory.new_system_test(test_package , application_system_test_case , default_includes ,
13 | default_size , tags )
14 |
15 |
16 | Create a `rails_system_test` macro for a Rails application.
17 |
18 | **PARAMETERS**
19 |
20 |
21 | | Name | Description | Default Value |
22 | | :------------- | :------------- | :------------- |
23 | | test_package | Optional. The name of the package that contains the test helpers. For example, if the Rails app is rooted in the `foo` directory, the test package is typically `foo/test`. | `None` |
24 | | application_system_test_case | Optional. The label for the Rails application's `application_system_test_case.rb`. | `None` |
25 | | default_includes | Optional. A `list` of Ruby includes that should be part of the Ruby test invocation. | `None` |
26 | | default_size | Optional. The default test size for the tests created with the resulting macro. | `"large"` |
27 | | tags | Optional. A `list` of tags that are added to the test declaration. | `["no-sandbox"]` |
28 |
29 | **RETURNS**
30 |
31 | A Bazel macro function that defines Rails system test targets using the
32 | provided attributes.
33 |
34 |
35 |
36 |
37 | ## rails_test_factory.new_test
38 |
39 |
40 | load("@rules_ruby//rails:rails_test_factory.bzl", "rails_test_factory")
41 |
42 | rails_test_factory.new_test(test_package , test_helper , default_includes , default_size , tags )
43 |
44 |
45 | Create a `rails_test` macro for a Rails application.
46 |
47 | The resulting macro encapsulates the application-specific attributes for the
48 | resulting test target.
49 |
50 |
51 | **PARAMETERS**
52 |
53 |
54 | | Name | Description | Default Value |
55 | | :------------- | :------------- | :------------- |
56 | | test_package | Optional. The name of the package that contains the test helpers. For example, if the Rails app is rooted in the `foo` directory, the test package is typically `foo/test`. | `None` |
57 | | test_helper | The label for the Rails application's `test_helper.rb`. | `None` |
58 | | default_includes | Optional. A `list` of Ruby includes that should be part of the Ruby test invocation. | `None` |
59 | | default_size | Optional. The default test size for the tests created with the resulting macro. | `"small"` |
60 | | tags | Optional. A `list` of tags that are added to the test declaration. | `[]` |
61 |
62 | **RETURNS**
63 |
64 | A Bazel macro function that defines Rails test targets using the
65 | provided attributes.
66 |
67 |
68 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | require "active_support/core_ext/integer/time"
2 |
3 | Rails.application.configure do
4 | # Settings specified here will take precedence over those in config/application.rb.
5 |
6 | # Code is not reloaded between requests.
7 | config.enable_reloading = false
8 |
9 | # Eager load code on boot for better performance and memory savings (ignored by Rake tasks).
10 | config.eager_load = true
11 |
12 | # Full error reports are disabled.
13 | config.consider_all_requests_local = false
14 |
15 | # Turn on fragment caching in view templates.
16 | config.action_controller.perform_caching = true
17 |
18 | # Cache assets for far-future expiry since they are all digest stamped.
19 | config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" }
20 |
21 | # Enable serving of images, stylesheets, and JavaScripts from an asset server.
22 | # config.asset_host = "http://assets.example.com"
23 |
24 | # Store uploaded files on the local file system (see config/storage.yml for options).
25 | config.active_storage.service = :local
26 |
27 | # Assume all access to the app is happening through a SSL-terminating reverse proxy.
28 | config.assume_ssl = true
29 |
30 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
31 | config.force_ssl = true
32 |
33 | # Skip http-to-https redirect for the default health check endpoint.
34 | # config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } }
35 |
36 | # Log to STDOUT with the current request id as a default log tag.
37 | config.log_tags = [ :request_id ]
38 | config.logger = ActiveSupport::TaggedLogging.logger(STDOUT)
39 |
40 | # Change to "debug" to log everything (including potentially personally-identifiable information!)
41 | config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")
42 |
43 | # Prevent health checks from clogging up the logs.
44 | config.silence_healthcheck_path = "/up"
45 |
46 | # Don't log any deprecations.
47 | config.active_support.report_deprecations = false
48 |
49 | # Replace the default in-process memory cache store with a durable alternative.
50 | # config.cache_store = :mem_cache_store
51 |
52 | # Replace the default in-process and non-durable queuing backend for Active Job.
53 | # config.active_job.queue_adapter = :resque
54 |
55 | # Ignore bad email addresses and do not raise email delivery errors.
56 | # Set this to true and configure the email server for immediate delivery to raise delivery errors.
57 | # config.action_mailer.raise_delivery_errors = false
58 |
59 | # Set host to be used by links generated in mailer templates.
60 | config.action_mailer.default_url_options = { host: "example.com" }
61 |
62 | # Specify outgoing SMTP server. Remember to add smtp/* credentials via rails credentials:edit.
63 | # config.action_mailer.smtp_settings = {
64 | # user_name: Rails.application.credentials.dig(:smtp, :user_name),
65 | # password: Rails.application.credentials.dig(:smtp, :password),
66 | # address: "smtp.example.com",
67 | # port: 587,
68 | # authentication: :plain
69 | # }
70 |
71 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
72 | # the I18n.default_locale when a translation cannot be found).
73 | config.i18n.fallbacks = true
74 |
75 | # Do not dump schema after migrations.
76 | config.active_record.dump_schema_after_migration = false
77 |
78 | # Only use :id for inspections in production.
79 | config.active_record.attributes_for_inspect = [ :id ]
80 |
81 | # Enable DNS rebinding protection and other `Host` header attacks.
82 | # config.hosts = [
83 | # "example.com", # Allow requests from example.com
84 | # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
85 | # ]
86 | #
87 | # Skip DNS rebinding protection for the default health check endpoint.
88 | # config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
89 | end
90 |
--------------------------------------------------------------------------------
/ruby/private/library.bzl:
--------------------------------------------------------------------------------
1 | "Implementation details for rb_library"
2 |
3 | load(
4 | "//ruby/private:providers.bzl",
5 | "BundlerInfo",
6 | "RubyFilesInfo",
7 | "get_bundle_env",
8 | "get_transitive_data",
9 | "get_transitive_deps",
10 | "get_transitive_runfiles",
11 | "get_transitive_srcs",
12 | )
13 |
14 | ATTRS = {
15 | "srcs": attr.label_list(
16 | allow_files = [".rb", ".gemspec", "Gemfile", "Gemfile.lock"],
17 | doc = "List of Ruby source files used to build the library.",
18 | ),
19 | "deps": attr.label_list(
20 | doc = "List of other Ruby libraries the target depends on.",
21 | ),
22 | "data": attr.label_list(
23 | allow_files = True,
24 | doc = "List of runtime dependencies needed by a program that depends on this library.",
25 | ),
26 | "bundle_env": attr.string_dict(
27 | default = {},
28 | doc = "List of bundle environment variables to set when building the library.",
29 | ),
30 | }
31 |
32 | def _rb_library_impl(ctx):
33 | # TODO: avoid expanding the depset to a list, it may be expensive in a large graph
34 | transitive_data = get_transitive_data(ctx.files.data, ctx.attr.deps).to_list()
35 | transitive_deps = get_transitive_deps(ctx.attr.deps).to_list()
36 | transitive_srcs = get_transitive_srcs(ctx.files.srcs, ctx.attr.deps).to_list()
37 |
38 | runfiles = ctx.runfiles(transitive_srcs + transitive_data)
39 | runfiles = get_transitive_runfiles(runfiles, ctx.attr.srcs, ctx.attr.deps, ctx.attr.data)
40 |
41 | providers = [
42 | DefaultInfo(
43 | files = depset(transitive_srcs + transitive_data),
44 | runfiles = runfiles,
45 | ),
46 | RubyFilesInfo(
47 | binary = None,
48 | transitive_data = depset(transitive_data),
49 | transitive_deps = depset(transitive_deps),
50 | transitive_srcs = depset(transitive_srcs),
51 | bundle_env = get_bundle_env(ctx.attr.bundle_env, ctx.attr.deps),
52 | ),
53 | ]
54 |
55 | for dep in transitive_deps:
56 | if BundlerInfo in dep:
57 | providers.append(dep[BundlerInfo])
58 | break
59 |
60 | return providers
61 |
62 | rb_library = rule(
63 | implementation = _rb_library_impl,
64 | attrs = ATTRS,
65 | doc = """
66 | Defines a Ruby library.
67 |
68 | Suppose you have the following Ruby gem:
69 |
70 | ```output
71 | |-- BUILD
72 | |-- Gemfile
73 | |-- WORKSPACE
74 | |-- gem.gemspec
75 | `-- lib
76 | |-- BUILD
77 | |-- gem
78 | | |-- BUILD
79 | | |-- add.rb
80 | | |-- subtract.rb
81 | | `-- version.rb
82 | `-- gem.rb
83 | ```
84 |
85 | You can define packages for the gem source files:
86 |
87 | `BUILD`:
88 | ```bazel
89 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
90 |
91 | package(default_visibility = ["//:__subpackages__"])
92 |
93 | rb_library(
94 | name = "gem",
95 | deps = ["//lib:gem"],
96 | )
97 | ```
98 |
99 | `lib/BUILD`:
100 | ```bazel
101 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
102 |
103 | package(default_visibility = ["//:__subpackages__"])
104 |
105 | rb_library(
106 | name = "gem",
107 | srcs = ["gem.rb"],
108 | deps = [
109 | "//lib/gem:add",
110 | "//lib/gem:subtract",
111 | "//lib/gem:version",
112 | ],
113 | )
114 | ```
115 |
116 | `lib/gem/BUILD`:
117 | ```bazel
118 | load("@rules_ruby//ruby:defs.bzl", "rb_library")
119 |
120 | package(default_visibility = ["//:__subpackages__"])
121 |
122 | rb_library(
123 | name = "add",
124 | srcs = ["add.rb"],
125 | )
126 |
127 | rb_library(
128 | name = "subtract",
129 | srcs = ["subtract.rb"],
130 | )
131 |
132 | rb_library(
133 | name = "version",
134 | srcs = ["version.rb"],
135 | )
136 | ```
137 |
138 | Once the packages are defined, you can use them in other targets
139 | such as `rb_gem_build()` to build a Ruby gem. See examples of
140 | using other rules.
141 | """,
142 | )
143 |
--------------------------------------------------------------------------------
/examples/rails/people_tracker/config/deploy.yml:
--------------------------------------------------------------------------------
1 | # Name of your application. Used to uniquely configure containers.
2 | service: people_tracker
3 |
4 | # Name of the container image.
5 | image: your-user/people_tracker
6 |
7 | # Deploy to these servers.
8 | servers:
9 | web:
10 | - 192.168.0.1
11 | # job:
12 | # hosts:
13 | # - 192.168.0.1
14 | # cmd: bin/jobs
15 |
16 | # Enable SSL auto certification via Let's Encrypt and allow for multiple apps on a single web server.
17 | # Remove this section when using multiple web servers and ensure you terminate SSL at your load balancer.
18 | #
19 | # Note: If using Cloudflare, set encryption mode in SSL/TLS setting to "Full" to enable CF-to-app encryption.
20 | proxy:
21 | ssl: true
22 | host: app.example.com
23 |
24 | # Credentials for your image host.
25 | registry:
26 | # Specify the registry server, if you're not using Docker Hub
27 | # server: registry.digitalocean.com / ghcr.io / ...
28 | username: your-user
29 |
30 | # Always use an access token rather than real password when possible.
31 | password:
32 | - KAMAL_REGISTRY_PASSWORD
33 |
34 | # Inject ENV variables into containers (secrets come from .kamal/secrets).
35 | env:
36 | secret:
37 | - RAILS_MASTER_KEY
38 | clear:
39 | # Run the Solid Queue Supervisor inside the web server's Puma process to do jobs.
40 | # When you start using multiple servers, you should split out job processing to a dedicated machine.
41 | SOLID_QUEUE_IN_PUMA: true
42 |
43 | # Set number of processes dedicated to Solid Queue (default: 1)
44 | # JOB_CONCURRENCY: 3
45 |
46 | # Set number of cores available to the application on each server (default: 1).
47 | # WEB_CONCURRENCY: 2
48 |
49 | # Match this to any external database server to configure Active Record correctly
50 | # Use people_tracker-db for a db accessory server on same machine via local kamal docker network.
51 | # DB_HOST: 192.168.0.2
52 |
53 | # Log everything from Rails
54 | # RAILS_LOG_LEVEL: debug
55 |
56 | # Aliases are triggered with "bin/kamal ". You can overwrite arguments on invocation:
57 | # "bin/kamal logs -r job" will tail logs from the first server in the job section.
58 | aliases:
59 | console: app exec --interactive --reuse "bin/rails console"
60 | shell: app exec --interactive --reuse "bash"
61 | logs: app logs -f
62 | dbc: app exec --interactive --reuse "bin/rails dbconsole"
63 |
64 | # Use a persistent storage volume for sqlite database files and local Active Storage files.
65 | # Recommended to change this to a mounted volume path that is backed up off server.
66 | volumes:
67 | - "people_tracker_storage:/rails/storage"
68 |
69 | # Bridge fingerprinted assets, like JS and CSS, between versions to avoid
70 | # hitting 404 on in-flight requests. Combines all files from new and old
71 | # version inside the asset_path.
72 | asset_path: /rails/public/assets
73 |
74 | # Configure the image builder.
75 | builder:
76 | arch: amd64
77 |
78 | # # Build image via remote server (useful for faster amd64 builds on arm64 computers)
79 | # remote: ssh://docker@docker-builder-server
80 | #
81 | # # Pass arguments and secrets to the Docker build process
82 | # args:
83 | # RUBY_VERSION: ruby-3.4.5
84 | # secrets:
85 | # - GITHUB_TOKEN
86 | # - RAILS_MASTER_KEY
87 |
88 | # Use a different ssh user than root
89 | # ssh:
90 | # user: app
91 |
92 | # Use accessory services (secrets come from .kamal/secrets).
93 | # accessories:
94 | # db:
95 | # image: mysql:8.0
96 | # host: 192.168.0.2
97 | # # Change to 3306 to expose port to the world instead of just local network.
98 | # port: "127.0.0.1:3306:3306"
99 | # env:
100 | # clear:
101 | # MYSQL_ROOT_HOST: '%'
102 | # secret:
103 | # - MYSQL_ROOT_PASSWORD
104 | # files:
105 | # - config/mysql/production.cnf:/etc/mysql/my.cnf
106 | # - db/production.sql:/docker-entrypoint-initdb.d/setup.sql
107 | # directories:
108 | # - data:/var/lib/mysql
109 | # redis:
110 | # image: redis:7.0
111 | # host: 192.168.0.2
112 | # port: 6379
113 | # directories:
114 | # - data:/data
115 |
--------------------------------------------------------------------------------
/examples/gem/WORKSPACE:
--------------------------------------------------------------------------------
1 | local_repository(
2 | name = "rules_ruby",
3 | path = "../..",
4 | )
5 |
6 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
7 |
8 | http_archive(
9 | name = "bazel_skylib",
10 | sha256 = "66ffd9315665bfaafc96b52278f57c7e2dd09f5ede279ea6d39b2be471e7e3aa",
11 | urls = [
12 | "https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-1.4.2.tar.gz",
13 | ],
14 | )
15 |
16 | load("@rules_ruby//ruby:deps.bzl", "rb_bundle_fetch", "rb_register_toolchains")
17 |
18 | rb_register_toolchains(
19 | version_file = "//:.ruby-version",
20 | )
21 |
22 | rb_bundle_fetch(
23 | name = "bundle",
24 | srcs = [
25 | "//:gem.gemspec",
26 | "//:lib/gem/version.rb",
27 | ],
28 | env = {
29 | "BUNDLE_BUILD__FOO": "bar",
30 | },
31 | gem_checksums = {
32 | "ast-2.4.2": "1e280232e6a33754cde542bc5ef85520b74db2aac73ec14acef453784447cc12",
33 | "concurrent-ruby-1.3.5": "813b3e37aca6df2a21a3b9f1d497f8cbab24a2b94cab325bffe65ee0f6cbebc6",
34 | "date-3.4.1": "bf268e14ef7158009bfeaec40b5fa3c7271906e88b196d958a89d4b408abe64f",
35 | "date-3.4.1-java": "74740d914c65a922a15657c25ff0e203c16f1d0f7aa910a9ebed712afe9819c4",
36 | "debug-1.10.0": "11e28ca74875979e612444104f3972bd5ffb9e79179907d7ad46dba44bd2e7a4",
37 | "diff-lcs-1.5.1": "273223dfb40685548436d32b4733aa67351769c7dea621da7d9dd4813e63ddfe",
38 | "i18n-1.14.7": "ceba573f8138ff2c0915427f1fc5bdf4aa3ab8ae88c8ce255eb3ecf0a11a5d0f",
39 | "io-console-0.8.0": "cd6a9facbc69871d69b2cb8b926fc6ea7ef06f06e505e81a64f14a470fddefa2",
40 | "io-console-0.8.0-java": "3cc6fd5c66e587145c1fdf8dc40c2e3d851e90722a5d0cc3f38da352f06fe1bd",
41 | "irb-1.15.1": "d9bca745ac4207a8b728a52b98b766ca909b86ff1a504bcde3d6f8c84faae890",
42 | "jar-dependencies-0.5.3": "f6a7a0bf3f917252461e2a87f9f54005424502f7dc9ef912d8b9540658dbd0bc",
43 | "json-2.9.1": "d2bdef4644052fad91c1785d48263756fe32fcac08b96a20bb15840e96550d11",
44 | "json-2.9.1-java": "88de8c79b54fee6ae1b4854bc48b8d7089f524cbacaf4596df24f86b10896ee8",
45 | "language_server-protocol-3.17.0.3": "3d5c58c02f44a20d972957a9febe386d7e7468ab3900ce6bd2b563dd910c6b3f",
46 | "parallel-1.26.3": "d86babb7a2b814be9f4b81587bf0b6ce2da7d45969fab24d8ae4bf2bb4d4c7ef",
47 | "parser-3.3.7.0": "7449011771e3e7881297859b849de26a6f4fccd515bece9520a87e7d2116119b",
48 | "pp-0.6.2": "947ec3120c6f92195f8ee8aa25a7b2c5297bb106d83b41baa02983686577b6ff",
49 | "prettyprint-0.2.0": "2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193",
50 | "psych-5.2.3": "84a54bb952d14604fea22d99938348814678782f58b12648fcdfa4d2fce859ee",
51 | "psych-5.2.3-java": "3e5425b9e8a2f41cc2707d5ef14fdc1ae908abbafb12fe45727bd63900056585",
52 | "racc-1.8.1": "4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f",
53 | "racc-1.8.1-java": "54f2e6d1e1b91c154013277d986f52a90e5ececbe91465d29172e49342732b98",
54 | "rainbow-3.1.1": "039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a",
55 | "rake-13.2.1": "46cb38dae65d7d74b6020a4ac9d48afed8eb8149c040eccf0523bec91907059d",
56 | "rdoc-6.11.0": "bec66fb9b019be64f7ba7d2cd2aecb283a3a01fef23a95b33e2349c6d1aa0040",
57 | "regexp_parser-2.10.0": "cb6f0ddde88772cd64bff1dbbf68df66d376043fe2e66a9ef77fcb1b0c548c61",
58 | "reline-0.6.0": "57620375dcbe56ec09bac7192bfb7460c716bbf0054dc94345ecaa5438e539d2",
59 | "rspec-3.13.0": "d490914ac1d5a5a64a0e1400c1d54ddd2a501324d703b8cfe83f458337bab993",
60 | "rspec-core-3.13.2": "94fbda6e4738e478f1c7532b7cc241272fcdc8b9eac03a97338b1122e4573300",
61 | "rspec-expectations-3.13.3": "0e6b5af59b900147698ea0ff80456c4f2e69cac4394fbd392fbd1ca561f66c58",
62 | "rspec-mocks-3.13.2": "2327335def0e1665325a9b617e3af9ae20272741d80ac550336309a7c59abdef",
63 | "rspec-support-3.13.2": "cea3a2463fd9b84b9dcc9685efd80ea701aa8f7b3decb3b3ce795ed67737dbec",
64 | "rubocop-1.71.0": "e19679efd447346ac476122313d3788ae23c38214790bcf660e984c747608bf0",
65 | "rubocop-ast-1.37.0": "9513ac88aaf113d04b52912533ffe46475de1362d4aa41141b51b2455827c080",
66 | "ruby-progressbar-1.13.0": "80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33",
67 | "stringio-3.1.2": "204f1828f85cdb39d57cac4abc6dc44b04505a223f131587f2e20ae3729ba131",
68 | "unicode-display_width-3.1.4": "8caf2af1c0f2f07ec89ef9e18c7d88c2790e217c482bfc78aaa65eadd5415ac1",
69 | "unicode-emoji-4.0.4": "2c2c4ef7f353e5809497126285a50b23056cc6e61b64433764a35eff6c36532a",
70 | },
71 | gemfile = "//:Gemfile",
72 | gemfile_lock = "//:Gemfile.lock",
73 | )
74 |
--------------------------------------------------------------------------------
/examples/gem/MODULE.bazel:
--------------------------------------------------------------------------------
1 | "Bazel dependencies"
2 |
3 | bazel_dep(name = "bazel_skylib", version = "1.5.0", dev_dependency = True)
4 | bazel_dep(name = "aspect_bazel_lib", version = "2.19.4", dev_dependency = True)
5 | bazel_dep(name = "rules_ruby", version = "0.0.0", dev_dependency = True)
6 | bazel_dep(name = "rules_shell", version = "0.4.0", dev_dependency = True)
7 |
8 | local_path_override(
9 | module_name = "rules_ruby",
10 | path = "../..",
11 | )
12 |
13 | ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby")
14 | ruby.toolchain(
15 | name = "ruby",
16 | version_file = "//:.ruby-version",
17 | )
18 | use_repo(ruby, "ruby")
19 |
20 | ruby.bundle_fetch(
21 | name = "bundle",
22 | srcs = [
23 | "//:gem.gemspec",
24 | "//:lib/gem/version.rb",
25 | ],
26 | env = {
27 | "BUNDLE_BUILD__FOO": "bar",
28 | },
29 | gem_checksums = {
30 | "ast-2.4.2": "1e280232e6a33754cde542bc5ef85520b74db2aac73ec14acef453784447cc12",
31 | "concurrent-ruby-1.3.5": "813b3e37aca6df2a21a3b9f1d497f8cbab24a2b94cab325bffe65ee0f6cbebc6",
32 | "date-3.4.1": "bf268e14ef7158009bfeaec40b5fa3c7271906e88b196d958a89d4b408abe64f",
33 | "date-3.4.1-java": "74740d914c65a922a15657c25ff0e203c16f1d0f7aa910a9ebed712afe9819c4",
34 | "debug-1.10.0": "11e28ca74875979e612444104f3972bd5ffb9e79179907d7ad46dba44bd2e7a4",
35 | "diff-lcs-1.5.1": "273223dfb40685548436d32b4733aa67351769c7dea621da7d9dd4813e63ddfe",
36 | "i18n-1.14.7": "ceba573f8138ff2c0915427f1fc5bdf4aa3ab8ae88c8ce255eb3ecf0a11a5d0f",
37 | "io-console-0.8.0": "cd6a9facbc69871d69b2cb8b926fc6ea7ef06f06e505e81a64f14a470fddefa2",
38 | "io-console-0.8.0-java": "3cc6fd5c66e587145c1fdf8dc40c2e3d851e90722a5d0cc3f38da352f06fe1bd",
39 | "irb-1.15.1": "d9bca745ac4207a8b728a52b98b766ca909b86ff1a504bcde3d6f8c84faae890",
40 | "jar-dependencies-0.5.3": "f6a7a0bf3f917252461e2a87f9f54005424502f7dc9ef912d8b9540658dbd0bc",
41 | "json-2.9.1": "d2bdef4644052fad91c1785d48263756fe32fcac08b96a20bb15840e96550d11",
42 | "json-2.9.1-java": "88de8c79b54fee6ae1b4854bc48b8d7089f524cbacaf4596df24f86b10896ee8",
43 | "language_server-protocol-3.17.0.3": "3d5c58c02f44a20d972957a9febe386d7e7468ab3900ce6bd2b563dd910c6b3f",
44 | "parallel-1.26.3": "d86babb7a2b814be9f4b81587bf0b6ce2da7d45969fab24d8ae4bf2bb4d4c7ef",
45 | "parser-3.3.7.0": "7449011771e3e7881297859b849de26a6f4fccd515bece9520a87e7d2116119b",
46 | "pp-0.6.2": "947ec3120c6f92195f8ee8aa25a7b2c5297bb106d83b41baa02983686577b6ff",
47 | "prettyprint-0.2.0": "2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193",
48 | "psych-5.2.3": "84a54bb952d14604fea22d99938348814678782f58b12648fcdfa4d2fce859ee",
49 | "psych-5.2.3-java": "3e5425b9e8a2f41cc2707d5ef14fdc1ae908abbafb12fe45727bd63900056585",
50 | "racc-1.8.1": "4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f",
51 | "racc-1.8.1-java": "54f2e6d1e1b91c154013277d986f52a90e5ececbe91465d29172e49342732b98",
52 | "rainbow-3.1.1": "039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a",
53 | "rake-13.2.1": "46cb38dae65d7d74b6020a4ac9d48afed8eb8149c040eccf0523bec91907059d",
54 | "rdoc-6.11.0": "bec66fb9b019be64f7ba7d2cd2aecb283a3a01fef23a95b33e2349c6d1aa0040",
55 | "regexp_parser-2.10.0": "cb6f0ddde88772cd64bff1dbbf68df66d376043fe2e66a9ef77fcb1b0c548c61",
56 | "reline-0.6.0": "57620375dcbe56ec09bac7192bfb7460c716bbf0054dc94345ecaa5438e539d2",
57 | "rspec-3.13.0": "d490914ac1d5a5a64a0e1400c1d54ddd2a501324d703b8cfe83f458337bab993",
58 | "rspec-core-3.13.2": "94fbda6e4738e478f1c7532b7cc241272fcdc8b9eac03a97338b1122e4573300",
59 | "rspec-expectations-3.13.3": "0e6b5af59b900147698ea0ff80456c4f2e69cac4394fbd392fbd1ca561f66c58",
60 | "rspec-mocks-3.13.2": "2327335def0e1665325a9b617e3af9ae20272741d80ac550336309a7c59abdef",
61 | "rspec-support-3.13.2": "cea3a2463fd9b84b9dcc9685efd80ea701aa8f7b3decb3b3ce795ed67737dbec",
62 | "rubocop-1.71.0": "e19679efd447346ac476122313d3788ae23c38214790bcf660e984c747608bf0",
63 | "rubocop-ast-1.37.0": "9513ac88aaf113d04b52912533ffe46475de1362d4aa41141b51b2455827c080",
64 | "ruby-progressbar-1.13.0": "80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33",
65 | "stringio-3.1.2": "204f1828f85cdb39d57cac4abc6dc44b04505a223f131587f2e20ae3729ba131",
66 | "unicode-display_width-3.1.4": "8caf2af1c0f2f07ec89ef9e18c7d88c2790e217c482bfc78aaa65eadd5415ac1",
67 | "unicode-emoji-4.0.4": "2c2c4ef7f353e5809497126285a50b23056cc6e61b64433764a35eff6c36532a",
68 | },
69 | gemfile = "//:Gemfile",
70 | gemfile_lock = "//:Gemfile.lock",
71 | )
72 | use_repo(ruby, "bundle", "ruby_toolchains")
73 |
74 | register_toolchains("@ruby_toolchains//:all")
75 |
--------------------------------------------------------------------------------
/ruby/private/gem_install.bzl:
--------------------------------------------------------------------------------
1 | "Implementation details for rb_gem_install"
2 |
3 | load("//ruby/private:providers.bzl", "GemInfo")
4 | load(
5 | "//ruby/private:utils.bzl",
6 | _convert_env_to_script = "convert_env_to_script",
7 | _is_windows = "is_windows",
8 | _normalize_path = "normalize_path",
9 | )
10 |
11 | def _rb_gem_install_impl(ctx):
12 | gem = ctx.file.gem
13 | install_dir = ctx.actions.declare_directory(gem.basename[:-4])
14 | toolchain = ctx.toolchains["@rules_ruby//ruby:toolchain_type"]
15 | if ctx.attr.ruby != None:
16 | toolchain = ctx.attr.ruby[platform_common.ToolchainInfo]
17 |
18 | env = {}
19 | env.update(toolchain.env)
20 |
21 | tools = []
22 | tools.extend(toolchain.files)
23 |
24 | if toolchain.version.startswith("jruby"):
25 | java_toolchain = ctx.toolchains["@bazel_tools//tools/jdk:runtime_toolchain_type"]
26 | tools.extend(java_toolchain.java_runtime.files.to_list())
27 | env.update({"JAVA_HOME": java_toolchain.java_runtime.java_home})
28 |
29 | if _is_windows(ctx):
30 | gem_install = ctx.actions.declare_file("gem_install_{}.cmd".format(ctx.label.name))
31 | template = ctx.file._gem_install_cmd_tpl
32 | env.update({"PATH": _normalize_path(ctx, toolchain.ruby.dirname) + ";%PATH%"})
33 | else:
34 | gem_install = ctx.actions.declare_file("gem_install_{}.sh".format(ctx.label.name))
35 | template = ctx.file._gem_install_sh_tpl
36 | env.update({"PATH": "%s:$PATH" % toolchain.ruby.dirname})
37 |
38 | ctx.actions.expand_template(
39 | template = template,
40 | output = gem_install,
41 | substitutions = {
42 | "{env}": _convert_env_to_script(ctx, env),
43 | "{gem_binary}": _normalize_path(ctx, toolchain.gem.path),
44 | "{gem}": gem.path,
45 | "{install_dir}": install_dir.path,
46 | },
47 | )
48 |
49 | name, _, version = ctx.attr.name.rpartition("-")
50 | ctx.actions.run(
51 | executable = gem_install,
52 | inputs = depset([gem, gem_install]),
53 | outputs = [install_dir],
54 | mnemonic = "GemInstall",
55 | progress_message = "Installing %{input} (%{label})",
56 | tools = tools,
57 | use_default_shell_env = True,
58 | )
59 |
60 | return [
61 | DefaultInfo(files = depset([gem, install_dir])),
62 | GemInfo(
63 | name = name,
64 | version = version,
65 | ),
66 | ]
67 |
68 | rb_gem_install = rule(
69 | _rb_gem_install_impl,
70 | attrs = {
71 | "gem": attr.label(
72 | allow_single_file = [".gem"],
73 | mandatory = True,
74 | doc = "Gem file to install.",
75 | ),
76 | "ruby": attr.label(
77 | doc = "Override Ruby toolchain to use when installing the gem.",
78 | providers = [platform_common.ToolchainInfo],
79 | ),
80 | "_gem_install_cmd_tpl": attr.label(
81 | allow_single_file = True,
82 | default = "@rules_ruby//ruby/private/gem_install:gem_install.cmd.tpl",
83 | ),
84 | "_gem_install_sh_tpl": attr.label(
85 | allow_single_file = True,
86 | default = "@rules_ruby//ruby/private/gem_install:gem_install.sh.tpl",
87 | ),
88 | "_windows_constraint": attr.label(
89 | default = "@platforms//os:windows",
90 | ),
91 | },
92 | toolchains = [
93 | "@rules_ruby//ruby:toolchain_type",
94 | "@bazel_tools//tools/jdk:runtime_toolchain_type",
95 | ],
96 | doc = """
97 | Installs a built Ruby gem.
98 |
99 | Suppose you have the following Ruby gem, where `rb_library()` is used
100 | in `BUILD` files to define the packages for the gem and `rb_gem_build()` is used
101 | to build a Ruby gem package from the sources.
102 |
103 | ```output
104 | |-- BUILD
105 | |-- Gemfile
106 | |-- WORKSPACE
107 | |-- gem.gemspec
108 | `-- lib
109 | |-- BUILD
110 | |-- gem
111 | | |-- BUILD
112 | | |-- add.rb
113 | | |-- subtract.rb
114 | | `-- version.rb
115 | `-- gem.rb
116 | ```
117 |
118 | You can now install the built `.gem` file by defining a target:
119 |
120 | `BUILD`:
121 | ```bazel
122 | load("@rules_ruby//ruby:defs.bzl", "rb_gem_build", "rb_gem_install")
123 |
124 | package(default_visibility = ["//:__subpackages__"])
125 |
126 | rb_gem_build(
127 | name = "gem-build",
128 | gemspec = "gem.gemspec",
129 | deps = ["//lib:gem"],
130 | )
131 |
132 | rb_gem_install(
133 | name = "gem-install",
134 | gem = ":gem-build",
135 | )
136 | ```
137 |
138 | ```output
139 | $ bazel build :gem-install
140 | ...
141 | Successfully installed example-0.1.0
142 | 1 gem installed
143 | ...
144 | ```
145 | """,
146 | )
147 |
--------------------------------------------------------------------------------