diff options
| author | Zhiming Wang | 2016-12-25 18:54:08 -0500 | 
|---|---|---|
| committer | Mike McQuaid | 2017-03-20 18:20:31 +0200 | 
| commit | 1c10a6260fb4f4036d68b4c34acc6135b26b93d6 (patch) | |
| tree | 2924c8b8295cbe1a60a6d5980f3a656c67387cc1 | |
| parent | 00af5250f0a7988178ed8d26520bf1a98a8dea9a (diff) | |
| download | brew-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.rb | 22 | ||||
| -rw-r--r-- | Library/Homebrew/cmd/install.rb | 13 | ||||
| -rw-r--r-- | Library/Homebrew/exceptions.rb | 13 | ||||
| -rw-r--r-- | Library/Homebrew/historic.rb | 57 | ||||
| -rw-r--r-- | Library/Homebrew/test/historic_test.rb | 46 | 
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 | 
