brew log

Google “brew log” and you’ll find many ways to log your homebrewing adventures, such as this page, from which the photo is taken.
Picking up where I left off (way back in this post)… here’s a discussion of the test coverage I added for brew log.
Like brew home, brew log can be run with or without arguments. When run without any arguments, brew log is akin to running git log on the Homebrew repository, i.e., it returns the commit history of the entire Git repository. When run with an argument in the form of a formula’s name, e.g., brew log ack, it returns the commit history for that formula.
My pull request for brew log proved more challenging than its 33 lines of code and existing 75% test coverage lead me to believe.
def test_log
FileUtils.cd HOMEBREW_REPOSITORY do
shutup do
system "git", "init"
system "git", "commit", "--allow-empty", "-m", "This is a test commit"
end
end
assert_match "This is a test commit", cmd("log")
ensure
(HOMEBREW_REPOSITORY/".git").rmtree
endAs shown above, the previously existing test does all these things:
- changes directory (
FileUtils.cd) into the directory containing the Homebrew Git repository.- (from within this directory) calls
shutup(defined inHomebrew/test/testing_env.rb) to shut up or suppress output from the commands that are enclosed betweendoandend:- calls
system"git","init", which runsgit initin a subshell:git initinitializes an empty Git repo by creating a/.gitdirectory with various subdirectories and files.
- calls
system "git","commit", which runsgit commitin a subshell:git commitrecords a commit that includes no new changes from its parent commit (which is allowed when--allow-emptyis passed), and uses the commit message,"This is a test commit".
- calls
- (from within this directory) calls
-
makes the assertion (with
assert_match) that the recorded commit message is output whenbrew logis run. - ensures (with
ensure) the removal of the/.gitdirectory at the end of the test.
In my pull request, I aimed to add coverage for the behavior that brew log exhibits when it’s called on a formula file or a shallow clone. My pull request broke a few things (oops) that were soon rectified by Martin’s follow-up PR (yay).
Here’s the incarnation of test_log_formula that emerged (and was soon updated again with the refactoring of the integration tests file):
def test_log_formula
core_tap = CoreTap.new
formula_file = core_tap.formula_dir/"testball.rb"
formula_file.write <<-EOS.undent
class Testball < Formula
url "https://example.com/testball-0.1.tar.gz"
end
EOS
core_tap.path.cd do
shutup do
system "git", "init"
system "git", "add", "--all"
system "git", "commit", "-m", "This is a test commit for Testball"
end
end
core_tap_url = "file://#{core_tap.path}"
shallow_tap = Tap.fetch("homebrew", "shallow")
shutup do
system "git", "clone", "--depth=1", core_tap_url, shallow_tap.path
end
assert_match "This is a test commit for Testball",
cmd("log", "#{shallow_tap}/testball")
assert_predicate shallow_tap.path/".git/shallow", :exist?,
"A shallow clone should have been created."
ensure
formula_file.unlink
(core_tap.path/".git").rmtree
shallow_tap.path.rmtree
end
test_log_formula does these things:
-
creates a
testball.rbformula file in theHomebrew/homebrew-coretap. - changes directory (
core_tap.path.cd) into the directory containing theHomebrew/homebrew-coretap, which is/usr/local/Library/Taps/homebrew/homebrew-core.- (from within this directory) calls
shutupand:- initializes an empty Git repo;
- adds all new or modified files to the index, which holds a snapshot of the repo’s current content; and
- records a commit and commit message.
- (from within this directory) calls
-
creates a
core_tap_urlvariable and sets it equal to a string containing the file URI-formatted path to theHomebrew/homebrew-coretap. -
creates a
shallow_tapvariable and sets it equal to a newly instantiatedTap(namedHomebrew/homebrew-shallow). - calls
shutupand:- makes a shallow Git clone (
--depth=1) of theHomebrew/homebrew-corerepo into the location whereHomebrew/homebrew-shallowresides.
- makes a shallow Git clone (
-
makes a couple of assertions.
- ensures that all newly created files and directories are removed at the end of the test.
There you have it!