
Now we handle some things more explicitly and in the process get rid of the blanket rescue on the mktemp block, which is something of an antipattern. By unloading the class *after* determining the version, we avoid the case where the class had previously been unloaded but Formula.factory failed, and trying to unload the nonexistent class results in a NameError. Doing it this way, we avoid having to rescue NameError and thereby avoid hiding other cases where it may occur. We also rescue TypeError which gets us past a few more bad formula in the history in some instances. Signed-off-by: Jack Nagel <jacknagel@gmail.com>
80 lines
1.9 KiB
Ruby
80 lines
1.9 KiB
Ruby
require 'formula'
|
|
|
|
module Homebrew extend self
|
|
def versions
|
|
raise "Please `brew install git` first" unless system "/usr/bin/which -s git"
|
|
|
|
ARGV.formulae.all? do |f|
|
|
if ARGV.include? '--compact'
|
|
puts f.versions * " "
|
|
else
|
|
f.versions do |version, sha|
|
|
print Tty.white.to_s
|
|
print "#{version.ljust(8)} "
|
|
print Tty.reset.to_s
|
|
puts "git checkout #{sha} #{f.pretty_relative_path}"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
class Formula
|
|
def versions
|
|
versions = []
|
|
rev_list.each do |sha|
|
|
version = version_for_sha sha
|
|
unless versions.include? version or version.nil?
|
|
yield version, sha if block_given?
|
|
versions << version
|
|
end
|
|
end
|
|
return versions
|
|
end
|
|
|
|
def pretty_relative_path
|
|
if Pathname.pwd == HOMEBREW_REPOSITORY
|
|
"Library/Formula/#{name}.rb"
|
|
else
|
|
"#{HOMEBREW_REPOSITORY}/Library/Formula/#{name}.rb"
|
|
end
|
|
end
|
|
|
|
private
|
|
def rev_list
|
|
HOMEBREW_REPOSITORY.cd do
|
|
`git rev-list --abbrev-commit HEAD -- Library/Formula/#{name}.rb`.split
|
|
end
|
|
end
|
|
|
|
def text_from_sha sha
|
|
HOMEBREW_REPOSITORY.cd do
|
|
`git cat-file blob #{sha}:Library/Formula/#{name}.rb`
|
|
end
|
|
end
|
|
|
|
def sha_for_version version
|
|
rev_list.find{ |sha| version == version_for_sha(sha) }
|
|
end
|
|
|
|
def version_for_sha sha
|
|
mktemp do
|
|
path = Pathname.new(Pathname.pwd+"#{name}.rb")
|
|
path.write text_from_sha(sha)
|
|
|
|
# Unload the class so Formula#version returns the correct value
|
|
# FIXME shouldn't have to do this?
|
|
begin
|
|
version = nostdout { Formula.factory(path).version }
|
|
Object.send(:remove_const, Formula.class_s(name))
|
|
version
|
|
rescue SyntaxError, TypeError
|
|
# We rescue these so that we can skip bad versions and
|
|
# continue walking the history
|
|
nil
|
|
end
|
|
end
|
|
end
|
|
end
|