aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhiming Wang2016-12-25 18:54:08 -0500
committerMike McQuaid2017-03-20 18:20:31 +0200
commit1c10a6260fb4f4036d68b4c34acc6135b26b93d6 (patch)
tree2924c8b8295cbe1a60a6d5980f3a656c67387cc1
parent00af5250f0a7988178ed8d26520bf1a98a8dea9a (diff)
downloadbrew-1c10a6260fb4f4036d68b4c34acc6135b26b93d6.tar.bz2
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.
-rw-r--r--Library/Homebrew/cmd/info.rb22
-rw-r--r--Library/Homebrew/cmd/install.rb13
-rw-r--r--Library/Homebrew/exceptions.rb13
-rw-r--r--Library/Homebrew/historic.rb57
-rw-r--r--Library/Homebrew/test/historic_test.rb46
5 files changed, 148 insertions, 3 deletions
diff --git a/Library/Homebrew/cmd/info.rb b/Library/Homebrew/cmd/info.rb
index b7de0005c..2d5e34ce2 100644
--- a/Library/Homebrew/cmd/info.rb
+++ b/Library/Homebrew/cmd/info.rb
@@ -23,6 +23,7 @@ require "formula"
require "keg"
require "tab"
require "json"
+require "historic"
module Homebrew
module_function
@@ -54,10 +55,25 @@ module Homebrew
else
info_formula Formulary.find_with_priority(f)
end
- rescue FormulaUnavailableError
+ rescue FormulaUnavailableError => e
# No formula with this name, try a blacklist lookup
- raise unless (blacklist = blacklisted?(f))
- puts blacklist
+ if (blacklist = blacklisted?(f))
+ 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
diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb
index c825e2796..8a99bd397 100644
--- a/Library/Homebrew/cmd/install.rb
+++ b/Library/Homebrew/cmd/install.rb
@@ -62,6 +62,7 @@ require "formula_installer"
require "tap"
require "hardware"
require "development_tools"
+require "historic"
module Homebrew
module_function
@@ -212,6 +213,18 @@ module Homebrew
ofail "What's updog?"
else
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)
ohai "Searching for similarly named formulae..."
diff --git a/Library/Homebrew/exceptions.rb b/Library/Homebrew/exceptions.rb
index 77da4489e..e9885890b 100644
--- a/Library/Homebrew/exceptions.rb
+++ b/Library/Homebrew/exceptions.rb
@@ -94,6 +94,19 @@ class TapFormulaUnavailableError < FormulaUnavailableError
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
attr_reader :path
attr_reader :class_name
diff --git a/Library/Homebrew/historic.rb b/Library/Homebrew/historic.rb
new file mode 100644
index 000000000..0afb9646a
--- /dev/null
+++ b/Library/Homebrew/historic.rb
@@ -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
diff --git a/Library/Homebrew/test/historic_test.rb b/Library/Homebrew/test/historic_test.rb
new file mode 100644
index 000000000..d09656fe0
--- /dev/null
+++ b/Library/Homebrew/test/historic_test.rb
@@ -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