diff --git a/.circleci/Dockerfile b/.circleci/Dockerfile index 73c74c7..cff3ce5 100644 --- a/.circleci/Dockerfile +++ b/.circleci/Dockerfile @@ -1,7 +1,7 @@ # # rules_ruby circleci Docker file. # -FROM ruby:3.0.1 +FROM ruby:3.0.2 # make Apt non-interactive RUN echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/90circleci \ @@ -95,7 +95,10 @@ RUN apt-get install -y openjdk-11-jdk python2.7 python3 golang-go RUN curl -L -o /usr/bin/bazel https://github.com/bazelbuild/bazelisk/releases/download/v1.3.0/bazelisk-linux-amd64 \ && sudo chmod +x /usr/bin/bazel +RUN cd /usr/bin && ln -s python3 python + USER circleci ENV PATH /home/circleci/.local/bin:/home/circleci/bin:/usr/local/bin:/usr/bin:/bin:/sbin:${PATH} -CMD ["/bin/sh"] + +CMD ["/bin/bash"] diff --git a/.circleci/config.yml b/.circleci/config.yml index a848906..5ee0d7e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,7 +5,7 @@ jobs: working_directory: /home/circleci/repo resource_class: medium docker: - - image: bazelruby/ruby-3.0.1 + - image: bazelruby/ruby-3.0.2 environment: PATH: "/usr/local/bin:/usr/bin:/sbin:/opt/bin:/home/circleci/repo/bin:/bin:/sbin:/usr/sbin" BUNDLE_PATH: /home/circleci/.bundle_cache @@ -24,7 +24,7 @@ jobs: - run: name: Install Bundler command: | - gem install bundler:2.0.2 --no-doc + gem install bundler:2.2.28 --no-doc bundle install --jobs=4 --retry=3 --path ${BUNDLE_PATH} - run: diff --git a/.envrc b/.envrc index 3b31e6f..72e49b3 100644 --- a/.envrc +++ b/.envrc @@ -1,15 +1,6 @@ # vi: ft=sh PATH_add bin - -[[ -n $(command -V brew) ]] && { - completion="$(brew --prefix)/etc/bash_completion" - [[ -f "${completion}" ]] && { - echo "Loading bash completion" - source "${completion}" - } -} - eval "$(rbenv init -)" rbenv local $(cat .ruby-version) echo "Ruby Version is $(ruby --version)" diff --git a/.gitignore b/.gitignore index 7ecc9a6..3cecada 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,3 @@ .bazelrc.user user.bazelrc -.readme.adoc diff --git a/.rubocop.yml b/.rubocop.yml index 0d331a5..632114d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,4 +1,8 @@ -inherit_from: .relaxed-rubocop-2.4.yml +inherit_from: + - .rubocop_todo.yml + - .relaxed-rubocop-2.4.yml + + AllCops: TargetRubyVersion: 2.6 @@ -23,6 +27,7 @@ AllCops: - '**/*.ru' - '**/Gemfile' - '**/Rakefile' + NewCops: enable Layout/HashAlignment: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 0000000..e7302d7 --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,20 @@ +# This configuration was generated by +# `rubocop --auto-gen-config` +# on 2021-11-08 22:06:35 UTC using RuboCop version 0.93.1. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 1 +Lint/UnreachableLoop: + Exclude: + - 'ruby/tests/testdata/bundle_includes_workspace/script.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: always, always_true, never +Style/FrozenStringLiteralComment: + Exclude: + - 'ruby/tests/testdata/bundle_includes_workspace/script.rb' diff --git a/.ruby-version b/.ruby-version index cb2b00e..b502146 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.0.1 +3.0.2 diff --git a/.rules_version b/.rules_version index cb0c939..a918a2a 100644 --- a/.rules_version +++ b/.rules_version @@ -1 +1 @@ -0.5.2 +0.6.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ae06b8..5efd5e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,40 @@ # Changelog +## [v0.5.2](https://github.com/bazelruby/rules_ruby/tree/v0.5.2) (2021-11-09) + +[Full Changelog](https://github.com/bazelruby/rules_ruby/compare/v0.6.0...v0.5.2) + +## [v0.6.0](https://github.com/bazelruby/rules_ruby/tree/v0.6.0) (2021-11-09) + +[Full Changelog](https://github.com/bazelruby/rules_ruby/compare/v0.5.1...v0.6.0) + +**Closed issues:** + +- require\_paths attribute does not work [\#97](https://github.com/bazelruby/rules_ruby/issues/97) +- google-protobuf and grpc gems fail [\#86](https://github.com/bazelruby/rules_ruby/issues/86) +- Ruby Gem isn't including generated files [\#85](https://github.com/bazelruby/rules_ruby/issues/85) + +**Merged pull requests:** + +- Bump nokogiri from 1.11.7 to 1.12.5 in /examples/simple\_rails\_api [\#120](https://github.com/bazelruby/rules_ruby/pull/120) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Upstream changes from Selenium's fork [\#118](https://github.com/bazelruby/rules_ruby/pull/118) ([p0deje](https://github.com/p0deje)) +- Bump puma from 4.3.8 to 4.3.9 in /examples/simple\_rails\_api [\#117](https://github.com/bazelruby/rules_ruby/pull/117) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump nokogiri from 1.11.7 to 1.12.5 in /examples/simple\_rails\_api [\#116](https://github.com/bazelruby/rules_ruby/pull/116) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump Ruby primary to 3.0.2 & Add sdk versions: 2.5.9, 2.6.8, 2.7.3, 2.7.4, 3.0.2 [\#114](https://github.com/bazelruby/rules_ruby/pull/114) ([kigster](https://github.com/kigster)) +- Add `includes` option to `ruby_bundle` rule for per-gem load path customization [\#102](https://github.com/bazelruby/rules_ruby/pull/102) ([mmizutani](https://github.com/mmizutani)) + +## [v0.5.1](https://github.com/bazelruby/rules_ruby/tree/v0.5.1) (2021-07-08) + +[Full Changelog](https://github.com/bazelruby/rules_ruby/compare/v0.5.0...v0.5.1) + +**Closed issues:** + +- `ruby_bundle` should support local gems [\#62](https://github.com/bazelruby/rules_ruby/issues/62) + +**Merged pull requests:** + +- feat: Support mapping the vendor cache from workspace [\#92](https://github.com/bazelruby/rules_ruby/pull/92) ([russell](https://github.com/russell)) + ## [v0.5.0](https://github.com/bazelruby/rules_ruby/tree/v0.5.0) (2021-07-08) [Full Changelog](https://github.com/bazelruby/rules_ruby/compare/v0.4.1...v0.5.0) diff --git a/Gemfile.lock b/Gemfile.lock index 2004164..9243824 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,8 +2,8 @@ GEM remote: https://rubygems.org/ specs: ast (2.4.2) - parallel (1.20.1) - parser (3.0.1.1) + parallel (1.21.0) + parser (3.0.2.0) ast (~> 2.4.1) rainbow (3.0.0) regexp_parser (2.1.1) @@ -17,10 +17,10 @@ GEM rubocop-ast (>= 0.6.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 2.0) - rubocop-ast (1.7.0) + rubocop-ast (1.11.0) parser (>= 3.0.1.1) ruby-progressbar (1.11.0) - unicode-display_width (1.7.0) + unicode-display_width (1.8.0) PLATFORMS ruby @@ -30,4 +30,4 @@ DEPENDENCIES rubocop (~> 0.88) BUNDLED WITH - 2.1.4 + 2.2.27 diff --git a/Makefile b/Makefile index 089c5a5..51231a5 100755 --- a/Makefile +++ b/Makefile @@ -21,6 +21,7 @@ SCREEN_WIDTH := 100 MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) CURRENT_DIR := $(notdir $(patsubst %/,%,$(dir $(MAKEFILE_PATH)))) PATH := $(shell echo "$(HOME)/.rbenv/shims:$(PATH)") +RULES_VERSION := $(shell cat .rules_version) help: ## Prints help message auto-generated from the comments. @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' @@ -32,14 +33,13 @@ update-changelog: ## Auto-generate the doc/CHANGELOG (requires GITHUB_TOKEN en @bash -c "$(BASHMATIC_HOME)/bin/regen-changelog" update-readme: ## Generate the PDF version of the README - @printf "\n$(bold) ๐Ÿ‘‰ $(red)๎‚ฐ$(clear) $(green)Converting README.md into the ASCIIDOC...$(clear)\n" - @bash -c "command -v kramdoc || gem install kramdoc; kramdoc README.md" @rm -fv README.pdf @printf "\n$(bold) ๐Ÿ‘‰ $(red)๎‚ฐ$(clear) $(green)Converting ASCIIDOC into the PDF...$(clear)\n" - @mv README.adoc .readme.adoc - @cat .readme .readme.adoc | sed -E "s/source,bazel/source,python/g; s/%VERSION%/$(RULES_VERSION)/g" > README.adoc @$(BASHMATIC_HOME)/bin/adoc2pdf README.adoc @git add README.pdf @open README.pdf +tag: ## Tag this commit with .rules_version and push to remote + @git tag "v$(RULES_VERSION)" -f + @git push --tags -f diff --git a/README.adoc b/README.adoc new file mode 100644 index 0000000..758e9bb --- /dev/null +++ b/README.adoc @@ -0,0 +1,989 @@ += Ruby Rulesยฎ for Bazel +:subtitle: Version 0.5.2 +:author: Yuki (Yugui) Sonoda, Konstantin Gredeskoul & Contributors. +:doctype: book +:source-highlighter: rouge +:rouge-style: base16.monokai +:toclevels: 5 +:toc: +:sectnums: 9 +:icons: font +:license: apache + + +==== +This repo is primarily maintained by https://github.com/kigster[Konstantin Gredeskoul] and https://github.com/yugui[Yuki "Yugui" Sonoda]. We are both very busy and would really love more contributors to join the core team. If you are interested in developing Ruby Rules for Bazel, please submit a couple of PRs and then lets talk! +==== + +TIP: You can read or print this README in a proper PDF format by grabbing our link:README.pdf[README.pdf]. + +== Build Status & Activity + +[cols="3,9",options="header",] +|=== +| *CI Status* | *Activity & Documentation* + +| image:https://circleci.com/gh/bazelruby/rules_ruby.svg?style=shield[CircleCI,link=https://circleci.com/gh/bazelruby/rules_ruby]   +| image:https://img.shields.io/github/commit-activity/m/bazelruby/rules_ruby?style=for-the-badge[activity]   + +| image:https://travis-ci.org/bazelruby/rules_ruby.svg?branch=master[Build Status,link=https://travis-ci.org/bazelruby/rules_ruby]   +| xref:CHANGELOG.md[image:https://img.shields.io/badge/change-log-brightgreen[changelog\]] link:README.pdf[image:https://img.shields.io/badge/README-pdf-blue[readme.pdf\]] +|=== + +== Rules Development Status + +[cols="3,9",options="header",] +|=== +| *Readiness* | *Types of Applications* + +| image:docs/img/status-ready.svg[Ready] +| ruby apps, ruby gems, micro-services, ideally in a mono-repo + +| image:docs/img/status-ready.svg[Wait] +| medium-sized Ruby on Rails apps, ideally in a mono-repo + +| image:docs/img/status-wait.svg[Not Ready] +| complex Ruby on Rails monoliths, single-repo +|=== + +NOTE: we have a short guide on https://github.com/bazelruby/rules_ruby/wiki/Build-your-ruby-project[Building your first Ruby Project] on the Wiki. We encourage you to check it out. + +== Table of Contents + +* <> + ** <> + ** <> + ** <> + ** <> + *** <> + *** <> *** <> *** <> + ** <> + *** <> + *** <> + *** <> + *** <> + *** <> + *** <> + ** <> + ** <> + *** <> + *** <> + *** <> + *** <> + *** <> + *** <> + ** <> + +== Usage + +=== `WORKSPACE` File + +==== Load dependencies, select Ruby SDK and define one or more Bundles + +[source,python] +---- +workspace(name = "my_ruby_project") + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") + +#โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” +# To get the latest ruby rules, grab the 'master' branch. +#โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” + +git_repository( + name = "bazelruby_rules_ruby", + remote = "https://github.com/bazelruby/rules_ruby.git", + branch = "master" +) + +load( + "@bazelruby_rules_ruby//ruby:deps.bzl", + "rules_ruby_dependencies", + "rules_ruby_select_sdk", +) + +rules_ruby_dependencies() + +#โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” +# Specify Ruby version โ€” this will either build Ruby or use a local +# RBENV installation if the Ruby version matches. +#โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” + +load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") +bazel_skylib_workspace() + +rules_ruby_select_sdk(version = "3.0.2") + +#โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” +# Now, load the ruby_bundle rule & install gems specified in the Gemfile +#โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” + +load( + "@bazelruby_rules_ruby//ruby:defs.bzl", + "ruby_bundle", +) + +ruby_bundle( + name = "bundle", + # Specify additional paths to be loaded from the gems at runtime, if any. + # Since spec.require_paths in Gem specifications are auto-included, directory paths + # in spec.require_paths do not need to be listed in includes hash. + includes = { + "grpc": ["etc"], + }, + excludes = { + "mini_portile": ["test/**/*"], + }, + gemfile = "//:Gemfile", + gemfile_lock = "//:Gemfile.lock", +) + +# You can specify more than one bundle in the WORKSPACE file +ruby_bundle( + name = "bundle_app_shopping", + gemfile = "//:apps/shopping/Gemfile", + gemfile_lock = "//:apps/shopping/Gemfile.lock", +) + +# You can also install from Gemfile using `gemspec`. +ruby_bundle( + name = "bundle_gemspec", + srcs = ["//:lib/my_gem/my_gem.gemspec"], + gemfile = "//:lib/my_gem/Gemfile", + gemfile_lock = "//:lib/my_gem/Gemfile.lock", +) +---- + +=== `BUILD.bazel` file(s) + +Any of the project `BUILD` files can now reference any gems included in the `Gemfile` referenced by the `ruby_bundle` rule, and defined in the project's `WORKSPACE` file. + +==== Define Ruby Executable, Library and an RSpec + +Add `ruby_library`, `ruby_binary`, `ruby_rspec` or `ruby_test` into your `BUILD.bazel` files. + +[source,python] +---- +#โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” +# Define Ruby executable, test, spec and package a gem +#โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” + +load( + "@bazelruby_rules_ruby//ruby:defs.bzl", + "ruby_binary", + "ruby_library", + "ruby_test", + "ruby_rspec", +) + +ruby_library( + name = "foo", + srcs = glob(["lib/**/*.rb"]), + includes = ["lib"], + deps = [ + "@bundle//:activesupport", + "@bundle//:awesome_print", + "@bundle//:rubocop", + ] +) + +ruby_binary( + name = "bar", + srcs = ["bin/bar"], + deps = [":foo"], +) + +ruby_test( + name = "foo-test", + srcs = ["test/foo_test.rb"], + deps = [":foo"], +) + +ruby_rspec( + name = "foo-spec", + specs = glob(["spec/**/*.rb"]), + rspec_args = { "--format": "progress" }, + deps = [":foo"] +} +---- + +==== Package Ruby files as a Gem + +Use `ruby_gem` rule to package any number of ruby files or folders into a Ruby-Gem compatible ZIP archive. + +[source,python] +---- +load( + "@bazelruby_rules_ruby//ruby:defs.bzl", + "ruby_gem", +) + +ruby_gem( + name = "awesome-sauce-gem", # name of the build target + gem_name = "awesome-sauce", # name of the gem + gem_version = "0.1.0", + gem_summary = "Example gem to demonstrate Bazel Gem packaging", + gem_description = "Example gem to demonstrate Bazel Gem packaging", + gem_homepage = "https://github.com/bazelruby/rules_ruby", + gem_authors = [ + "BazelRuby", + "Konstantin Gredeskoul" + ], + gem_author_emails = [ + "bazelruby@googlegroups.com", + ], + gem_runtime_dependencies = { + "colored2": "~> 3.1.2", + "hashie": "", + }, + gem_development_dependencies = { + "rspec": "", + "rspec-its": "", + "rubocop": "", + }, + srcs = [ + glob("{bin,exe,lib,spec}/**/*.rb") + ], + deps = [ + "//lib:example_gem", + ], +) +---- + +=== Tool Specific Setup + +==== ASDF + +If you are using ASDF to manage your ruby installs, you can use them by adding `.bazelrc`: + +---- +build --test_env=ASDF_DIR --test_env=ASDF_DATA_DIR +build --action_env=ASDF_DIR --test_env=ASDF_DATA_DIR +---- + +You will have to be sure to export the `ASDF_DATA_DIR` in your profile since it's not set by default. e.g. `export ASDF_DATA_DIR="$HOME/.asdf"` + +=== Rule Dependency Diagram + +NOTE: this diagram is somewhat outdated. + +The following diagram attempts to capture the implementation behind `ruby_library` that depends on the result of `bundle install`, and a `ruby_binary` that depends on both: + +image::docs/img/ruby_rules.png[Ruby Rules] + +== Rules + +=== `ruby_library` + +[source,python] +---- +ruby_library( + name, + deps, + srcs, + data, + compatible_with, + deprecation, + distribs, + features, + licenses, + restricted_to, + tags, + testonly, + toolchains, + visibility) +---- + +[cols="15,85",options="header",] +|=== +|Attributes | +|`name` a| +`Name, required` + +A unique name for this rule. + +|`srcs` a| +`List of Labels, optional` + +List of `.rb` files. + +At least `srcs` or `deps` must be present + +|`deps` a| +`List of labels, optional` + +List of targets that are required by the `srcs` Ruby files. + +At least `srcs` or `deps` must be present + +|`includes` a| +`List of strings, optional` + +List of paths to be added to `$LOAD_PATH` at runtime. The paths must be relative to the the workspace which this rule belongs to. + +|`rubyopt` a| +`List of strings, optional` + +List of options to be passed to the Ruby interpreter at runtime. + +NOTE: `-I` option should usually go to `includes` attribute. + +2+ 3.0` means that all versions up to `4.0` are accepted. + +|`gem_development_dependencies` a| +`String Dictionary, optional` + +Similar to the above, this specifies gems necessary for the development of the above gem, such as testing gems, linters, code coverage and more. + +2+<|And other https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes[common attributes]. +|=== + + + +== Potential Future Features + +==== +icon:check-square[fw] Using various versions of Ruby installed locally + +icon:square[fw] Building native extensions in gems with Bazel + +icon:square[fw] Releasing your gems with Bazel (https://github.com/coinbase/rules_ruby[Coinbase fork] might have this feature, worth checking) +==== + +== Contributing + +We welcome contributions to RulesRuby. Please make yourself familiar with the xref:CODE_OF_CONDUCT.adoc[code of conduct], which basically says -- don't be an a-hole. + +You may notice that there is more than one Bazel WORKSPACE inside this repo. There is one in `examples/simple_script` for instance, because +we use this example to validate and test the rules. So be mindful whether your current directory contains `WORKSPACE` file or not. + +=== Setup + +==== Using the Script + +You will need Homebrew installed prior to running the script. + +After that, cd into the top level folder and run the setup script in your Terminal: + +[source,bash] +---- +โฏ bin/setup +---- + +This runs a complete setup, shouldn't take too long. You can explore various script options with the `help` command: + +[source,bash] +---- +โฏ bin/setup -h + +USAGE + # without any arguments runs a complete setup. + bin/setup + + # alternatively, a sub-setup function name can be passed: + bin/setup [ gems | git-hook | help | main | os-specific | rbenv | remove-git-hook ] + +DESCRIPTION: + Runs full setup without any arguments. + + Accepts one optional argument โ€” one of the actions that typically run + as part of setup, with one exception โ€” remove-git-hook. + This action removes the git commit hook installed by the setup. + +EXAMPLES: + bin/setup + + Or, to run only one of the sub-functions (actions), pass + it as an argument: + + bin/setup help + bin/setup remove-git-hook +---- + +==== OS-Specific Setup + +Note that the setup contains `os-specific` section. This is because there are two extension scripts: + +* `bin/setup-linux` +* `bin/setup-darwin` + +Those will install Bazel and everything else you need on either platform. In fact, we use the linux version on CI. + +=== Verifying Your Environment + +We provided a handy script `bin/show-env` to display where your dependencies are coming from. Here is an example of running it on a Mac OS-X system: + +[source,bash] +---- +โฏ bin/show-env +---- + +image::docs/img/env.png[bin/show-env] + +==== Issues During Setup + +____ +*Please report any errors to `bin/setup` as Issues on Github. You can assign them to @kigster.* If I am not responding fast enough, and you are in a hurry, please email kigster AT gmail directly. +____ + +=== Developing Rules + +Besides making yourself familiar with the existing code, and https://docs.bazel.build/versions/master/skylark/concepts.html[Bazel documentation on writing rules], you might want to follow this order: + +. Setup dev tools as described in the <> section. +. hack, hack, hack... +. Make sure all tests pass -- you can run a single command for that (but see more on it <>. + +[source,bash] +---- +bin/test-suite +---- + +OR, you can run individual Bazel test commands from the inside. + +* `bazel test //...` +* `cd examples/simple_script && bazel test //...` + +. Open a pull request in Github, and please be as verbose as possible in your description. + +In general, it's always a good idea to ask questions first -- you can do so by creating an issue. + +=== Running Tests + +After running setup, and since this is a bazel repo you can use Bazel commands: + +[source,python] +---- +bazel build //...:all +bazel query //...:all +bazel test //...:all +---- + +But to run tests inside each sub-WORKSPACE, you will need to repeat that in each sub-folder. Luckily, there is a better way. + +==== Test Script + +This script runs all tests (including sub-workspaces) when ran without arguments: + +[source,bash] +---- +bin/test-suite +---- + +Run it with `help` command to see other options, and to see what parts you can run individually. At the moment they are: + +[source,bash] +---- +# alternatively, a partial test name can be passed: +bin/test-suite [ all | bazel-info | buildifier | help | rspec | rubocop | simple-script | workspace ] +---- + +On a MacBook Pro it takes about 3 minutes to run. + +=== Linter + +We are using RuboCop for ruby and Buildifier for Bazel. Both are represented by a single script `bin/linter`, which just like the scripts above runs ALL linters when ran without arguments, accepts `help` commnd, and can be run on a subset of linting strategies: + +[source,bash] +---- +bin/linter +---- + +The following are the partial linting functions you can run: + +[source,bash] +---- +# alternatively, a partial linter name can be passed: +bin/linter [ all | buildifier | help | rubocop ] +---- + +=== Regenerating README.pdf & Changelog + +To regenerate, first you may need to grab an https://github.com/settings/tokens[API token] and export the `GITHUB_TOKEN` variable: + +[source,bash] +---- +export GITHUB_TOKEN=.... +---- + +Then use the `make` target: + +[source,bash] +---- +make update +---- + +Or, manually: + +[source,bash] +---- +gem install github_changelog_generator +github_changelog_generator -u bazelruby -p rules_ruby -t your-github-token +---- + +== Copyright + +ยฉ 2018-2021 BazelRuby Contributors. + +Core Team: + +* https://github.com/yugui/[Yuki Yugui Sonoda] +* https://kig.re/[Konstantin Gredeskoul] + +Core Team (Emeritus): + +* https://github.com/grahamjenson[Graham Jenson] + +Licensed under the http://www.apache.org/licenses/LICENSE-2.0[Apache License, Version 2.0 (the "License")]. + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/README.md b/README.md deleted file mode 100644 index fb831c3..0000000 --- a/README.md +++ /dev/null @@ -1,1159 +0,0 @@ -# Ruby Rulesยฎ for [Bazel](https://bazel.build) Build System - -> This repo is primarily maintained by [Konstantin Gredeskoul](https://github.com/kigster) and [Yuki "Yugui" Sonoda](https://github.com/yugui). We are both very busy and would really love more contributors to join the core team. If you are interested in developing Ruby Rules for Bazel, please submit a couple of PRs and then lets talk! - -## Build Status & Activity - -| **CI Status** | **Activity & Documentation** | -| :------------------------------------------ | :----------------------------------------------------------- | -| [![CircleCI](https://circleci.com/gh/bazelruby/rules_ruby.svg?style=shield)](https://circleci.com/gh/bazelruby/rules_ruby)   | ![activity](https://img.shields.io/github/commit-activity/m/bazelruby/rules_ruby?style=for-the-badge)   | -| [![Build Status](https://travis-ci.org/bazelruby/rules_ruby.svg?branch=master)](https://travis-ci.org/bazelruby/rules_ruby)   | [![changelog](https://img.shields.io/badge/change-log-brightgreen)](CHANGELOG.md) [![readme.pdf](https://img.shields.io/badge/README-pdf-blue)](README.pdf) | - - -## Rules Development Status - -| **Readiness** | **Types of Applications** | -| :------------------------------------------ | :----------------------------------------------------------- | -| ![Ready](docs/img/status-ready.svg) | ruby apps, ruby gems, micro-services, ideally in a mono-repo | -| ![Wait](docs/img/status-ready.svg) | medium-sized Ruby on Rails apps, ideally in a mono-repo | -| ![Not Ready](docs/img/status-wait.svg) | complex Ruby on Rails monoliths, single-repo | - -Note: we have a short guide on [Building your first Ruby Project](https://github.com/bazelruby/rules_ruby/wiki/Build-your-ruby-project) on the Wiki. We encourage you to check it out. - -## Table of Contents - -- [Ruby Rulesยฎ for Bazel Build System](#ruby-rules-for-bazelhttpsbazelbuild-build-system) - - [Build Status & Activity](#build-status-activity) - - [Rules Development Status](#rules-development-status) - - [Table of Contents](#table-of-contents) - - [Usage](#usage) - - [`WORKSPACE` File](#workspace-file) - - [`BUILD.bazel` file(s)](#buildbazel-files) - - [Tool Specific Setup](#tool-specific-setup) - - [Rule Dependency Diagram](#rule-dependency-diagram) - - [Rules](#rules) - - [`ruby_library`](#ruby_library) - - [`ruby_binary`](#ruby_binary) - - [`ruby_test`](#ruby_test) - - [`ruby_bundle`](#ruby_bundle) - - [`ruby_rspec`](#ruby_rspec) - - [`ruby_gem`](#ruby_gem) - - [Potential Future Features](#potential-future-features) - - [Contributing](#contributing) - - [Setup](#setup) - - [Verifying Your Environment](#verifying-your-environment) - - [Developing Rules](#developing-rules) - - [Running Tests](#running-tests) - - [Linter](#linter) - - [Regenerating README.pdf & Changelog](#regenerating-readmepdf-changelog) - - [Copyright](#copyright) - -## Usage - -### `WORKSPACE` File - -#### Load dependencies, select Ruby SDK and define one or more Bundles - -```python -workspace(name = "my_ruby_project") - -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") -load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") - -#โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” -# To get the latest ruby rules, grab the 'master' branch. -#โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” - -git_repository( - name = "bazelruby_rules_ruby", - remote = "https://github.com/bazelruby/rules_ruby.git", - branch = "master" -) - -load( - "@bazelruby_rules_ruby//ruby:deps.bzl", - "rules_ruby_dependencies", - "rules_ruby_select_sdk", -) - -rules_ruby_dependencies() - -#โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” -# Specify Ruby version โ€” this will either build Ruby or use a local -# RBENV installation if the Ruby version matches. -#โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” - -load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") -bazel_skylib_workspace() - -rules_ruby_select_sdk(version = "3.0.1") - -#โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” -# Now, load the ruby_bundle rule & install gems specified in the Gemfile -#โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” - -load( - "@bazelruby_rules_ruby//ruby:defs.bzl", - "ruby_bundle", -) - -ruby_bundle( - name = "bundle", - # Specify additional paths to be loaded from the gems at runtime, if any. - # Since spec.require_paths in Gem specifications are auto-included, directory paths - # in spec.require_paths do not need to be listed in includes hash. - includes = { - "grpc": ["etc"], - }, - excludes = { - "mini_portile": ["test/**/*"], - }, - gemfile = "//:Gemfile", - gemfile_lock = "//:Gemfile.lock", -) - -# You can specify more than one bundle in the WORKSPACE file -ruby_bundle( - name = "bundle_app_shopping", - gemfile = "//apps/shopping:Gemfile", - gemfile_lock = "//apps/shopping:Gemfile.lock", -) -``` - -### `BUILD.bazel` file(s) - -Any of the project `BUILD` files can now reference any gems included in the `Gemfile` referenced by the `ruby_bundle` rule, and defined in the project's `WORKSPACE` file. - -#### Define Ruby Executable, Library and an RSpec - -Add `ruby_library`, `ruby_binary`, `ruby_rspec` or `ruby_test` into your `BUILD.bazel` files. - -```python -#โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” -# Define Ruby executable, test, spec and package a gem -#โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” - -load( - "@bazelruby_rules_ruby//ruby:defs.bzl", - "ruby_binary", - "ruby_library", - "ruby_test", - "ruby_rspec", -) - -ruby_library( - name = "foo", - srcs = glob(["lib/**/*.rb"]), - includes = ["lib"], - deps = [ - "@bundle//:activesupport", - "@bundle//:awesome_print", - "@bundle//:rubocop", - ] -) - -ruby_binary( - name = "bar", - srcs = ["bin/bar"], - deps = [":foo"], -) - -ruby_test( - name = "foo-test", - srcs = ["test/foo_test.rb"], - deps = [":foo"], -) - -ruby_rspec( - name = "foo-spec", - specs = glob(["spec/**/*.rb"]), - rspec_args = { "--format": "progress" }, - deps = [":foo"] -} -``` - -#### Package Ruby files as a Gem - -Use `ruby_gem` rule to package any number of ruby files or folders into a Ruby-Gem compatible ZIP archive. - -```python -load( - "@bazelruby_rules_ruby//ruby:defs.bzl", - "ruby_gem", -) - -ruby_gem( - name = "awesome-sauce-gem", # name of the build target - gem_name = "awesome-sauce", # name of the gem - gem_version = "0.1.0", - gem_summary = "Example gem to demonstrate Bazel Gem packaging", - gem_description = "Example gem to demonstrate Bazel Gem packaging", - gem_homepage = "https://github.com/bazelruby/rules_ruby", - gem_authors = [ - "BazelRuby", - "Konstantin Gredeskoul" - ], - gem_author_emails = [ - "bazelruby@googlegroups.com", - ], - gem_runtime_dependencies = { - "colored2": "~> 3.1.2", - "hashie": "", - }, - gem_development_dependencies = { - "rspec": "", - "rspec-its": "", - "rubocop": "", - }, - srcs = [ - glob("{bin,exe,lib,spec}/**/*.rb") - ], - deps = [ - "//lib:example_gem", - ], -) - -``` - -### Tool Specific Setup - -#### ASDF - -If you are using ASDF to manage your ruby installs, you can use them by adding `.bazelrc`: - -``` -build --test_env=ASDF_DIR --test_env=ASDF_DATA_DIR -build --action_env=ASDF_DIR --test_env=ASDF_DATA_DIR -``` - -You will have to be sure to export the `ASDF_DATA_DIR` in your profile since it's not set by default. e.g. `export ASDF_DATA_DIR="$HOME/.asdf"` - -### Rule Dependency Diagram - -> NOTE: this diagram is somewhat outdated. - -The following diagram attempts to capture the implementation behind `ruby_library` that depends on the result of `bundle install`, and a `ruby_binary` that depends on both: - -![Ruby Rules](docs/img/ruby_rules.png) - -## Rules - -### `ruby_library` - -```python -ruby_library( - name, - deps, - srcs, - data, - compatible_with, - deprecation, - distribs, - features, - licenses, - restricted_to, - tags, - testonly, - toolchains, - visibility) -``` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Attributes
name - Name, required -

A unique name for this rule.

-
srcs - List of Labels, optional -

- List of .rb files. -

-

At least srcs or deps must be present

-
deps - List of labels, optional -

- List of targets that are required by the srcs Ruby - files. -

-

At least srcs or deps must be present

-
includes - List of strings, optional -

- List of paths to be added to $LOAD_PATH at runtime. - The paths must be relative to the the workspace which this rule belongs to. -

-
rubyopt - List of strings, optional -

- List of options to be passed to the Ruby interpreter at runtime. -

-

- NOTE: -I option should usually go to includes attribute. -

-
And other common attributes
- - -### `ruby_binary` - -```python -ruby_binary( - name, - deps, - srcs, - data, - main, - compatible_with, - deprecation, - distribs, - features, - licenses, - restricted_to, - tags, - testonly, - toolchains, - visibility, - args, - output_licenses -) -``` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Attributes
name - Name, required -

A unique name for this rule.

-
srcs - List of Labels, required -

- List of .rb files. -

-
deps - List of labels, optional -

- List of targets that are required by the srcs Ruby - files. -

-
main - Label, optional -

The entrypoint file. It must be also in srcs.

-

If not specified, $(NAME).rb where $(NAME) is the name of this rule.

-
includes - List of strings, optional -

- List of paths to be added to $LOAD_PATH at runtime. - The paths must be relative to the the workspace which this rule belongs to. -

-
rubyopt - List of strings, optional -

- List of options to be passed to the Ruby interpreter at runtime. -

-

- NOTE: -I option should usually go to includes attribute. -

-
And other common attributes
- - -### `ruby_test` - -```python -ruby_test( - name, - deps, - srcs, - data, - main, - compatible_with, - deprecation, - distribs, - features, - licenses, - restricted_to, - tags, - testonly, - toolchains, - visibility, - args, - size, - timeout, - flaky, - local, - shard_count -) -``` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Attributes
name - Name, required -

A unique name for this rule.

-
srcs - List of Labels, required -

- List of .rb files. -

-
deps - List of labels, optional -

- List of targets that are required by the srcs Ruby - files. -

-
main - Label, optional -

The entrypoint file. It must be also in srcs.

-

If not specified, $(NAME).rb where $(NAME) is the name of this rule.

-
includes - List of strings, optional -

- List of paths to be added to $LOAD_PATH at runtime. - The paths must be relative to the the workspace which this rule belongs to. -

-
rubyopt - List of strings, optional -

- List of options to be passed to the Ruby interpreter at runtime. -

-

- NOTE: -I option should usually go to includes attribute. -

-
And other common attributes
- - -### `ruby_bundle` - -**NOTE: This is a repository rule, and can only be used in a `WORKSPACE` file.** - -This rule installs gems defined in a Gemfile using Bundler, and exports individual gems from the bundle, as well as the entire bundle, available as a `ruby_library` that can be depended upon from other targets. - -```python -ruby_bundle( - name, - gemfile, - gemfile_lock, - bundler_version = "2.1.4", - includes = {}, - excludes = {}, - vendor_cache = False, - ruby_sdk = "@org_ruby_lang_ruby_toolchain", - ruby_interpreter = "@org_ruby_lang_ruby_toolchain//:ruby", -) -``` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Attributes
name - Name, required -

A unique name for this rule.

-
gemfile - Label, required -

- The Gemfile which Bundler runs with. -

-
gemfile_lock - Label, required -

The Gemfile.lock which Bundler runs with.

-

NOTE: This rule never updates the Gemfile.lock. It is your responsibility to generate/update Gemfile.lock

-
vendor_cache - Bool, optional -

Symlink the vendor directory into the Bazel build space, this allows Bundler to access vendored Gems

-
bundler_version - String, optional -

The Version of Bundler to use. Defaults to 2.1.4.

-

NOTE: This rule never updates the Gemfile.lock. It is your responsibility to generate/update Gemfile.lock

-
includes - Dictionary of key-value-pairs (key: string, value: list of strings), optional -

- List of glob patterns per gem to be additionally loaded from the library. - Keys are the names of the gems which require some file/directory paths not listed in the require_paths attribute of the gemspecs to be also added to $LOAD_PATH at runtime. - Values are lists of blob path patterns, which are relative to the root directories of the gems. -

-
excludes - Dictionary of key-value-pairs (key: string, value: list of strings), optional -

- List of glob patterns per gem to be excluded from the library. - Keys are the names of the gems. - Values are lists of blob path patterns, which are relative to the root directories of the gems. - The default value is ["**/* *.*", "**/* */*"] -

-
- - -#### Limitations - -Installing using a `Gemfile` that uses the `gemspec` keyword is not currently supported. - -#### Conventions - -`ruby_bundle` creates several targets that can be used downstream. In the examples below we assume that your `ruby_bundle` has a name `app_bundle`: - -- `@app_bundle//:bundler` โ€” references just the Bundler from the bundle. -- `@app_bundle//:gems` โ€” references _all_ gems in the bundle (i.e. "the entire bundle"). -- `@app_bundle//:gem-name` โ€” references _just the specified_ gem in the bundle, eg. `@app_bundle//:awesome_print`. -- `@app_bundle//:bin` โ€” references to all installed executables from this bundle, with individual executables accessible via eg. `@app_bundle//:bin/rubocop` - -#### `WORKSPACE`: - -```python -load("@bazelruby_rules_ruby//ruby:defs.bzl", "ruby_bundle") - -ruby_bundle( - name = "gems", - bundler_version = '2.1.4', - gemfile = "//:Gemfile", - gemfile_lock = "//:Gemfile.lock", -) -``` - -##### Vendor directory handling - -To use the vendor cache, you have to declare a `managed_directory` in -your workspace. The name should match the name of the bundle. - -``` bazel -load("@bazelruby_rules_ruby//ruby:defs.bzl", "ruby_bundle") - -workspace( - name = "my_wksp", - managed_directories = {"@bundle": ["vendor"]}, -) - -ruby_bundle( - name = "bundle", - bundler_version = "2.1.2", - vendor_cache = True, - gemfile = "//:Gemfile", - gemfile_lock = "//:Gemfile.lock", -) -``` - -#### `BUILD.bazel`: - -```python -# Reference the entire bundle with :gems - -ruby_library( - name = "foo", - srcs = ["foo.rb"], - deps = ["@gems//:gems"], -) - -# Or, reference specific gems from the bundle like so: - -ruby_binary( - name = "rubocop", - srcs = [":foo", ".rubocop.yml"], - args = ["-P", "-D", "-c" ".rubocop.yml"], - main = "@gems//:bin/rubocop", - deps = ["@gems//:rubocop"], -) -``` - -### `ruby_rspec` - -```python -ruby_rspec( - name, - deps, - srcs, - data, - main, - rspec_args, - bundle, - compatible_with, - deprecation, - distribs, - features, - licenses, - restricted_to, - tags, - testonly, - toolchains, - visibility, - args, - size, - timeout, - flaky, - local, - shard_count -) -``` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Attributes
name - Name, required -

A unique name for this rule.

-
srcs - List of Labels, required -

- List of .rb files. -

-
deps - List of labels, optional -

- List of targets that are required by the srcs Ruby - files. -

-
main - Label, optional -

The entrypoint file. It must be also in srcs.

-

If not specified, $(NAME).rb where $(NAME) is the name of this rule.

-
rspec_args - List of strings, optional -

Command line arguments to the rspec binary, eg ["--progress", "-p2", "-b"]

-

If not specified, the default arguments defined in `constants.bzl` are used: --format=documentation --force-color.

-
includes - List of strings, optional -

- List of paths to be added to $LOAD_PATH at runtime. - The paths must be relative to the the workspace which this rule belongs to. -

-
rubyopt - List of strings, optional -

- List of options to be passed to the Ruby interpreter at runtime. -

-

- NOTE: -I option should usually go to includes attribute. -

-
And other common attributes
- - -### `ruby_gem` - -Used to generate a zipped gem containing its srcs, dependencies and a gemspec. - -```python -ruby_gem( - name, - gem_name, - gem_version, - gem_summary, - gem_description, - gem_homepage, - gem_authors, - gem_author_emails, - gem_runtime_dependencies, - gem_development_dependencies, - require_paths = ["lib"], - srcs = srcs, - deps = deps, - data = data -) -``` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Attributes
name - Name, required -

A unique name for this build target.

-
gem_name - Name of the gem, required -

The name of the gem to be generated.

-
gem_version - String, optional -

- The version of the gem. Is used to name the output file, - which becomes name-version.zip, and also - included in the Gemspec. -

-
gem_summary - String, optional -

One line summary of the gem purpose.

-
gem_description - String, required -

Single-line, paragraph-sized description text for the gem.

-
gem_homepage - String, optional -

Homepage URL of the gem.

-
gem_authors - List of Strings, required -

- List of human readable names of the gem authors. - Required to generate a valid gemspec. -

-
gem_author_emails - List of Strings, optional -

- List of email addresses of the authors. -

-
srcs - List of Labels, optional -

- List of .rb files. -

-

At least srcs or deps must be present

-
deps - List of labels, optional -

- List of targets that are required by the srcs Ruby - files. -

-

At least srcs or deps must be present

-
require_paths - List of Strings, optional -

- List of paths to be added to the Ruby LOAD_PATH when using this gem. - Typically this value is just `lib` (which is also the default). -

-
gem_runtime_dependencies - String Dictionary, optional -

- This is a dictionary where keys are gem names, and values are either an empty - string or a gem version specification. - For instance, the pessimistic version specifier ~> 3.0 means that all versions up to 4.0 are accepted. -

-
gem_development_dependencies - String Dictionary, optional -

- Similar to the above, this specifies gems necessary for the development of the above gem, such as - testing gems, linters, code coverage and more. -

-
- - -## Potential Future Features - -- [x] Using various versions of Ruby installed locally -- [ ] Building native extensions in gems with Bazel -- [ ] Releasing your gems with Bazel ([Coinbase fork](https://github.com/coinbase/rules_ruby) might have this feature, worth checking) - -## Contributing - -We welcome contributions to RulesRuby. Please make yourself familiar with the [code of conduct](CODE_OF_CONDUCT.md), which basically says โ€” don't be an a-hole. - -You may notice that there is more than one Bazel WORKSPACE inside this repo. There is one in `examples/simple_script` for instance, because -we use this example to validate and test the rules. So be mindful whether your current directory contains `WORKSPACE` file or not. - -### Setup - -#### Using the Script - -You will need Homebrew installed prior to running the script. - -After that, cd into the top level folder and run the setup script in your Terminal: - -```bash -โฏ bin/setup -``` - -This runs a complete setup, shouldn't take too long. You can explore various script options with the `help` command: - -```bash -โฏ bin/setup -h - -USAGE - # without any arguments runs a complete setup. - bin/setup - - # alternatively, a sub-setup function name can be passed: - bin/setup [ gems | git-hook | help | main | os-specific | rbenv | remove-git-hook ] - -DESCRIPTION: - Runs full setup without any arguments. - - Accepts one optional argument โ€” one of the actions that typically run - as part of setup, with one exception โ€” remove-git-hook. - This action removes the git commit hook installed by the setup. - -EXAMPLES: - bin/setup - - Or, to run only one of the sub-functions (actions), pass - it as an argument: - - bin/setup help - bin/setup remove-git-hook -``` - -#### OS-Specific Setup - -Note that the setup contains `os-specific` section. This is because there are two extension scripts: - -- `bin/setup-linux` -- `bin/setup-darwin` - -Those will install Bazel and everything else you need on either platform. In fact, we use the linux version on CI. - -### Verifying Your Environment - -We provided a handy script `bin/show-env` to display where your dependencies are coming from. Here is an example of running it on a Mac OS-X system: - -```bash -โฏ bin/show-env -``` - -![bin/show-env](docs/img/env.png) - -#### Issues During Setup - -> **Please report any errors to `bin/setup` as Issues on Github. You can assign them to @kigster.** If I am not responding fast enough, and you are in a hurry, please email kigster AT gmail directly. - -### Developing Rules - -Besides making yourself familiar with the existing code, and [Bazel documentation on writing rules](https://docs.bazel.build/versions/master/skylark/concepts.html), you might want to follow this order: - -1. Setup dev tools as described in the [setup](#Setup) section. -2. hack, hack, hack... -3. Make sure all tests pass โ€” you can run a single command for that (but see more on it [below](#test-script). - - -```bash -bin/test-suite -``` - -OR, you can run individual Bazel test commands from the inside. - -- `bazel test //...` -- `cd examples/simple_script && bazel test //...` - -4. Open a pull request in Github, and please be as verbose as possible in your description. - -In general, it's always a good idea to ask questions first โ€” you can do so by creating an issue. - -### Running Tests - -After running setup, and since this is a bazel repo you can use Bazel commands: - -```python -bazel build //...:all -bazel query //...:all -bazel test //...:all -``` - -But to run tests inside each sub-WORKSPACE, you will need to repeat that in each sub-folder. Luckily, there is a better way. - -#### Test Script - -This script runs all tests (including sub-workspaces) when ran without arguments: - -```bash -bin/test-suite -``` - -Run it with `help` command to see other options, and to see what parts you can run individually. At the moment they are: - -```bash -# alternatively, a partial test name can be passed: -bin/test-suite [ all | bazel-info | buildifier | help | rspec | rubocop | simple-script | workspace ] -``` - -On a MacBook Pro it takes about 3 minutes to run. - -### Linter - -We are using RuboCop for ruby and Buildifier for Bazel. Both are represented by a single script `bin/linter`, which just like the scripts above runs ALL linters when ran without arguments, accepts `help` commnd, and can be run on a subset of linting strategies: - -```bash -bin/linter -``` - -The following are the partial linting functions you can run: - -```bash -# alternatively, a partial linter name can be passed: -bin/linter [ all | buildifier | help | rubocop ] -``` - -### Regenerating README.pdf & Changelog - -To regenerate, first you may need to grab an [API token](https://github.com/settings/tokens) and export the `GITHUB_TOKEN` variable: - -```bash -export GITHUB_TOKEN=.... -``` - -Then use the `make` target: - -```bash -make update -``` - -Or, manually: - -```bash -gem install github_changelog_generator -github_changelog_generator -u bazelruby -p rules_ruby -t your-github-token -``` - - -## Copyright - -ยฉ 2018-2021 BazelRuby Contributors. - -Core Team: - - * [Yuki Yugui Sonoda](https://github.com/yugui/) - * [Konstantin Gredeskoul](https://kig.re/) - -Core Team (Emeritus): - - * [Graham Jenson](https://github.com/grahamjenson) - -Licensed under the [Apache License, Version 2.0 (the "License")](http://www.apache.org/licenses/LICENSE-2.0). - - -Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - diff --git a/README.pdf b/README.pdf index 2a47d91..87bfb50 100644 Binary files a/README.pdf and b/README.pdf differ diff --git a/VERSION.yml b/VERSION.yml index 0d19763..23aefb4 100644 --- a/VERSION.yml +++ b/VERSION.yml @@ -1,4 +1,4 @@ rules_ruby: - version: 0.5.2 + version: 0.6.0 diff --git a/WORKSPACE b/WORKSPACE index 0ebc4dd..e08c5ee 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -12,7 +12,7 @@ load("@bazel_skylib//lib:versions.bzl", "versions") versions.check("3.4.1") -rules_ruby_select_sdk("3.0.1") +rules_ruby_select_sdk("3.0.2") local_repository( name = "bazelruby_rules_ruby_ruby_tests_testdata_another_workspace", diff --git a/bin/deps b/bin/deps index 13688af..dfdbbcc 100755 --- a/bin/deps +++ b/bin/deps @@ -15,7 +15,6 @@ # shellcheck disable=SC1090 source "${BASHMATIC_HOME}/init.sh" 1>/dev/null 2>&1 - command -v rbenv >/dev/null && eval "$(rbenv init -)" __version.detect() { diff --git a/examples/example_gem/WORKSPACE b/examples/example_gem/WORKSPACE index 06b7964..0f096a7 100644 --- a/examples/example_gem/WORKSPACE +++ b/examples/example_gem/WORKSPACE @@ -15,7 +15,7 @@ load( rules_ruby_dependencies() -rules_ruby_select_sdk("3.0.1") +rules_ruby_select_sdk("3.0.2") load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") diff --git a/examples/simple_rails_api/Gemfile.lock b/examples/simple_rails_api/Gemfile.lock index 07a3f1a..63737a6 100644 --- a/examples/simple_rails_api/Gemfile.lock +++ b/examples/simple_rails_api/Gemfile.lock @@ -1,124 +1,124 @@ GEM remote: https://rubygems.org/ specs: - actioncable (6.0.4) - actionpack (= 6.0.4) + actioncable (6.0.4.1) + actionpack (= 6.0.4.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.0.4) - actionpack (= 6.0.4) - activejob (= 6.0.4) - activerecord (= 6.0.4) - activestorage (= 6.0.4) - activesupport (= 6.0.4) + actionmailbox (6.0.4.1) + actionpack (= 6.0.4.1) + activejob (= 6.0.4.1) + activerecord (= 6.0.4.1) + activestorage (= 6.0.4.1) + activesupport (= 6.0.4.1) mail (>= 2.7.1) - actionmailer (6.0.4) - actionpack (= 6.0.4) - actionview (= 6.0.4) - activejob (= 6.0.4) + actionmailer (6.0.4.1) + actionpack (= 6.0.4.1) + actionview (= 6.0.4.1) + activejob (= 6.0.4.1) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.0.4) - actionview (= 6.0.4) - activesupport (= 6.0.4) + actionpack (6.0.4.1) + actionview (= 6.0.4.1) + activesupport (= 6.0.4.1) rack (~> 2.0, >= 2.0.8) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.0.4) - actionpack (= 6.0.4) - activerecord (= 6.0.4) - activestorage (= 6.0.4) - activesupport (= 6.0.4) + actiontext (6.0.4.1) + actionpack (= 6.0.4.1) + activerecord (= 6.0.4.1) + activestorage (= 6.0.4.1) + activesupport (= 6.0.4.1) nokogiri (>= 1.8.5) - actionview (6.0.4) - activesupport (= 6.0.4) + actionview (6.0.4.1) + activesupport (= 6.0.4.1) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.0.4) - activesupport (= 6.0.4) + activejob (6.0.4.1) + activesupport (= 6.0.4.1) globalid (>= 0.3.6) - activemodel (6.0.4) - activesupport (= 6.0.4) - activerecord (6.0.4) - activemodel (= 6.0.4) - activesupport (= 6.0.4) - activestorage (6.0.4) - actionpack (= 6.0.4) - activejob (= 6.0.4) - activerecord (= 6.0.4) + activemodel (6.0.4.1) + activesupport (= 6.0.4.1) + activerecord (6.0.4.1) + activemodel (= 6.0.4.1) + activesupport (= 6.0.4.1) + activestorage (6.0.4.1) + actionpack (= 6.0.4.1) + activejob (= 6.0.4.1) + activerecord (= 6.0.4.1) marcel (~> 1.0.0) - activesupport (6.0.4) + activesupport (6.0.4.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) zeitwerk (~> 2.2, >= 2.2.2) - bootsnap (1.7.5) + bootsnap (1.9.1) msgpack (~> 1.0) builder (3.2.4) byebug (11.1.3) concurrent-ruby (1.1.9) crass (1.0.6) erubi (1.10.0) - ffi (1.15.3) - globalid (0.4.2) - activesupport (>= 4.2.0) + ffi (1.15.4) + globalid (0.5.2) + activesupport (>= 5.0) i18n (1.8.10) concurrent-ruby (~> 1.0) listen (3.0.8) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - loofah (2.10.0) + loofah (2.12.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) - marcel (1.0.1) + marcel (1.0.2) method_source (1.0.0) - mini_mime (1.1.0) - mini_portile2 (2.5.3) + mini_mime (1.1.1) + mini_portile2 (2.6.1) minitest (5.14.4) msgpack (1.4.2) - nio4r (2.5.7) - nokogiri (1.11.7) - mini_portile2 (~> 2.5.0) + nio4r (2.5.8) + nokogiri (1.12.5) + mini_portile2 (~> 2.6.1) racc (~> 1.4) - puma (4.3.8) + puma (4.3.9) nio4r (~> 2.0) - racc (1.5.2) + racc (1.6.0) rack (2.2.3) rack-test (1.1.0) rack (>= 1.0, < 3) - rails (6.0.4) - actioncable (= 6.0.4) - actionmailbox (= 6.0.4) - actionmailer (= 6.0.4) - actionpack (= 6.0.4) - actiontext (= 6.0.4) - actionview (= 6.0.4) - activejob (= 6.0.4) - activemodel (= 6.0.4) - activerecord (= 6.0.4) - activestorage (= 6.0.4) - activesupport (= 6.0.4) + rails (6.0.4.1) + actioncable (= 6.0.4.1) + actionmailbox (= 6.0.4.1) + actionmailer (= 6.0.4.1) + actionpack (= 6.0.4.1) + actiontext (= 6.0.4.1) + actionview (= 6.0.4.1) + activejob (= 6.0.4.1) + activemodel (= 6.0.4.1) + activerecord (= 6.0.4.1) + activestorage (= 6.0.4.1) + activesupport (= 6.0.4.1) bundler (>= 1.3.0) - railties (= 6.0.4) + railties (= 6.0.4.1) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) - rails-html-sanitizer (1.3.0) + rails-html-sanitizer (1.4.2) loofah (~> 2.3) - railties (6.0.4) - actionpack (= 6.0.4) - activesupport (= 6.0.4) + railties (6.0.4.1) + actionpack (= 6.0.4.1) + activesupport (= 6.0.4.1) method_source rake (>= 0.8.7) thor (>= 0.20.3, < 2.0) - rake (13.0.4) + rake (13.0.6) rb-fsevent (0.11.0) rb-inotify (0.10.1) ffi (~> 1.0) @@ -158,4 +158,4 @@ DEPENDENCIES tzinfo-data BUNDLED WITH - 2.1.4 + 2.2.24 diff --git a/examples/simple_rails_api/WORKSPACE b/examples/simple_rails_api/WORKSPACE index 17e28c3..8585cfe 100644 --- a/examples/simple_rails_api/WORKSPACE +++ b/examples/simple_rails_api/WORKSPACE @@ -15,7 +15,7 @@ load( rules_ruby_dependencies() -rules_ruby_select_sdk(version = "3.0.1") +rules_ruby_select_sdk(version = "3.0.2") load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") diff --git a/examples/simple_script/.ruby-version b/examples/simple_script/.ruby-version new file mode 100644 index 0000000..b502146 --- /dev/null +++ b/examples/simple_script/.ruby-version @@ -0,0 +1 @@ +3.0.2 diff --git a/examples/simple_script/Gemfile.lock b/examples/simple_script/Gemfile.lock index b5d358f..002c127 100644 --- a/examples/simple_script/Gemfile.lock +++ b/examples/simple_script/Gemfile.lock @@ -5,8 +5,8 @@ GEM awesome_print (1.9.2) colored2 (3.1.2) diff-lcs (1.4.4) - parallel (1.20.1) - parser (3.0.1.1) + parallel (1.21.0) + parser (3.0.2.0) ast (~> 2.4.1) rainbow (3.0.0) regexp_parser (2.1.1) @@ -27,19 +27,19 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.7.0) rspec-support (3.7.1) - rubocop (1.18.3) + rubocop (1.21.0) parallel (~> 1.10) parser (>= 3.0.0.0) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml - rubocop-ast (>= 1.7.0, < 2.0) + rubocop-ast (>= 1.9.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.7.0) + rubocop-ast (1.11.0) parser (>= 3.0.1.1) ruby-progressbar (1.11.0) - unicode-display_width (2.0.0) + unicode-display_width (2.1.0) PLATFORMS ruby @@ -52,4 +52,4 @@ DEPENDENCIES rubocop BUNDLED WITH - 2.1.4 + 2.2.24 diff --git a/examples/simple_script/WORKSPACE b/examples/simple_script/WORKSPACE index 13cf766..4ad11d1 100644 --- a/examples/simple_script/WORKSPACE +++ b/examples/simple_script/WORKSPACE @@ -15,7 +15,7 @@ load( rules_ruby_dependencies() -rules_ruby_select_sdk(version = "3.0.1") +rules_ruby_select_sdk(version = "3.0.2") load("@bazelruby_rules_ruby//ruby:defs.bzl", "ruby_bundle") diff --git a/examples/simple_script/spec/script_spec.rb b/examples/simple_script/spec/script_spec.rb index 458b928..b325d32 100644 --- a/examples/simple_script/spec/script_spec.rb +++ b/examples/simple_script/spec/script_spec.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true require 'spec_helper' -require 'script' + +require_relative '../script' describe 'oss_rand' do it 'generates a String' do diff --git a/examples/simple_script_vendored/.rubocop.yml b/examples/simple_script_vendored/.rubocop.yml index 7b653d9..0687ca7 100644 --- a/examples/simple_script_vendored/.rubocop.yml +++ b/examples/simple_script_vendored/.rubocop.yml @@ -1,7 +1,7 @@ inherit_from: .relaxed-rubocop-2.4.yml AllCops: - TargetRubyVersion: 2.6 + TargetRubyVersion: 3.0 UseCache: true DefaultFormatter: progress DisplayStyleGuide: true @@ -23,6 +23,8 @@ AllCops: - '**/*.ru' - '**/Gemfile' - '**/Rakefile' + SuggestExtensions: false + NewCops: enable Layout/HashAlignment: Enabled: true diff --git a/examples/simple_script_vendored/Gemfile b/examples/simple_script_vendored/Gemfile index efb2cf7..48bd8b2 100644 --- a/examples/simple_script_vendored/Gemfile +++ b/examples/simple_script_vendored/Gemfile @@ -4,4 +4,4 @@ source 'https://rubygems.org' gem 'rspec', '~> 3.7.0' gem 'rspec-its' -gem 'rubocop', '~> 0.78.0' +gem 'rubocop' diff --git a/examples/simple_script_vendored/Gemfile.lock b/examples/simple_script_vendored/Gemfile.lock index 4460ad6..315f6e6 100644 --- a/examples/simple_script_vendored/Gemfile.lock +++ b/examples/simple_script_vendored/Gemfile.lock @@ -3,11 +3,12 @@ GEM specs: ast (2.4.2) diff-lcs (1.4.4) - jaro_winkler (1.5.4) - parallel (1.20.1) - parser (3.0.0.0) + parallel (1.21.0) + parser (3.0.2.0) ast (~> 2.4.1) rainbow (3.0.0) + regexp_parser (2.1.1) + rexml (3.2.5) rspec (3.7.0) rspec-core (~> 3.7.0) rspec-expectations (~> 3.7.0) @@ -24,15 +25,19 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.7.0) rspec-support (3.7.1) - rubocop (0.78.0) - jaro_winkler (~> 1.5.1) + rubocop (1.21.0) parallel (~> 1.10) - parser (>= 2.6) + parser (>= 3.0.0.0) rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml + rubocop-ast (>= 1.9.1, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 1.7) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.11.0) + parser (>= 3.0.1.1) ruby-progressbar (1.11.0) - unicode-display_width (1.6.1) + unicode-display_width (2.1.0) PLATFORMS ruby @@ -40,7 +45,7 @@ PLATFORMS DEPENDENCIES rspec (~> 3.7.0) rspec-its - rubocop (~> 0.78.0) + rubocop BUNDLED WITH - 2.1.4 + 2.2.24 diff --git a/examples/simple_script_vendored/spec/spec_helper.rb b/examples/simple_script_vendored/spec/spec_helper.rb index 9c7f07a..9de82de 100644 --- a/examples/simple_script_vendored/spec/spec_helper.rb +++ b/examples/simple_script_vendored/spec/spec_helper.rb @@ -11,9 +11,13 @@ # it is invoked by rpsec/autorun. So #warn_with raises an exception # 5. The process fails with an unhandled exception. -ENV['HOME'] ||= '/' +LIB = File.expand_path(File.dirname(__dir__)) +$LOAD_PATH.unshift(LIB) unless $LOAD_PATH.include?(LIB) -require 'rspec' +ENV["HOME"] ||= "/" + +require "rspec" +require "script" RSpec.configure do |config| config.expect_with :rspec do |expectations| diff --git a/examples/simple_script_vendored/vendor/cache/jaro_winkler-1.5.4.gem b/examples/simple_script_vendored/vendor/cache/jaro_winkler-1.5.4.gem deleted file mode 100644 index 5ed9b9b..0000000 Binary files a/examples/simple_script_vendored/vendor/cache/jaro_winkler-1.5.4.gem and /dev/null differ diff --git a/examples/simple_script_vendored/vendor/cache/parallel-1.20.1.gem b/examples/simple_script_vendored/vendor/cache/parallel-1.20.1.gem deleted file mode 100644 index 7804c61..0000000 Binary files a/examples/simple_script_vendored/vendor/cache/parallel-1.20.1.gem and /dev/null differ diff --git a/examples/simple_script_vendored/vendor/cache/parallel-1.21.0.gem b/examples/simple_script_vendored/vendor/cache/parallel-1.21.0.gem new file mode 100644 index 0000000..ca8f636 Binary files /dev/null and b/examples/simple_script_vendored/vendor/cache/parallel-1.21.0.gem differ diff --git a/examples/simple_script_vendored/vendor/cache/parser-3.0.0.0.gem b/examples/simple_script_vendored/vendor/cache/parser-3.0.0.0.gem deleted file mode 100644 index f542329..0000000 Binary files a/examples/simple_script_vendored/vendor/cache/parser-3.0.0.0.gem and /dev/null differ diff --git a/examples/simple_script_vendored/vendor/cache/parser-3.0.2.0.gem b/examples/simple_script_vendored/vendor/cache/parser-3.0.2.0.gem new file mode 100644 index 0000000..ee615aa Binary files /dev/null and b/examples/simple_script_vendored/vendor/cache/parser-3.0.2.0.gem differ diff --git a/examples/simple_script_vendored/vendor/cache/regexp_parser-2.1.1.gem b/examples/simple_script_vendored/vendor/cache/regexp_parser-2.1.1.gem new file mode 100644 index 0000000..4bb25a0 Binary files /dev/null and b/examples/simple_script_vendored/vendor/cache/regexp_parser-2.1.1.gem differ diff --git a/examples/simple_script_vendored/vendor/cache/rexml-3.2.5.gem b/examples/simple_script_vendored/vendor/cache/rexml-3.2.5.gem new file mode 100644 index 0000000..5680fec Binary files /dev/null and b/examples/simple_script_vendored/vendor/cache/rexml-3.2.5.gem differ diff --git a/examples/simple_script_vendored/vendor/cache/rubocop-0.78.0.gem b/examples/simple_script_vendored/vendor/cache/rubocop-0.78.0.gem deleted file mode 100644 index b8f797d..0000000 Binary files a/examples/simple_script_vendored/vendor/cache/rubocop-0.78.0.gem and /dev/null differ diff --git a/examples/simple_script_vendored/vendor/cache/rubocop-1.21.0.gem b/examples/simple_script_vendored/vendor/cache/rubocop-1.21.0.gem new file mode 100644 index 0000000..ddeba66 Binary files /dev/null and b/examples/simple_script_vendored/vendor/cache/rubocop-1.21.0.gem differ diff --git a/examples/simple_script_vendored/vendor/cache/rubocop-ast-1.11.0.gem b/examples/simple_script_vendored/vendor/cache/rubocop-ast-1.11.0.gem new file mode 100644 index 0000000..9a444da Binary files /dev/null and b/examples/simple_script_vendored/vendor/cache/rubocop-ast-1.11.0.gem differ diff --git a/examples/simple_script_vendored/vendor/cache/unicode-display_width-1.6.1.gem b/examples/simple_script_vendored/vendor/cache/unicode-display_width-1.6.1.gem deleted file mode 100644 index 55f1986..0000000 Binary files a/examples/simple_script_vendored/vendor/cache/unicode-display_width-1.6.1.gem and /dev/null differ diff --git a/examples/simple_script_vendored/vendor/cache/unicode-display_width-2.1.0.gem b/examples/simple_script_vendored/vendor/cache/unicode-display_width-2.1.0.gem new file mode 100644 index 0000000..bec8f2a Binary files /dev/null and b/examples/simple_script_vendored/vendor/cache/unicode-display_width-2.1.0.gem differ diff --git a/ruby/private/bundle/create_bundle_build_file.rb b/ruby/private/bundle/create_bundle_build_file.rb index db40418..52626cf 100755 --- a/ruby/private/bundle/create_bundle_build_file.rb +++ b/ruby/private/bundle/create_bundle_build_file.rb @@ -58,12 +58,30 @@ ) ALL_GEMS +# For ordinary gems, this path is like 'lib/ruby/3.0.0/gems/rspec-3.10.0'. +# For gems with native extension installed via prebuilt packages, the last part of this path can +# contain an OS-specific suffix like 'grpc-1.38.0-universal-darwin' or 'grpc-1.38.0-x86_64-linux' +# instead of 'grpc-1.38.0'. +# +# Since OS platform is unlikely to change between Bazel builds on the same machine, +# `#{gem_name}-#{gem_version}*` would be sufficient to narrow down matches to at most one. +# +# Library path differs across implementations as `lib/ruby` on MRI and `lib/jruby` on JRuby. GEM_PATH = ->(ruby_version, gem_name, gem_version) do - Dir.glob("lib/ruby/#{ruby_version}/gems/#{gem_name}-#{gem_version}*").first + Dir.glob("lib/#{RbConfig::CONFIG['RUBY_INSTALL_NAME']}/#{ruby_version}/gems/#{gem_name}-#{gem_version}*").first end +# For ordinary gems, this path is like 'lib/ruby/3.0.0/specifications/rspec-3.10.0.gemspec'. +# For gems with native extension installed via prebuilt packages, the last part of this path can +# contain an OS-specific suffix like 'grpc-1.38.0-universal-darwin.gemspec' or +# 'grpc-1.38.0-x86_64-linux.gemspec' instead of 'grpc-1.38.0.gemspec'. +# +# Since OS platform is unlikely to change between Bazel builds on the same machine, +# `#{gem_name}-#{gem_version}*.gemspec` would be sufficient to narrow down matches to at most one. +# +# Library path differs across implementations as `lib/ruby` on MRI and `lib/jruby` on JRuby. SPEC_PATH = ->(ruby_version, gem_name, gem_version) do - Dir.glob("lib/ruby/#{ruby_version}/specifications/#{gem_name}-#{gem_version}*.gemspec").first + Dir.glob("lib/#{RbConfig::CONFIG['RUBY_INSTALL_NAME']}/#{ruby_version}/specifications/#{gem_name}-#{gem_version}*.gemspec").first end require 'bundler' @@ -140,8 +158,7 @@ def buildify! puts 'Buildifier gave ๐Ÿ‘ '.green + (output ? " and said: #{output}" : '') else raise BuildifierFailedError, - 'Generated BUILD file failed buildifier, with error โ€” '.red + "\n\n" + - output.yellow + "Generated BUILD file failed buildifier, with error:\n\n#{output.yellow}\n\n".red end end end @@ -164,8 +181,7 @@ def initialize(workspace_name:, build_file: 'BUILD.bazel', gemfile_lock: 'Gemfile.lock', includes: nil, - excludes: nil, - additional_require_paths: nil) + excludes: nil) @workspace_name = workspace_name @repo_name = repo_name @build_file = build_file @@ -233,6 +249,9 @@ def remove_bundler_version! end def register_gem(spec, template_out, bundle_lib_paths, bundle_binaries) + # Do not register local gems + return if spec.source.path? + gem_path = GEM_PATH[ruby_version, spec.name, spec.version] spec_path = SPEC_PATH[ruby_version, spec.name, spec.version] base_dir = "lib/ruby/#{ruby_version}" @@ -280,7 +299,7 @@ def find_bundle_binaries(gem_path) end.flatten .compact .sort - .map { |binary| 'bin/' + binary } + .map { |binary| "bin/#{binary}" } end def include_array(gem_name) diff --git a/ruby/private/bundle/def.bzl b/ruby/private/bundle/def.bzl index 1e1243b..e368bd4 100644 --- a/ruby/private/bundle/def.bzl +++ b/ruby/private/bundle/def.bzl @@ -114,16 +114,20 @@ def install_bundler(runtime_ctx, bundler_version): ) def bundle_install(runtime_ctx, previous_result): + cwd = runtime_ctx.ctx.path(".") + bundler_args = [ + "install", + "--binstubs={}".format(cwd.get_child(BUNDLE_BIN_PATH)), + "--path={}".format(cwd.get_child(BUNDLE_PATH)), + "--standalone", + "--gemfile={}".format(runtime_ctx.ctx.attr.gemfile.name), + ] + if runtime_ctx.ctx.attr.gemfile_lock: + bundler_args += ["--deployment", "--frozen"] + result = run_bundler( runtime_ctx, - [ - "install", - "--binstubs={}".format(BUNDLE_BIN_PATH), - "--path={}".format(BUNDLE_PATH), - "--deployment", - "--standalone", - "--frozen", - ], + bundler_args, previous_result, ) @@ -133,6 +137,11 @@ def bundle_install(runtime_ctx, previous_result): return result def generate_bundle_build_file(runtime_ctx, previous_result): + if runtime_ctx.ctx.attr.gemfile_lock: + gemfile_lock = runtime_ctx.ctx.attr.gemfile_lock.name + else: + gemfile_lock = "{}.lock".format(runtime_ctx.ctx.attr.gemfile.name) + # Create the BUILD file to expose the gems to the WORKSPACE # USAGE: ./create_bundle_build_file.rb BUILD.bazel Gemfile.lock repo-name [excludes-json] workspace-name args = [ @@ -142,7 +151,7 @@ def generate_bundle_build_file(runtime_ctx, previous_result): "bundler/lib", SCRIPT_BUILD_FILE_GENERATOR, # The template used to created bundle file "BUILD.bazel", # Bazel build file (can be empty) - "Gemfile.lock", # Gemfile.lock where we list all direct and transitive dependencies + gemfile_lock, # Gemfile.lock where we list all direct and transitive dependencies runtime_ctx.ctx.name, # Name of the target repr(runtime_ctx.ctx.attr.includes), repr(runtime_ctx.ctx.attr.excludes), @@ -154,8 +163,9 @@ def generate_bundle_build_file(runtime_ctx, previous_result): fail("build file generation failed: %s%s" % (result.stdout, result.stderr)) def _ruby_bundle_impl(ctx): - ctx.symlink(ctx.attr.gemfile, "Gemfile") - ctx.symlink(ctx.attr.gemfile_lock, "Gemfile.lock") + ctx.symlink(ctx.attr.gemfile, ctx.attr.gemfile.name) + if ctx.attr.gemfile_lock: + ctx.symlink(ctx.attr.gemfile_lock, ctx.attr.gemfile_lock.name) if ctx.attr.vendor_cache: ctx.symlink( ctx.path(str(ctx.path(ctx.attr.gemfile).dirname) + "/vendor"), @@ -163,6 +173,8 @@ def _ruby_bundle_impl(ctx): ) ctx.symlink(ctx.attr._create_bundle_build_file, SCRIPT_BUILD_FILE_GENERATOR) ctx.symlink(ctx.attr._install_bundler, SCRIPT_INSTALL_GEM) + for src in ctx.attr.srcs: + ctx.symlink(src, src.name) bundler_version = ctx.attr.bundler_version diff --git a/ruby/private/constants.bzl b/ruby/private/constants.bzl index d615ea6..a76f8f3 100644 --- a/ruby/private/constants.bzl +++ b/ruby/private/constants.bzl @@ -79,6 +79,9 @@ BUNDLE_ATTRS = { "gemfile_lock": attr.label( allow_single_file = True, ), + "srcs": attr.label_list( + allow_files = True, + ), "vendor_cache": attr.bool( doc = "Symlink the vendor directory into the Bazel build space, this allows Bundler to access vendored Gems", ), diff --git a/ruby/private/sdk.bzl b/ruby/private/sdk.bzl index f509d23..40f23a7 100644 --- a/ruby/private/sdk.bzl +++ b/ruby/private/sdk.bzl @@ -9,15 +9,20 @@ def rules_ruby_select_sdk(version = "host"): supported_versions = [ "host", "2.5.8", + "2.5.9", "2.6.3", "2.6.4", "2.6.5", "2.6.6", "2.6.7", + "2.6.8", "2.7.1", "2.7.2", + "2.7.3", + "2.7.4", "3.0.0", "3.0.1", + "3.0.2", ] if version in supported_versions: diff --git a/ruby/private/toolchain.bzl b/ruby/private/toolchain.bzl index b8b6dc5..cbaebd6 100644 --- a/ruby/private/toolchain.bzl +++ b/ruby/private/toolchain.bzl @@ -11,13 +11,15 @@ RubyRuntimeInfo = provider( ) def _ruby_toolchain_impl(ctx): - return [platform_common.ToolchainInfo( - ruby_runtime = RubyRuntimeInfo( - interpreter = ctx.attr.interpreter, - runtime = ctx.files.runtime, - rubyopt = ctx.attr.rubyopt, + return [ + platform_common.ToolchainInfo( + ruby_runtime = RubyRuntimeInfo( + interpreter = ctx.attr.interpreter, + runtime = ctx.files.runtime, + rubyopt = ctx.attr.rubyopt, + ), ), - )] + ] _ruby_toolchain = rule( implementation = _ruby_toolchain_impl, diff --git a/ruby/private/toolchains/repository_context.bzl b/ruby/private/toolchains/repository_context.bzl index b151531..221a4ac 100644 --- a/ruby/private/toolchains/repository_context.bzl +++ b/ruby/private/toolchains/repository_context.bzl @@ -45,6 +45,8 @@ def ruby_repository_context(repository_ctx, interpreter_path): rel_interpreter_path = str(interpreter_path) if rel_interpreter_path.startswith("/"): rel_interpreter_path = rel_interpreter_path[1:] + elif rel_interpreter_path.startswith("C:/"): + rel_interpreter_path = rel_interpreter_path[3:] return struct( # Location of the interpreter diff --git a/ruby/private/toolchains/ruby_runtime.bzl b/ruby/private/toolchains/ruby_runtime.bzl index 048084f..d3ec3ed 100644 --- a/ruby/private/toolchains/ruby_runtime.bzl +++ b/ruby/private/toolchains/ruby_runtime.bzl @@ -32,6 +32,8 @@ def _relativate(path): # TODO(yugui) support windows if path.startswith("/"): return path[1:] + elif path.startswith("C:/"): + return path[3:] else: return path @@ -44,6 +46,19 @@ def _list_libdirs(ruby): def _install_dirs(ctx, ruby, *names): paths = sorted([ruby.rbconfig(ruby, name) for name in names]) + + # JRuby reports some of the directories as nulls. + paths = [path for path in paths if path] + + # Sometimes we end up with the same directory multiple times + # so make sure paths are unique by converting it to set. + # For example, this is what we have on Fedora 34: + # $ ruby -rrbconfig -e "p RbConfig::CONFIG['rubyhdrdir']" + # "/usr/include" + # $ ruby -rrbconfig -e "p RbConfig::CONFIG['rubyarchhdrdir']" + # "/usr/include" + paths = depset(paths).to_list() + rel_paths = [_relativate(path) for path in paths] for i, (path, rel_path) in enumerate(zip(paths, rel_paths)): if not _is_subpath(path, paths[:i]): diff --git a/ruby/tests/testdata/bundle_includes_workspace/BUILD.bazel b/ruby/tests/testdata/bundle_includes_workspace/BUILD.bazel index 5df776a..01b33fa 100644 --- a/ruby/tests/testdata/bundle_includes_workspace/BUILD.bazel +++ b/ruby/tests/testdata/bundle_includes_workspace/BUILD.bazel @@ -10,6 +10,7 @@ ruby_binary( srcs = ["script.rb"], main = "script.rb", deps = [ + "@gems//:awesome_print", "@gems//:grpc", ], ) diff --git a/ruby/tests/testdata/bundle_includes_workspace/Gemfile b/ruby/tests/testdata/bundle_includes_workspace/Gemfile index 9595a03..9f5ba60 100644 --- a/ruby/tests/testdata/bundle_includes_workspace/Gemfile +++ b/ruby/tests/testdata/bundle_includes_workspace/Gemfile @@ -2,4 +2,5 @@ source 'https://rubygems.org' +gem 'awesome_print' gem 'grpc' diff --git a/ruby/tests/testdata/bundle_includes_workspace/Gemfile.lock b/ruby/tests/testdata/bundle_includes_workspace/Gemfile.lock index 0417ff0..20db546 100644 --- a/ruby/tests/testdata/bundle_includes_workspace/Gemfile.lock +++ b/ruby/tests/testdata/bundle_includes_workspace/Gemfile.lock @@ -1,6 +1,7 @@ GEM remote: https://rubygems.org/ specs: + awesome_print (1.9.2) google-protobuf (3.17.3) googleapis-common-protos-types (1.1.0) google-protobuf (~> 3.14) @@ -12,7 +13,8 @@ PLATFORMS ruby DEPENDENCIES + awesome_print grpc BUNDLED WITH - 2.2.22 + 2.2.28 diff --git a/ruby/tests/testdata/bundle_includes_workspace/WORKSPACE b/ruby/tests/testdata/bundle_includes_workspace/WORKSPACE index c97411c..00a3bb4 100644 --- a/ruby/tests/testdata/bundle_includes_workspace/WORKSPACE +++ b/ruby/tests/testdata/bundle_includes_workspace/WORKSPACE @@ -13,7 +13,7 @@ load( rules_ruby_dependencies() -rules_ruby_select_sdk(version = "3.0.1") +rules_ruby_select_sdk(version = "3.0.2") load("@bazelruby_rules_ruby//ruby:defs.bzl", "ruby_bundle") diff --git a/ruby/tests/testdata/bundle_includes_workspace/script.rb b/ruby/tests/testdata/bundle_includes_workspace/script.rb index c29eab5..bc718e5 100644 --- a/ruby/tests/testdata/bundle_includes_workspace/script.rb +++ b/ruby/tests/testdata/bundle_includes_workspace/script.rb @@ -1,25 +1,24 @@ -# frozen_string_literal: true - -expected_gem_require_paths = [ - 'etc', - 'src/ruby/bin', - 'src/ruby/lib', - 'src/ruby/pb' +expected_gem_require_paths = %w[ + etc + src/ruby/bin + src/ruby/lib + src/ruby/pb ] - gem_require_paths = $LOAD_PATH.map do |load_path| %r{.+script.runfiles/(?:gems|bundle)/lib/ruby/3.0.0/gems/grpc-.+?/(.+)}.match(load_path).to_a[1] end.compact -(expected_gem_require_paths - gem_require_paths).each do |missing_require_path| - raise "Expected requir_path '#{missing_require_path}' is missing in $LOAD_PATH." -end - begin require 'grpc' -rescue LoadError - $stderr.puts 'Failed to load grpc gem' +rescue LoadError => e + warn "Failed to load grpc gem: #{e.message}" raise end -puts GRPC::RpcServer.new +pp GRPC::RpcServer.new + +# TODO: what is this? I am not sure I fully understand the purpose of this +# check. Please elaborate, or it will be removed. --@kigster +(expected_gem_require_paths - gem_require_paths).each do |missing_require_path| + raise "Expected requir_path '#{missing_require_path}' is missing in $LOAD_PATH." +end