diff options
Diffstat (limited to 'Library')
| -rw-r--r-- | Library/Homebrew/brew.rb | 8 | ||||
| -rw-r--r-- | Library/Homebrew/cask/lib/hbc/cli/reinstall.rb | 16 | ||||
| -rw-r--r-- | Library/Homebrew/cmd/install.rb | 47 | ||||
| -rw-r--r-- | Library/Homebrew/cmd/reinstall.rb | 15 | ||||
| -rw-r--r-- | Library/Homebrew/cmd/upgrade.rb | 2 | ||||
| -rw-r--r-- | Library/Homebrew/dependency.rb | 8 | ||||
| -rw-r--r-- | Library/Homebrew/download_strategy.rb | 7 | ||||
| -rw-r--r-- | Library/Homebrew/exceptions.rb | 4 | ||||
| -rw-r--r-- | Library/Homebrew/formula.rb | 22 | ||||
| -rw-r--r-- | Library/Homebrew/formula_installer.rb | 44 | ||||
| -rw-r--r-- | Library/Homebrew/formulary.rb | 13 | ||||
| -rw-r--r-- | Library/Homebrew/keg.rb | 2 | ||||
| -rw-r--r-- | Library/Homebrew/test/install_test.rb | 94 | ||||
| -rw-r--r-- | Library/Homebrew/test/reinstall_test.rb | 2 | ||||
| -rw-r--r-- | Library/Homebrew/utils/analytics.rb | 4 |
15 files changed, 233 insertions, 55 deletions
diff --git a/Library/Homebrew/brew.rb b/Library/Homebrew/brew.rb index ac35feee8..ba43e65c4 100644 --- a/Library/Homebrew/brew.rb +++ b/Library/Homebrew/brew.rb @@ -138,6 +138,14 @@ rescue RuntimeError, SystemCallError => e onoe e $stderr.puts e.backtrace if ARGV.debug? exit 1 +rescue MethodDeprecatedError => e + Utils::Analytics.report_exception(e) + onoe e + if e.issues_url + $stderr.puts "If reporting this issue please do so at (not Homebrew/brew or Homebrew/core):" + $stderr.puts " #{Formatter.url(e.issues_url)}" + end + exit 1 rescue Exception => e Utils::Analytics.report_exception(e) onoe e diff --git a/Library/Homebrew/cask/lib/hbc/cli/reinstall.rb b/Library/Homebrew/cask/lib/hbc/cli/reinstall.rb index 3560a4795..30d9b694c 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/reinstall.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/reinstall.rb @@ -7,6 +7,13 @@ module Hbc begin cask = Hbc.load(cask_token) + installer = Installer.new(cask, + force: force, + skip_cask_deps: skip_cask_deps, + require_sha: require_sha) + installer.print_caveats + installer.fetch + if cask.installed? # use copy of cask for uninstallation to avoid 'No such file or directory' bug installed_cask = cask @@ -26,10 +33,11 @@ module Hbc Installer.new(installed_cask, force: true).uninstall end - Installer.new(cask, - force: force, - skip_cask_deps: skip_cask_deps, - require_sha: require_sha).install + installer.stage + installer.install_artifacts + installer.enable_accessibility_access + puts installer.summary + count += 1 rescue CaskUnavailableError => e warn_unavailable_with_suggestion cask_token, e 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/cmd/reinstall.rb b/Library/Homebrew/cmd/reinstall.rb index 598286562..2eb2840a5 100644 --- a/Library/Homebrew/cmd/reinstall.rb +++ b/Library/Homebrew/cmd/reinstall.rb @@ -20,19 +20,15 @@ module Homebrew end def reinstall_formula(f) - options = BuildOptions.new(Options.create(ARGV.flags_only), f.options).used_options - options |= f.build.used_options - options &= f.options - - notice = "Reinstalling #{f.full_name}" - notice += " with #{options * ", "}" unless options.empty? - oh1 notice - if f.opt_prefix.directory? keg = Keg.new(f.opt_prefix.resolved_path) backup keg end + options = BuildOptions.new(Options.create(ARGV.flags_only), f.options).used_options + options |= f.build.used_options + options &= f.options + fi = FormulaInstaller.new(f) fi.options = options fi.build_bottle = ARGV.build_bottle? || (!f.bottled? && f.build.build_bottle?) @@ -43,6 +39,9 @@ module Homebrew fi.verbose = ARGV.verbose? fi.debug = ARGV.debug? fi.prelude + + oh1 "Reinstalling #{f.full_name} #{options.to_a.join " "}" + fi.install fi.finish rescue FormulaInstallationAlreadyAttemptedError diff --git a/Library/Homebrew/cmd/upgrade.rb b/Library/Homebrew/cmd/upgrade.rb index f92832aa2..5b49a9f65 100644 --- a/Library/Homebrew/cmd/upgrade.rb +++ b/Library/Homebrew/cmd/upgrade.rb @@ -104,7 +104,7 @@ module Homebrew fi.debug = ARGV.debug? fi.prelude - oh1 "Upgrading #{f.full_specified_name}" + oh1 "Upgrading #{f.full_specified_name} #{fi.options.to_a.join " "}" # first we unlink the currently active keg for this formula otherwise it is # possible for the existing build to interfere with the build we are about to diff --git a/Library/Homebrew/dependency.rb b/Library/Homebrew/dependency.rb index 6b60654e1..253ba4bee 100644 --- a/Library/Homebrew/dependency.rb +++ b/Library/Homebrew/dependency.rb @@ -43,8 +43,12 @@ class Dependency end def missing_options(inherited_options) - required = options | inherited_options - required - Tab.for_formula(to_formula).used_options + formula = to_formula + required = options + required |= inherited_options + required &= formula.options.to_a + required -= Tab.for_formula(formula).used_options + required end def modify_build_environment 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/exceptions.rb b/Library/Homebrew/exceptions.rb index c2b78f878..c5d888d64 100644 --- a/Library/Homebrew/exceptions.rb +++ b/Library/Homebrew/exceptions.rb @@ -56,7 +56,9 @@ end class FormulaSpecificationError < StandardError; end -class MethodDeprecatedError < StandardError; end +class MethodDeprecatedError < StandardError + attr_accessor :issues_url +end class FormulaUnavailableError < RuntimeError attr_reader :name diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index bfaa41ad3..c80cd517f 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/formula_installer.rb b/Library/Homebrew/formula_installer.rb index 19b619625..bd1cc9379 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -60,10 +60,6 @@ class FormulaInstaller @pour_failed = false end - def skip_deps_check? - ignore_deps? - end - # When no build tools are available and build flags are passed through ARGV, # it's necessary to interrupt the user before any sort of installation # can proceed. Only invoked when the user has no developer tools. @@ -125,7 +121,7 @@ class FormulaInstaller def prelude Tab.clear_cache - verify_deps_exist unless skip_deps_check? + verify_deps_exist unless ignore_deps? lock check_install_sanity end @@ -147,7 +143,7 @@ class FormulaInstaller def check_install_sanity raise FormulaInstallationAlreadyAttemptedError, formula if @@attempted.include?(formula) - return if skip_deps_check? + return if ignore_deps? recursive_deps = formula.recursive_dependencies unlinked_deps = recursive_deps.map(&:to_formula).select do |dep| @@ -197,7 +193,7 @@ class FormulaInstaller raise BuildToolsError, [formula] end - unless skip_deps_check? + unless ignore_deps? deps = compute_dependencies check_dependencies_bottled(deps) if pour_bottle? && !DevelopmentTools.installed? install_dependencies(deps) @@ -219,16 +215,16 @@ class FormulaInstaller opoo "#{formula.full_name}: this formula has no #{option} option so it will be ignored!" end - oh1 "Installing #{Formatter.identifier(formula.full_name)}" if show_header? + options = [] + if formula.head? + options << "--HEAD" + elsif formula.devel? + options << "--devel" + end + options += effective_build_options_for(formula).used_options.to_a + oh1 "Installing #{Formatter.identifier(formula.full_name)} #{options.join " "}" if show_header? if formula.tap && !formula.tap.private? - options = [] - if formula.head? - options << "--HEAD" - elsif formula.devel? - options << "--devel" - end - options += effective_build_options_for(formula).used_options.to_a category = "install" action = ([formula.full_name] + options).join(" ") Utils::Analytics.report_event(category, action) @@ -236,8 +232,7 @@ class FormulaInstaller @@attempted << formula - pour_bottle = pour_bottle?(warn: true) - if pour_bottle + if pour_bottle?(warn: true) begin pour rescue Exception => e @@ -251,18 +246,17 @@ class FormulaInstaller onoe e.message opoo "Bottle installation failed: building from source." raise BuildToolsError, [formula] unless DevelopmentTools.installed? + compute_and_install_dependencies unless ignore_deps? else - puts_requirement_messages @poured_bottle = true end end + puts_requirement_messages + build_bottle_preinstall if build_bottle? unless @poured_bottle - not_pouring = !pour_bottle || @pour_failed - compute_and_install_dependencies if not_pouring && !ignore_deps? - puts_requirement_messages build clean @@ -444,12 +438,6 @@ class FormulaInstaller @show_header = true unless deps.empty? end - class DependencyInstaller < FormulaInstaller - def skip_deps_check? - true - end - end - def install_dependency(dep, inherited_options) df = dep.to_formula tab = Tab.for_formula(df) @@ -465,7 +453,7 @@ class FormulaInstaller installed_keg.rename(tmp_keg) end - fi = DependencyInstaller.new(df) + fi = FormulaInstaller.new(df) fi.options |= tab.used_options fi.options |= Tab.remap_deprecated_options(df.deprecated_options, dep.options) fi.options |= inherited_options diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb index 772f4c902..6ed5b91ba 100644 --- a/Library/Homebrew/formulary.rb +++ b/Library/Homebrew/formulary.rb @@ -151,6 +151,11 @@ class Formulary FileUtils.rm_f(path) curl url, "-o", path super + rescue MethodDeprecatedError => e + if url =~ %r{github.com/([\w-]+)/homebrew-([\w-]+)/} + e.issues_url = "https://github.com/#{$1}/homebrew-#{$2}/issues/new" + end + raise end end @@ -202,6 +207,13 @@ class Formulary rescue FormulaUnavailableError => e raise TapFormulaUnavailableError.new(tap, name), "", e.backtrace end + + def load_file + super + rescue MethodDeprecatedError => e + e.issues_url = formula.tap.issues_url || formula.tap.to_s + raise + end end class NullLoader < FormulaLoader @@ -276,6 +288,7 @@ class Formulary end end f.build = tab + f.build.used_options = Tab.remap_deprecated_options(f.deprecated_options, tab.used_options).as_flags f.version.update_commit(keg.version.version.commit) if f.head? && keg.version.head? f end diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb index 5c8e71d07..1de4ce1f0 100644 --- a/Library/Homebrew/keg.rb +++ b/Library/Homebrew/keg.rb @@ -66,7 +66,7 @@ class Keg INFOFILE_RX = %r{info/([^.].*?\.info|dir)$} TOP_LEVEL_DIRECTORIES = %w[bin etc include lib sbin share var Frameworks].freeze ALL_TOP_LEVEL_DIRECTORIES = (TOP_LEVEL_DIRECTORIES + %w[lib/pkgconfig share/locale share/man opt]).freeze - PRUNEABLE_DIRECTORIES = %w[bin etc include lib sbin share Frameworks LinkedKegs var/homebrew/linked].map do |dir| + PRUNEABLE_DIRECTORIES = %w[bin etc include lib sbin share opt Frameworks LinkedKegs var/homebrew/linked].map do |dir| case dir when "LinkedKegs" HOMEBREW_LIBRARY/dir 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!", diff --git a/Library/Homebrew/test/reinstall_test.rb b/Library/Homebrew/test/reinstall_test.rb index 73877b35d..613c06188 100644 --- a/Library/Homebrew/test/reinstall_test.rb +++ b/Library/Homebrew/test/reinstall_test.rb @@ -8,7 +8,7 @@ class IntegrationCommandTestReinstall < IntegrationCommandTestCase foo_dir = HOMEBREW_CELLAR/"testball/0.1/foo" assert foo_dir.exist? foo_dir.rmtree - assert_match "Reinstalling testball with --with-foo", + assert_match "Reinstalling testball --with-foo", cmd("reinstall", "testball") assert foo_dir.exist? end diff --git a/Library/Homebrew/utils/analytics.rb b/Library/Homebrew/utils/analytics.rb index 9066cce73..cc7ad54d2 100644 --- a/Library/Homebrew/utils/analytics.rb +++ b/Library/Homebrew/utils/analytics.rb @@ -63,7 +63,9 @@ module Utils def report_exception(exception, options = {}) if exception.is_a?(BuildError) && - exception.formula.tap && !exception.formula.tap.private? + exception.formula.tap && + exception.formula.tap.installed? && + !exception.formula.tap.private? report_event("BuildError", exception.formula.full_name) end |
