aboutsummaryrefslogtreecommitdiffstats
path: root/Library
diff options
context:
space:
mode:
Diffstat (limited to 'Library')
-rw-r--r--Library/Homebrew/brew.rb8
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/reinstall.rb16
-rw-r--r--Library/Homebrew/cmd/install.rb47
-rw-r--r--Library/Homebrew/cmd/reinstall.rb15
-rw-r--r--Library/Homebrew/cmd/upgrade.rb2
-rw-r--r--Library/Homebrew/dependency.rb8
-rw-r--r--Library/Homebrew/download_strategy.rb7
-rw-r--r--Library/Homebrew/exceptions.rb4
-rw-r--r--Library/Homebrew/formula.rb22
-rw-r--r--Library/Homebrew/formula_installer.rb44
-rw-r--r--Library/Homebrew/formulary.rb13
-rw-r--r--Library/Homebrew/keg.rb2
-rw-r--r--Library/Homebrew/test/install_test.rb94
-rw-r--r--Library/Homebrew/test/reinstall_test.rb2
-rw-r--r--Library/Homebrew/utils/analytics.rb4
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