Improvements to brew versions
The output happens as it is determined, rather than all at once, which is preferable for CLI commands. This meant I had to hard-code the left-justification. The pre-amble warning is removed. Instead the command outputs the git checkout command for each she that you can type to get that old formula. I decided that reseting the one file will work 99% of the time and that it is too risky to reset the whole repo, this will roll-back bug fixes. Instead we should add functionality to compat/ in order to support old formula as required. Sometimes deps may have to be rolled-back too, but the user will have to figure this out on an ad-hoc basis. We are assuming a failure sophisticated user anyway, one who would like to get old versions of stuff. I moved most of the functions into Formula since IMO this makes more conceptual sense. I made the she get abbreviated by git (using --abbrev-commit) itself so it as short as can be.
This commit is contained in:
parent
b36dcc4ffd
commit
18a54259e9
@ -3,89 +3,64 @@ require 'formula'
|
|||||||
module Homebrew extend self
|
module Homebrew extend self
|
||||||
|
|
||||||
module Versions
|
module Versions
|
||||||
|
# yields version, sha for all versions in the git history
|
||||||
# The commit SHA for a specific version of a formula
|
def self.old_versions f
|
||||||
def self.sha_for name, version
|
yielded = []
|
||||||
shas_for(name).each do |sha|
|
f.rev_list.each do |sha|
|
||||||
return sha if version == version_for(name, sha)
|
version = f.version_for_sha sha
|
||||||
end
|
unless yielded.include? version
|
||||||
|
yield version, sha
|
||||||
nil
|
yielded << version
|
||||||
end
|
|
||||||
|
|
||||||
# All SHAs of the commits the named formula has been changed in
|
|
||||||
def self.shas_for name
|
|
||||||
`git --git-dir=#{HOMEBREW_REPOSITORY}/.git rev-list HEAD^ -- Library/Formula/#{name}.rb`.split
|
|
||||||
end
|
|
||||||
|
|
||||||
# Returns the version number for the named formula and the given commit SHA
|
|
||||||
def self.version_for name, sha
|
|
||||||
code = `git --git-dir=#{HOMEBREW_REPOSITORY}/.git show #{sha}:Library/Formula/#{name}.rb`
|
|
||||||
version = code.match(/class #{Formula.class_s name} < ?Formula.*?(?:version\s|@version\s*=)\s*(?:'|")(.+?)(?:'|").*?end\s/m)
|
|
||||||
if version.nil?
|
|
||||||
url = code.match(/class #{Formula.class_s name} < ?Formula.*?(?:url\s|@url\s*=)\s*(?:'|")(.+?)(?:'|").*?end\s/m)
|
|
||||||
if url.nil?
|
|
||||||
head = code.match(/class #{Formula.class_s name} < ?Formula.*?head\s'(.*?)'.*?end\s\s/m)
|
|
||||||
if head.nil?
|
|
||||||
opoo "Version of #{name} could not be determined for #{sha}."
|
|
||||||
nil
|
|
||||||
else
|
|
||||||
'HEAD'
|
|
||||||
end
|
|
||||||
else
|
|
||||||
Pathname.new(url[1]).version
|
|
||||||
end
|
|
||||||
else
|
|
||||||
version[1]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# All older versions of a formula together with the SHA of their most recent
|
|
||||||
# revision
|
|
||||||
def self.old_versions(formula)
|
|
||||||
old_versions = []
|
|
||||||
|
|
||||||
shas_for(formula.name).each do |sha|
|
|
||||||
old_version = version_for formula.name, sha
|
|
||||||
|
|
||||||
if old_version != formula.version &&
|
|
||||||
(old_versions.empty? || old_version != old_versions.last[0])
|
|
||||||
old_versions << [old_version, sha]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
old_versions
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def versions
|
def versions
|
||||||
puts "Listing older versions for: #{ARGV.formulae.join(', ')}"
|
raise "Please `brew install git` first" unless system "/usr/bin/which -s git"
|
||||||
|
|
||||||
puts <<-EOS.undent
|
|
||||||
|
|
||||||
If you want to install one of these old versions run `git reset --hard
|
|
||||||
$COMMIT_ID_OF_VERSION` in "#{HOMEBREW_REPOSITORY}". After that you can install the formula
|
|
||||||
like usual with `brew install formula`. When you're done use `git reset --hard
|
|
||||||
master@{1}` in "#{HOMEBREW_REPOSITORY}" to get back to the most recent versions again.
|
|
||||||
|
|
||||||
WARNING: This also reverts Homebrew itself to an old revision. This may lead to
|
|
||||||
broken installations and/or not being able to install an old formula at all.
|
|
||||||
EOS
|
|
||||||
|
|
||||||
ARGV.formulae.all? do |f|
|
ARGV.formulae.all? do |f|
|
||||||
old_versions = Versions.old_versions f
|
old_versions = Versions.old_versions f do |version, sha|
|
||||||
|
print Tty.white
|
||||||
if old_versions.empty?
|
print "#{version.ljust(8)} "
|
||||||
puts "\nThere are no older versions for \"#{f.name}\" (current: #{f.version})."
|
print Tty.reset
|
||||||
else
|
puts "git checkout #{sha} #{HOMEBREW_REPOSITORY}/Library/Formula/#{name}.rb"
|
||||||
puts "\nOlder versions for \"#{f.name}\" (current: #{f.version}):\n"
|
|
||||||
|
|
||||||
max_size = 0
|
|
||||||
old_versions.each { |v| max_size = v[0].size if v[0].size > max_size }
|
|
||||||
old_versions.each { |v| puts ' %s (%s)' % [v[0].ljust(max_size), v[1]] }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
class Formula
|
||||||
|
def rev_list
|
||||||
|
Dir.chdir HOMEBREW_REPOSITORY do
|
||||||
|
`git rev-list --abbrev-commit HEAD Library/Formula/#{name}.rb`.split
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def sha_for_version version
|
||||||
|
revlist.find{ |sha| version == version_for(sha) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def version_for_sha sha
|
||||||
|
# TODO really we should open a new ruby instance and parse the formula
|
||||||
|
# class and then get the version but this would be too slow (?)
|
||||||
|
|
||||||
|
code = Dir.chdir(HOMEBREW_REPOSITORY) do
|
||||||
|
`git show #{sha}:Library/Formula/#{name}.rb`
|
||||||
|
end
|
||||||
|
|
||||||
|
version = code.match(/class #{Formula.class_s name} < ?Formula.*?(?:version\s|@version\s*=)\s*(?:'|")(.+?)(?:'|").*?end\s/m)
|
||||||
|
return version[1] unless version.nil?
|
||||||
|
|
||||||
|
url = code.match(/class #{Formula.class_s name} < ?Formula.*?(?:url\s|@url\s*=)\s*(?:'|")(.+?)(?:'|").*?end\s/m)
|
||||||
|
return Pathname.new(url[1]).version unless url.nil?
|
||||||
|
|
||||||
|
head = code.match(/class #{Formula.class_s name} < ?Formula.*?head\s'(.*?)'.*?end\s\s/m)
|
||||||
|
return 'HEAD' unless head.nil?
|
||||||
|
|
||||||
|
opoo "Version of #{name} could not be determined for #{sha}."
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user