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.
This commit is contained in:
parent
87ecd621eb
commit
849e62c736
@ -115,119 +115,143 @@ module Homebrew
|
||||
end
|
||||
|
||||
class Reporter
|
||||
attr_reader :initial_revision, :current_revision, :repository
|
||||
class ReporterRevisionUnsetError < RuntimeError
|
||||
def initialize(var_name)
|
||||
super "#{var_name} is unset!"
|
||||
end
|
||||
end
|
||||
|
||||
def self.repository_variable(repository)
|
||||
if repository == HOMEBREW_REPOSITORY
|
||||
attr_reader :tap, :initial_revision, :current_revision
|
||||
|
||||
def initialize(tap)
|
||||
@tap = tap
|
||||
|
||||
initial_revision_var = "HOMEBREW_UPDATE_BEFORE#{repo_var}"
|
||||
@initial_revision = ENV[initial_revision_var].to_s
|
||||
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
|
||||
raise ReporterRevisionUnsetError, current_revision_var if @current_revision.empty?
|
||||
end
|
||||
|
||||
def report
|
||||
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
|
||||
|
||||
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 != current_revision
|
||||
end
|
||||
|
||||
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 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
|
||||
|
||||
private
|
||||
|
||||
def repo_var
|
||||
@repo_var ||= if tap.path == HOMEBREW_REPOSITORY
|
||||
""
|
||||
else
|
||||
repository.to_s.
|
||||
tap.path.to_s.
|
||||
strip_prefix(Tap::TAP_DIRECTORY.to_s).
|
||||
tr("^A-Za-z0-9", "_").
|
||||
upcase
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(repository)
|
||||
@repository = repository
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
map
|
||||
end
|
||||
|
||||
def updated?
|
||||
initial_revision && initial_revision != current_revision
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def formula_directory
|
||||
if repository == HOMEBREW_REPOSITORY
|
||||
"Library/Formula"
|
||||
elsif repository.join("Formula").directory?
|
||||
"Formula"
|
||||
elsif repository.join("HomebrewFormula").directory?
|
||||
"HomebrewFormula"
|
||||
else
|
||||
"."
|
||||
end
|
||||
end
|
||||
|
||||
def read_current_revision
|
||||
`git rev-parse -q --verify HEAD`.chomp
|
||||
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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user