aboutsummaryrefslogtreecommitdiffstats
path: root/Library
diff options
context:
space:
mode:
authorXu Cheng2016-02-25 15:34:11 +0800
committerXu Cheng2016-02-25 17:22:28 +0800
commit849e62c7368cf9d927448548b52387dc0e96c9ce (patch)
treed28824bdfb43f5af8a4af3b2c4f8836c7e28be32 /Library
parent87ecd621ebd3f3bfc170fc6e09eba84301b80027 (diff)
downloadbrew-849e62c7368cf9d927448548b52387dc0e96c9ce.tar.bz2
update-report: use tap inside Reporter
* Avoid tons of unnecessary file path manipulation. Use abstraction offered by Tap class if possible. * Handle formula rename/tap migration inside reporter in per tap basis. * Avoid duplicated computation. * Remove redundant/dead code.
Diffstat (limited to 'Library')
-rw-r--r--Library/Homebrew/cmd/update-report.rb186
1 files changed, 105 insertions, 81 deletions
diff --git a/Library/Homebrew/cmd/update-report.rb b/Library/Homebrew/cmd/update-report.rb
index 38e6164b4..1aea227e2 100644
--- a/Library/Homebrew/cmd/update-report.rb
+++ b/Library/Homebrew/cmd/update-report.rb
@@ -115,119 +115,143 @@ module Homebrew
end
class Reporter
- attr_reader :initial_revision, :current_revision, :repository
-
- def self.repository_variable(repository)
- if repository == HOMEBREW_REPOSITORY
- ""
- else
- repository.to_s.
- strip_prefix(Tap::TAP_DIRECTORY.to_s).
- tr("^A-Za-z0-9", "_").
- upcase
+ class ReporterRevisionUnsetError < RuntimeError
+ def initialize(var_name)
+ super "#{var_name} is unset!"
end
end
- def initialize(repository)
- @repository = repository
+ attr_reader :tap, :initial_revision, :current_revision
+
+ def initialize(tap)
+ @tap = tap
- repo_var = Reporter.repository_variable(@repository)
initial_revision_var = "HOMEBREW_UPDATE_BEFORE#{repo_var}"
@initial_revision = ENV[initial_revision_var].to_s
- if @initial_revision.empty?
- raise "#{initial_revision_var} is unset!" if ARGV.homebrew_developer?
- raise "update-report should not be called directly!"
- end
+ raise ReporterRevisionUnsetError, initial_revision_var if @initial_revision.empty?
current_revision_var = "HOMEBREW_UPDATE_AFTER#{repo_var}"
@current_revision = ENV[current_revision_var].to_s
- if @current_revision.empty?
- raise "#{current_revision_var} is unset!" if ARGV.homebrew_developer?
- raise "update-report should not be called directly!"
- end
+ raise ReporterRevisionUnsetError, current_revision_var if @current_revision.empty?
end
def report
- map = Hash.new { |h, k| h[k] = [] }
-
- if initial_revision && initial_revision != current_revision
- wc_revision = read_current_revision
-
- diff.each_line do |line|
- status, *paths = line.split
- src = paths.first
- dst = paths.last
-
- next unless File.extname(dst) == ".rb"
- next unless paths.any? { |p| File.dirname(p) == formula_directory }
-
- case status
- when "A", "D"
- map[status.to_sym] << repository.join(src)
- when "M"
- file = repository.join(src)
- begin
- formula = Formulary.factory(file)
- new_version = if wc_revision == current_revision
- formula.pkg_version
- else
- FormulaVersions.new(formula).formula_at_revision(@current_revision, &:pkg_version)
- end
- old_version = FormulaVersions.new(formula).formula_at_revision(@initial_revision, &:pkg_version)
- next if new_version == old_version
- # short term fix to prevent situation like https://github.com/Homebrew/homebrew/issues/45616
- rescue Exception => e
- onoe e if ARGV.homebrew_developer?
- end
- map[:M] << file
- when /^R\d{0,3}/
- map[:D] << repository.join(src) if File.dirname(src) == formula_directory
- map[:A] << repository.join(dst) if File.dirname(dst) == formula_directory
+ return @report if @report
+
+ @report = Hash.new { |h, k| h[k] = [] }
+ return @report unless updated?
+
+ diff.each_line do |line|
+ status, *paths = line.split
+ src = Pathname.new paths.first
+ dst = Pathname.new paths.last
+
+ next unless dst.extname == ".rb"
+ next unless paths.any? { |p| tap.formula_file?(p) }
+
+ case status
+ when "A", "D"
+ @report[status.to_sym] << tap.formula_file_to_name(src)
+ when "M"
+ begin
+ formula = Formulary.factory(tap.path/src)
+ new_version = formula.pkg_version
+ old_version = FormulaVersions.new(formula).formula_at_revision(@initial_revision, &:pkg_version)
+ next if new_version == old_version
+ rescue Exception => e
+ onoe e if ARGV.homebrew_developer?
end
+ @report[:M] << tap.formula_file_to_name(src)
+ when /^R\d{0,3}/
+ @report[:D] << tap.formula_file_to_name(src) if tap.formula_file?(src)
+ @report[:A] << tap.formula_file_to_name(dst) if tap.formula_file?(dst)
end
end
- map
+ renamed_formulae = []
+ @report[:D].each do |old_full_name|
+ old_name = old_full_name.split("/").last
+ new_name = tap.formula_renames[old_name]
+ next unless new_name
+
+ if tap.core_formula_repository?
+ new_full_name = new_name
+ else
+ new_full_name = "#{tap}/#{new_full_name}"
+ end
+
+ renamed_formulae << [old_full_name, new_full_name] if @report[:A].include? new_full_name
+ end
+
+ unless renamed_formulae.empty?
+ @report[:A] -= renamed_formulae.map(&:last)
+ @report[:D] -= renamed_formulae.map(&:first)
+ @report[:R] = renamed_formulae
+ end
+
+ @report
end
def updated?
- initial_revision && initial_revision != current_revision
+ initial_revision != current_revision
end
- private
+ def migrate_tap_migration
+ report[:D].each do |full_name|
+ name = full_name.split("/").last
+ next unless (dir = HOMEBREW_CELLAR/name).exist? # skip if formula is not installed.
+ next unless new_tap_name = tap.tap_migrations[name] # skip if formula is not in tap_migrations list.
+ tabs = dir.subdirs.map { |d| Tab.for_keg(Keg.new(d)) }
+ next unless tabs.first.tap == tap # skip if installed formula is not from this tap.
+ new_tap = Tap.fetch(new_tap_name)
+ new_tap.install unless new_tap.installed?
+ # update tap for each Tab
+ tabs.each { |tab| tab.tap = new_tap }
+ tabs.each(&:write)
+ end
+ end
- def formula_directory
- if repository == HOMEBREW_REPOSITORY
- "Library/Formula"
- elsif repository.join("Formula").directory?
- "Formula"
- elsif repository.join("HomebrewFormula").directory?
- "HomebrewFormula"
- else
- "."
+ def migrate_formula_rename
+ report[:R].each do |old_full_name, new_full_name|
+ old_name = old_full_name.split("/").last
+ next unless (dir = HOMEBREW_CELLAR/old_name).directory? && !dir.subdirs.empty?
+
+ begin
+ f = Formulary.factory(new_full_name)
+ rescue Exception => e
+ onoe e if ARGV.homebrew_developer?
+ next
+ end
+
+ begin
+ migrator = Migrator.new(f)
+ migrator.migrate
+ rescue Migrator::MigratorDifferentTapsError
+ rescue Exception => e
+ onoe e
+ end
end
end
- def read_current_revision
- `git rev-parse -q --verify HEAD`.chomp
+ private
+
+ def repo_var
+ @repo_var ||= if tap.path == HOMEBREW_REPOSITORY
+ ""
+ else
+ tap.path.to_s.
+ strip_prefix(Tap::TAP_DIRECTORY.to_s).
+ tr("^A-Za-z0-9", "_").
+ upcase
+ end
end
def diff
Utils.popen_read(
- "git", "diff-tree", "-r", "--name-status", "--diff-filter=AMDR",
+ "git", "-C", tap.path, "diff-tree", "-r", "--name-status", "--diff-filter=AMDR",
"-M85%", initial_revision, current_revision
)
end
-
- def `(cmd)
- out = super
- unless $?.success?
- $stderr.puts(out) unless out.empty?
- raise ErrorDuringExecution.new(cmd)
- end
- ohai(cmd, out) if ARGV.verbose?
- out
- end
end
class Report