brew/Library/Homebrew/cmd/versions.rb
Jiang Xin f30200890e versions: work for tapped formulae
brew versions is hardcoded to cd to HOMEBREW_REPOSITORY before running
git, and as such fails to report previous versions for any formulae
from a tapped repository.

Add two new private methods repository and entry_name to replace the
hardcoded HOMEBREW_REPOSITORY and formula path, and brew versions
work for both builtin and tapped formulae.

Closes Homebrew/homebrew#12356.
Closes Homebrew/homebrew#19069.

Reported-by: Misty De Meo <mistydemeo@gmail.com>
Suggested-by: Jack Nagel <jacknagel@gmail.com>
Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
Signed-off-by: Jack Nagel <jacknagel@gmail.com>
2013-04-11 23:45:15 -05:00

97 lines
2.4 KiB
Ruby

require 'formula'
module Homebrew extend self
def versions
raise "Please `brew install git` first" unless which "git"
raise "Please `brew update' first" unless (HOMEBREW_REPOSITORY/".git").directory?
raise FormulaUnspecifiedError if ARGV.named.empty?
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.to_s.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 == repository
entry_name
else
repository/"#{entry_name}"
end
end
private
def repository
@repository ||= begin
if path.realpath.to_s =~ %r{#{HOMEBREW_REPOSITORY}/Library/Taps/(\w+)-(\w+)}
HOMEBREW_REPOSITORY/"Library/Taps/#$1-#$2"
else
HOMEBREW_REPOSITORY
end
end
end
def entry_name
@entry_name ||= begin
repository == HOMEBREW_REPOSITORY ? "Library/Formula/#{name}.rb" : "#{name}.rb"
end
end
def rev_list
repository.cd do
`git rev-list --abbrev-commit HEAD -- #{entry_name}`.split
end
end
def text_from_sha sha
repository.cd do
`git cat-file blob #{sha}:#{entry_name}`
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
begin
Object.send(:remove_const, Formula.class_s(name))
nostdout { Formula.factory(path).version }
rescue SyntaxError, TypeError, NameError, ArgumentError => e
# We rescue these so that we can skip bad versions and
# continue walking the history
ohai "#{e} in #{name} at revision #{sha}", e.backtrace if ARGV.debug?
end
end
end
end