diff --git a/.bazelversion b/.bazelversion index 47b322c9..ee74734a 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -3.4.1 +4.1.0 diff --git a/.circleci/Dockerfile b/.circleci/Dockerfile index aaaf8c35..cff3ce50 100644 --- a/.circleci/Dockerfile +++ b/.circleci/Dockerfile @@ -1,7 +1,7 @@ # # rules_ruby circleci Docker file. # -FROM ruby:2.7.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 0e941bec..5ee0d7e9 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-2.7.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 861e4437..72e49b34 100644 --- a/.envrc +++ b/.envrc @@ -1,12 +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/.readme b/.readme new file mode 100644 index 00000000..ec69a7ed --- /dev/null +++ b/.readme @@ -0,0 +1,10 @@ +=Ruby Rules® for Bazel +:subtitle: Version %VERSION% +:doctype: book +:source-highlighter: rouge +:rouge-style: base16.monokai +:toclevels: 5 +:toc: +:sectnums: 9 +:icons: font +:license: apache diff --git a/.rubocop.yml b/.rubocop.yml index 0d331a58..632114d5 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 00000000..e7302d7d --- /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 860487ca..b5021469 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.7.1 +3.0.2 diff --git a/.rules_version b/.rules_version index 1d0ba9ea..a918a2aa 100644 --- a/.rules_version +++ b/.rules_version @@ -1 +1 @@ -0.4.0 +0.6.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a511203..3d1c3afe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,28 +1,88 @@ # Changelog +## [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.2...v0.6.0) + +**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)) + +## [v0.5.2](https://github.com/bazelruby/rules_ruby/tree/v0.5.2) (2021年07月09日) + +[Full Changelog](https://github.com/bazelruby/rules_ruby/compare/v0.5.1...v0.5.2) + +**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:** + +- 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) + +**Closed issues:** + +- ruby\_binary - how to package up runfiles dir [\#101](https://github.com/bazelruby/rules_ruby/issues/101) +- bin/setup Failure [\#95](https://github.com/bazelruby/rules_ruby/issues/95) +- `warning: string literal in condition` from generated wrapper [\#87](https://github.com/bazelruby/rules_ruby/issues/87) +- Setup script attempts to delete ~/.rbenv if rbenv is installed with Homebrew [\#81](https://github.com/bazelruby/rules_ruby/issues/81) +- ruby\_rspec specs argument not resolved [\#79](https://github.com/bazelruby/rules_ruby/issues/79) +- ruby\_test and ruby\_rspec rules use system ruby [\#63](https://github.com/bazelruby/rules_ruby/issues/63) + +**Merged pull requests:** + +- Adding makefile for auto-generating PDF [\#106](https://github.com/bazelruby/rules_ruby/pull/106) ([kigster](https://github.com/kigster)) +- Massive upgrade of everything at once ;-\) [\#105](https://github.com/bazelruby/rules_ruby/pull/105) ([kigster](https://github.com/kigster)) +- Support ruby 3 [\#103](https://github.com/bazelruby/rules_ruby/pull/103) ([mmizutani](https://github.com/mmizutani)) +- Bump nokogiri from 1.11.2 to 1.11.5 in /examples/simple\_rails\_api [\#99](https://github.com/bazelruby/rules_ruby/pull/99) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump nokogiri from 1.10.10 to 1.11.2 in /examples/simple\_rails\_api [\#94](https://github.com/bazelruby/rules_ruby/pull/94) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Update README.md [\#93](https://github.com/bazelruby/rules_ruby/pull/93) ([JustusFT](https://github.com/JustusFT)) +- Fix warning due to string literal in condition [\#91](https://github.com/bazelruby/rules_ruby/pull/91) ([russell](https://github.com/russell)) +- Add description for how to configure ASDF [\#90](https://github.com/bazelruby/rules_ruby/pull/90) ([russell](https://github.com/russell)) +- Remove print statements from ruby\_runtime.bzl [\#84](https://github.com/bazelruby/rules_ruby/pull/84) ([adzenith](https://github.com/adzenith)) +- Document path argument to ruby\_test [\#80](https://github.com/bazelruby/rules_ruby/pull/80) ([sayrer](https://github.com/sayrer)) + +## [v0.4.1](https://github.com/bazelruby/rules_ruby/tree/v0.4.1) (2020年08月10日) + +[Full Changelog](https://github.com/bazelruby/rules_ruby/compare/v0.4.0...v0.4.1) + ## [v0.4.0](https://github.com/bazelruby/rules_ruby/tree/v0.4.0) (2020年08月04日) [Full Changelog](https://github.com/bazelruby/rules_ruby/compare/v0.3.0...v0.4.0) **Closed issues:** -- private method `define_method` called for `Dir:Class \(NoMethodError\)` [\#74](https://github.com/bazelruby/rules_ruby/issues/74) +- private method `define\_method' called for Dir:Class \(NoMethodError\) [\#74](https://github.com/bazelruby/rules_ruby/issues/74) **Merged pull requests:** - Version vandidate 0.4.0 — upgrade Rubies + Setup [\#77](https://github.com/bazelruby/rules_ruby/pull/77) ([kigster](https://github.com/kigster)) - * Updating .bazelrc - * Moving rbenv install to bin/setup + .travis.yml - * Fixing buildifier complaints - * Fixed TravisCI errors - * Comment out failing test with Docker - * Upgrade various top-level dependencies to the latest - * Upgrade Bazel to 3.4.1 - * Switch to Ruby 2.7.1 as the default - Upgrading Gemfiles [\#76](https://github.com/bazelruby/rules_ruby/pull/76) ([kigster](https://github.com/kigster)) -- Ruby 2.3 compatibility for binary_wrapper [\#75](https://github.com/bazelruby/rules_ruby/pull/75) ([lalten](https://github.com/lalten)) -- Bump puma from 4.3.3 to 4.3.5 in /examples/simple_rails_api [\#71](https://github.com/bazelruby/rules_ruby/pull/71) ([dependabot[bot]](https://github.com/apps/dependabot)) -- Bump puma from 4.3.1 to 4.3.3 in /examples/simple_rails_api [\#70](https://github.com/bazelruby/rules_ruby/pull/70) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Ruby 2.3 compatibility for binary\_wrapper [\#75](https://github.com/bazelruby/rules_ruby/pull/75) ([lalten](https://github.com/lalten)) +- Bump puma from 4.3.3 to 4.3.5 in /examples/simple\_rails\_api [\#71](https://github.com/bazelruby/rules_ruby/pull/71) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump puma from 4.3.1 to 4.3.3 in /examples/simple\_rails\_api [\#70](https://github.com/bazelruby/rules_ruby/pull/70) ([dependabot[bot]](https://github.com/apps/dependabot)) ## [v0.3.0](https://github.com/bazelruby/rules_ruby/tree/v0.3.0) (2020年03月03日) @@ -30,7 +90,7 @@ **Closed issues:** -- 🐛 "Could not create symlink... File exists" [\#54](https://github.com/bazelruby/rules_ruby/issues/54) +- 🐛 "Could not create symlink... \(File exists\)" [\#54](https://github.com/bazelruby/rules_ruby/issues/54) - When using a local ruby installation it includes the local `LOAD_PATH` [\#44](https://github.com/bazelruby/rules_ruby/issues/44) - \[Cleanup\] Pretty sure `eval` is never used in `repository_context` [\#43](https://github.com/bazelruby/rules_ruby/issues/43) - Importing a bundle gem adds all gems onto the load path \(although they are not there\) [\#42](https://github.com/bazelruby/rules_ruby/issues/42) @@ -42,14 +102,14 @@ **Merged pull requests:** -- Renaming the repo to @bazelruby_rules_ruby [\#69](https://github.com/bazelruby/rules_ruby/pull/69) ([kigster](https://github.com/kigster)) +- Renaming the repo to @bazelruby\_rules\_ruby [\#69](https://github.com/bazelruby/rules_ruby/pull/69) ([kigster](https://github.com/kigster)) - Fixing outdated rule names in the README [\#68](https://github.com/bazelruby/rules_ruby/pull/68) ([kigster](https://github.com/kigster)) - Adding method Dir.children when it's not found. [\#67](https://github.com/bazelruby/rules_ruby/pull/67) ([kigster](https://github.com/kigster)) - Merging select features from Coinbase upstream branch [\#66](https://github.com/bazelruby/rules_ruby/pull/66) ([kigster](https://github.com/kigster)) - Upgrade Bazel and Bazelist; add ruby 2.7.0 [\#65](https://github.com/bazelruby/rules_ruby/pull/65) ([kigster](https://github.com/kigster)) -- Bump nokogiri from 1.10.7 to 1.10.8 in /examples/simple_rails_api [\#64](https://github.com/bazelruby/rules_ruby/pull/64) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump nokogiri from 1.10.7 to 1.10.8 in /examples/simple\_rails\_api [\#64](https://github.com/bazelruby/rules_ruby/pull/64) ([dependabot[bot]](https://github.com/apps/dependabot)) - This PR refactors bundle steps and :bin generation [\#61](https://github.com/bazelruby/rules_ruby/pull/61) ([kigster](https://github.com/kigster)) -- Adds ruby_rspec and refactors the ruby_bundle rule, plus some more [\#60](https://github.com/bazelruby/rules_ruby/pull/60) ([kigster](https://github.com/kigster)) +- Adds ruby\_rspec and refactors the ruby\_bundle rule, plus some more [\#60](https://github.com/bazelruby/rules_ruby/pull/60) ([kigster](https://github.com/kigster)) ## [v0.2.0](https://github.com/bazelruby/rules_ruby/tree/v0.2.0) (2019年12月31日) @@ -62,8 +122,9 @@ **Closed issues:** - Ability to package all files related to a bazel target in a zip file [\#29](https://github.com/bazelruby/rules_ruby/issues/29) -- Build rules_ruby on CircleCI using workflows \(in addition to Travis\) [\#26](https://github.com/bazelruby/rules_ruby/issues/26) +- Build rules\_ruby on CircleCI using workflows \(in addition to Travis\) [\#26](https://github.com/bazelruby/rules_ruby/issues/26) - Restore functionality that supported symlinking an existing Ruby interpreter [\#21](https://github.com/bazelruby/rules_ruby/issues/21) +- Move ruby files under ruby\_rules/examples into a mini-mono repo [\#8](https://github.com/bazelruby/rules_ruby/issues/8) **Merged pull requests:** @@ -71,7 +132,7 @@ - Upgrading Bazel version to 2.0.0 [\#53](https://github.com/bazelruby/rules_ruby/pull/53) ([kigster](https://github.com/kigster)) - Renaming and making consistent all scripts [\#52](https://github.com/bazelruby/rules_ruby/pull/52) ([kigster](https://github.com/kigster)) - Adding auto-fix buildifier and auto-fix rubocop [\#50](https://github.com/bazelruby/rules_ruby/pull/50) ([kigster](https://github.com/kigster)) -- Bump rack from 2.0.7 to 2.0.8 in /examples/simple_rails_api [\#49](https://github.com/bazelruby/rules_ruby/pull/49) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump rack from 2.0.7 to 2.0.8 in /examples/simple\_rails\_api [\#49](https://github.com/bazelruby/rules_ruby/pull/49) ([dependabot[bot]](https://github.com/apps/dependabot)) - Deprecate ruby/def.bzl + spelling + v0.1.2 [\#48](https://github.com/bazelruby/rules_ruby/pull/48) ([kigster](https://github.com/kigster)) - Speed up CircleCI/Travis ensure \*correctness\* with builds [\#46](https://github.com/bazelruby/rules_ruby/pull/46) ([kigster](https://github.com/kigster)) - \[Feature\] example rails server running [\#41](https://github.com/bazelruby/rules_ruby/pull/41) ([grahamjenson](https://github.com/grahamjenson)) @@ -80,15 +141,15 @@ - \[Fix\] no spaces in files bug, remove deprecated code, remove host [\#38](https://github.com/bazelruby/rules_ruby/pull/38) ([grahamjenson](https://github.com/grahamjenson)) - Sight facelift to shell files: [\#35](https://github.com/bazelruby/rules_ruby/pull/35) ([kigster](https://github.com/kigster)) - \[Feature\] install ruby if none exists [\#34](https://github.com/bazelruby/rules_ruby/pull/34) ([grahamjenson](https://github.com/grahamjenson)) -- Add `files` to DefaultInfo of the ruby_library [\#32](https://github.com/bazelruby/rules_ruby/pull/32) ([kigster](https://github.com/kigster)) +- Add `files` to DefaultInfo of the ruby\_library [\#32](https://github.com/bazelruby/rules_ruby/pull/32) ([kigster](https://github.com/kigster)) - Upgrade Bazel version to 1.2.1 + use bin/setup\(s\) [\#31](https://github.com/bazelruby/rules_ruby/pull/31) ([kigster](https://github.com/kigster)) - Fixing Gemfile bundle dependency and bin/setup [\#30](https://github.com/bazelruby/rules_ruby/pull/30) ([kigster](https://github.com/kigster)) -- Expose rake, erb and other commands as sh_binary [\#28](https://github.com/bazelruby/rules_ruby/pull/28) ([yugui](https://github.com/yugui)) +- Expose rake, erb and other commands as sh\_binary [\#28](https://github.com/bazelruby/rules_ruby/pull/28) ([yugui](https://github.com/yugui)) - Reorganize sections in README [\#23](https://github.com/bazelruby/rules_ruby/pull/23) ([yugui](https://github.com/yugui)) -- Run ruby_binary with the interpreter in a SDK again [\#22](https://github.com/bazelruby/rules_ruby/pull/22) ([yugui](https://github.com/yugui)) +- Run ruby\_binary with the interpreter in a SDK again [\#22](https://github.com/bazelruby/rules_ruby/pull/22) ([yugui](https://github.com/yugui)) - Upgrade bundler [\#18](https://github.com/bazelruby/rules_ruby/pull/18) ([yugui](https://github.com/yugui)) -- Make ruby_binary compatible with container [\#17](https://github.com/bazelruby/rules_ruby/pull/17) ([yugui](https://github.com/yugui)) -- Fix errors in the simple_script example [\#16](https://github.com/bazelruby/rules_ruby/pull/16) ([yugui](https://github.com/yugui)) +- Make ruby\_binary compatible with container [\#17](https://github.com/bazelruby/rules_ruby/pull/17) ([yugui](https://github.com/yugui)) +- Fix errors in the simple\_script example [\#16](https://github.com/bazelruby/rules_ruby/pull/16) ([yugui](https://github.com/yugui)) - Adding relaxed-rubocop and fixing styling issues [\#15](https://github.com/bazelruby/rules_ruby/pull/15) ([grahamjenson](https://github.com/grahamjenson)) ## [v0.1.0](https://github.com/bazelruby/rules_ruby/tree/v0.1.0) (2019年11月20日) @@ -101,7 +162,7 @@ **Merged pull requests:** -- Ignore examples/ because it is an independent workspace to test rules_ruby [\#5](https://github.com/bazelruby/rules_ruby/pull/5) ([yugui](https://github.com/yugui)) +- Ignore examples/ because it is an independent workspace to test rules\_ruby [\#5](https://github.com/bazelruby/rules_ruby/pull/5) ([yugui](https://github.com/yugui)) - Updating the remote reference to match the Org [\#4](https://github.com/bazelruby/rules_ruby/pull/4) ([kigster](https://github.com/kigster)) diff --git a/Gemfile.lock b/Gemfile.lock index 228e9571..92438240 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,26 +1,26 @@ GEM remote: https://rubygems.org/ specs: - ast (2.4.1) - parallel (1.19.2) - parser (2.7.1.4) + ast (2.4.2) + parallel (1.21.0) + parser (3.0.2.0) ast (~> 2.4.1) rainbow (3.0.0) - regexp_parser (1.7.1) - rexml (3.2.4) - rubocop (0.88.0) + regexp_parser (2.1.1) + rexml (3.2.5) + rubocop (0.93.1) parallel (~> 1.10) - parser (>= 2.7.1.1) + parser (>= 2.7.1.5) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.7) + regexp_parser (>= 1.8) rexml - rubocop-ast (>= 0.1.0, < 1.0) + rubocop-ast (>= 0.6.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 2.0) - rubocop-ast (0.2.0) - parser (>= 2.7.0.1) - ruby-progressbar (1.10.1) - unicode-display_width (1.7.0) + rubocop-ast (1.11.0) + parser (>= 3.0.1.1) + ruby-progressbar (1.11.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 new file mode 100755 index 00000000..51231a58 --- /dev/null +++ b/Makefile @@ -0,0 +1,45 @@ +# vim: tabstop=8 +# vim: shiftwidth=8 +# vim: noexpandtab + +# grep '^[a-z\-]*:' Makefile | cut -d: -f 1 | tr '\n' ' ' +.PHONY: help update-changelog update-readme update + +red := 033円[0;31m +bold := 033円[1;45m +yellow := 033円[0;33m +blue := 033円[0;34m +green := 033円[0;35m +clear := 033円[0m + +RUBY_VERSION := $(shell cat .ruby-version) +RULES_VERSION := $(shell cat .rules_version) +OS := $(shell uname -s | tr '[:upper:]' '[:lower:]') + +# see: https://stackoverflow.com/questions/18136918/how-to-get-current-relative-directory-of-your-makefile/18137056#18137056 +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%-30s033円[0m %s\n", $1,ドル $2ドル}' + +update: update-changelog update-readme ## Runs all of the updates, add locally modiofied files to git. + +update-changelog: ## Auto-generate the doc/CHANGELOG (requires GITHUB_TOKEN env var set) + @printf "\n$(bold) 👉 $(red)$(clear) $(green)Regenerating CHANGELOG....$(clear)\n" + @bash -c "$(BASHMATIC_HOME)/bin/regen-changelog" + +update-readme: ## Generate the PDF version of the README + @rm -fv README.pdf + @printf "\n$(bold) 👉 $(red)$(clear) $(green)Converting ASCIIDOC into the PDF...$(clear)\n" + @$(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 00000000..d5cac3c6 --- /dev/null +++ b/README.adoc @@ -0,0 +1,992 @@ += 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 + +== New Rules Ruby! + +This repo will be retired eventually, as these rules have not been actively maintained and are in the process of being replaced by the new rules, which you can find here: https://github.com/bazel-contrib/rules_ruby + + + + + +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 3964b0c7..00000000 --- a/README.md +++ /dev/null @@ -1,1080 +0,0 @@ -![activity](https://img.shields.io/github/commit-activity/m/bazelruby/rules_ruby?style=for-the-badge) - -- [Rules Development Status](#rules-development-status) -- [Usage](#usage) - - [`WORKSPACE` File](#workspace-file) - - [Load dependencies, select Ruby SDK and define one or more Bundles](#load-dependencies-select-ruby-sdk-and-define-one-or-more-bundles) - - [`BUILD.bazel` file(s)](#buildbazel-files) - - [Define Ruby Executable, Library and an RSpec](#define-ruby-executable-library-and-an-rspec) - - [Package Ruby files as a Gem](#package-ruby-files-as-a-gem) - - [Rule Dependency Diagram](#rule-dependency-diagram) -- [Rules](#rules) - - [`ruby_library`](#ruby_library) - - [`ruby_binary`](#ruby_binary) - - [`ruby_test`](#ruby_test) - - [`ruby_bundle`](#ruby_bundle) - - [Limitations](#limitations) - - [Conventions](#conventions) - - [`WORKSPACE`:](#workspace) - - [`BUILD.bazel`:](#buildbazel) - - [`ruby_rspec`](#ruby_rspec) - - [`ruby_gem`](#ruby_gem) -- [What's coming next](#whats-coming-next) -- [Contributing](#contributing) - - [Setup](#setup) - - [Using the Script](#using-the-script) - - [OS-Specific Setup](#os-specific-setup) - - [Issues During Setup](#issues-during-setup) - - [Developing Rules](#developing-rules) - - [Running Tests](#running-tests) - - [Test Script](#test-script) - - [Linter](#linter) -- [Copyright](#copyright) - -### Build Status - -| Build | Status | -|---------: |--------------------------------------------------------------------------------------------------------------------------------------------------- | -| CircleCI | [![CircleCI](https://circleci.com/gh/bazelruby/rules_ruby/tree/develop.svg?style=svg)](https://circleci.com/gh/bazelruby/rules_ruby/tree/develop) | -| TravisCI | [![Build Status](https://travis-ci.org/bazelruby/rules_ruby.svg?branch=develop)](https://travis-ci.org/bazelruby/rules_ruby) | - -### [Change Log](CHANGELOG.md) - -To regenerate: - -```bash -gem install github_changelog_generator -github_changelog_generator -u bazelruby -p rules_ruby -``` - -# Rules Ruby - -This is the README for Ruby Rules for the [Bazel Build](https://bazel.build) system. - -## 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-wait.svg) | medium-sized Ruby on Rails apps, ideally in a mono-repo | -| ![Not Ready](docs/img/status-not-ready.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. - -## 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 'develop' branch. -#——————————————————————————————————————————————————————————————————————— - -git_repository( - name = "bazelruby_rules_ruby", - remote = "https://github.com/bazelruby/rules_ruby.git", - branch = "develop" -) - -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 = "2.7.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", - 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", - ], -) - -``` - -### Rule Dependency Diagram - -> NOTE: this diagram is slightly 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.2", - excludes = [], - 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

-
bundler_version - String, optional -

The Version of Bundler to use. Defaults to 2.1.2.

-

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

-
- -#### 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.2', - gemfile = "//:Gemfile", - gemfile_lock = "//:Gemfile.lock", -) -``` - -#### `BUILD.bazel`: - -```pythonj -# 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. -

-
- -## What's coming next - -1. Building native extensions in gems with Bazel -2. Using a specified version of Ruby. -3. Releasing your gems with Bazel - -## Contributing - -We welcome contributions to RulesRuby. Please make yourself familiar with the [CODE_OF_CONDUCT](CODE_OF_CONDUCT.md) document. - -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 help -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 | os-specific | main | 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 — runs the entire setup. -``` - -#### 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. - -##### Issues During Setup - -**Please report any errors to `bin/setup` as Issues on Github. You can assign them to @kigster.** - -### 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. - 3. hack, hack, hack... - 4. 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: - -```bazel -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 ] -``` - -## Copyright - -© 2018-2019 Yuki Yugui Sonoda & BazelRuby Authors - -Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - - - -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. - - - - - - - [Build Status](#build-status) - - [Change Log](#change-logchangelogmd) -- [Rules Ruby](#rules-ruby) - - [Rules Development Status](#rules-development-status) - - [Usage](#usage) - - [`WORKSPACE` File](#workspace-file) - - [Load dependencies, select Ruby SDK and define one or more Bundles](#load-dependencies-select-ruby-sdk-and-define-one-or-more-bundles) - - [`BUILD.bazel` file(s)](#buildbazel-files) - - [Define Ruby Executable, Library and an RSpec](#define-ruby-executable-library-and-an-rspec) - - [Package Ruby files as a Gem](#package-ruby-files-as-a-gem) - - [Rule Dependency Diagram](#rule-dependency-diagram) - - [Rules](#rules) - - [`ruby_library`](#ruby_library) - - [`ruby_binary`](#ruby_binary) - - [`ruby_test`](#ruby_test) - - [`ruby_bundle`](#ruby_bundle) - - [Limitations](#limitations) - - [Conventions](#conventions) - - [`WORKSPACE`:](#workspace) - - [`BUILD.bazel`:](#buildbazel) - - [`ruby_rspec`](#ruby_rspec) - - [`ruby_gem`](#ruby_gem) - - [What's coming next](#whats-coming-next) - - [Contributing](#contributing) - - [Setup](#setup) - - [Using the Script](#using-the-script) - - [OS-Specific Setup](#os-specific-setup) - - [Issues During Setup](#issues-during-setup) - - [Developing Rules](#developing-rules) - - [Running Tests](#running-tests) - - [Test Script](#test-script) - - [Linter](#linter) - - [Copyright](#copyright) - - diff --git a/README.pdf b/README.pdf new file mode 100644 index 00000000..87bfb50c Binary files /dev/null and b/README.pdf differ diff --git a/VERSION.yml b/VERSION.yml index f5ab055e..23aefb4a 100644 --- a/VERSION.yml +++ b/VERSION.yml @@ -1,5 +1,4 @@ rules_ruby: - version: 0.3.0 - + version: 0.6.0 diff --git a/WORKSPACE b/WORKSPACE index 028298dd..e08c5ee3 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -12,13 +12,18 @@ load("@bazel_skylib//lib:versions.bzl", "versions") versions.check("3.4.1") -rules_ruby_select_sdk("2.7.1") +rules_ruby_select_sdk("3.0.2") local_repository( name = "bazelruby_rules_ruby_ruby_tests_testdata_another_workspace", path = "ruby/tests/testdata/another_workspace", ) +local_repository( + name = "bazelruby_rules_ruby_ruby_tests_testdata_bundle_includes_workspace", + path = "ruby/tests/testdata/bundle_includes_workspace", +) + load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") @@ -94,7 +99,7 @@ load("@bazelruby_rules_ruby//ruby:defs.bzl", "ruby_bundle") ruby_bundle( name = "bundle", - bundler_version = "2.1.2", + bundler_version = "2.1.4", excludes = { "mini_portile": ["test/**/*"], }, diff --git a/bin/clean b/bin/clean index 61717634..edfc3b59 100755 --- a/bin/clean +++ b/bin/clean @@ -1,38 +1,39 @@ #!/usr/bin/env bash # vim: ft=sh # ————————————————————————————————————————————————————————————————————————————————————— -# NOTE: These setup scripts rely on an open source BASH framework BashMatic. +# NOTE: These setup scripts rely on an open source BASH framework BASHMATIC_HOME. # https://github.com/kigster/bashmatic # # The framework is pretty light-weight, and is installed in your $HOME/.bashmatic folder. -# You can safely remove that folder after the setup if you wish, although re-running the +# You can safely remove that folder after the setup if you wish, although re-running the # setup will re-install it. # ————————————————————————————————————————————————————————————————————————————————————— -export BashMatic="${HOME}/.bashmatic" - -if [[ ! -f "${BashMatic}/init.sh" ]]; then - rm -rf "${BashMatic}" 2>/dev/null - git clone https://github.com/kigster/bashmatic "${BashMatic}" 1>/dev/null 2>&1 -fi +[[ -z ${BASHMATIC_HOME} ]] && export BASHMATIC_HOME="${HOME}/.bashmatic" +[[ -d ${BASHMATIC_HOME} ]] || bash -c "$(curl -fsSL https://bashmatic.re1.re); bashmatic-install -q" # shellcheck disable=SC1090 -source "${BashMatic}/init.sh" 1>/dev/null 2>&1 +source "${BASHMATIC_HOME}/init.sh" 1>/dev/null 2>&1 + +export BAZEL_OPTS="--max_idle_secs=10800 --noshutdown_on_low_sys_mem --connect_timeout_secs=30" main() { - export BAZEL_OPTS="--max_idle_secs=10800 --noshutdown_on_low_sys_mem --connect_timeout_secs=30" h1 "Cleaning Bazel directories... Please wait." + # shellcheck disable=SC2207 local -a du_before=($(du -hs .)) run "bazel clean --expunge" - for dir in $(ls -1 examples); do + # shellcheck disable=SC2207 + local -a examples=($(ls -1 examples)) + for dir in "${examples[@]}"; do run "cd examples/${dir}" run "bazel clean --expunge" run "cd -" done + + # shellcheck disable=SC2207 local -a du_after=($(du -hs .)) h2 "Space before cleaning: ${bldylw}${du_before[0]}" \ "Space after cleaning: ${bldgrn}${du_after[0]}" } main "$@" - diff --git a/bin/deps b/bin/deps index 353492a0..dfdbbccd 100755 --- a/bin/deps +++ b/bin/deps @@ -9,15 +9,13 @@ # setup will re-install it. # ————————————————————————————————————————————————————————————————————————————————————— -export BashMatic="${HOME}/.bashmatic" -if [[ ! -f "${BashMatic}/init.sh" ]]; then - rm -rf "${BashMatic}" 2>/dev/null - git clone https://github.com/kigster/bashmatic "${BashMatic}" 1>/dev/null 2>&1 -fi +[[ -z ${BASHMATIC_HOME} ]] && export BASHMATIC_HOME="${HOME}/.bashmatic" +[[ -d ${BASHMATIC_HOME} ]] || bash -c "$(curl -fsSL https://bashmatic.re1.re); bashmatic-install -q" # shellcheck disable=SC1090 -source "${BashMatic}/init.sh" 1>/dev/null 2>&1 +source "${BASHMATIC_HOME}/init.sh" 1>/dev/null 2>&1 +command -v rbenv>/dev/null && eval "$(rbenv init -)" __version.detect() { local file="1ドル" @@ -35,7 +33,7 @@ __version.detect() { # Application Constants export RulesRuby__RulesVersion="$(__version.detect .rules_version)" -export RulesRuby__RubyVersion="$(__version.detect .ruby_version)" +export RulesRuby__RubyVersion="$(__version.detect .ruby-version)" export RulesRuby__BazelVersion="$(__version.detect .bazelversion)" bazel-sha() { diff --git a/bin/setup b/bin/setup index f3133356..c0799cad 100755 --- a/bin/setup +++ b/bin/setup @@ -41,21 +41,26 @@ setup.rbenv() { fi fi - [[ -d "${rbenv_home}" && -f "${rbenv_home}/bin/rbenv" ]] || { + [[ -d "${rbenv_home}" && -n "$(command -v rbenv)" ]] || { if [[ -z ${CI} ]]; then - warning "You are on a local system without any RBENV..." - run.ui.ask "Are you sure you want to wipe your local ~/.rbenv?" + warning "You are on a local system without any RBENV..." \ + "We are going to move your ~/.rbenv to a backup location and" \ + "install it from scratch to ensure it is up to date." + run.ui.ask "Should we proceed with building a new Ruby and backing up your ~/.rbenv?" fi - warning "Recreating RBENV home, downloading rbenv..." - run "rm -rf ${rbenv_home}" + [[ -d ${rbenv_home} ]] && { + local rbenv_backup="${rbenv_home}.backup.$(time.now.db)" + info "Moving your current ${rbenv_home} to ${bldylw}${rbenv_backup}" + run "mv -v ${rbenv_home} ${rbenv_backup}" + } run "git clone https://github.com/rbenv/rbenv.git ${rbenv_home}" export PATH="${rbenv_home}/bin:${rbenv_home}/shims:${PATH}" } export PATH="${rbenv_home}/bin:${rbenv_home}/shims:${PATH}" - [[ $(which rbenv) == "${rbenv_home}/bin/rbenv" ]] || { + [[ $(command -v rbenv) == "${rbenv_home}/bin/rbenv" || $(command -v rbenv) == "/usr/local/bin/rbenv" ]] || { error "Can't find rbenv in the PATH — which rbenv returns: $(which rbenv)" error "PATH: ${PATH}" return 1 diff --git a/bin/setup-darwin b/bin/setup-darwin index a21487a5..3327bb4b 100755 --- a/bin/setup-darwin +++ b/bin/setup-darwin @@ -58,14 +58,18 @@ setup.xcode-tools() { } setup.bazel() { - brew.package.is-installed bazelbuild/tap/bazelisk && - brew.uninstall.package bazelbuild/tap/bazelisk + brew.package.is-installed bazelisk && + brew.uninstall.package bazelisk && + run "brew unlink bazel" if __setup.is-bazelisk-installed && __setup.is-bazel-installed ; then info: "Bazel & bazelisk are already installed." else brew.install.packages bazel bazelisk + run "brew link bazel || true" fi + + } setup.darwin() { diff --git a/bin/show-env b/bin/show-env index 6f396daa..7019b626 100755 --- a/bin/show-env +++ b/bin/show-env @@ -32,19 +32,21 @@ function setup.print-versions() { set +e h2 "Your Current Runtime Environment:" echo - setup.table-rows 'Bazel' "$(bazel --version)" "$(command -v bazel)" - setup.table-rows 'Bazelisk' "${bazelisk_version}" + setup.table-rows 'RULES_RUBY' "$(cat .rules_version)" "Last updated on $(file.last-modified-date CHANGELOG.md)" + hr + setup.table-rows 'BAZEL' "$(bazel --version)" "$(command -v bazel)" + setup.table-rows 'BAZELISK' "${bazelisk_version}" setup.table-rows 'BASH' "$(bash --version 2>/dev/null | tr -d ',')" "$(command -v bash)" setup.table-rows 'CC' "$(cc --version 2>/dev/null)" "$(cc --version | grep clang)" setup.table-rows 'GO' "$(go version 2>/dev/null)" "$(command -v go)" hr - setup.table-rows 'Ruby' "$(ruby --version | sed -E 's/p[0-9]+.*$//g' 2>&1)" "$(command -v ruby)" + setup.table-rows 'RUBY' "$(ruby --version | sed -E 's/p[0-9]+.*$//g' 2>&1)" "$(command -v ruby)" setup.table-rows 'RBENV' "$(rbenv --version 2>/dev/null)" "$(command -v rbenv)" - setup.table-rows 'RUBIES' " " "$(rbenv versions 2>/dev/null | sed 's/ (.*//g; s/[ \*]//g' | tr '\n' '|')" + setup.table-rows 'RUBIES' "List of installed Ruby Versions" "$(rbenv versions 2>/dev/null | sed 's/ (.*//g; s/[ \*]//g' | sed 's/$/, /g' | tr -d '\n')" hr - setup.table-rows 'Python' "$(python --version 2>&1)" "$(command -v python) -> $(readlink "$(command -v python)")" - setup.table-rows 'Python2' "$(python2 --version 2>&1)" "$(command -v python2)" - setup.table-rows 'Python3' "$(python3 --version 2>&1)" "$(command -v python3)" + setup.table-rows 'PYTHON' "$(python --version 2>&1)" "$(command -v python) -> $(readlink "$(command -v python)")" + setup.table-rows 'PYTHON2' "$(python2 --version 2>&1)" "$(command -v python2)" + setup.table-rows 'PYTHON3' "$(python3 --version 2>&1)" "$(command -v python3)" hr set -e diff --git a/bin/test-suite b/bin/test-suite index 7c17406e..63643f16 100755 --- a/bin/test-suite +++ b/bin/test-suite @@ -12,7 +12,7 @@ set -e # shellcheck disable=SC1091 -source "bin/deps" 2>/dev/null 1>/dev/null +source "bin/deps" export SHELL_INIT="${HOME}/.bashrc" export BUNDLE_PATH="${BUNDLE_PATH:-${HOME}/.bundle/gems}" @@ -21,10 +21,12 @@ export PATH="${HOME}/.rbenv/bin:${HOME}/.rbenv/shims:/usr/local/bin:/usr/bin:/bi export BAZEL_OPTS="--host_jvm_args=-Xmx500m --host_jvm_args=-Xms500m" export BAZEL_BUILD_OPTS="--curses=no --verbose_failures -j 30 --progress_report_interval=2" export BAZEL_TEST_OPTS="--verbose_failures --test_verbose_timeout_warnings --verbose_explanations" -export RUBY_VERSION="$(__version.detect .ruby_version)" +export RUBY_VERSION="$(__version.detect .ruby-version)" export BUNDLER_VERSION=$(gem.gemfile.bundler-version) export RULES_VERSION=$(__version.detect .rules_version) +h3bg "RUBY_VERSION=${RUBY_VERSION}" + export BashMatic__Expr=" [[ -f ${SHELL_INIT} ]] && source ${SHELL_INIT}; [[ -f ${HOME}/.bashmatic/init.sh ]] && source ${HOME}/.bashmatic/init.sh; diff --git a/docs/img/env.png b/docs/img/env.png new file mode 100644 index 00000000..3593b88c Binary files /dev/null and b/docs/img/env.png differ diff --git a/examples/example_gem/WORKSPACE b/examples/example_gem/WORKSPACE index d0ee2209..0f096a77 100644 --- a/examples/example_gem/WORKSPACE +++ b/examples/example_gem/WORKSPACE @@ -15,7 +15,7 @@ load( rules_ruby_dependencies() -rules_ruby_select_sdk("2.7.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 324aa9f0..a4ffd85a 100644 --- a/examples/simple_rails_api/Gemfile.lock +++ b/examples/simple_rails_api/Gemfile.lock @@ -1,149 +1,147 @@ GEM remote: https://rubygems.org/ specs: - actioncable (6.0.3.2) - actionpack (= 6.0.3.2) + actioncable (6.0.4.1) + actionpack (= 6.0.4.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.0.3.2) - actionpack (= 6.0.3.2) - activejob (= 6.0.3.2) - activerecord (= 6.0.3.2) - activestorage (= 6.0.3.2) - activesupport (= 6.0.3.2) + 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.3.2) - actionpack (= 6.0.3.2) - actionview (= 6.0.3.2) - activejob (= 6.0.3.2) + 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.3.2) - actionview (= 6.0.3.2) - activesupport (= 6.0.3.2) + 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.3.2) - actionpack (= 6.0.3.2) - activerecord (= 6.0.3.2) - activestorage (= 6.0.3.2) - activesupport (= 6.0.3.2) + 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.3.2) - activesupport (= 6.0.3.2) + 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.3.2) - activesupport (= 6.0.3.2) + activejob (6.0.4.1) + activesupport (= 6.0.4.1) globalid (>= 0.3.6) - activemodel (6.0.3.2) - activesupport (= 6.0.3.2) - activerecord (6.0.3.2) - activemodel (= 6.0.3.2) - activesupport (= 6.0.3.2) - activestorage (6.0.3.2) - actionpack (= 6.0.3.2) - activejob (= 6.0.3.2) - activerecord (= 6.0.3.2) - marcel (~> 0.3.1) - activesupport (6.0.3.2) + 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.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.4.6) + bootsnap (1.9.1) msgpack (~> 1.0) builder (3.2.4) byebug (11.1.3) - concurrent-ruby (1.1.6) + concurrent-ruby (1.1.10) crass (1.0.6) - erubi (1.9.0) - ffi (1.13.1) - globalid (0.4.2) - activesupport (>= 4.2.0) - i18n (1.8.3) + erubi (1.10.0) + ffi (1.15.4) + globalid (1.0.1) + activesupport (>= 5.0) + i18n (1.12.0) concurrent-ruby (~> 1.0) - listen (3.1.5) + listen (3.0.8) rb-fsevent (~> 0.9,>= 0.9.4) rb-inotify (~> 0.9,>= 0.9.7) - ruby_dep (~> 1.2) - loofah (2.6.0) + loofah (2.12.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) - marcel (0.3.3) - mimemagic (~> 0.3.2) + marcel (1.0.2) method_source (1.0.0) - mimemagic (0.3.5) - mini_mime (1.0.2) - mini_portile2 (2.4.0) - minitest (5.14.1) - msgpack (1.3.3) - nio4r (2.5.2) - nokogiri (1.10.10) - mini_portile2 (~> 2.4.0) - puma (4.3.5) + mini_mime (1.1.1) + mini_portile2 (2.8.0) + minitest (5.17.0) + msgpack (1.4.2) + nio4r (2.5.8) + nokogiri (1.13.4) + mini_portile2 (~> 2.8.0) + racc (~> 1.4) + puma (4.3.12) nio4r (~> 2.0) - rack (2.2.3) + racc (1.6.0) + rack (2.2.3.1) rack-test (1.1.0) rack (>= 1.0, < 3) - rails (6.0.3.2) - actioncable (= 6.0.3.2) - actionmailbox (= 6.0.3.2) - actionmailer (= 6.0.3.2) - actionpack (= 6.0.3.2) - actiontext (= 6.0.3.2) - actionview (= 6.0.3.2) - activejob (= 6.0.3.2) - activemodel (= 6.0.3.2) - activerecord (= 6.0.3.2) - activestorage (= 6.0.3.2) - activesupport (= 6.0.3.2) + 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.3.2) + 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.3.2) - actionpack (= 6.0.3.2) - activesupport (= 6.0.3.2) + 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.1) - rb-fsevent (0.10.4) + rake (13.0.6) + rb-fsevent (0.11.0) rb-inotify (0.10.1) ffi (~> 1.0) - ruby_dep (1.5.0) - spring (2.1.0) + spring (2.1.1) spring-watcher-listen (2.0.1) listen (>= 2.7, < 4.0) spring (>= 1.2, < 3.0) sprockets (4.0.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.2.1) + sprockets-rails (3.2.2) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) sqlite3 (1.4.2) - thor (1.0.1) + thor (1.1.0) thread_safe (0.3.6) - tzinfo (1.2.7) + tzinfo (1.2.10) thread_safe (~> 0.1) - websocket-driver (0.7.3) + websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - zeitwerk (2.4.0) + zeitwerk (2.6.6) PLATFORMS ruby @@ -160,4 +158,4 @@ DEPENDENCIES tzinfo-data BUNDLED WITH - 2.1.2 + 2.2.24 diff --git a/examples/simple_rails_api/WORKSPACE b/examples/simple_rails_api/WORKSPACE index c0febc9b..8585cfec 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 = "2.7.1") +rules_ruby_select_sdk(version = "3.0.2") load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") diff --git a/examples/simple_script/.rubocop.yml b/examples/simple_script/.rubocop.yml index 7b653d9d..7a33ed81 100644 --- a/examples/simple_script/.rubocop.yml +++ b/examples/simple_script/.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,7 @@ AllCops: - '**/*.ru' - '**/Gemfile' - '**/Rakefile' + NewCops: enable Layout/HashAlignment: Enabled: true diff --git a/examples/simple_script/.ruby-version b/examples/simple_script/.ruby-version new file mode 100644 index 00000000..b5021469 --- /dev/null +++ b/examples/simple_script/.ruby-version @@ -0,0 +1 @@ +3.0.2 diff --git a/examples/simple_script/BUILD.bazel b/examples/simple_script/BUILD.bazel index bf0e8032..3f81e7b9 100644 --- a/examples/simple_script/BUILD.bazel +++ b/examples/simple_script/BUILD.bazel @@ -31,6 +31,8 @@ ruby_test( ] + glob([ "spec/**/*.rb", ]), + # This is a WORKSPACE-relative path to a spec directory. + # It could be longer, like "my/path/to/spec". args = [ "spec", ], diff --git a/examples/simple_script/Gemfile b/examples/simple_script/Gemfile index d677fb55..9fade231 100644 --- a/examples/simple_script/Gemfile +++ b/examples/simple_script/Gemfile @@ -5,5 +5,5 @@ source 'https://rubygems.org' gem 'awesome_print' gem 'colored2' gem 'rspec', '~> 3.7.0' -gem 'rspec-its' -gem 'rubocop', '~> 0.78.0' +gem 'rspec-its', github: "rspec/rspec-its", ref: "3d36b4a7b004ffa204a0e392f27c8b6b0b674ecf" # v1.3.0 +gem 'rubocop' diff --git a/examples/simple_script/Gemfile.lock b/examples/simple_script/Gemfile.lock index 6dbbfbb4..ee74d259 100644 --- a/examples/simple_script/Gemfile.lock +++ b/examples/simple_script/Gemfile.lock @@ -1,15 +1,25 @@ +GIT + remote: https://github.com/rspec/rspec-its.git + revision: 3d36b4a7b004ffa204a0e392f27c8b6b0b674ecf + ref: 3d36b4a7b004ffa204a0e392f27c8b6b0b674ecf + specs: + rspec-its (1.3.0) + rspec-core (>= 3.0.0) + rspec-expectations (>= 3.0.0) + GEM remote: https://rubygems.org/ specs: - ast (2.4.1) - awesome_print (1.8.0) + ast (2.4.2) + awesome_print (1.9.2) colored2 (3.1.2) diff-lcs (1.4.4) - jaro_winkler (1.5.4) - parallel (1.19.2) - parser (2.7.1.4) + 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) @@ -19,22 +29,23 @@ GEM rspec-expectations (3.7.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.7.0) - rspec-its (1.3.0) - rspec-core (>= 3.0.0) - rspec-expectations (>= 3.0.0) rspec-mocks (3.7.0) 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) - ruby-progressbar (1.10.1) - unicode-display_width (1.6.1) + 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 (2.1.0) PLATFORMS ruby @@ -43,8 +54,8 @@ DEPENDENCIES awesome_print colored2 rspec (~> 3.7.0) - rspec-its - rubocop (~> 0.78.0) + rspec-its! + rubocop BUNDLED WITH - 2.1.2 + 2.2.24 diff --git a/examples/simple_script/WORKSPACE b/examples/simple_script/WORKSPACE index 1caa54b9..4ad11d15 100644 --- a/examples/simple_script/WORKSPACE +++ b/examples/simple_script/WORKSPACE @@ -15,13 +15,13 @@ load( rules_ruby_dependencies() -rules_ruby_select_sdk(version = "2.7.1") +rules_ruby_select_sdk(version = "3.0.2") load("@bazelruby_rules_ruby//ruby:defs.bzl", "ruby_bundle") ruby_bundle( name = "bundle", - bundler_version = "2.1.2", + bundler_version = "2.1.4", excludes = { "mini_portile": ["test/**/*"], }, diff --git a/examples/simple_script/spec/script_spec.rb b/examples/simple_script/spec/script_spec.rb index 458b928c..b325d32d 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/.gitignore b/examples/simple_script_vendored/.gitignore new file mode 100644 index 00000000..a6ef824c --- /dev/null +++ b/examples/simple_script_vendored/.gitignore @@ -0,0 +1 @@ +/bazel-* diff --git a/examples/simple_script_vendored/.relaxed-rubocop-2.4.yml b/examples/simple_script_vendored/.relaxed-rubocop-2.4.yml new file mode 100644 index 00000000..fce806fe --- /dev/null +++ b/examples/simple_script_vendored/.relaxed-rubocop-2.4.yml @@ -0,0 +1,174 @@ +# Relaxed.Ruby.Style +## Version 2.4 + +Style/Alias: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylealias + +Style/AsciiComments: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#styleasciicomments + +Style/BeginBlock: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylebeginblock + +Style/BlockDelimiters: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#styleblockdelimiters + +Style/CommentAnnotation: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylecommentannotation + +Style/Documentation: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#styledocumentation + +Layout/DotPosition: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#layoutdotposition + +Style/DoubleNegation: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#styledoublenegation + +Style/EndBlock: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#styleendblock + +Style/FormatString: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#styleformatstring + +Style/IfUnlessModifier: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#styleifunlessmodifier + +Style/Lambda: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylelambda + +Style/ModuleFunction: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylemodulefunction + +Style/MultilineBlockChain: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylemultilineblockchain + +Style/NegatedIf: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylenegatedif + +Style/NegatedWhile: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylenegatedwhile + +Style/NumericPredicate: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylenumericpredicate + +Style/ParallelAssignment: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#styleparallelassignment + +Style/PercentLiteralDelimiters: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylepercentliteraldelimiters + +Style/PerlBackrefs: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#styleperlbackrefs + +Style/Semicolon: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylesemicolon + +Style/SignalException: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylesignalexception + +Style/SingleLineBlockParams: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylesinglelineblockparams + +Style/SingleLineMethods: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylesinglelinemethods + +Layout/SpaceBeforeBlockBraces: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#layoutspacebeforeblockbraces + +Layout/SpaceInsideParens: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#layoutspaceinsideparens + +Layout/LineLength: + Enabled: false + +Style/SpecialGlobalVars: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylespecialglobalvars + +Style/StringLiterals: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylestringliterals + +Style/TrailingCommaInArguments: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#styletrailingcommainarguments + +Style/TrailingCommaInArrayLiteral: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#styletrailingcommainarrayliteral + +Style/TrailingCommaInHashLiteral: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#styletrailingcommainhashliteral + +Style/SymbolArray: + Enabled: false + StyleGuide: http://relaxed.ruby.style/#stylesymbolarray + +Style/WhileUntilModifier: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylewhileuntilmodifier + +Style/WordArray: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#stylewordarray + +Lint/AmbiguousRegexpLiteral: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#lintambiguousregexpliteral + +Lint/AssignmentInCondition: + Enabled: false + StyleGuide: https://relaxed.ruby.style/#lintassignmentincondition + +Metrics/AbcSize: + Enabled: false + +Metrics/BlockNesting: + Enabled: false + +Metrics/ClassLength: + Enabled: false + +Metrics/ModuleLength: + Enabled: false + +Metrics/CyclomaticComplexity: + Enabled: false + +Metrics/MethodLength: + Enabled: false + +Metrics/ParameterLists: + Enabled: false + +Metrics/PerceivedComplexity: + Enabled: false + diff --git a/examples/simple_script_vendored/.rubocop.yml b/examples/simple_script_vendored/.rubocop.yml new file mode 100644 index 00000000..0687ca77 --- /dev/null +++ b/examples/simple_script_vendored/.rubocop.yml @@ -0,0 +1,38 @@ +inherit_from: .relaxed-rubocop-2.4.yml + +AllCops: + TargetRubyVersion: 3.0 + UseCache: true + DefaultFormatter: progress + DisplayStyleGuide: true + DisplayCopNames: true + Exclude: + - "external*/**/*" + - "bazel-*/**/*" + - "**/examples/**/*" + - "**/BUILD" + - "**/*.bazel" + - "**/*.bzl" + - "**/rubocop" + - "**/vendor/bundle/**/*" + Include: + - '**/*.rb' + - '**/*.gemfile' + - '**/*.gemspec' + - '**/*.rake' + - '**/*.ru' + - '**/Gemfile' + - '**/Rakefile' + SuggestExtensions: false + NewCops: enable + +Layout/HashAlignment: + Enabled: true + EnforcedColonStyle: table + +Style/Dir: + Enabled: false + +# In Bazel we want to use __FILE__ because __dir__points to the actual sources +Style/ExpandPathArguments: + Enabled: false diff --git a/examples/simple_script_vendored/BUILD.bazel b/examples/simple_script_vendored/BUILD.bazel new file mode 100644 index 00000000..1fc2d136 --- /dev/null +++ b/examples/simple_script_vendored/BUILD.bazel @@ -0,0 +1,94 @@ +load( + "@bazelruby_rules_ruby//ruby:defs.bzl", + "ruby_binary", + "ruby_rspec", + "ruby_rubocop", + "ruby_test", +) + +package(default_visibility = ["//:__subpackages__"]) + +ruby_binary( + name = "bin", + srcs = ["script.rb"], + main = "script.rb", + deps = [ + "//lib:foo", + ], +) + +# This is an example of the RSpec definition that uses autorun +# and points to spec_helper as the main spec file. It specifies +# which specs to run using the args. + +ruby_test( + name = "all-specs", + timeout = "short", + srcs = [ + "script.rb", + "//lib:foo", + ] + glob([ + "spec/**/*.rb", + ]), + # This is a WORKSPACE-relative path to a spec directory. + # It could be longer, like "my/path/to/spec". + args = [ + "spec", + ], + main = "@bundle//:bin/rspec", + deps = [ + "@bundle//:bin", + "@bundle//:rspec", + "@bundle//:rspec-its", + ], +) + +# Finally, this is the short version of the same thing, expressed +# via the ruby_rspec_test rule that does what the above example +# shows but encapsulated in the rule itself. It adds rspec and rspec-its +# gems to the dependency list, executes bin/rspec and passes spec_targets +# as arguments to rspec. +ruby_rspec( + name = "ruby-rspec-test", + srcs = [ + "script.rb", + "//lib:foo", + ], + rspec_args = { + # NOTE: the output is only visible with --test_output=streamed flag + "--format": "progress", # this is how we can override rspec output format + }, + specs = glob([ + "spec/**/*.rb", + ]), + deps = [], +) + +ruby_binary( + name = "rubocop-bin", + srcs = [ + "script.rb", + "//lib:foo", + ] + glob([ + "spec/**/*.rb", + ]), + args = [ + "-- *.rb spec/*.rb lib/*.rb -a", + ], + main = "@bundle//:bin/rubocop", + deps = [ + "//lib:foo", + "@bundle//:bin", + ], +) + +# Rubocop rule +# To check +# bazel run rubocop -- -a +ruby_rubocop( + name = "rubocop", + bin = "@bundle//:bin/rubocop", + deps = [ + "@bundle//:rubocop", + ], +) diff --git a/examples/simple_script_vendored/Gemfile b/examples/simple_script_vendored/Gemfile new file mode 100644 index 00000000..48bd8b2d --- /dev/null +++ b/examples/simple_script_vendored/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +source 'https://rubygems.org' + +gem 'rspec', '~> 3.7.0' +gem 'rspec-its' +gem 'rubocop' diff --git a/examples/simple_script_vendored/Gemfile.lock b/examples/simple_script_vendored/Gemfile.lock new file mode 100644 index 00000000..315f6e68 --- /dev/null +++ b/examples/simple_script_vendored/Gemfile.lock @@ -0,0 +1,51 @@ +GEM + remote: https://rubygems.org/ + specs: + ast (2.4.2) + diff-lcs (1.4.4) + 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) + rspec-mocks (~> 3.7.0) + rspec-core (3.7.1) + rspec-support (~> 3.7.0) + rspec-expectations (3.7.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.7.0) + rspec-its (1.3.0) + rspec-core (>= 3.0.0) + rspec-expectations (>= 3.0.0) + rspec-mocks (3.7.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.7.0) + rspec-support (3.7.1) + 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.9.1, < 2.0) + ruby-progressbar (~> 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 (2.1.0) + +PLATFORMS + ruby + +DEPENDENCIES + rspec (~> 3.7.0) + rspec-its + rubocop + +BUNDLED WITH + 2.2.24 diff --git a/examples/simple_script_vendored/README.md b/examples/simple_script_vendored/README.md new file mode 100644 index 00000000..4949968e --- /dev/null +++ b/examples/simple_script_vendored/README.md @@ -0,0 +1,17 @@ +# Simple Script Example + +This Workspace includes a simple ruby script that includes and external gem and an internal library + +### Bundle + +Update gemfile using +``` +bundle update +``` + +### Rubocop +Run rubocop with: + +``` +bazel run //:rubocop +``` diff --git a/examples/simple_script_vendored/WORKSPACE b/examples/simple_script_vendored/WORKSPACE new file mode 100644 index 00000000..3aff264d --- /dev/null +++ b/examples/simple_script_vendored/WORKSPACE @@ -0,0 +1,34 @@ +workspace( + name = "bazelruby_rules_ruby_example", + managed_directories = {"@bundle": ["vendor"]}, +) + +# Importing rules_ruby from the parent directory for developing +# rules_ruby itself... +local_repository( + name = "bazelruby_rules_ruby", + path = "../..", +) + +load( + "@bazelruby_rules_ruby//ruby:deps.bzl", + "rules_ruby_dependencies", + "rules_ruby_select_sdk", +) + +rules_ruby_dependencies() + +rules_ruby_select_sdk(version = "2.7.1") + +load("@bazelruby_rules_ruby//ruby:defs.bzl", "ruby_bundle") + +ruby_bundle( + name = "bundle", + bundler_version = "2.1.2", + excludes = { + "mini_portile": ["test/**/*"], + }, + gemfile = "//:Gemfile", + gemfile_lock = "//:Gemfile.lock", + vendor_cache = True, +) diff --git a/examples/simple_script_vendored/lib/BUILD b/examples/simple_script_vendored/lib/BUILD new file mode 100644 index 00000000..f125ff86 --- /dev/null +++ b/examples/simple_script_vendored/lib/BUILD @@ -0,0 +1,11 @@ +load( + "@bazelruby_rules_ruby//ruby:defs.bzl", + "ruby_library", +) + +package(default_visibility = ["//:__subpackages__"]) + +ruby_library( + name = "foo", + srcs = ["foo.rb"], +) diff --git a/examples/simple_script_vendored/lib/foo.rb b/examples/simple_script_vendored/lib/foo.rb new file mode 100644 index 00000000..eff4466c --- /dev/null +++ b/examples/simple_script_vendored/lib/foo.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +class Foo + class << self + def yell_aha + puts aha + end + + def aha + 'You said, aha?' + end + + def rot13(value) + return nil unless value.is_a?(String) + + value.tr('abcdefghijklmnopqrstuvwxyz', 'nopqrstuvwxyzabcdefghijklm') + end + end + + attr_reader :goo, :foo + + def initialize(goo) + @goo = goo + @foo = transform(goo) + end + + def transform(incoming = goo) + Foo.rot13(incoming) + end +end diff --git a/examples/simple_script_vendored/script.rb b/examples/simple_script_vendored/script.rb new file mode 100644 index 00000000..64c6ea20 --- /dev/null +++ b/examples/simple_script_vendored/script.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require 'openssl' + +require_relative 'lib/foo' + +def oss_rand + OpenSSL::BN.rand(512).to_s +end + +puts Foo.aha + ' ' + oss_rand diff --git a/examples/simple_script_vendored/spec/lib/foo_spec.rb b/examples/simple_script_vendored/spec/lib/foo_spec.rb new file mode 100644 index 00000000..31ca6658 --- /dev/null +++ b/examples/simple_script_vendored/spec/lib/foo_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require_relative '../spec_helper' +require_relative '../../lib/foo' + +RSpec.describe Foo do + let(:goo) { 'Green slime was dripping down his throat into his lapdomen...' } + subject(:foo) { Foo.new(goo) } + + context 'without the aha' do + before { allow(Foo).to receive(:yell_aha).and_return('tiny dongle') } + + it "should have goo" do + expect(subject.goo).to eql goo + end + it "should have transformed goo" do + expect(subject.transform).not_to eql goo + end + + # Some rot13 old school encryption :) + it "should use rot13 for transform" do + expect(subject.transform).to eql 'Gerra fyvzr jnf qevccvat qbja uvf guebng vagb uvf yncqbzra...' + end + end + + context 'aha' do + it 'should print aha' do + expect(Foo).to receive(:puts).with('You said, aha?').and_return(nil) + Foo.yell_aha + end + end +end diff --git a/examples/simple_script_vendored/spec/script_spec.rb b/examples/simple_script_vendored/spec/script_spec.rb new file mode 100644 index 00000000..458b928c --- /dev/null +++ b/examples/simple_script_vendored/spec/script_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'script' + +describe 'oss_rand' do + it 'generates a String' do + expect(oss_rand).to be_a_kind_of String + end +end diff --git a/examples/simple_script_vendored/spec/spec_helper.rb b/examples/simple_script_vendored/spec/spec_helper.rb new file mode 100644 index 00000000..9de82de9 --- /dev/null +++ b/examples/simple_script_vendored/spec/spec_helper.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +# Sets HOME here because: +# If otherwise, it causes a runtime failure with the following steps. +# 1. RSpec::Core::ConfigurationOptions.global_options_file raises an exception +# because $HOME is not set in the sandbox environment of Bazel +# 2. the rescue clause calls RSpec::Support.#warning +# 3. #warning calls #warn_with +# 4. #warn_with tries to lookup the first caller which is not a part of RSpec. +# But all the call stack entires are about RSpec at this time because +# it is invoked by rpsec/autorun. So #warn_with raises an exception +# 5. The process fails with an unhandled exception. + +LIB = File.expand_path(File.dirname(__dir__)) +$LOAD_PATH.unshift(LIB) unless $LOAD_PATH.include?(LIB) + +ENV["HOME"] ||= "/" + +require "rspec" +require "script" + +RSpec.configure do |config| + config.expect_with :rspec do |expectations| + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + config.mock_with :rspec do |mocks| + mocks.verify_partial_doubles = true + end + + config.shared_context_metadata_behavior = :apply_to_host_groups + + config.warnings = true + config.filter_run_when_matching :focus + # config.disable_monkey_patching! + config.order = :random + Kernel.srand config.seed +end diff --git a/examples/simple_script_vendored/vendor/cache/ast-2.4.2.gem b/examples/simple_script_vendored/vendor/cache/ast-2.4.2.gem new file mode 100644 index 00000000..abe16436 Binary files /dev/null and b/examples/simple_script_vendored/vendor/cache/ast-2.4.2.gem differ diff --git a/examples/simple_script_vendored/vendor/cache/diff-lcs-1.4.4.gem b/examples/simple_script_vendored/vendor/cache/diff-lcs-1.4.4.gem new file mode 100644 index 00000000..3be4edc1 Binary files /dev/null and b/examples/simple_script_vendored/vendor/cache/diff-lcs-1.4.4.gem 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 00000000..ca8f6362 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.2.0.gem b/examples/simple_script_vendored/vendor/cache/parser-3.0.2.0.gem new file mode 100644 index 00000000..ee615aaa 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/rainbow-3.0.0.gem b/examples/simple_script_vendored/vendor/cache/rainbow-3.0.0.gem new file mode 100644 index 00000000..c53caf7a Binary files /dev/null and b/examples/simple_script_vendored/vendor/cache/rainbow-3.0.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 00000000..4bb25a0e 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 00000000..5680fec4 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/rspec-3.7.0.gem b/examples/simple_script_vendored/vendor/cache/rspec-3.7.0.gem new file mode 100644 index 00000000..6ce573a5 Binary files /dev/null and b/examples/simple_script_vendored/vendor/cache/rspec-3.7.0.gem differ diff --git a/examples/simple_script_vendored/vendor/cache/rspec-core-3.7.1.gem b/examples/simple_script_vendored/vendor/cache/rspec-core-3.7.1.gem new file mode 100644 index 00000000..d949df80 Binary files /dev/null and b/examples/simple_script_vendored/vendor/cache/rspec-core-3.7.1.gem differ diff --git a/examples/simple_script_vendored/vendor/cache/rspec-expectations-3.7.0.gem b/examples/simple_script_vendored/vendor/cache/rspec-expectations-3.7.0.gem new file mode 100644 index 00000000..119eda3e Binary files /dev/null and b/examples/simple_script_vendored/vendor/cache/rspec-expectations-3.7.0.gem differ diff --git a/examples/simple_script_vendored/vendor/cache/rspec-its-1.3.0.gem b/examples/simple_script_vendored/vendor/cache/rspec-its-1.3.0.gem new file mode 100644 index 00000000..bcff4af6 Binary files /dev/null and b/examples/simple_script_vendored/vendor/cache/rspec-its-1.3.0.gem differ diff --git a/examples/simple_script_vendored/vendor/cache/rspec-mocks-3.7.0.gem b/examples/simple_script_vendored/vendor/cache/rspec-mocks-3.7.0.gem new file mode 100644 index 00000000..f34bef2e Binary files /dev/null and b/examples/simple_script_vendored/vendor/cache/rspec-mocks-3.7.0.gem differ diff --git a/examples/simple_script_vendored/vendor/cache/rspec-support-3.7.1.gem b/examples/simple_script_vendored/vendor/cache/rspec-support-3.7.1.gem new file mode 100644 index 00000000..4d29cf93 Binary files /dev/null and b/examples/simple_script_vendored/vendor/cache/rspec-support-3.7.1.gem 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 00000000..ddeba664 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 00000000..9a444dae 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/ruby-progressbar-1.11.0.gem b/examples/simple_script_vendored/vendor/cache/ruby-progressbar-1.11.0.gem new file mode 100644 index 00000000..a9d84e50 Binary files /dev/null and b/examples/simple_script_vendored/vendor/cache/ruby-progressbar-1.11.0.gem 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 00000000..bec8f2a7 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/binary_wrapper.tpl b/ruby/private/binary_wrapper.tpl old mode 100644 new mode 100755 index 33f57caf..09e04024 --- a/ruby/private/binary_wrapper.tpl +++ b/ruby/private/binary_wrapper.tpl @@ -119,8 +119,8 @@ def main(args) runfiles_envkey, runfiles_envvalue = runfiles_envvar(runfiles) ENV[runfiles_envkey] = runfiles_envvalue if runfiles_envkey - ENV["GEM_PATH"] = File.join(runfiles, "{gem_path}") if "{gem_path}" - ENV["GEM_HOME"] = File.join(runfiles, "{gem_path}") if "{gem_path}" + ENV["GEM_PATH"] = File.join(runfiles, "{gem_path}") if !"{gem_path}".empty? + ENV["GEM_HOME"] = File.join(runfiles, "{gem_path}") if !"{gem_path}".empty? ruby_program = find_ruby_binary diff --git a/ruby/private/bundle/create_bundle_build_file.rb b/ruby/private/bundle/create_bundle_build_file.rb index b283b404..2dcc6d4a 100755 --- a/ruby/private/bundle/create_bundle_build_file.rb +++ b/ruby/private/bundle/create_bundle_build_file.rb @@ -33,14 +33,14 @@ srcs = glob( include = [ ".bundle/config", - "{gem_lib_files}", - "lib/ruby/{ruby_version}/specifications/{name}-{version}.gemspec", + {gem_lib_files}, + "{gem_spec}", {gem_binaries} ], exclude = {exclude}, ), deps = {deps}, - includes = ["lib/ruby/{ruby_version}/gems/{name}-{version}/lib"], + includes = [{gem_lib_paths}], ) GEM_TEMPLATE @@ -58,10 +58,34 @@ ) 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 - "lib/ruby/#{ruby_version}/gems/#{gem_name}-#{gem_version}" + 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/#{RbConfig::CONFIG['RUBY_INSTALL_NAME']}/#{ruby_version}/specifications/#{gem_name}-#{gem_version}*.gemspec").first +end + +HERE = File.absolute_path '.' + require 'bundler' require 'json' require 'stringio' @@ -96,8 +120,11 @@ class Buildifier # @formatter:off class BuildifierError < StandardError; end + class BuildifierNotFoundError < BuildifierError; end + class BuildifierFailedError < BuildifierError; end + class BuildifierNoBuildFileError < BuildifierError; end # @formatter:on @@ -133,8 +160,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 @@ -144,6 +170,7 @@ class BundleBuildFileGenerator :repo_name, :build_file, :gemfile_lock, + :includes, :excludes, :ruby_version @@ -155,11 +182,13 @@ def initialize(workspace_name:, repo_name:, build_file: 'BUILD.bazel', gemfile_lock: 'Gemfile.lock', + includes: nil, excludes: nil) @workspace_name = workspace_name @repo_name = repo_name @build_file = build_file @gemfile_lock = gemfile_lock + @includes = includes @excludes = excludes # This attribute returns 0 as the third minor version number, which happens to be # what Ruby uses in the PATH to gems, eg. ruby 2.6.5 would have a folder called @@ -222,8 +251,38 @@ def remove_bundler_version! end def register_gem(spec, template_out, bundle_lib_paths, bundle_binaries) - gem_path = GEM_PATH[ruby_version, spec.name, spec.version] - bundle_lib_paths << gem_lib_path = gem_path + '/lib' + # Do not register local gems + return if spec.source.path? + + base_dir = "lib/ruby/#{ruby_version}" + if spec.source.is_a?(Bundler::Source::Git) + stub = spec.source.specs.find { |s| s.name == spec.name }.stub + gem_path = "#{base_dir}/bundler/gems/#{Pathname(stub.full_gem_path).relative_path_from(stub.base_dir)}" + spec_path = "#{base_dir}/bundler/gems/#{Pathname(stub.loaded_from).relative_path_from(stub.base_dir)}" + + # paths to register to $LOAD_PATH + require_paths = stub.require_paths + else + gem_path = GEM_PATH[ruby_version, spec.name, spec.version] + spec_path = SPEC_PATH[ruby_version, spec.name, spec.version] + + # paths to register to $LOAD_PATH + require_paths = Gem::StubSpecification.gemspec_stub(spec_path, base_dir, "#{base_dir}/gems").require_paths + end + + # Usually, registering the directory paths listed in the `require_paths` of gemspecs is sufficient, but + # some gems also require additional paths to be included in the load paths. + require_paths += include_array(spec.name) + gem_lib_paths = require_paths.map do |require_path| + # Gems with native extensions (like ffi) will sometimes have elements of + # require_paths that are absolute rather than gem-path relative paths. + # It is incorrect to prepend those paths with the gem_path and Bazel will + # only allow relative paths as inputs to its glob() function. + pathname = Pathname.new(require_path) + pathname.absolute? ? pathname.relative_path_from(HERE).to_s : File.join(gem_path, require_path) + end + + bundle_lib_paths.push(*gem_lib_paths) # paths to search for executables gem_binaries = find_bundle_binaries(gem_path) @@ -234,8 +293,9 @@ def register_gem(spec, template_out, bundle_lib_paths, bundle_binaries) warn("registering gem #{spec.name} with binaries: #{gem_binaries}") if bundle_binaries.key?(spec.name) template_out.puts GEM_TEMPLATE - .gsub('{gem_lib_path}', gem_lib_path) - .gsub('{gem_lib_files}', gem_lib_path + '/**/*') + .gsub('{gem_lib_paths}', to_flat_string(gem_lib_paths)) + .gsub('{gem_lib_files}', to_flat_string(gem_lib_paths.map { |p| "#{p}/**/*" })) + .gsub('{gem_spec}', spec_path) .gsub('{gem_binaries}', to_flat_string(gem_binaries)) .gsub('{exclude}', exclude_array(spec.name).to_s) .gsub('{name}', spec.name) @@ -259,7 +319,11 @@ def find_bundle_binaries(gem_path) end.flatten .compact .sort - .map { |binary| 'bin/' + binary } + .map { |binary| "bin/#{binary}" } + end + + def include_array(gem_name) + (includes[gem_name] || []) end def exclude_array(gem_name) @@ -271,18 +335,19 @@ def to_flat_string(array) end end -# ruby ./create_bundle_build_file.rb "BUILD.bazel" "Gemfile.lock" "repo_name" "[]" "wsp_name" +# ruby ./create_bundle_build_file.rb "BUILD.bazel" "Gemfile.lock" "repo_name" "{}" "{}" "wsp_name" if 0ドル == __FILE__ - if ARGV.length != 5 - warn("USAGE: #{0ドル} BUILD.bazel Gemfile.lock repo-name [excludes-json] workspace-name".orange) + if ARGV.length != 6 + warn("USAGE: #{0ドル} BUILD.bazel Gemfile.lock repo-name {includes-json} {excludes-json} workspace-name".orange) exit(1) end - build_file, gemfile_lock, repo_name, excludes, workspace_name, * = *ARGV + build_file, gemfile_lock, repo_name, includes, excludes, workspace_name, * = *ARGV BundleBuildFileGenerator.new(build_file: build_file, gemfile_lock: gemfile_lock, repo_name: repo_name, + includes: JSON.parse(includes), excludes: JSON.parse(excludes), workspace_name: workspace_name).generate! diff --git a/ruby/private/bundle/def.bzl b/ruby/private/bundle/def.bzl index fade53ec..e368bd4c 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,8 +151,9 @@ 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), RULES_RUBY_WORKSPACE_NAME, ] @@ -153,10 +163,18 @@ 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"), + ctx.path("vendor"), + ) 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 633878fe..a76f8f3f 100644 --- a/ruby/private/constants.bzl +++ b/ruby/private/constants.bzl @@ -4,7 +4,7 @@ load(":providers.bzl", "RubyLibraryInfo") RULES_RUBY_WORKSPACE_NAME = "@bazelruby_rules_ruby" TOOLCHAIN_TYPE_NAME = "%s//ruby:toolchain_type" % RULES_RUBY_WORKSPACE_NAME -DEFAULT_BUNDLER_VERSION = "2.1.2" +DEFAULT_BUNDLER_VERSION = "2.1.4" DEFAULT_RSPEC_ARGS = {"--format": "documentation", "--force-color": None} DEFAULT_RSPEC_GEMS = ["rspec", "rspec-its"] DEFAULT_BUNDLE_NAME = "@bundle//" @@ -79,9 +79,18 @@ 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", + ), "bundler_version": attr.string( default = DEFAULT_BUNDLER_VERSION, ), + "includes": attr.string_list_dict( + doc = "List of glob patterns per gem to be additionally loaded from the library", + ), "excludes": attr.string_list_dict( doc = "List of glob patterns per gem to be excluded from the library", ), diff --git a/ruby/private/dependencies.bzl b/ruby/private/dependencies.bzl index f4be1281..0a51d7a9 100644 --- a/ruby/private/dependencies.bzl +++ b/ruby/private/dependencies.bzl @@ -9,10 +9,10 @@ def rules_ruby_dependencies(): http_archive( name = "bazel_skylib", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz", - "https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz", ], - sha256 = "97e70364e9249702246c0e9444bccdc4b847bed1eb03c5a3ece4f83dfe6abc44", + sha256 = "1c531376ac7e5a180e0237938a2536de0c54d93f5c278634818e0efc952dd56c", ) if "rules_pkg" not in native.existing_rules(): diff --git a/ruby/private/sdk.bzl b/ruby/private/sdk.bzl index 1e06c191..77e1114b 100644 --- a/ruby/private/sdk.bzl +++ b/ruby/private/sdk.bzl @@ -8,14 +8,22 @@ def rules_ruby_select_sdk(version = "host"): supported_versions = [ "host", - "2.5.8", - "2.6.3", - "2.6.4", - "2.6.5", - "2.6.6", + "2.7.0", "2.7.1", - "2.7.1", - "2.8.0", + "2.7.2", + "2.7.3", + "2.7.4", + "2.7.5", + "2.7.6", + "3.0.0", + "3.0.1", + "3.0.2", + "3.0.3", + "3.0.4", + "3.1.0", + "3.1.1", + "3.1.2", + "3.2.0", ] if version in supported_versions: diff --git a/ruby/private/toolchain.bzl b/ruby/private/toolchain.bzl index b8b6dc5d..cbaebd67 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 b151531f..221a4ac5 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 21f86250..5e533778 100644 --- a/ruby/private/toolchains/ruby_runtime.bzl +++ b/ruby/private/toolchains/ruby_runtime.bzl @@ -2,15 +2,13 @@ load("//ruby/private:constants.bzl", "RULES_RUBY_WORKSPACE_NAME") load("//ruby/private/toolchains:repository_context.bzl", "ruby_repository_context") def _install_ruby_version(ctx, version): - print("download and extract ruby-build") ctx.download_and_extract( - url = "https://github.com/rbenv/ruby-build/archive/v20200727.tar.gz", - sha256 = "71679d49d9190250059eaa0bc0bedd080c00a523ec47662f559f7629f71772ea", - stripPrefix = "ruby-build-20200727", + url = "https://github.com/rbenv/ruby-build/archive/refs/tags/v20220218.tar.gz", + sha256 = "35c82b13b7bc3713eee5615b0145c79fbbac32873f55f2ab796620d76970d8e3", + stripPrefix = "ruby-build-20220218", ) install_path = "./build" - print("./bin/ruby-build", "--verbose", version, install_path) ctx.execute( ["./bin/ruby-build", "--verbose", version, install_path], quiet = False, @@ -34,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 @@ -46,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 new file mode 100644 index 00000000..01b33fa7 --- /dev/null +++ b/ruby/tests/testdata/bundle_includes_workspace/BUILD.bazel @@ -0,0 +1,16 @@ +load( + "@bazelruby_rules_ruby//ruby:defs.bzl", + "ruby_binary", +) + +package(default_visibility = ["//:__subpackages__"]) + +ruby_binary( + name = "script", + 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 new file mode 100644 index 00000000..9f5ba60d --- /dev/null +++ b/ruby/tests/testdata/bundle_includes_workspace/Gemfile @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +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 new file mode 100644 index 00000000..20db5464 --- /dev/null +++ b/ruby/tests/testdata/bundle_includes_workspace/Gemfile.lock @@ -0,0 +1,20 @@ +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) + grpc (1.38.0) + google-protobuf (~> 3.15) + googleapis-common-protos-types (~> 1.0) + +PLATFORMS + ruby + +DEPENDENCIES + awesome_print + grpc + +BUNDLED WITH + 2.2.28 diff --git a/ruby/tests/testdata/bundle_includes_workspace/WORKSPACE b/ruby/tests/testdata/bundle_includes_workspace/WORKSPACE new file mode 100644 index 00000000..00a3bb41 --- /dev/null +++ b/ruby/tests/testdata/bundle_includes_workspace/WORKSPACE @@ -0,0 +1,35 @@ +workspace(name = "bazelruby_rules_ruby_ruby_tests_testdata_bundle_includes_workspace") + +local_repository( + name = "bazelruby_rules_ruby", + path = "../../../..", +) + +load( + "@bazelruby_rules_ruby//ruby:deps.bzl", + "rules_ruby_dependencies", + "rules_ruby_select_sdk", +) + +rules_ruby_dependencies() + +rules_ruby_select_sdk(version = "3.0.2") + +load("@bazelruby_rules_ruby//ruby:defs.bzl", "ruby_bundle") + +ruby_bundle( + name = "gems", + bundler_version = "2.2.21", + gemfile = "//:Gemfile", + gemfile_lock = "//:Gemfile.lock", + includes = { + # The gemspec of grpc gem lists ['src/ruby/bin', 'src/ruby/lib', 'src/ruby/pb'] as the `require_paths`. When installing + # pre-built versions of the gem using a package downloaded from rubygems.org, these paths are sufficient since the file + # `src/ruby/lib/grpc.rb` in the downloaded gem package does not `require` any file outside these directories. + # However, when installing grpc gem from source using Bundler, `src/ruby/lib/grpc.rb` in the source package does + # `require` 'etc/roots.pem', so the directory containing this `require`-d file also needs to be present in the `$LOAD_PATH`. + # Thus users have to manually add the 'etc' directory to the `$LOAD_PATH` using the `includes` option of `ruby_bundle` rule. + # The `includes` option of `ruby_bundle` rule is a means of workaround for such a peculiar situation. + "grpc": ["etc"], + }, +) diff --git a/ruby/tests/testdata/bundle_includes_workspace/script.rb b/ruby/tests/testdata/bundle_includes_workspace/script.rb new file mode 100644 index 00000000..bc718e56 --- /dev/null +++ b/ruby/tests/testdata/bundle_includes_workspace/script.rb @@ -0,0 +1,24 @@ +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 + +begin + require 'grpc' +rescue LoadError => e + warn "Failed to load grpc gem: #{e.message}" + raise +end + +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

AltStyle によって変換されたページ (->オリジナル) /