The goal of this BazelRuby integration project is to make Ruby a first-class citizen in the Bazel eco-system, to be able to support very large Ruby mono-repo, and to take advantage of the parallel builds and fast caching that Bazel is famous for.
NOTE: This is still work in progress, which attempts to bridge the world of Ruby gems and applications with the Bazel Build System.
NOTE: This project has been developed and tested on Mac OS-X. If you are on Windows, your mileage may vary.
The following screen-cast shows the basic usage of the bazel commands.
Install Bazel using a binary installer if you prefer, or using Homebrew: brew install bazel
.
Then run the provided setup script:
bin/setup
You should see something like this:
Since the expected audience of this README are relatively experienced Ruby Programmers, we will focus on the Bazel integration portion of this, and show how to run commands via Bazel.
As the goal of this "fake" mono-repo is to be an example on which other Ruby Projects can be combined into a singular tree, we tried including various permutations of the Ruby libraries and applications, with inter-dependencies, external dependencies, and so on.
NOTE: At the moment this Repo does NOT include a Ruby on Rails application, but that's coming soon.
It helps to start with the description of what is going on here:
This repo is a Bazel Workspace. It has a single WORKSPACE
file at the top level, which, among other things, loads rules_ruby
project as a third party dependency.
All pure ruby code is under the ruby
folder.
Under ruby/gems/hello_world
you would find a very simple Ruby Gem with a singular dependency on a gem called colored2
. The gem's claim to fame is its ability to say "Hello World" in 74 languages. Powerful, right?
-
The Gem provides both Ruby SDK and the command line utility that can be called with a language-substring as a parameter.
-
You can test is as follows:
cd ruby/gems/hello_world
bundle install
# arguments are full or partial languages
bundle exec exe/hello-worldr ru af kaz uz geo
You might see something like the following output:
Under ruby/apps/hello-world-web
you will find a simple Sinatra app that uses the hello_world
gem, not via the Gemfile, but via direct relative path inclusion.
To test it without Bazel:
cd ruby/apps/hello-world-web
bundle install
bin/start
# .../ruby-monorepo/ruby/gems/hello_world/lib
# == Shotgun/Puma on http://127.0.0.1:9393/
# Puma starting in single mode...
# * Version 4.3.1 (ruby 2.5.5-p157), codename: Mysterious Traveller
# * Min threads: 0, max threads: 16
# * Environment: development
# * Listening on tcp://127.0.0.1:9393
# Use Ctrl-C to stop
If you click on http://127.0.0.1:9393/ URL shown above, you should see a minimalistic user interface:
This folder is still under construction, so more info to come.
This completes our overview of included components.
This mono-repo depends on the rules_ruby repository (develop
branch).
Next examples we'll run from the top level folder of the project, but that's technically not necessary.
bazel query //...:all
#//ruby/gems/hello_world:specs
#//ruby/gems/hello_world:cli
#//ruby/apps/hello-world-web:server
#//ruby/gems/hello_world:lib
# Loading: 1 packages loaded
You can build all targets with:
bazel build //...:all # shows targets available
#.... lots of output is skipped
As part of the output, you should see the result of two bundle install
automatically called by Bazel Tooling.
Finally, you could run the same CLI using Bazel:
bazel run //ruby/gems/hello_world:cli russian
# INFO: Analyzed target //ruby/gems/hello_world:cli (0 packages loaded, 0 targets configured).
# INFO: Found 1 target...
# Target //ruby/gems/hello_world:cli up-to-date:
# bazel-bin/ruby/gems/hello_world/cli
# INFO: Elapsed time: 0.175s, Critical Path: 0.00s
# INFO: 0 processes.
# INFO: Build completed successfully, 1 total action
# INFO: Build completed successfully, 1 total action
Russian — Привет мир!
As one of the targets is hello_world:specs
you can run it like so:
bazel test //ruby/gems/hello_world:specs
It's best to show the results of running specs in a screenshot:
This is, perhaps, the most complicated Bazel task in this repo to date. This is because it depends on it's own Bundle (and gems such as Puma), but it also depends on the internal library hello_world
.
Here is the screenshot of running the server on the foreground, and hitting it a few times with requests:
Finally, below is the result of the tree -C
command showing how the files are layed out int his repo.
Please read and follow our Code of Conduct, and we are very happy to accept help and pull requests or issues, or whatever you can contribute.
© 2019-2020 Konstantin Gredeskoul, Coinbase, & 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
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.