Hint at new location of migrated formulae
Partial implementation of https://github.com/Homebrew/brew-evolution/pull/15, along with the ability to search for deleted formulae in git history (inspired by #1996) which is not described in the proposal. See also: #1371.
This commit is contained in:
parent
00af5250f0
commit
1c10a6260f
@ -23,6 +23,7 @@ require "formula"
|
|||||||
require "keg"
|
require "keg"
|
||||||
require "tab"
|
require "tab"
|
||||||
require "json"
|
require "json"
|
||||||
|
require "historic"
|
||||||
|
|
||||||
module Homebrew
|
module Homebrew
|
||||||
module_function
|
module_function
|
||||||
@ -54,10 +55,25 @@ module Homebrew
|
|||||||
else
|
else
|
||||||
info_formula Formulary.find_with_priority(f)
|
info_formula Formulary.find_with_priority(f)
|
||||||
end
|
end
|
||||||
rescue FormulaUnavailableError
|
rescue FormulaUnavailableError => e
|
||||||
# No formula with this name, try a blacklist lookup
|
# No formula with this name, try a blacklist lookup
|
||||||
raise unless (blacklist = blacklisted?(f))
|
if (blacklist = blacklisted?(f))
|
||||||
puts blacklist
|
ofail "#{e.message}\n#{blacklist}"
|
||||||
|
else
|
||||||
|
ofail e.message
|
||||||
|
|
||||||
|
# No point in searching if the specified tap isn't tapped yet
|
||||||
|
next if e.instance_of?(TapFormulaUnavailableError) && !e.tap.installed?
|
||||||
|
|
||||||
|
migrations = search_for_migrated_formula(f)
|
||||||
|
next unless migrations.empty?
|
||||||
|
ohai "Searching among deleted formulae..."
|
||||||
|
begin
|
||||||
|
search_for_deleted_formula(f)
|
||||||
|
rescue
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -62,6 +62,7 @@ require "formula_installer"
|
|||||||
require "tap"
|
require "tap"
|
||||||
require "hardware"
|
require "hardware"
|
||||||
require "development_tools"
|
require "development_tools"
|
||||||
|
require "historic"
|
||||||
|
|
||||||
module Homebrew
|
module Homebrew
|
||||||
module_function
|
module_function
|
||||||
@ -212,6 +213,18 @@ module Homebrew
|
|||||||
ofail "What's updog?"
|
ofail "What's updog?"
|
||||||
else
|
else
|
||||||
ofail e.message
|
ofail e.message
|
||||||
|
|
||||||
|
migrations = search_for_migrated_formula(e.name)
|
||||||
|
return unless migrations.empty?
|
||||||
|
|
||||||
|
ohai "Searching among deleted formulae..."
|
||||||
|
begin
|
||||||
|
search_for_deleted_formula(e.name)
|
||||||
|
return
|
||||||
|
rescue
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
query = query_regexp(e.name)
|
query = query_regexp(e.name)
|
||||||
|
|
||||||
ohai "Searching for similarly named formulae..."
|
ohai "Searching for similarly named formulae..."
|
||||||
|
|||||||
@ -94,6 +94,19 @@ class TapFormulaUnavailableError < FormulaUnavailableError
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class FormulaExistsError < RuntimeError
|
||||||
|
attr_reader :name, :path
|
||||||
|
|
||||||
|
def initialize(name, path)
|
||||||
|
@name = name
|
||||||
|
@path = path
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
"Formula #{name} exists in #{path}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class FormulaClassUnavailableError < FormulaUnavailableError
|
class FormulaClassUnavailableError < FormulaUnavailableError
|
||||||
attr_reader :path
|
attr_reader :path
|
||||||
attr_reader :class_name
|
attr_reader :class_name
|
||||||
|
|||||||
57
Library/Homebrew/historic.rb
Normal file
57
Library/Homebrew/historic.rb
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
require "formulary"
|
||||||
|
require "tap"
|
||||||
|
|
||||||
|
module Homebrew
|
||||||
|
module_function
|
||||||
|
|
||||||
|
# name should not be qualified, since migration of qualified names is already
|
||||||
|
# handled in Formulary::TapLoader.formula_name_path.
|
||||||
|
def search_for_migrated_formula(name, options = {})
|
||||||
|
print_messages = options.fetch(:print_messages, true)
|
||||||
|
migrations = []
|
||||||
|
Tap.each do |old_tap|
|
||||||
|
new_tap_name = old_tap.tap_migrations[name]
|
||||||
|
next unless new_tap_name
|
||||||
|
migrations << [old_tap, new_tap_name]
|
||||||
|
next unless print_messages
|
||||||
|
deprecation = (new_tap_name == "homebrew/boneyard") ? "deprecated " : ""
|
||||||
|
puts "A #{deprecation}formula named \"#{name}\" has been migrated from #{old_tap} to #{new_tap_name}."
|
||||||
|
end
|
||||||
|
migrations
|
||||||
|
end
|
||||||
|
|
||||||
|
# name may be qualified.
|
||||||
|
def search_for_deleted_formula(name, options = {})
|
||||||
|
print_messages = options.fetch(:print_messages, true)
|
||||||
|
warn_shallow = options.fetch(:warn_shallow, false)
|
||||||
|
|
||||||
|
path = Formulary.path name
|
||||||
|
raise FormulaExistsError.new(name, path) if File.exist? path
|
||||||
|
path.to_s =~ HOMEBREW_TAP_PATH_REGEX
|
||||||
|
tap = Tap.new ($1 == "Homebrew" ? "homebrew" : $1), $2.strip_prefix("homebrew-")
|
||||||
|
raise TapUnavailableError, tap.name unless File.exist? tap.path
|
||||||
|
relpath = path.relative_path_from tap.path
|
||||||
|
|
||||||
|
cd tap.path
|
||||||
|
|
||||||
|
if warn_shallow && File.exist?(".git/shallow")
|
||||||
|
opoo <<-EOS.undend
|
||||||
|
The git repository is a shallow clone therefore the output may be incomplete.
|
||||||
|
Use `git fetch -C #{tap.path} --unshallow` to get the full repository.
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
|
log_cmd = "git log --name-only --max-count=1 --format=$'format:%H\\n%h' -- #{relpath}"
|
||||||
|
hash, hash_abbrev, relpath = Utils.popen_read(log_cmd).lines.map(&:chomp)
|
||||||
|
if hash.to_s.empty? || hash_abbrev.to_s.empty? || relpath.to_s.empty?
|
||||||
|
raise FormulaUnavailableError, name
|
||||||
|
end
|
||||||
|
|
||||||
|
if print_messages
|
||||||
|
puts "#{name} was deleted from #{tap.name} in commit #{hash_abbrev}."
|
||||||
|
puts "Run `brew boneyard #{name}` to show the formula's content prior to its removal."
|
||||||
|
end
|
||||||
|
|
||||||
|
[tap, relpath, hash, hash_abbrev]
|
||||||
|
end
|
||||||
|
end
|
||||||
46
Library/Homebrew/test/historic_test.rb
Normal file
46
Library/Homebrew/test/historic_test.rb
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
require "testing_env"
|
||||||
|
require "historic"
|
||||||
|
|
||||||
|
class HistoricTest < Homebrew::TestCase
|
||||||
|
def setup
|
||||||
|
super
|
||||||
|
|
||||||
|
@path = Tap::TAP_DIRECTORY/"homebrew/homebrew-foo"
|
||||||
|
@path.mkpath
|
||||||
|
@tap = Tap.new("Homebrew", "foo")
|
||||||
|
|
||||||
|
(@path/"tap_migrations.json").write <<-EOS.undent
|
||||||
|
{ "migrated-formula": "homebrew/bar" }
|
||||||
|
EOS
|
||||||
|
(@path/"Formula/to-delete.rb").write "placeholder"
|
||||||
|
|
||||||
|
@path.cd do
|
||||||
|
shutup do
|
||||||
|
system "git", "init"
|
||||||
|
system "git", "add", "--all"
|
||||||
|
system "git", "commit", "-m", "initial state"
|
||||||
|
system "git", "rm", "Formula/to-delete.rb"
|
||||||
|
system "git", "commit", "-m", "delete formula 'to-delete'"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
@path.rmtree
|
||||||
|
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_search_for_migrated_formula
|
||||||
|
migrations = Homebrew.search_for_migrated_formula("migrated-formula", print_messages: false)
|
||||||
|
assert_equal [[@tap, "homebrew/bar"]], migrations
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_search_for_deleted_formula
|
||||||
|
tap, relpath, hash, = Homebrew.search_for_deleted_formula("homebrew/foo/to-delete",
|
||||||
|
print_messages: false)
|
||||||
|
assert_equal tap, @tap
|
||||||
|
assert_equal relpath, "Formula/to-delete.rb"
|
||||||
|
assert_equal `git rev-parse HEAD`.chomp, hash
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
x
Reference in New Issue
Block a user