The Homebrew package manager uses external commands to
extend its functionality. These are either shell scripts or ruby scripts that can be added on top of the existing brew
infrastructure via the brew tap
command.
When creating the license external command, I needed to add an external
ruby dependency of the octokit
gem to facilitate attempting to fetch a formula's licensing information from the Github
API. It was obvious that I needed to add
require 'octokit'
to my brew-license.rb
script, but it wasn't obvious how I could trigger that gem being installed on a user's machine
if it wasn't already present.
The solution that I settled on was to create a Gemfile
where I defined my dependencies:
source 'https://rubygems.org'
gem 'octokit'
Then, at the beginning of my brew-license.rb
script, which is what is executed when a user types brew license
in
their shell, I needed my ruby script to invoke bundler
if the octokit gem wasn't installed locally on the user's
machine. This can be accomplished with the following:
REPO_ROOT = Pathname.new "#{File.dirname(__FILE__)}/.."
VENDOR_RUBY = "#{REPO_ROOT}/vendor/ruby".freeze
BUNDLER_SETUP = Pathname.new "#{VENDOR_RUBY}/bundler/setup.rb"
unless BUNDLER_SETUP.exist?
Homebrew.install_gem_setup_path! "bundler"
REPO_ROOT.cd do
safe_system "bundle", "install", "--standalone", "--path", "vendor/ruby"
end
end
require "rbconfig"
ENV["GEM_HOME"] = ENV["GEM_PATH"] = "#{VENDOR_RUBY}/#{RUBY_ENGINE}/#{RbConfig::CONFIG["ruby_version"]}"
Gem.clear_paths
Gem::Specification.reset
require_relative BUNDLER_SETUP
Now, the first time that a user executes brew license
, this bit of code will ensure that the octokit gem is installed
locally.
You can see this in action
by installing and using brew license
, and if you're interested
in adding licensing information for your favorite Homebrew formulae, please do feel free to submit issues or PRs!