diff options
| author | Uladzislau Shablinski | 2016-12-11 14:26:46 +0300 | 
|---|---|---|
| committer | GitHub | 2016-12-11 14:26:46 +0300 | 
| commit | 45ef7ea0b0ac8665d3eeae8acf0e17ef646be0b3 (patch) | |
| tree | 5358d19dabb2ddb84459c1ea666e18da0522dbce | |
| parent | a3bacf1238031067ba1ca3fba8d5611f490f3076 (diff) | |
| parent | a24a919a40f09930c5ef9f2fe811d16e83fa963a (diff) | |
| download | brew-45ef7ea0b0ac8665d3eeae8acf0e17ef646be0b3.tar.bz2 | |
Merge pull request #1343 from vladshablinsky/explicit-specs
Allow to install any spec
| -rw-r--r-- | Library/Homebrew/cmd/install.rb | 47 | ||||
| -rw-r--r-- | Library/Homebrew/download_strategy.rb | 7 | ||||
| -rw-r--r-- | Library/Homebrew/formula.rb | 22 | ||||
| -rw-r--r-- | Library/Homebrew/test/install_test.rb | 94 | 
4 files changed, 162 insertions, 8 deletions
diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb index c3c3b4bb9..700cd9c3d 100644 --- a/Library/Homebrew/cmd/install.rb +++ b/Library/Homebrew/cmd/install.rb @@ -135,14 +135,45 @@ module Homebrew            raise "No devel block is defined for #{f.full_name}"          end -        current = f if f.installed? -        current ||= f.old_installed_formulae.first +        installed_head_version = f.latest_head_version +        new_head_installed = installed_head_version && +                             !f.head_version_outdated?(installed_head_version, fetch_head: ARGV.fetch_head?) +        prefix_installed = f.prefix.exist? && !f.prefix.children.empty? -        if current -          msg = "#{current.full_name}-#{current.installed_version} already installed" -          unless current.linked_keg.symlink? || current.keg_only? -            msg << ", it's just not linked" -            puts "You can link formula with `brew link #{f}`" +        if f.keg_only? && f.any_version_installed? && f.optlinked? && !ARGV.force? +          # keg-only install is only possible when no other version is +          # linked to opt, because installing without any warnings can break +          # dependencies. Therefore before performing other checks we need to be +          # sure --force flag is passed. +          opoo "#{f.full_name} is a keg-only and another version is linked to opt." +          puts "Use `brew install --force` if you want to install this version" +        elsif (ARGV.build_head? && new_head_installed) || prefix_installed +          # After we're sure that --force flag is passed for linked to opt +          # keg-only we need to be sure that the version we're attempting to +          # install is not already installed. + +          installed_version = if ARGV.build_head? +            f.latest_head_version +          else +            f.pkg_version +          end + +          msg = "#{f.full_name}-#{installed_version} already installed" +          linked_not_equals_installed = f.linked_version != installed_version +          if f.linked? && linked_not_equals_installed +            msg << ", however linked version is #{f.linked_version}" +            opoo msg +            puts "You can use `brew switch #{f} #{installed_version}` to link this version." +          elsif !f.linked? || f.keg_only? +            msg << ", it's just not linked." +            opoo msg +          else +            opoo msg +          end +        elsif !f.any_version_installed? && old_formula = f.old_installed_formulae.first +          msg = "#{old_formula.full_name}-#{old_formula.installed_version} already installed" +          if !old_formula.linked? && !old_formula.keg_only? +            msg << ", it's just not linked."            end            opoo msg          elsif f.migration_needed? && !ARGV.force? @@ -152,6 +183,8 @@ module Homebrew            puts "You can migrate formula with `brew migrate #{f}`"            puts "Or you can force install it with `brew install #{f} --force`"          else +          # If none of the above is true and the formula is linked, then +          # FormulaInstaller will handle this case.            formulae << f          end        end diff --git a/Library/Homebrew/download_strategy.rb b/Library/Homebrew/download_strategy.rb index 1f77fa20c..9f9b2abab 100644 --- a/Library/Homebrew/download_strategy.rb +++ b/Library/Homebrew/download_strategy.rb @@ -832,7 +832,12 @@ class GitHubGitDownloadStrategy < GitDownloadStrategy      else        return true unless commit        return true unless @last_commit.start_with?(commit) -      multiple_short_commits_exist?(commit) +      if multiple_short_commits_exist?(commit) +        true +      else +        version.update_commit(commit) +        false +      end      end    end  end diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 3f2653e4a..64631a789 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -553,6 +553,28 @@ class Formula      Pathname.new("#{HOMEBREW_CELLAR}/#{name}/#{v}")    end +  # Is the formula linked? +  def linked? +    linked_keg.symlink? +  end + +  # Is the formula linked to opt? +  def optlinked? +    opt_prefix.symlink? +  end + +  # Is formula's linked keg points to the prefix. +  def prefix_linked?(v = pkg_version) +    return false unless linked? +    linked_keg.resolved_path == prefix(v) +  end + +  # {PkgVersion} of the linked keg for the formula. +  def linked_version +    return unless linked? +    Keg.for(linked_keg).version +  end +    # The parent of the prefix; the named directory in the cellar containing all    # installed versions of this software    # @private diff --git a/Library/Homebrew/test/install_test.rb b/Library/Homebrew/test/install_test.rb index 9fe5fff0e..e047c0030 100644 --- a/Library/Homebrew/test/install_test.rb +++ b/Library/Homebrew/test/install_test.rb @@ -22,6 +22,100 @@ class IntegrationCommandTestInstall < IntegrationCommandTestCase        cmd("install", "testball2")    end +  def test_install_failures +    path = setup_test_formula "testball1", "version \"1.0\"" +    devel_content = <<-EOS.undent +      version "3.0" +      devel do +        url "#{Formulary.factory("testball1").stable.url}" +        sha256 "#{TESTBALL_SHA256}" +        version "2.0" +      end +    EOS + +    assert_match "#{HOMEBREW_CELLAR}/testball1/1.0", cmd("install", "testball1") + +    FileUtils.rm path +    setup_test_formula "testball1", devel_content + +    assert_match "first `brew unlink testball1`", cmd_fail("install", "testball1") +    assert_match "#{HOMEBREW_CELLAR}/testball1/1.0", cmd("unlink", "testball1") +    assert_match "#{HOMEBREW_CELLAR}/testball1/2.0", cmd("install", "testball1", "--devel") +    assert_match "#{HOMEBREW_CELLAR}/testball1/2.0", cmd("unlink", "testball1") +    assert_match "#{HOMEBREW_CELLAR}/testball1/3.0", cmd("install", "testball1") + +    cmd("switch", "testball1", "2.0") +    assert_match "already installed, however linked version is", +      cmd("install", "testball1") +    assert_match "#{HOMEBREW_CELLAR}/testball1/2.0", cmd("unlink", "testball1") +    assert_match "just not linked", cmd("install", "testball1") +  end + +  def test_install_keg_only_outdated +    path_keg_only = setup_test_formula "testball1", <<-EOS.undent +    version "1.0" +    keg_only "test reason" +    EOS + +    assert_match "#{HOMEBREW_CELLAR}/testball1/1.0", cmd("install", "testball1") + +    FileUtils.rm path_keg_only +    setup_test_formula "testball1", <<-EOS.undent +      version "2.0" +      keg_only "test reason" +    EOS + +    assert_match "keg-only and another version is linked to opt", +      cmd("install", "testball1") + +    assert_match "#{HOMEBREW_CELLAR}/testball1/2.0", +      cmd("install", "testball1", "--force") +  end + +  def test_install_head_installed +    initial_env = ENV.to_hash +    %w[AUTHOR COMMITTER].each do |role| +      ENV["GIT_#{role}_NAME"] = "brew tests" +      ENV["GIT_#{role}_EMAIL"] = "brew-tests@localhost" +      ENV["GIT_#{role}_DATE"] = "Thu May 21 00:04:11 2009 +0100" +    end + +    repo_path = HOMEBREW_CACHE.join("repo") +    repo_path.join("bin").mkpath + +    repo_path.cd do +      shutup do +        system "git", "init" +        system "git", "remote", "add", "origin", "https://github.com/Homebrew/homebrew-foo" +        FileUtils.touch "bin/something.bin" +        FileUtils.touch "README" +        system "git", "add", "--all" +        system "git", "commit", "-m", "Initial repo commit" +      end +    end + +    setup_test_formula "testball1", <<-EOS.undent +      version "1.0" +      head "file://#{repo_path}", :using => :git +      def install +        prefix.install Dir["*"] +      end +    EOS + +    # Ignore dependencies, because we'll try to resolve requirements in build.rb +    # and there will be the git requirement, but we cannot instantiate git +    # formula since we only have testball1 formula. +    assert_match "#{HOMEBREW_CELLAR}/testball1/HEAD-2ccdf4f", cmd("install", "testball1", "--HEAD", "--ignore-dependencies") +    assert_match "testball1-HEAD-2ccdf4f already installed", +      cmd("install", "testball1", "--HEAD", "--ignore-dependencies") +    assert_match "#{HOMEBREW_CELLAR}/testball1/HEAD-2ccdf4f", cmd("unlink", "testball1") +    assert_match "#{HOMEBREW_CELLAR}/testball1/1.0", cmd("install", "testball1") + +  ensure +    ENV.replace(initial_env) +    repo_path.rmtree +  end +    def test_install_with_invalid_option      setup_test_formula "testball1"      assert_match "testball1: this formula has no --with-fo option so it will be ignored!",  | 
