diff options
Diffstat (limited to 'Library')
157 files changed, 1598 insertions, 907 deletions
diff --git a/Library/Homebrew/.rubocop_todo.yml b/Library/Homebrew/.rubocop_todo.yml index 3705170fd..99080b546 100644 --- a/Library/Homebrew/.rubocop_todo.yml +++ b/Library/Homebrew/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config --exclude-limit 100` -# on 2016-10-24 17:14:14 +0200 using RuboCop version 0.44.1. +# on 2016-12-31 22:41:53 +0000 using RuboCop version 0.45.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -59,31 +59,24 @@ Lint/ShadowedException: Exclude: - 'utils/fork.rb' -# Offense count: 14 +# Offense count: 13 Metrics/BlockNesting: Max: 5 # Offense count: 19 # Configuration parameters: CountComments. Metrics/ModuleLength: - Max: 367 + Max: 400 -# Offense count: 2 +# Offense count: 1 # Configuration parameters: CountKeywordArgs. Metrics/ParameterLists: Max: 6 -# Offense count: 8 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: percent_q, bare_percent -Style/BarePercentLiterals: +# Offense count: 1 +Style/AccessorMethodName: Exclude: - - 'dev-cmd/audit.rb' - - 'test/test_diagnostic.rb' - - 'test/test_exceptions.rb' - - 'test/test_patch.rb' - - 'test/test_string.rb' + - 'extend/ENV/super.rb' # Offense count: 6 Style/ClassVars: diff --git a/Library/Homebrew/README.md b/Library/Homebrew/README.md index b8bf5fd99..18a41e363 100644 --- a/Library/Homebrew/README.md +++ b/Library/Homebrew/README.md @@ -3,6 +3,6 @@ This is the (partially) documented public API for Homebrew. The main class you should look at is the {Formula} class (and classes linked from there). That's the class that's used to create Homebrew formulae (i.e. package descriptions). Assume anything else you stumble upon is private. -You may also find the [Formula Cookbook](https://github.com/Homebrew/brew/blob/master/docs/Formula-Cookbook.md) and [Ruby Style Guide](https://github.com/styleguide/ruby) helpful in creating formulae. +You may also find the [Formula Cookbook](http://docs.brew.sh/Formula-Cookbook.html) and [Ruby Style Guide](https://github.com/styleguide/ruby) helpful in creating formulae. Good luck! diff --git a/Library/Homebrew/brew.sh b/Library/Homebrew/brew.sh index 92953001d..81a52f474 100644 --- a/Library/Homebrew/brew.sh +++ b/Library/Homebrew/brew.sh @@ -82,6 +82,9 @@ unset GEM_PATH # bash processes inside builds unset BASH_ENV +# Users may have this set, breaking grep's output. +unset GREP_OPTIONS + HOMEBREW_SYSTEM="$(uname -s)" case "$HOMEBREW_SYSTEM" in Darwin) HOMEBREW_MACOS="1" ;; diff --git a/Library/Homebrew/build.rb b/Library/Homebrew/build.rb index c4e903642..c0f15158d 100644 --- a/Library/Homebrew/build.rb +++ b/Library/Homebrew/build.rb @@ -48,7 +48,7 @@ class Build Requirement.prune elsif req.build? && dependent != formula Requirement.prune - elsif req.satisfied? && req.default_formula? && (dep = req.to_dependency).installed? + elsif req.satisfied? && (dep = req.to_dependency) && dep.installed? deps << dep Requirement.prune end diff --git a/Library/Homebrew/cask/LICENSE b/Library/Homebrew/cask/LICENSE deleted file mode 100644 index 62542ae57..000000000 --- a/Library/Homebrew/cask/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Copyright © 2013-2016, Paul Hinze & Contributors -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Library/Homebrew/cask/lib/hbc.rb b/Library/Homebrew/cask/lib/hbc.rb index 69b6e8f21..775b9229f 100644 --- a/Library/Homebrew/cask/lib/hbc.rb +++ b/Library/Homebrew/cask/lib/hbc.rb @@ -46,7 +46,7 @@ module Hbc def self.init Cache.ensure_cache_exists - Cache.migrate_legacy_cache + Cache.delete_legacy_cache Caskroom.migrate_caskroom_from_repo_to_prefix Caskroom.ensure_caskroom_exists diff --git a/Library/Homebrew/cask/lib/hbc/artifact/base.rb b/Library/Homebrew/cask/lib/hbc/artifact/base.rb index 05dbedd8f..b53c13f08 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/base.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/base.rb @@ -46,7 +46,7 @@ module Hbc arguments = { executable: arguments } if arguments.is_a?(String) # key sanity - permitted_keys = [:args, :input, :executable, :must_succeed, :sudo, :bsexec, :print_stdout, :print_stderr] + permitted_keys = [:args, :input, :executable, :must_succeed, :sudo, :print_stdout, :print_stderr] unknown_keys = arguments.keys - permitted_keys unless unknown_keys.empty? opoo %Q{Unknown arguments to #{description} -- #{unknown_keys.inspect} (ignored). Running "brew update; brew cleanup; brew cask cleanup" will likely fix it.} diff --git a/Library/Homebrew/cask/lib/hbc/audit.rb b/Library/Homebrew/cask/lib/hbc/audit.rb index ab2f1bce5..12cefb939 100644 --- a/Library/Homebrew/cask/lib/hbc/audit.rb +++ b/Library/Homebrew/cask/lib/hbc/audit.rb @@ -60,6 +60,7 @@ module Hbc def check_version return unless cask.version check_no_string_version_latest + check_no_file_separator_in_version end def check_no_string_version_latest @@ -68,6 +69,13 @@ module Hbc add_error "you should use version :latest instead of version 'latest'" end + def check_no_file_separator_in_version + odebug "Verifying version does not contain '#{File::SEPARATOR}'" + return unless cask.version.raw_version.is_a?(String) + return unless cask.version.raw_version.include?(File::SEPARATOR) + add_error "version should not contain '#{File::SEPARATOR}'" + end + def check_sha256 return unless cask.sha256 check_sha256_no_check_if_latest @@ -125,20 +133,19 @@ module Hbc def check_appcast_checkpoint_accuracy odebug "Verifying appcast checkpoint is accurate" - result = @command.run("/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", URL::FAKE_USER_AGENT, cask.appcast], print_stderr: false) - if result.success? - processed_appcast_text = result.stdout.gsub(%r{<pubDate>[^<]*</pubDate>}, "") - # This step is necessary to replicate running `sed` from the command line - processed_appcast_text << "\n" unless processed_appcast_text.end_with?("\n") + result = cask.appcast.calculate_checkpoint + + actual_checkpoint = result[:checkpoint] + + if actual_checkpoint.nil? + add_warning "error retrieving appcast: #{result[:command_result].stderr}" + else expected = cask.appcast.checkpoint - actual = Digest::SHA2.hexdigest(processed_appcast_text) - add_warning <<-EOS.undent unless expected == actual + add_warning <<-EOS.undent unless expected == actual_checkpoint appcast checkpoint mismatch Expected: #{expected} - Actual: #{actual} + Actual: #{actual_checkpoint} EOS - else - add_warning "error retrieving appcast: #{result.stderr}" end end diff --git a/Library/Homebrew/cask/lib/hbc/cache.rb b/Library/Homebrew/cask/lib/hbc/cache.rb index e343da3fa..7b586528e 100644 --- a/Library/Homebrew/cask/lib/hbc/cache.rb +++ b/Library/Homebrew/cask/lib/hbc/cache.rb @@ -9,27 +9,10 @@ module Hbc Hbc.cache.mkpath end - def migrate_legacy_cache + def delete_legacy_cache return unless Hbc.legacy_cache.exist? - ohai "Migrating cached files to #{Hbc.cache}..." - Hbc.legacy_cache.children.select(&:symlink?).each do |symlink| - file = symlink.readlink - - new_name = file.basename - .sub(/\-((?:(\d|#{DSL::Version::DIVIDER_REGEX})*\-\2*)*[^\-]+)$/x, - '--\1') - - renamed_file = Hbc.cache.join(new_name) - - if file.exist? - puts "#{file} -> #{renamed_file}" - FileUtils.mv(file, renamed_file) - end - - FileUtils.rm(symlink) - end - + ohai "Deleting legacy cache at #{Hbc.legacy_cache}..." FileUtils.remove_entry_secure(Hbc.legacy_cache) end end diff --git a/Library/Homebrew/cask/lib/hbc/cli.rb b/Library/Homebrew/cask/lib/hbc/cli.rb index c9625c7e2..36fae3034 100644 --- a/Library/Homebrew/cask/lib/hbc/cli.rb +++ b/Library/Homebrew/cask/lib/hbc/cli.rb @@ -19,11 +19,11 @@ require "hbc/cli/reinstall" require "hbc/cli/search" require "hbc/cli/style" require "hbc/cli/uninstall" -require "hbc/cli/update" require "hbc/cli/zap" require "hbc/cli/internal_use_base" require "hbc/cli/internal_audit_modified_casks" +require "hbc/cli/internal_appcast_checkpoint" require "hbc/cli/internal_checkurl" require "hbc/cli/internal_dump" require "hbc/cli/internal_help" @@ -77,6 +77,7 @@ module Hbc def self.command_classes @command_classes ||= constants.map(&method(:const_get)) .select { |sym| sym.respond_to?(:run) } + .sort_by(&:command_name) end def self.commands diff --git a/Library/Homebrew/cask/lib/hbc/cli/internal_appcast_checkpoint.rb b/Library/Homebrew/cask/lib/hbc/cli/internal_appcast_checkpoint.rb new file mode 100644 index 000000000..790e917b2 --- /dev/null +++ b/Library/Homebrew/cask/lib/hbc/cli/internal_appcast_checkpoint.rb @@ -0,0 +1,61 @@ +module Hbc + class CLI + class InternalAppcastCheckpoint < InternalUseBase + def self.run(*args) + calculate = args.include? "--calculate" + cask_tokens = cask_tokens_from(args) + raise CaskUnspecifiedError if cask_tokens.empty? + + if cask_tokens.all? { |t| t =~ %r{^https?://} && t !~ /\.rb$/ } + appcask_checkpoint_for_url(cask_tokens) + else + appcask_checkpoint(cask_tokens, calculate) + end + end + + def self.appcask_checkpoint_for_url(urls) + urls.each do |url| + appcast = DSL::Appcast.new(url) + puts appcast.calculate_checkpoint[:checkpoint] + end + end + + def self.appcask_checkpoint(cask_tokens, calculate) + count = 0 + + cask_tokens.each do |cask_token| + cask = Hbc.load(cask_token) + + if cask.appcast.nil? + opoo "Cask '#{cask}' is missing an `appcast` stanza." + else + if calculate + result = cask.appcast.calculate_checkpoint + + checkpoint = result[:checkpoint] + else + checkpoint = cask.appcast.checkpoint + end + + if checkpoint.nil? + onoe "Could not retrieve `appcast` checkpoint for cask '#{cask}': #{result[:command_result].stderr}" + else + puts cask_tokens.count > 1 ? "#{checkpoint} #{cask}": checkpoint + count += 1 + end + end + end + + count == cask_tokens.count + end + + def self.help + "prints or calculates a given Cask's or URL's appcast checkpoint" + end + + def self.needs_init? + true + end + end + end +end diff --git a/Library/Homebrew/cask/lib/hbc/cli/internal_dump.rb b/Library/Homebrew/cask/lib/hbc/cli/internal_dump.rb index af1494e5f..ac1b20493 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/internal_dump.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/internal_dump.rb @@ -27,7 +27,7 @@ module Hbc end def self.help - "Dump the given Cask in YAML format" + "dump the given Cask in YAML format" end end end diff --git a/Library/Homebrew/cask/lib/hbc/cli/internal_help.rb b/Library/Homebrew/cask/lib/hbc/cli/internal_help.rb index 6c646cfd7..0908ee05e 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/internal_help.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/internal_help.rb @@ -16,7 +16,7 @@ module Hbc end def self.help - "Print help strings for unstable internal-use commands" + "print help strings for unstable internal-use commands" end end end diff --git a/Library/Homebrew/cask/lib/hbc/cli/internal_stanza.rb b/Library/Homebrew/cask/lib/hbc/cli/internal_stanza.rb index e5c04ee51..105e946d7 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/internal_stanza.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/internal_stanza.rb @@ -50,12 +50,12 @@ module Hbc :uninstall_postflight, ] - def self.run(*arguments) - table = arguments.include? "--table" - quiet = arguments.include? "--quiet" - format = :to_yaml if arguments.include? "--yaml" - format = :inspect if arguments.include? "--inspect" - cask_tokens = arguments.reject { |arg| arg.chars.first == "-" } + def self.run(*args) + table = args.include? "--table" + quiet = args.include? "--quiet" + format = :to_yaml if args.include? "--yaml" + format = :inspect if args.include? "--inspect" + cask_tokens = cask_tokens_from(args) stanza = cask_tokens.shift.to_sym cask_tokens = Hbc.all_tokens if cask_tokens.empty? @@ -125,7 +125,7 @@ module Hbc end def self.help - "Extract and render a specific stanza for the given Casks" + "extract and render a specific stanza for the given Casks" end end end diff --git a/Library/Homebrew/cask/lib/hbc/cli/update.rb b/Library/Homebrew/cask/lib/hbc/cli/update.rb deleted file mode 100644 index 86d02bb55..000000000 --- a/Library/Homebrew/cask/lib/hbc/cli/update.rb +++ /dev/null @@ -1,20 +0,0 @@ -module Hbc - class CLI - class Update < Base - def self.run(*_ignored) - result = SystemCommand.run(HOMEBREW_BREW_FILE, - args: ["update"]) - # TODO: separating stderr/stdout is undesirable here. - # Hbc::SystemCommand should have an option for plain - # unbuffered output. - print result.stdout - $stderr.print result.stderr - exit result.exit_status - end - - def self.help - "a synonym for 'brew update'" - end - end - end -end diff --git a/Library/Homebrew/cask/lib/hbc/dsl/appcast.rb b/Library/Homebrew/cask/lib/hbc/dsl/appcast.rb index 2f1245d3d..e27870622 100644 --- a/Library/Homebrew/cask/lib/hbc/dsl/appcast.rb +++ b/Library/Homebrew/cask/lib/hbc/dsl/appcast.rb @@ -1,3 +1,5 @@ +require "hbc/system_command" + module Hbc class DSL class Appcast @@ -9,6 +11,20 @@ module Hbc @checkpoint = @parameters[:checkpoint] end + def calculate_checkpoint + result = SystemCommand.run("/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", URL::FAKE_USER_AGENT, @uri], print_stderr: false) + + checkpoint = if result.success? + processed_appcast_text = result.stdout.gsub(%r{<pubDate>[^<]*</pubDate>}m, "") + Digest::SHA2.hexdigest(processed_appcast_text) + end + + { + checkpoint: checkpoint, + command_result: result, + } + end + def to_yaml [@uri, @parameters].to_yaml end diff --git a/Library/Homebrew/cask/lib/hbc/dsl/depends_on.rb b/Library/Homebrew/cask/lib/hbc/dsl/depends_on.rb index 2168b7090..a8c1a1b73 100644 --- a/Library/Homebrew/cask/lib/hbc/dsl/depends_on.rb +++ b/Library/Homebrew/cask/lib/hbc/dsl/depends_on.rb @@ -13,30 +13,9 @@ module Hbc ].freeze VALID_ARCHES = { - intel: { type: :intel, bits: [32, 64] }, - ppc: { type: :ppc, bits: [32, 64] }, + intel: { type: :intel, bits: 64 }, # specific - i386: { type: :intel, bits: 32 }, x86_64: { type: :intel, bits: 64 }, - ppc_7400: { type: :ppc, bits: 32 }, - ppc_64: { type: :ppc, bits: 64 }, - }.freeze - - # Intentionally undocumented: catch variant spellings. - ARCH_SYNONYMS = { - x86_32: :i386, - x8632: :i386, - x8664: :x86_64, - intel_32: :i386, - intel32: :i386, - intel_64: :x86_64, - intel64: :x86_64, - amd_64: :x86_64, - amd64: :x86_64, - ppc7400: :ppc_7400, - ppc_32: :ppc_7400, - ppc32: :ppc_7400, - ppc64: :ppc_64, }.freeze attr_accessor :java @@ -100,8 +79,7 @@ module Hbc def arch=(*args) @arch ||= [] arches = args.map do |elt| - elt = elt.to_s.downcase.sub(/^:/, "").tr("-", "_").to_sym - ARCH_SYNONYMS.key?(elt) ? ARCH_SYNONYMS[elt] : elt + elt.to_s.downcase.sub(/^:/, "").tr("-", "_").to_sym end invalid_arches = arches - VALID_ARCHES.keys raise "invalid 'depends_on arch' values: #{invalid_arches.inspect}" unless invalid_arches.empty? diff --git a/Library/Homebrew/cask/lib/hbc/installer.rb b/Library/Homebrew/cask/lib/hbc/installer.rb index 3875e1c8f..465011735 100644 --- a/Library/Homebrew/cask/lib/hbc/installer.rb +++ b/Library/Homebrew/cask/lib/hbc/installer.rb @@ -141,8 +141,8 @@ module Hbc artifacts.each do |artifact| odebug "Installing artifact of class #{artifact}" - already_installed_artifacts.unshift(artifact) artifact.new(@cask, options).install_phase + already_installed_artifacts.unshift(artifact) end rescue StandardError => e begin diff --git a/Library/Homebrew/cask/lib/hbc/locations.rb b/Library/Homebrew/cask/lib/hbc/locations.rb index f28e84b2e..292b45d0c 100644 --- a/Library/Homebrew/cask/lib/hbc/locations.rb +++ b/Library/Homebrew/cask/lib/hbc/locations.rb @@ -1,3 +1,5 @@ +require "tap" + module Hbc module Locations def self.included(base) diff --git a/Library/Homebrew/cask/lib/hbc/system_command.rb b/Library/Homebrew/cask/lib/hbc/system_command.rb index 638069386..06ce276df 100644 --- a/Library/Homebrew/cask/lib/hbc/system_command.rb +++ b/Library/Homebrew/cask/lib/hbc/system_command.rb @@ -48,13 +48,11 @@ module Hbc def process_options! options.extend(HashValidator) - .assert_valid_keys :input, :print_stdout, :print_stderr, :args, :must_succeed, :sudo, :bsexec + .assert_valid_keys :input, :print_stdout, :print_stderr, :args, :must_succeed, :sudo sudo_prefix = %w[/usr/bin/sudo -E --] sudo_prefix = sudo_prefix.insert(1, "-A") unless ENV["SUDO_ASKPASS"].nil? - bsexec_prefix = ["/bin/launchctl", "bsexec", options[:bsexec] == :startup ? "/" : options[:bsexec]] @command = [executable] options[:print_stderr] = true unless options.key?(:print_stderr) - @command.unshift(*bsexec_prefix) if options[:bsexec] @command.unshift(*sudo_prefix) if options[:sudo] @command.concat(options[:args]) if options.key?(:args) && !options[:args].empty? @command[0] = Shellwords.shellescape(@command[0]) if @command.size == 1 diff --git a/Library/Homebrew/cask/spec/cask/audit_spec.rb b/Library/Homebrew/cask/spec/cask/audit_spec.rb index c12063a1d..193b58fd6 100644 --- a/Library/Homebrew/cask/spec/cask/audit_spec.rb +++ b/Library/Homebrew/cask/spec/cask/audit_spec.rb @@ -162,7 +162,7 @@ describe Hbc::Audit do before do allow(audit).to receive(:check_appcast_http_code) - allow(fake_system_command).to receive(:run).and_return(fake_curl_result) + allow(Hbc::SystemCommand).to receive(:run).and_return(fake_curl_result) allow(fake_curl_result).to receive(:success?).and_return(success) end diff --git a/Library/Homebrew/cask/spec/cask/cli_spec.rb b/Library/Homebrew/cask/spec/cask/cli_spec.rb index 9964275f1..6b2313a41 100644 --- a/Library/Homebrew/cask/spec/cask/cli_spec.rb +++ b/Library/Homebrew/cask/spec/cask/cli_spec.rb @@ -39,17 +39,17 @@ describe Hbc::CLI do end it "respects the env variable when choosing what appdir to create" do - with_environment "HOMEBREW_CASK_OPTS" => "--appdir=/custom/appdir" do - expect(Hbc).to receive(:appdir=).with(Pathname("/custom/appdir")) - described_class.process("noop") - end + allow(ENV).to receive(:[]) + allow(ENV).to receive(:[]).with("HOMEBREW_CASK_OPTS").and_return("--appdir=/custom/appdir") + expect(Hbc).to receive(:appdir=).with(Pathname.new("/custom/appdir")) + described_class.process("noop") end it "respects the env variable when choosing a non-default Caskroom location" do - with_environment "HOMEBREW_CASK_OPTS" => "--caskroom=/custom/caskdir" do - expect(Hbc).to receive(:caskroom=).with(Pathname("/custom/caskdir")) - described_class.process("noop") - end + allow(ENV).to receive(:[]) + allow(ENV).to receive(:[]).with("HOMEBREW_CASK_OPTS").and_return("--caskroom=/custom/caskdir") + expect(Hbc).to receive(:caskroom=).with(Pathname.new("/custom/caskdir")) + described_class.process("noop") end it "exits with a status of 1 when something goes wrong" do diff --git a/Library/Homebrew/cask/spec/spec_helper.rb b/Library/Homebrew/cask/spec/spec_helper.rb index 458fe00f4..162cb3b8f 100644 --- a/Library/Homebrew/cask/spec/spec_helper.rb +++ b/Library/Homebrew/cask/spec/spec_helper.rb @@ -15,7 +15,6 @@ require "global" # add Homebrew-Cask to load path $LOAD_PATH.push(HOMEBREW_LIBRARY_PATH.join("cask", "lib").to_s) -require "test/support/helper/env" require "test/support/helper/shutup" Pathname.glob(HOMEBREW_LIBRARY_PATH.join("cask", "spec", "support", "*.rb")).each(&method(:require)) @@ -38,6 +37,5 @@ end RSpec.configure do |config| config.order = :random - config.include(Test::Helper::Env) config.include(Test::Helper::Shutup) end diff --git a/Library/Homebrew/cask/test/cask/artifact/suite_test.rb b/Library/Homebrew/cask/test/cask/artifact/suite_test.rb index b2949950e..ed151e45c 100644 --- a/Library/Homebrew/cask/test/cask/artifact/suite_test.rb +++ b/Library/Homebrew/cask/test/cask/artifact/suite_test.rb @@ -13,6 +13,8 @@ describe Hbc::Artifact::Suite do end it "moves the suite to the proper directory" do + skip("flaky test") + shutup do install_phase.call end diff --git a/Library/Homebrew/cask/test/cask/depends_on_test.rb b/Library/Homebrew/cask/test/cask/depends_on_test.rb index ce2e54178..4516dad37 100644 --- a/Library/Homebrew/cask/test/cask/depends_on_test.rb +++ b/Library/Homebrew/cask/test/cask/depends_on_test.rb @@ -79,15 +79,6 @@ describe "Satisfy Dependencies and Requirements" do Hbc::Installer.new(arch_cask).install end end - - it "raises an exception when depends_on arch is not satisfied" do - arch_cask = Hbc.load("with-depends-on-arch-failure") - lambda { - shutup do - Hbc::Installer.new(arch_cask).install - end - }.must_raise(Hbc::CaskError) - end end describe "depends_on x11" do diff --git a/Library/Homebrew/cask/test/cask/dsl_test.rb b/Library/Homebrew/cask/test/cask/dsl_test.rb index 96d24a1a1..0ea928f40 100644 --- a/Library/Homebrew/cask/test/cask/dsl_test.rb +++ b/Library/Homebrew/cask/test/cask/dsl_test.rb @@ -69,7 +69,11 @@ describe Hbc::DSL do end it "may use deprecated DSL version hash syntax" do - with_environment "HOMEBREW_DEVELOPER" => nil do + stub = proc do |arg| + arg == "HOMEBREW_DEVELOPER" ? nil : ENV[arg] + end + + ENV.stub :[], stub do shutup do test_cask = Hbc.load("with-dsl-version") test_cask.token.must_equal "with-dsl-version" diff --git a/Library/Homebrew/cask/test/support/Casks/with-depends-on-arch-failure.rb b/Library/Homebrew/cask/test/support/Casks/with-depends-on-arch-failure.rb deleted file mode 100644 index 14c916573..000000000 --- a/Library/Homebrew/cask/test/support/Casks/with-depends-on-arch-failure.rb +++ /dev/null @@ -1,12 +0,0 @@ -test_cask 'with-depends-on-arch-failure' do - version '1.2.3' - sha256 '67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94' - - url "file://#{TEST_FIXTURE_DIR}/cask/caffeine.zip" - homepage 'http://example.com/with-depends-on-arch-failure' - - # guarantee mismatched hardware - depends_on arch: Hardware::CPU.intel? ? :ppc : :intel - - app 'Caffeine.app' -end diff --git a/Library/Homebrew/cask/test/support/Casks/with-depends-on-arch.rb b/Library/Homebrew/cask/test/support/Casks/with-depends-on-arch.rb index fe5e4ba03..e0c4e3fa7 100644 --- a/Library/Homebrew/cask/test/support/Casks/with-depends-on-arch.rb +++ b/Library/Homebrew/cask/test/support/Casks/with-depends-on-arch.rb @@ -6,7 +6,7 @@ test_cask 'with-depends-on-arch' do homepage 'http://example.com/with-depends-on-arch' # covers all known hardware; always succeeds - depends_on arch: [:ppc, :intel] + depends_on arch: :intel app 'Caffeine.app' end diff --git a/Library/Homebrew/cask/test/test_helper.rb b/Library/Homebrew/cask/test/test_helper.rb index 275ede304..7315839f5 100644 --- a/Library/Homebrew/cask/test/test_helper.rb +++ b/Library/Homebrew/cask/test/test_helper.rb @@ -13,9 +13,7 @@ require "global" # add Homebrew-Cask to load path $LOAD_PATH.push(HOMEBREW_LIBRARY_PATH.join("cask", "lib").to_s) -require "test/support/helper/env" require "test/support/helper/shutup" -include Test::Helper::Env include Test::Helper::Shutup def sudo(*args) diff --git a/Library/Homebrew/caveats.rb b/Library/Homebrew/caveats.rb index 3dfdb1c87..d1dda9d4c 100644 --- a/Library/Homebrew/caveats.rb +++ b/Library/Homebrew/caveats.rb @@ -23,7 +23,6 @@ class Caveats caveats << fish_function_caveats caveats << plist_caveats caveats << python_caveats - caveats << app_caveats caveats << elisp_caveats caveats.compact.join("\n") end @@ -169,16 +168,6 @@ class Caveats s end - def app_caveats - return unless keg - return unless keg.app_installed? - - <<-EOS.undent - .app bundles were installed. - Run `brew linkapps #{keg.name}` to symlink these to /Applications. - EOS - end - def elisp_caveats return if f.keg_only? return unless keg diff --git a/Library/Homebrew/cmd/--prefix.rb b/Library/Homebrew/cmd/--prefix.rb index c59830833..f6e7d2ee2 100644 --- a/Library/Homebrew/cmd/--prefix.rb +++ b/Library/Homebrew/cmd/--prefix.rb @@ -11,7 +11,7 @@ module Homebrew if ARGV.named.empty? puts HOMEBREW_PREFIX else - puts ARGV.resolved_formulae.map { |f| f.opt_prefix.exist? ? f.opt_prefix : f.installed_prefix } + puts ARGV.resolved_formulae.map(&:installed_prefix) end end end diff --git a/Library/Homebrew/cmd/analytics.rb b/Library/Homebrew/cmd/analytics.rb index 2efa5a2d2..8a67a54a4 100644 --- a/Library/Homebrew/cmd/analytics.rb +++ b/Library/Homebrew/cmd/analytics.rb @@ -1,6 +1,6 @@ #: * `analytics` [`state`]: #: Display anonymous user behaviour analytics state. -#: Read more at <https://git.io/brew-analytics>. +#: Read more at <http://docs.brew.sh/Analytics.html>. #: #: * `analytics` (`on`|`off`): #: Turn on/off Homebrew's analytics. diff --git a/Library/Homebrew/cmd/deps.rb b/Library/Homebrew/cmd/deps.rb index a5089392f..205cbe172 100644 --- a/Library/Homebrew/cmd/deps.rb +++ b/Library/Homebrew/cmd/deps.rb @@ -66,16 +66,16 @@ module Homebrew else all_deps = deps_for_formulae(ARGV.formulae, !ARGV.one?, &(mode.union? ? :| : :&)) all_deps = all_deps.select(&:installed?) if mode.installed? - all_deps = if ARGV.include? "--full-name" - all_deps.map(&:to_formula).map(&:full_name) - else - all_deps.map(&:name) - end.uniq + all_deps = all_deps.map(&method(:dep_display_name)).uniq all_deps.sort! unless mode.topo_order? puts all_deps end end + def dep_display_name(d) + ARGV.include?("--full-name") ? d.to_formula.full_name : d.name + end + def deps_for_formula(f, recursive = false) includes = [] ignores = [] @@ -127,7 +127,10 @@ module Homebrew end def puts_deps(formulae) - formulae.each { |f| puts "#{f.full_name}: #{deps_for_formula(f).sort_by(&:name) * " "}" } + formulae.each do |f| + deps = deps_for_formula(f).sort_by(&:name).map(&method(:dep_display_name)) + puts "#{f.full_name}: #{deps.join(" ")}" + end end def puts_deps_tree(formulae) @@ -140,17 +143,25 @@ module Homebrew def recursive_deps_tree(f, prefix) reqs = f.requirements.select(&:default_formula?) + deps = f.deps.default max = reqs.length - 1 reqs.each_with_index do |req, i| - chr = i == max ? "└──" : "├──" - puts prefix + "#{chr} :#{req.to_dependency.name}" + chr = if i == max && deps.empty? + "└──" + else + "├──" + end + puts prefix + "#{chr} :#{dep_display_name(req.to_dependency)}" end - deps = f.deps.default max = deps.length - 1 deps.each_with_index do |dep, i| - chr = i == max ? "└──" : "├──" + chr = if i == max + "└──" + else + "├──" + end prefix_ext = i == max ? " " : "│ " - puts prefix + "#{chr} #{dep.name}" + puts prefix + "#{chr} #{dep_display_name(dep)}" recursive_deps_tree(Formulary.factory(dep.name), prefix + prefix_ext) end end diff --git a/Library/Homebrew/cmd/fetch.rb b/Library/Homebrew/cmd/fetch.rb index f92ef03b2..820a27e31 100644 --- a/Library/Homebrew/cmd/fetch.rb +++ b/Library/Homebrew/cmd/fetch.rb @@ -18,8 +18,9 @@ #: If `--build-from-source` is passed, download the source rather than a #: bottle. #: -#: If `--force-bottle` is passed, download a bottle if it exists for the current -#: version of macOS, even if it would not be used during installation. +#: If `--force-bottle` is passed, download a bottle if it exists for the +#: current or newest version of macOS, even if it would not be used during +#: installation. require "formula" diff --git a/Library/Homebrew/cmd/help.rb b/Library/Homebrew/cmd/help.rb index 982e24965..1378e7b1f 100644 --- a/Library/Homebrew/cmd/help.rb +++ b/Library/Homebrew/cmd/help.rb @@ -16,7 +16,7 @@ Troubleshooting: Developers: brew create [URL [--no-fetch]] brew edit [FORMULA...] - https://github.com/Homebrew/brew/blob/master/docs/Formula-Cookbook.md + http://docs.brew.sh/Formula-Cookbook.html Further help: man brew diff --git a/Library/Homebrew/cmd/info.rb b/Library/Homebrew/cmd/info.rb index fc47e1731..1850ae003 100644 --- a/Library/Homebrew/cmd/info.rb +++ b/Library/Homebrew/cmd/info.rb @@ -14,7 +14,7 @@ #: information on all installed formulae. #: #: See the docs for examples of using the JSON: -#: <https://github.com/Homebrew/brew/blob/master/docs/Querying-Brew.md> +#: <http://docs.brew.sh/Querying-Brew.html> require "blacklist" require "caveats" diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb index 700cd9c3d..5a3aeb7b3 100644 --- a/Library/Homebrew/cmd/install.rb +++ b/Library/Homebrew/cmd/install.rb @@ -32,10 +32,10 @@ #: passed, then both <formula> and the dependencies installed as part of this process #: are built from source even if bottles are available. #: -# Hidden developer option: -# If `--force-bottle` is passed, install from a bottle if it exists -# for the current version of macOS, even if custom options are given. -# +#: If `--force-bottle` is passed, install from a bottle if it exists for the +#: current or newest version of macOS, even if it would not normally be used +#: for installation. +#: #: If `--devel` is passed, and <formula> defines it, install the development version. #: #: If `--HEAD` is passed, and <formula> defines it, install the HEAD version, @@ -44,9 +44,6 @@ #: If `--keep-tmp` is passed, the temporary files created during installation #: are not deleted. #: -#: To install a newer version of HEAD use -#: `brew rm <foo> && brew install --HEAD <foo>`. -#: #: * `install` `--interactive` [`--git`] <formula>: #: Download and patch <formula>, then open a shell. This allows the user to #: run `./configure --help` and otherwise determine how to turn the software @@ -187,6 +184,14 @@ module Homebrew # FormulaInstaller will handle this case. formulae << f end + + # Even if we don't install this formula mark it as no longer just + # installed as a dependency. + next unless f.opt_prefix.directory? + keg = Keg.new(f.opt_prefix.resolved_path) + tab = Tab.for_keg(keg) + tab.installed_on_request = true + tab.write end perform_preinstall_checks diff --git a/Library/Homebrew/cmd/linkapps.rb b/Library/Homebrew/cmd/linkapps.rb index bd88409aa..7dd1a6b93 100644 --- a/Library/Homebrew/cmd/linkapps.rb +++ b/Library/Homebrew/cmd/linkapps.rb @@ -1,6 +1,11 @@ #: * `linkapps` [`--local`] [<formulae>]: #: Find installed formulae that provide `.app`-style macOS apps and symlink them -#: into `/Applications`, allowing for easier access. +#: into `/Applications`, allowing for easier access (deprecated). +#: +#: Unfortunately `brew linkapps` cannot behave nicely with e.g. Spotlight using +#: either aliases or symlinks and Homebrew formulae do not build "proper" `.app` +#: bundles that can be relocated. Instead, please consider using `brew cask` and +#: migrate formulae using `.app`s to casks. #: #: If no <formulae> are provided, all of them will have their apps symlinked. #: @@ -14,6 +19,15 @@ module Homebrew module_function def linkapps + opoo <<-EOS.undent + `brew linkapps` has been deprecated and will eventually be removed! + + Unfortunately `brew linkapps` cannot behave nicely with e.g. Spotlight using + either aliases or symlinks and Homebrew formulae do not build "proper" `.app` + bundles that can be relocated. Instead, please consider using `brew cask` and + migrate formulae using `.app`s to casks. + EOS + target_dir = linkapps_target(local: ARGV.include?("--local")) unless target_dir.directory? diff --git a/Library/Homebrew/cmd/tap-info.rb b/Library/Homebrew/cmd/tap-info.rb index 0d9f8db3d..b46de30c1 100644 --- a/Library/Homebrew/cmd/tap-info.rb +++ b/Library/Homebrew/cmd/tap-info.rb @@ -13,7 +13,7 @@ #: Pass `--installed` to get information on installed taps. #: #: See the docs for examples of using the JSON: -#: <https://github.com/Homebrew/brew/blob/master/docs/Querying-Brew.md> +#: <http://docs.brew.sh/Querying-Brew.html> require "tap" diff --git a/Library/Homebrew/cmd/uninstall.rb b/Library/Homebrew/cmd/uninstall.rb index 505d4e4b2..5d02ebd1e 100644 --- a/Library/Homebrew/cmd/uninstall.rb +++ b/Library/Homebrew/cmd/uninstall.rb @@ -102,8 +102,8 @@ module Homebrew attr_reader :reqs, :deps def initialize(requireds, dependents) - @reqs = requireds.compact - @deps = dependents.compact + @reqs = requireds + @deps = dependents end protected @@ -121,7 +121,7 @@ module Homebrew end def sample_command - "brew uninstall --ignore-dependencies #{list reqs.map(&:name)}" + "brew uninstall --ignore-dependencies #{ARGV.named.join(" ")}" end def are_required_by_deps diff --git a/Library/Homebrew/cmd/unlinkapps.rb b/Library/Homebrew/cmd/unlinkapps.rb index d04ef9ee4..b2ba458bf 100644 --- a/Library/Homebrew/cmd/unlinkapps.rb +++ b/Library/Homebrew/cmd/unlinkapps.rb @@ -1,5 +1,10 @@ #: * `unlinkapps` [`--local`] [`--dry-run`] [<formulae>]: -#: Remove symlinks created by `brew linkapps` from `/Applications`. +#: Remove symlinks created by `brew linkapps` from `/Applications` (deprecated). +#: +#: Unfortunately `brew linkapps` cannot behave nicely with e.g. Spotlight using +#: either aliases or symlinks and Homebrew formulae do not build "proper" `.app` +#: bundles that can be relocated. Instead, please consider using `brew cask` and +#: migrate formulae using `.app`s to casks. #: #: If no <formulae> are provided, all linked apps will be removed. #: @@ -15,6 +20,12 @@ module Homebrew module_function def unlinkapps + opoo <<-EOS.undent + `brew unlinkapps` has been deprecated and will eventually be removed! + + Unfortunately `brew linkapps` cannot behave nicely with e.g. Spotlight using either aliases or symlinks and Homebrew formulae do not build "proper" `.app` bundles that can be relocated. Instead, please consider using `brew cask` and migrate formulae using `.app`s to casks. + EOS + target_dir = linkapps_target(local: ARGV.include?("--local")) unlinkapps_from_dir(target_dir, dry_run: ARGV.dry_run?) diff --git a/Library/Homebrew/cmd/update-report.rb b/Library/Homebrew/cmd/update-report.rb index 10b433dd2..dcf2891d9 100644 --- a/Library/Homebrew/cmd/update-report.rb +++ b/Library/Homebrew/cmd/update-report.rb @@ -35,7 +35,7 @@ module Homebrew ohai "Homebrew has enabled anonymous aggregate user behaviour analytics." puts <<-EOS.undent #{Tty.bold}Read the analytics documentation (and how to opt-out) here: - #{Formatter.url("https://git.io/brew-analytics")}#{Tty.reset} + #{Formatter.url("http://docs.brew.sh/Analytics.html")}#{Tty.reset} EOS @@ -387,7 +387,7 @@ class Reporter end end - renamed_formulae = [] + renamed_formulae = Set.new @report[:D].each do |old_full_name| old_name = old_full_name.split("/").last new_name = tap.formula_renames[old_name] @@ -402,10 +402,24 @@ class Reporter renamed_formulae << [old_full_name, new_full_name] if @report[:A].include? new_full_name end + @report[:A].each do |new_full_name| + new_name = new_full_name.split("/").last + old_name = tap.formula_renames.key(new_name) + next unless old_name + + if tap.core_tap? + old_full_name = old_name + else + old_full_name = "#{tap}/#{old_name}" + end + + renamed_formulae << [old_full_name, new_full_name] + end + unless renamed_formulae.empty? @report[:A] -= renamed_formulae.map(&:last) @report[:D] -= renamed_formulae.map(&:first) - @report[:R] = renamed_formulae + @report[:R] = renamed_formulae.to_a end @report @@ -421,18 +435,27 @@ class Reporter new_tap_name = tap.tap_migrations[name] next if new_tap_name.nil? # skip if not in tap_migrations list. + new_tap_user, new_tap_repo, new_tap_new_name = new_tap_name.split("/") + new_name = if new_tap_new_name + new_full_name = new_tap_new_name + new_tap_name = "#{new_tap_user}/#{new_tap_repo}" + new_tap_new_name + else + new_full_name = "#{new_tap_name}/#{name}" + name + end + # This means it is a Cask if report[:DC].include? full_name - next unless (HOMEBREW_PREFIX/"Caskroom"/name).exist? + next unless (HOMEBREW_PREFIX/"Caskroom"/new_name).exist? new_tap = Tap.fetch(new_tap_name) new_tap.install unless new_tap.installed? ohai "#{name} has been moved to Homebrew.", <<-EOS.undent To uninstall the cask run: brew cask uninstall --force #{name} EOS - new_full_name = "#{new_tap_name}/#{name}" - next if (HOMEBREW_CELLAR/name.split("/").last).directory? - ohai "Installing #{name}..." + next if (HOMEBREW_CELLAR/new_name.split("/").last).directory? + ohai "Installing #{new_name}..." system HOMEBREW_BREW_FILE, "install", new_full_name begin unless Formulary.factory(new_full_name).keg_only? @@ -456,13 +479,13 @@ class Reporter system HOMEBREW_BREW_FILE, "uninstall", "--force", name ohai "brew prune" system HOMEBREW_BREW_FILE, "prune" - ohai "brew cask install #{name}" - system HOMEBREW_BREW_FILE, "cask", "install", name + ohai "brew cask install #{new_name}" + system HOMEBREW_BREW_FILE, "cask", "install", new_name else ohai "#{name} has been moved to Homebrew-Cask.", <<-EOS.undent To uninstall the formula and install the cask run: brew uninstall --force #{name} - brew cask install #{name} + brew cask install #{new_name} EOS end else diff --git a/Library/Homebrew/cmd/upgrade.rb b/Library/Homebrew/cmd/upgrade.rb index 5b49a9f65..ce892f85c 100644 --- a/Library/Homebrew/cmd/upgrade.rb +++ b/Library/Homebrew/cmd/upgrade.rb @@ -94,14 +94,24 @@ module Homebrew .select(&:directory?) .map { |k| Keg.new(k.resolved_path) } + if f.opt_prefix.directory? + keg = Keg.new(f.opt_prefix.resolved_path) + tab = Tab.for_keg(keg) + end + fi = FormulaInstaller.new(f) - fi.options = f.build.used_options - fi.options &= f.options - fi.build_bottle = ARGV.build_bottle? || (!f.bottled? && f.build.build_bottle?) - fi.build_from_source = ARGV.build_from_source? || ARGV.build_all_from_source? - fi.verbose = ARGV.verbose? - fi.quieter = ARGV.quieter? - fi.debug = ARGV.debug? + fi.options = f.build.used_options + fi.options &= f.options + fi.build_bottle = ARGV.build_bottle? || (!f.bottled? && f.build.build_bottle?) + fi.build_from_source = ARGV.build_from_source? || ARGV.build_all_from_source? + fi.verbose = ARGV.verbose? + fi.quieter = ARGV.quieter? + fi.debug = ARGV.debug? + fi.installed_on_request = !ARGV.named.empty? + if tab + fi.installed_as_dependency = tab.installed_as_dependency + fi.installed_on_request ||= tab.installed_on_request + end fi.prelude oh1 "Upgrading #{f.full_specified_name} #{fi.options.to_a.join " "}" diff --git a/Library/Homebrew/cmd/uses.rb b/Library/Homebrew/cmd/uses.rb index fb11a31a7..5f6611dfc 100644 --- a/Library/Homebrew/cmd/uses.rb +++ b/Library/Homebrew/cmd/uses.rb @@ -57,16 +57,36 @@ module Homebrew elsif dep.build? Dependency.prune unless includes.include?("build?") end + + # If a tap isn't installed, we can't find the dependencies of one + # its formulae, and an exception will be thrown if we try. + if dep.is_a?(TapDependency) && !dep.tap.installed? + Dependency.keep_but_prune_recursive_deps + end + end + + dep_formulae = deps.map do |dep| + begin + dep.to_formula + rescue + end + end.compact + + reqs_by_formula = ([f] + dep_formulae).flat_map do |formula| + formula.requirements.map { |req| [formula, req] } end - reqs = f.recursive_requirements do |dependent, req| + + reqs_by_formula.reject! do |dependent, req| if req.recommended? - Requirement.prune if ignores.include?("recommended?") || dependent.build.without?(req) + ignores.include?("recommended?") || dependent.build.without?(req) elsif req.optional? - Requirement.prune if !includes.include?("optional?") && !dependent.build.with?(req) + !includes.include?("optional?") && !dependent.build.with?(req) elsif req.build? - Requirement.prune unless includes.include?("build?") + !includes.include?("build?") end end + + reqs = reqs_by_formula.map(&:last) else deps = f.deps.reject do |dep| ignores.any? { |ignore| dep.send(ignore) } && !includes.any? { |include| dep.send(include) } diff --git a/Library/Homebrew/compat.rb b/Library/Homebrew/compat.rb index 5d78c715f..92b687725 100644 --- a/Library/Homebrew/compat.rb +++ b/Library/Homebrew/compat.rb @@ -22,3 +22,6 @@ require "compat/json" require "compat/ARGV" require "compat/build_options" require "compat/tab" +require "compat/ENV/shared" +require "compat/ENV/std" +require "compat/ENV/super" diff --git a/Library/Homebrew/compat/ENV/shared.rb b/Library/Homebrew/compat/ENV/shared.rb new file mode 100644 index 000000000..200e7b132 --- /dev/null +++ b/Library/Homebrew/compat/ENV/shared.rb @@ -0,0 +1,6 @@ +module SharedEnvExtension + def j1 + odeprecated "ENV.j1", "ENV.deparallelize" + deparallelize + end +end diff --git a/Library/Homebrew/compat/ENV/std.rb b/Library/Homebrew/compat/ENV/std.rb new file mode 100644 index 000000000..26dabe440 --- /dev/null +++ b/Library/Homebrew/compat/ENV/std.rb @@ -0,0 +1,27 @@ +module Stdenv + def fast + odeprecated "ENV.fast" + end + + def O4 + odeprecated "ENV.O4" + end + + def Og + odeprecated "ENV.Og" + end + + def gcc_4_0_1 + odeprecated "ENV.gcc_4_0_1", "ENV.gcc_4_0" + gcc_4_0 + end + + def gcc + odeprecated "ENV.gcc", "ENV.gcc_4_2" + gcc_4_2 + end + + def libpng + odeprecated "ENV.libpng", "ENV.x11" + end +end diff --git a/Library/Homebrew/compat/ENV/super.rb b/Library/Homebrew/compat/ENV/super.rb new file mode 100644 index 000000000..2020ad752 --- /dev/null +++ b/Library/Homebrew/compat/ENV/super.rb @@ -0,0 +1,47 @@ +module Superenv + def fast + odeprecated "ENV.fast" + end + + def O4 + odeprecated "ENV.O4" + end + + def Og + odeprecated "ENV.Og" + end + + def gcc_4_0_1 + odeprecated "ENV.gcc_4_0_1", "ENV.gcc_4_0" + gcc_4_0 + end + + def gcc + odeprecated "ENV.gcc", "ENV.gcc_4_2" + gcc_4_2 + end + + def libxml2 + odeprecated "ENV.libxml2" + end + + def minimal_optimization + odeprecated "ENV.minimal_optimization" + end + + def no_optimization + odeprecated "ENV.no_optimization" + end + + def enable_warnings + odeprecated "ENV.enable_warnings" + end + + def macosxsdk + odeprecated "ENV.macosxsdk" + end + + def remove_macosxsdk + odeprecated "ENV.remove_macosxsdk" + end +end diff --git a/Library/Homebrew/compat/hbc.rb b/Library/Homebrew/compat/hbc.rb index a1d1414a5..179639953 100644 --- a/Library/Homebrew/compat/hbc.rb +++ b/Library/Homebrew/compat/hbc.rb @@ -1 +1,2 @@ require "compat/hbc/cask_loader" +require "compat/hbc/cli/update" diff --git a/Library/Homebrew/compat/hbc/cli/update.rb b/Library/Homebrew/compat/hbc/cli/update.rb new file mode 100644 index 000000000..7820997cb --- /dev/null +++ b/Library/Homebrew/compat/hbc/cli/update.rb @@ -0,0 +1,23 @@ +require "cask/lib/hbc/cli/base" + +module Hbc + class CLI + class Update < Base + def self.run(*_ignored) + odeprecated "`brew cask update`", "`brew update`", disable_on: Time.utc(2017, 7, 1) + result = SystemCommand.run(HOMEBREW_BREW_FILE, args: ["update"], + print_stderr: true, + print_stdout: true) + exit result.exit_status + end + + def self.visible + false + end + + def self.help + "a synonym for 'brew update'" + end + end + end +end diff --git a/Library/Homebrew/compat/macos.rb b/Library/Homebrew/compat/macos.rb index 17f4670cc..3acd2f9ef 100644 --- a/Library/Homebrew/compat/macos.rb +++ b/Library/Homebrew/compat/macos.rb @@ -100,23 +100,23 @@ module OS end def gcc_40_build_version - odeprecated "MacOS.gcc_40_build_version", "DevelopmentTools.gcc_40_build_version" - DevelopmentTools.gcc_40_build_version + odeprecated "MacOS.gcc_40_build_version", "DevelopmentTools.gcc_4_0_build_version" + DevelopmentTools.gcc_4_0_build_version end def gcc_4_0_build_version - odeprecated "MacOS.gcc_4_0_build_version", "DevelopmentTools.gcc_40_build_version" - DevelopmentTools.gcc_40_build_version + odeprecated "MacOS.gcc_4_0_build_version", "DevelopmentTools.gcc_4_0_build_version" + DevelopmentTools.gcc_4_0_build_version end def gcc_42_build_version - odeprecated "MacOS.gcc_42_build_version", "DevelopmentTools.gcc_42_build_version" - DevelopmentTools.gcc_42_build_version + odeprecated "MacOS.gcc_42_build_version", "DevelopmentTools.gcc_4_2_build_version" + DevelopmentTools.gcc_4_2_build_version end def gcc_build_version - odeprecated "MacOS.gcc_build_version", "DevelopmentTools.gcc_42_build_version" - DevelopmentTools.gcc_42_build_version + odeprecated "MacOS.gcc_build_version", "DevelopmentTools.gcc_4_2_build_version" + DevelopmentTools.gcc_4_2_build_version end def llvm_build_version diff --git a/Library/Homebrew/compilers.rb b/Library/Homebrew/compilers.rb index 9ee847db0..628e71e9b 100644 --- a/Library/Homebrew/compilers.rb +++ b/Library/Homebrew/compilers.rb @@ -4,7 +4,7 @@ module CompilerConstants GNU_GCC_REGEXP = /^gcc-(4\.[3-9]|[5-7])$/ COMPILER_SYMBOL_MAP = { "gcc-4.0" => :gcc_4_0, - "gcc-4.2" => :gcc, + "gcc-4.2" => :gcc_4_2, "clang" => :clang, "llvm_clang" => :llvm_clang, }.freeze @@ -68,7 +68,7 @@ class CompilerFailure COLLECTIONS = { cxx11: [ create(:gcc_4_0), - create(:gcc), + create(:gcc_4_2), create(:clang) { build 425 }, create(gcc: "4.3"), create(gcc: "4.4"), @@ -87,9 +87,9 @@ class CompilerSelector Compiler = Struct.new(:name, :version) COMPILER_PRIORITY = { - clang: [:clang, :gcc, :gnu, :gcc_4_0, :llvm_clang], - gcc: [:gcc, :gnu, :clang, :gcc_4_0], - gcc_4_0: [:gcc_4_0, :gcc, :gnu, :clang], + clang: [:clang, :gcc_4_2, :gnu, :gcc_4_0, :llvm_clang], + gcc_4_2: [:gcc_4_2, :gnu, :clang, :gcc_4_0], + gcc_4_0: [:gcc_4_0, :gcc_4_2, :gnu, :clang], }.freeze def self.select_for(formula, compilers = self.compilers) diff --git a/Library/Homebrew/dependency.rb b/Library/Homebrew/dependency.rb index 253ba4bee..4a452440a 100644 --- a/Library/Homebrew/dependency.rb +++ b/Library/Homebrew/dependency.rb @@ -175,7 +175,7 @@ class TapDependency < Dependency attr_reader :tap def initialize(name, tags = [], env_proc = DEFAULT_ENV_PROC, option_names = [name.split("/").last]) - @tap = name.rpartition("/").first + @tap = Tap.fetch(name.rpartition("/").first) super(name, tags, env_proc, option_names) end diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index fffe14b47..af1e4a71b 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -169,6 +169,33 @@ class FormulaAuditor @specs = %w[stable devel head].map { |s| formula.send(s) }.compact end + def url_status_code(url, range: false, user_agent: :default) + # The system Curl is too old and unreliable with HTTPS homepages on + # Yosemite and below. + return "200" unless DevelopmentTools.curl_handles_most_https_homepages? + + extra_args = [ + "--connect-timeout", "15", + "--output", "/dev/null", + "--write-out", "%{http_code}" + ] + extra_args << "--range" << "0-0" if range + extra_args << url + + args = curl_args( + extra_args: extra_args, + show_output: true, + user_agent: user_agent + ) + retries = 3 + status_code = nil + retries.times do + status_code = Open3.popen3(*args) { |_, stdout, _, _| stdout.read } + break if status_code.start_with? "20" + end + status_code + end + def audit_style return unless @style_offenses display_cop_names = ARGV.include?("--display-cop-names") @@ -432,6 +459,14 @@ class FormulaAuditor end def audit_conflicts + if formula.conflicts.any? && formula.versioned_formula? + problem <<-EOS + Versioned formulae should not use `conflicts_with`. + Use `keg_only :versioned_formula` instead. + EOS + return + end + formula.conflicts.each do |c| begin Formulary.factory(c.name) @@ -454,6 +489,10 @@ class FormulaAuditor next unless @strict + if o.name == "universal" && !Formula["wine"].recursive_dependencies.map(&:name).include?(formula.name) + problem "macOS has been 64-bit only since 10.6 so universal options are deprecated." + end + if o.name !~ /with(out)?-/ && o.name != "c++11" && o.name != "universal" problem "Options should begin with with/without. Migrate '--#{o.name}' with `deprecated_option`." end @@ -466,7 +505,7 @@ class FormulaAuditor return unless @new_formula return if formula.deprecated_options.empty? - return if formula.name.include?("@") + return if formula.versioned_formula? problem "New formulae should not use `deprecated_option`." end @@ -569,11 +608,10 @@ class FormulaAuditor end return unless @online - begin - nostdout { curl "--connect-timeout", "15", "-o", "/dev/null", homepage } - rescue ErrorDuringExecution - problem "The homepage is not reachable (curl exit code #{$?.exitstatus})" - end + + status_code = url_status_code(homepage, user_agent: :browser) + return if status_code.start_with? "20" + problem "The homepage #{homepage} is not reachable (HTTP status code #{status_code})" end def audit_bottle_spec @@ -652,11 +690,47 @@ class FormulaAuditor end end + unstable_whitelist = %w[ + aalib 1.4rc5 + automysqlbackup 3.0-rc6 + aview 1.3.0rc1 + distcc 3.2rc1 + elm-format 0.5.2-alpha + ftgl 2.1.3-rc5 + hidapi 0.8.0-rc1 + libcaca 0.99b19 + premake 4.4-beta5 + pwnat 0.3-beta + pxz 4.999.9 + recode 3.7-beta2 + speexdsp 1.2rc3 + sqoop 1.4.6 + tcptraceroute 1.5beta7 + testssl 2.8rc3 + tiny-fugue 5.0b8 + vbindiff 3.0_beta4 + ].each_slice(2).to_a.map do |formula, version| + [formula, version.sub(/\d+$/, "")] + end + + gnome_devel_whitelist = %w[ + gtk-doc 1.25 + libart 2.3.21 + pygtkglext 1.1.0 + ].each_slice(2).to_a.map do |formula, version| + [formula, version.split(".")[0..1].join(".")] + end + stable = formula.stable case stable && stable.url when /[\d\._-](alpha|beta|rc\d)/ - problem "Stable version URLs should not contain #{$1}" + matched = $1 + version_prefix = stable.version.to_s.sub(/\d+$/, "") + return if unstable_whitelist.include?([formula.name, version_prefix]) + problem "Stable version URLs should not contain #{matched}" when %r{download\.gnome\.org/sources}, %r{ftp\.gnome\.org/pub/GNOME/sources}i + version_prefix = stable.version.to_s.split(".")[0..1].join(".") + return if gnome_devel_whitelist.include?([formula.name, version_prefix]) version = Version.parse(stable.url) if version >= Version.create("1.0") minor_version = version.to_s.split(".", 3)[1].to_i @@ -789,6 +863,15 @@ class FormulaAuditor problem "Please set plist_options when using a formula-defined plist." end + if text =~ /depends_on\s+['"]openssl['"]/ && text =~ /depends_on\s+['"]libressl['"]/ + problem "Formulae should not depend on both OpenSSL and LibreSSL (even optionally)." + end + + if text =~ /virtualenv_(create|install_with_resources)/ && + text =~ /resource\s+['"]setuptools['"]\s+do/ + problem "Formulae using virtualenvs do not need a `setuptools` resource." + end + return unless text.include?('require "language/go"') && !text.include?("go_resource") problem "require \"language/go\" is unnecessary unless using `go_resource`s" end @@ -1018,6 +1101,8 @@ class FormulaAuditor return unless @strict + problem "`#{$1}` in formulae is deprecated" if line =~ /(env :(std|userpaths))/ + if line =~ /system ((["'])[^"' ]*(?:\s[^"' ]*)+\2)/ bad_system = $1 unless %w[| < > & ; *].any? { |c| bad_system.include? c } diff --git a/Library/Homebrew/dev-cmd/bottle.rb b/Library/Homebrew/dev-cmd/bottle.rb index 9618cf412..7367e5c37 100644 --- a/Library/Homebrew/dev-cmd/bottle.rb +++ b/Library/Homebrew/dev-cmd/bottle.rb @@ -435,6 +435,7 @@ module Homebrew else string = s.sub!( /( + (\ {2}\#[^\n]*\n)* # comments \ {2}( # two spaces at the beginning (url|head)\ ['"][\S\ ]+['"] # url or head with a string ( @@ -442,7 +443,7 @@ module Homebrew (\n^\ {3}[\S\ ]+$)* # options can be in multiple lines )?| (homepage|desc|sha1|sha256|version|mirror)\ ['"][\S\ ]+['"]| # specs with a string - rebuild\ \d+ # rebuild with a number + revision\ \d+ # revision with a number )\n+ # multiple empty lines )+ /mx, '\0' + output + "\n" diff --git a/Library/Homebrew/dev-cmd/bump-formula-pr.rb b/Library/Homebrew/dev-cmd/bump-formula-pr.rb index b1f851b8d..68bf32d0b 100644 --- a/Library/Homebrew/dev-cmd/bump-formula-pr.rb +++ b/Library/Homebrew/dev-cmd/bump-formula-pr.rb @@ -124,6 +124,8 @@ module Homebrew false elsif !hash_type odie "#{formula}: no tag/revision specified!" + elsif !new_url + odie "#{formula}: no url specified!" else rsrc_url = if requested_spec != :devel && new_url =~ /.*ftpmirror.gnu.*/ new_mirror = new_url.sub "ftpmirror.gnu.org", "ftp.gnu.org/gnu" @@ -156,7 +158,9 @@ module Homebrew replacement_pairs << [/^ revision \d+\n(\n( head "))?/m, "\\2"] end - replacement_pairs << [/(^ mirror .*\n)?/, ""] if requested_spec == :stable + replacement_pairs += formula_spec.mirrors.map do |mirror| + [/ +mirror \"#{mirror}\"\n/m, ""] + end replacement_pairs += if new_url_hash [ diff --git a/Library/Homebrew/dev-cmd/create.rb b/Library/Homebrew/dev-cmd/create.rb index f684f95f6..b4cda0fad 100644 --- a/Library/Homebrew/dev-cmd/create.rb +++ b/Library/Homebrew/dev-cmd/create.rb @@ -1,4 +1,4 @@ -#: * `create` <URL> [`--autotools`|`--cmake`] [`--no-fetch`] [`--set-name` <name>] [`--set-version` <version>] [`--tap` <user>`/`<repo>]: +#: * `create` <URL> [`--autotools`|`--cmake`|`--meson`] [`--no-fetch`] [`--set-name` <name>] [`--set-version` <version>] [`--tap` <user>`/`<repo>]: #: Generate a formula for the downloadable file at <URL> and open it in the editor. #: Homebrew will attempt to automatically derive the formula name #: and version, but if it fails, you'll have to make your own template. The `wget` @@ -8,6 +8,7 @@ #: #: If `--autotools` is passed, create a basic template for an Autotools-style build. #: If `--cmake` is passed, create a basic template for a CMake-style build. +#: If `--meson` is passed, create a basic template for a Meson-style build. #: #: If `--no-fetch` is passed, Homebrew will not download <URL> to the cache and #: will thus not add the SHA256 to the formula for you. @@ -59,6 +60,8 @@ module Homebrew :cmake elsif ARGV.include? "--autotools" :autotools + elsif ARGV.include? "--meson" + :meson end if fc.name.nil? || fc.name.strip.empty? @@ -139,12 +142,10 @@ class FormulaCreator def generate! raise "#{path} already exists" if path.exist? - if version.nil? + if version.nil? || version.null? opoo "Version cannot be determined from URL." puts "You'll need to add an explicit 'version' to the formula." - end - - if fetch? && version + elsif fetch? r = Resource.new r.url(url) r.version(version) @@ -156,7 +157,7 @@ class FormulaCreator end def template; <<-EOS.undent - # Documentation: https://github.com/Homebrew/brew/blob/master/docs/Formula-Cookbook.md + # Documentation: http://docs.brew.sh/Formula-Cookbook.html # http://www.rubydoc.info/github/Homebrew/brew/master/Formula # PLEASE REMOVE ALL GENERATED COMMENTS BEFORE SUBMITTING YOUR PULL REQUEST! @@ -175,10 +176,12 @@ class FormulaCreator <% if mode == :cmake %> depends_on "cmake" => :build + <% elsif mode == :meson %> + depends_on "meson" => :build + depends_on "ninja" => :build <% elsif mode.nil? %> # depends_on "cmake" => :build <% end %> - depends_on :x11 # if your formula requires any X11/XQuartz components def install # ENV.deparallelize # if your formula fails when building in parallel @@ -191,6 +194,13 @@ class FormulaCreator "--disable-dependency-tracking", "--disable-silent-rules", "--prefix=\#{prefix}" + <% elsif mode == :meson %> + mkdir "build" do + system "meson", "--prefix=\#{prefix}", ".." + system "ninja" + system "ninja", "test" + system "ninja", "install" + end <% else %> # Remove unrecognized options if warned by configure system "./configure", "--disable-debug", @@ -199,7 +209,9 @@ class FormulaCreator "--prefix=\#{prefix}" # system "cmake", ".", *std_cmake_args <% end %> + <% if mode != :meson %> system "make", "install" # if this fails, try separate make/make install steps + <% end %> end test do diff --git a/Library/Homebrew/dev-cmd/tests.rb b/Library/Homebrew/dev-cmd/tests.rb index b4f3c2d40..05bdda8d2 100644 --- a/Library/Homebrew/dev-cmd/tests.rb +++ b/Library/Homebrew/dev-cmd/tests.rb @@ -34,6 +34,7 @@ module Homebrew %w[AUTHOR COMMITTER].each do |role| ENV["GIT_#{role}_NAME"] = "brew tests" ENV["GIT_#{role}_EMAIL"] = "brew-tests@localhost" + ENV["GIT_#{role}_DATE"] = "Sun Jan 22 19:59:13 2017 +0000" end Homebrew.install_gem_setup_path! "bundler" diff --git a/Library/Homebrew/development_tools.rb b/Library/Homebrew/development_tools.rb index ea7f5837d..625d5ea86 100644 --- a/Library/Homebrew/development_tools.rb +++ b/Library/Homebrew/development_tools.rb @@ -34,15 +34,11 @@ class DevelopmentTools end def default_compiler - if default_cc =~ /^gcc/ - :gcc - else - :clang - end + :clang end - def gcc_40_build_version - @gcc_40_build_version ||= begin + def gcc_4_0_build_version + @gcc_4_0_build_version ||= begin if (path = locate("gcc-4.0")) && build_version = `#{path} --version 2>/dev/null`[/build (\d{4,})/, 1] Version.new build_version @@ -51,10 +47,9 @@ class DevelopmentTools end end end - alias gcc_4_0_build_version gcc_40_build_version - def gcc_42_build_version - @gcc_42_build_version ||= begin + def gcc_4_2_build_version + @gcc_4_2_build_version ||= begin gcc = locate("gcc-4.2") || HOMEBREW_PREFIX.join("opt/apple-gcc42/bin/gcc-4.2") if gcc.exist? && !gcc.realpath.basename.to_s.start_with?("llvm")&& build_version = `#{gcc} --version 2>/dev/null`[/build (\d{4,})/, 1] @@ -64,7 +59,6 @@ class DevelopmentTools end end end - alias gcc_build_version gcc_42_build_version def clang_version @clang_version ||= begin @@ -115,13 +109,13 @@ class DevelopmentTools end def clear_version_cache - @gcc_40_build_version = @gcc_42_build_version = nil + @gcc_4_0_build_version = @gcc_4_2_build_version = nil @clang_version = @clang_build_version = nil @non_apple_gcc_version = {} end - def tar_supports_xz? - false + def curl_handles_most_https_homepages? + true end end end diff --git a/Library/Homebrew/diagnostic.rb b/Library/Homebrew/diagnostic.rb index 81404c625..5ac57273a 100644 --- a/Library/Homebrew/diagnostic.rb +++ b/Library/Homebrew/diagnostic.rb @@ -1087,6 +1087,29 @@ module Homebrew message end + def check_for_tap_ruby_files_locations + bad_tap_files = {} + Tap.each do |tap| + unused_formula_dirs = tap.potential_formula_dirs - [tap.formula_dir] + unused_formula_dirs.each do |dir| + next unless dir.exist? + dir.children.each do |path| + next unless path.extname == ".rb" + bad_tap_files[tap] ||= [] + bad_tap_files[tap] << path + end + end + end + return if bad_tap_files.empty? + bad_tap_files.keys.map do |tap| + <<-EOS.undent + Found Ruby file outside #{tap} tap formula directory + (#{tap.formula_dir}): + #{bad_tap_files[tap].join("\n ")} + EOS + end.join("\n") + end + def all methods.map(&:to_s).grep(/^check_/) end diff --git a/Library/Homebrew/download_strategy.rb b/Library/Homebrew/download_strategy.rb index 9f9b2abab..bd036067d 100644 --- a/Library/Homebrew/download_strategy.rb +++ b/Library/Homebrew/download_strategy.rb @@ -532,6 +532,110 @@ class S3DownloadStrategy < CurlDownloadStrategy end end +# GitHubPrivateRepositoryDownloadStrategy downloads contents from GitHub +# Private Repository. To use it, add +# ":using => GitHubPrivateRepositoryDownloadStrategy" to the URL section of +# your formula. This download strategy uses GitHub access tokens (in the +# environment variables HOMEBREW_GITHUB_API_TOKEN) to sign the request. This +# strategy is suitable for corporate use just like S3DownloadStrategy, because +# it lets you use a private GttHub repository for internal distribution. It +# works with public one, but in that case simply use CurlDownloadStrategy. +class GitHubPrivateRepositoryDownloadStrategy < CurlDownloadStrategy + require "utils/formatter" + require "utils/github" + + def initialize(name, resource) + super + parse_url_pattern + set_github_token + end + + def parse_url_pattern + url_pattern = %r{https://github.com/([^/]+)/([^/]+)/(\S+)} + unless @url =~ url_pattern + raise CurlDownloadStrategyError, "Invalid url pattern for GitHub Repository." + end + + _, @owner, @repo, @filepath = *@url.match(url_pattern) + end + + def download_url + "https://#{@github_token}@github.com/#{@owner}/#{@repo}/#{@filepath}" + end + + def _fetch + curl download_url, "-C", downloaded_size, "-o", temporary_path + end + + private + + def set_github_token + @github_token = ENV["HOMEBREW_GITHUB_API_TOKEN"] + unless @github_token + raise CurlDownloadStrategyError, "Environmental variable HOMEBREW_GITHUB_API_TOKEN is required." + end + validate_github_repository_access! + end + + def validate_github_repository_access! + # Test access to the repository + GitHub.repository(@owner, @repo) + rescue GitHub::HTTPNotFoundError + # We only handle HTTPNotFoundError here, + # becase AuthenticationFailedError is handled within util/github. + message = <<-EOS.undent + HOMEBREW_GITHUB_API_TOKEN can not access the repository: #{@owner}/#{@repo} + This token may not have permission to access the repository or the url of formula may be incorrect. + EOS + raise CurlDownloadStrategyError, message + end +end + +# GitHubPrivateRepositoryReleaseDownloadStrategy downloads tarballs from GitHub +# Release assets. To use it, add +# ":using => GitHubPrivateRepositoryReleaseDownloadStrategy" to the URL section +# of your formula. This download strategy uses GitHub access tokens (in the +# environment variables HOMEBREW_GITHUB_API_TOKEN) to sign the request. +class GitHubPrivateRepositoryReleaseDownloadStrategy < GitHubPrivateRepositoryDownloadStrategy + def parse_url_pattern + url_pattern = %r{https://github.com/([^/]+)/([^/]+)/releases/download/([^/]+)/(\S+)} + unless @url =~ url_pattern + raise CurlDownloadStrategyError, "Invalid url pattern for GitHub Release." + end + + _, @owner, @repo, @tag, @filename = *@url.match(url_pattern) + end + + def download_url + "https://#{@github_token}@api.github.com/repos/#{@owner}/#{@repo}/releases/assets/#{asset_id}" + end + + def _fetch + # HTTP request header `Accept: application/octet-stream` is required. + # Without this, the GitHub API will respond with metadata, not binary. + curl download_url, "-C", downloaded_size, "-o", temporary_path, "-H", "Accept: application/octet-stream" + end + + private + + def asset_id + @asset_id ||= resolve_asset_id + end + + def resolve_asset_id + release_metadata = fetch_release_metadata + assets = release_metadata["assets"].select { |a| a["name"] == @filename } + raise CurlDownloadStrategyError, "Asset file not found." if assets.empty? + + assets.first["id"] + end + + def fetch_release_metadata + release_url = "https://api.github.com/repos/#{@owner}/#{@repo}/releases/tags/#{@tag}" + GitHub.open(release_url) + end +end + class SubversionDownloadStrategy < VCSDownloadStrategy def initialize(name, resource) super diff --git a/Library/Homebrew/emoji.rb b/Library/Homebrew/emoji.rb index 8c58ca895..43fa781e6 100644 --- a/Library/Homebrew/emoji.rb +++ b/Library/Homebrew/emoji.rb @@ -1,17 +1,7 @@ module Emoji class << self - def tick - # necessary for 1.8.7 unicode handling since many installs are on 1.8.7 - @tick ||= ["2714".hex].pack("U*") - end - - def cross - # necessary for 1.8.7 unicode handling since many installs are on 1.8.7 - @cross ||= ["2718".hex].pack("U*") - end - def install_badge - ENV["HOMEBREW_INSTALL_BADGE"] || "\xf0\x9f\x8d\xba" + ENV["HOMEBREW_INSTALL_BADGE"] || "🍺" end def enabled? diff --git a/Library/Homebrew/extend/ARGV.rb b/Library/Homebrew/extend/ARGV.rb index d361a99a8..767ddc6e3 100644 --- a/Library/Homebrew/extend/ARGV.rb +++ b/Library/Homebrew/extend/ARGV.rb @@ -44,7 +44,7 @@ module HomebrewArgvExtension else Formulary.find_with_priority(name, spec) end - end + end.uniq(&:name) end def resolved_formulae @@ -79,7 +79,7 @@ module HomebrewArgvExtension f.follow_installed_alias = false f - end + end.uniq(&:name) end def casks diff --git a/Library/Homebrew/extend/ENV/shared.rb b/Library/Homebrew/extend/ENV/shared.rb index a93c1ee1f..7b468574a 100644 --- a/Library/Homebrew/extend/ENV/shared.rb +++ b/Library/Homebrew/extend/ENV/shared.rb @@ -17,7 +17,7 @@ module SharedEnvExtension FC_FLAG_VARS = %w[FCFLAGS FFLAGS].freeze # @private SANITIZED_VARS = %w[ - CDPATH GREP_OPTIONS CLICOLOR_FORCE + CDPATH CLICOLOR_FORCE CPATH C_INCLUDE_PATH CPLUS_INCLUDE_PATH OBJC_INCLUDE_PATH CC CXX OBJC OBJCXX CPP MAKE LD LDSHARED CFLAGS CXXFLAGS OBJCFLAGS OBJCXXFLAGS LDFLAGS CPPFLAGS diff --git a/Library/Homebrew/extend/ENV/std.rb b/Library/Homebrew/extend/ENV/std.rb index 14f9b81b8..403ea1978 100644 --- a/Library/Homebrew/extend/ENV/std.rb +++ b/Library/Homebrew/extend/ENV/std.rb @@ -82,10 +82,6 @@ module Stdenv old end - alias j1 deparallelize - - # These methods are no-ops for compatibility. - %w[fast O4 Og].each { |opt| define_method(opt) {} } %w[O3 O2 O1 O0 Os].each do |opt| define_method opt do @@ -110,13 +106,11 @@ module Stdenv super set_cpu_cflags "-march=nocona -mssse3" end - alias gcc_4_0_1 gcc_4_0 - def gcc + def gcc_4_2 super set_cpu_cflags end - alias gcc_4_2 gcc GNU_GCC_VERSIONS.each do |n| define_method(:"gcc-#{n}") do @@ -144,13 +138,6 @@ module Stdenv end alias generic_no_optimization no_optimization - def libxml2 - end - - def x11 - end - alias libpng x11 - # we've seen some packages fail to build when warnings are disabled! def enable_warnings remove_from_cflags "-w" diff --git a/Library/Homebrew/extend/ENV/super.rb b/Library/Homebrew/extend/ENV/super.rb index a75cba406..39ddb6681 100644 --- a/Library/Homebrew/extend/ENV/super.rb +++ b/Library/Homebrew/extend/ENV/super.rb @@ -16,9 +16,7 @@ module Superenv # @private attr_accessor :keg_only_deps, :deps - attr_accessor :x11 - alias x11? x11 def self.extended(base) base.keg_only_deps = [] @@ -263,7 +261,6 @@ module Superenv old end - alias j1 deparallelize def make_jobs self["MAKEFLAGS"] =~ /-\w*j(\d+)/ @@ -329,23 +326,10 @@ module Superenv def set_x11_env_if_installed end + # This method does nothing in superenv since there's no custom CFLAGS API # @private - def noop(*_args); end - - # These methods are no longer necessary under superenv, but are needed to - # maintain an interface compatible with stdenv. - alias fast noop - alias O4 noop - alias Og noop - alias libxml2 noop - alias set_cpu_flags noop - - # These methods provide functionality that has not yet been ported to - # superenv. - alias gcc_4_0_1 noop - alias minimal_optimization noop - alias no_optimization noop - alias enable_warnings noop + def set_cpu_flags(*_args) + end end class Array diff --git a/Library/Homebrew/extend/fileutils.rb b/Library/Homebrew/extend/fileutils.rb index 4f20d36a3..287a1408f 100644 --- a/Library/Homebrew/extend/fileutils.rb +++ b/Library/Homebrew/extend/fileutils.rb @@ -3,7 +3,7 @@ require "tmpdir" require "etc" # Homebrew extends Ruby's `FileUtils` to make our code more readable. -# @see http://ruby-doc.org/stdlib-1.8.7/libdoc/fileutils/rdoc/FileUtils.html Ruby's FileUtils API +# @see http://ruby-doc.org/stdlib-2.0.0/libdoc/fileutils/rdoc/FileUtils.html Ruby's FileUtils API module FileUtils # Create a temporary directory then yield. When the block returns, # recursively delete the temporary directory. Passing opts[:retain] diff --git a/Library/Homebrew/extend/os/linux/hardware/cpu.rb b/Library/Homebrew/extend/os/linux/hardware/cpu.rb index 2472c60ed..9d779f789 100644 --- a/Library/Homebrew/extend/os/linux/hardware/cpu.rb +++ b/Library/Homebrew/extend/os/linux/hardware/cpu.rb @@ -47,6 +47,8 @@ module Hardware :haswell when 0x3d, 0x47, 0x4f, 0x56 :broadwell + when 0x8e + :kabylake else cpu_family_model end diff --git a/Library/Homebrew/extend/os/mac/development_tools.rb b/Library/Homebrew/extend/os/mac/development_tools.rb index 7c97b9d69..1bb12a3d1 100644 --- a/Library/Homebrew/extend/os/mac/development_tools.rb +++ b/Library/Homebrew/extend/os/mac/development_tools.rb @@ -64,21 +64,22 @@ class DevelopmentTools case default_cc # if GCC 4.2 is installed, e.g. via Tigerbrew, prefer it # over the system's GCC 4.0 - when /^gcc-4\.0/ then gcc_42_build_version ? :gcc : :gcc_4_0 - when /^gcc/ then :gcc + when /^gcc-4\.0/ then gcc_4_2_build_version ? :gcc_4_2 : :gcc_4_0 + when /^gcc/ then :gcc_4_2 when "clang" then :clang else # guess :( if MacOS::Xcode.version >= "4.3" :clang else - :gcc + :gcc_4_2 end end end - def tar_supports_xz? - false + def curl_handles_most_https_homepages? + # The system Curl is too old for some modern HTTPS homepages on Yosemite. + MacOS.version >= :el_capitan end end end diff --git a/Library/Homebrew/extend/os/mac/extend/ENV/super.rb b/Library/Homebrew/extend/os/mac/extend/ENV/super.rb index 5f4a3e4aa..f97a2dbbb 100644 --- a/Library/Homebrew/extend/os/mac/extend/ENV/super.rb +++ b/Library/Homebrew/extend/os/mac/extend/ENV/super.rb @@ -1,4 +1,6 @@ module Superenv + alias x11? x11 + # @private def self.bin return unless DevelopmentTools.installed? @@ -120,9 +122,4 @@ module Superenv def no_weak_imports append "HOMEBREW_CCCFG", "w" if no_weak_imports_support? end - - # These methods are no longer necessary under superenv, but are needed to - # maintain an interface compatible with stdenv. - alias macosxsdk noop - alias remove_macosxsdk noop end diff --git a/Library/Homebrew/extend/os/mac/formula_cellar_checks.rb b/Library/Homebrew/extend/os/mac/formula_cellar_checks.rb index 8bc42ad35..5b1c648bf 100644 --- a/Library/Homebrew/extend/os/mac/formula_cellar_checks.rb +++ b/Library/Homebrew/extend/os/mac/formula_cellar_checks.rb @@ -6,6 +6,8 @@ module FormulaCellarChecks formula.name.start_with?(formula_name) end + return if formula.name =~ /^php\d+$/ + return if MacOS.version < :mavericks && formula.name.start_with?("postgresql") return if MacOS.version < :yosemite && formula.name.start_with?("memcached") diff --git a/Library/Homebrew/extend/os/mac/keg_relocate.rb b/Library/Homebrew/extend/os/mac/keg_relocate.rb index 8f73daba5..f44a97b31 100644 --- a/Library/Homebrew/extend/os/mac/keg_relocate.rb +++ b/Library/Homebrew/extend/os/mac/keg_relocate.rb @@ -6,7 +6,9 @@ class Keg each_install_name_for(file) do |bad_name| # Don't fix absolute paths unless they are rooted in the build directory - next if bad_name.start_with?("/") && !bad_name.start_with?(HOMEBREW_TEMP.to_s) + next if bad_name.start_with?("/") && + !bad_name.start_with?(HOMEBREW_TEMP.to_s) && + !bad_name.start_with?(HOMEBREW_TEMP.realpath.to_s) new_name = fixed_name(file, bad_name) change_install_name(bad_name, new_name, file) unless new_name == bad_name diff --git a/Library/Homebrew/extend/os/mac/utils/bottles.rb b/Library/Homebrew/extend/os/mac/utils/bottles.rb index 18312c9fa..c54e4e5b7 100644 --- a/Library/Homebrew/extend/os/mac/utils/bottles.rb +++ b/Library/Homebrew/extend/os/mac/utils/bottles.rb @@ -49,6 +49,8 @@ module Utils if key.to_s.end_with?("_or_later") later_tag = key.to_s[/(\w+)_or_later$/, 1].to_sym MacOS::Version.from_symbol(later_tag) <= tag_version + elsif ARGV.force_bottle? + true end end end diff --git a/Library/Homebrew/extend/pathname.rb b/Library/Homebrew/extend/pathname.rb index 976ea7dd8..cfb028704 100644 --- a/Library/Homebrew/extend/pathname.rb +++ b/Library/Homebrew/extend/pathname.rb @@ -26,11 +26,17 @@ module DiskUsageExtension private def compute_disk_usage - if directory? + path = if symlink? + resolved_path + else + self + end + + if path.directory? scanned_files = Set.new @file_count = 0 @disk_usage = 0 - find do |f| + path.find do |f| if f.directory? @disk_usage += f.lstat.size else @@ -47,7 +53,7 @@ module DiskUsageExtension end else @file_count = 1 - @disk_usage = lstat.size + @disk_usage = path.lstat.size end end end diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index b3927d260..6df1eb4de 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -26,7 +26,7 @@ require "migrator" # @see SharedEnvExtension # @see FileUtils # @see Pathname -# @see https://github.com/Homebrew/brew/blob/master/docs/Formula-Cookbook.md Formula Cookbook +# @see http://docs.brew.sh/Formula-Cookbook.html Formula Cookbook # @see https://github.com/styleguide/ruby Ruby Style Guide # # <pre>class Wget < Formula @@ -198,6 +198,7 @@ class Formula @build = active_spec.build @pin = FormulaPin.new(self) @follow_installed_alias = true + @prefix_returns_versioned_prefix = false end # @private @@ -325,13 +326,13 @@ class Formula active_spec.bottle_disable_reason end - # Does the currently active {SoftwareSpec} has any bottle? + # Does the currently active {SoftwareSpec} have any bottle? # @private def bottle_defined? active_spec.bottle_defined? end - # Does the currently active {SoftwareSpec} has an installable bottle? + # Does the currently active {SoftwareSpec} have an installable bottle? # @private def bottled? active_spec.bottled? @@ -381,6 +382,11 @@ class Formula PkgVersion.new(version, revision) end + # If this is a `@`-versioned formula. + def versioned_formula? + name.include?("@") + end + # A named Resource for the currently active {SoftwareSpec}. # Additional downloads can be defined as {#resource}s. # {Resource#stage} will create a temporary directory and yield to a block. @@ -548,9 +554,17 @@ class Formula end # The directory in the cellar that the formula is installed to. - # This directory contains the formula's name and version. + # This directory points to {#opt_prefix} if it exists and if #{prefix} is not + # called from within the same formula's {#install} or {#post_install} methods. + # Otherwise, return the full path to the formula's versioned cellar. def prefix(v = pkg_version) - Pathname.new("#{HOMEBREW_CELLAR}/#{name}/#{v}") + versioned_prefix = versioned_prefix(v) + if !@prefix_returns_versioned_prefix && v == pkg_version && + versioned_prefix.directory? && Keg.new(versioned_prefix).optlinked? + opt_prefix + else + versioned_prefix + end end # Is the formula linked? @@ -566,7 +580,7 @@ class Formula # 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) + linked_keg.resolved_path == versioned_prefix(v) end # {PkgVersion} of the linked keg for the formula. @@ -579,7 +593,7 @@ class Formula # installed versions of this software # @private def rack - prefix.parent + Pathname.new("#{HOMEBREW_CELLAR}/#{name}") end # All currently installed prefix directories. @@ -994,6 +1008,7 @@ class Formula # @private def run_post_install + @prefix_returns_versioned_prefix = true build = self.build self.build = Tab.for_formula(self) old_tmpdir = ENV["TMPDIR"] @@ -1008,6 +1023,7 @@ class Formula ENV["TMPDIR"] = old_tmpdir ENV["TEMP"] = old_temp ENV["TMP"] = old_tmp + @prefix_returns_versioned_prefix = false end # Tell the user about any caveats regarding this package. @@ -1110,6 +1126,7 @@ class Formula # where staging is a Mktemp staging context # @private def brew + @prefix_returns_versioned_prefix = true stage do |staging| staging.retain! if ARGV.keep_tmp? prepare_patches @@ -1123,6 +1140,8 @@ class Formula cp Dir["config.log", "CMakeCache.txt"], logs end end + ensure + @prefix_returns_versioned_prefix = false end # @private @@ -1406,7 +1425,7 @@ class Formula Formulary.from_rack(rack) rescue FormulaUnavailableError, TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError end - end.compact + end.compact.uniq(&:name) end def self.installed_with_alias_path(alias_path) @@ -1505,7 +1524,15 @@ class Formula # Returns a list of Dependency objects that are required at runtime. # @private def runtime_dependencies - recursive_dependencies.reject(&:build?) + runtime_dependencies = recursive_dependencies do |_, dependency| + Dependency.prune if dependency.build? + Dependency.prune if !dependency.required? && build.without?(dependency) + end + runtime_requirement_deps = recursive_requirements do |_, requirement| + Requirement.prune if requirement.build? + Requirement.prune if !requirement.required? && build.without?(requirement) + end.map(&:to_dependency).compact + runtime_dependencies + runtime_requirement_deps end # Returns a list of formulae depended on by this formula that aren't @@ -1601,6 +1628,9 @@ class Formula "used_options" => tab.used_options.as_flags, "built_as_bottle" => tab.built_as_bottle, "poured_from_bottle" => tab.poured_from_bottle, + "runtime_dependencies" => tab.runtime_dependencies, + "installed_as_dependency" => tab.installed_as_dependency, + "installed_on_request" => tab.installed_on_request, } end @@ -1621,6 +1651,7 @@ class Formula # @private def run_test + @prefix_returns_versioned_prefix = true old_home = ENV["HOME"] old_curl_home = ENV["CURL_HOME"] old_tmpdir = ENV["TMPDIR"] @@ -1652,6 +1683,7 @@ class Formula ENV["TEMP"] = old_temp ENV["TMP"] = old_tmp ENV["TERM"] = old_term + @prefix_returns_versioned_prefix = false end # @private @@ -1836,6 +1868,12 @@ class Formula private + # Returns the prefix for a given formula version number. + # @private + def versioned_prefix(v) + rack/v + end + def exec_cmd(cmd, args, out, logfn) ENV["HOMEBREW_CC_LOG_PATH"] = logfn @@ -2041,7 +2079,7 @@ class Formula # and you haven't passed or previously used any options on this formula. # # If you maintain your own repository, you can add your own bottle links. - # https://github.com/Homebrew/brew/blob/master/docs/Bottles.md + # http://docs.brew.sh/Bottles.html # You can ignore this block entirely if submitting to Homebrew/Homebrew, It'll be # handled for you by the Brew Test Bot. # diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index bd1cc9379..e8f0e4bf8 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -32,6 +32,7 @@ class FormulaInstaller attr_reader :formula attr_accessor :options, :build_bottle, :invalid_option_names + attr_accessor :installed_as_dependency, :installed_on_request mode_attr_accessor :show_summary_heading, :show_header mode_attr_accessor :build_from_source, :force_bottle mode_attr_accessor :ignore_deps, :only_deps, :interactive, :git @@ -50,6 +51,8 @@ class FormulaInstaller @verbose = false @quieter = false @debug = false + @installed_as_dependency = false + @installed_on_request = true @options = Options.new @invalid_option_names = [] @requirement_messages = [] @@ -146,7 +149,29 @@ class FormulaInstaller return if ignore_deps? recursive_deps = formula.recursive_dependencies - unlinked_deps = recursive_deps.map(&:to_formula).select do |dep| + recursive_formulae = recursive_deps.map(&:to_formula) + + if ENV["HOMEBREW_CHECK_RECURSIVE_VERSION_DEPENDENCIES"] + version_hash = {} + version_conflicts = Set.new + recursive_formulae.each do |f| + name = f.name + unversioned_name, = name.split("@") + version_hash[unversioned_name] ||= Set.new + version_hash[unversioned_name] << name + next if version_hash[unversioned_name].length < 2 + version_conflicts += version_hash[unversioned_name] + end + unless version_conflicts.empty? + raise CannotInstallFormulaError, <<-EOS.undent + #{formula.full_name} contains conflicting version recursive dependencies: + #{version_conflicts.to_a.join ", "} + View these with `brew deps --tree #{formula.full_name}`. + EOS + end + end + + unlinked_deps = recursive_formulae.select do |dep| dep.installed? && !dep.keg_only? && !dep.linked_keg.directory? end @@ -228,6 +253,12 @@ class FormulaInstaller category = "install" action = ([formula.full_name] + options).join(" ") Utils::Analytics.report_event(category, action) + + if installed_on_request + category = "install_on_request" + action = ([formula.full_name] + options).join(" ") + Utils::Analytics.report_event(category, action) + end end @@attempted << formula @@ -265,6 +296,12 @@ class FormulaInstaller brew_prefix = formula.prefix/".brew" brew_prefix.mkdir Pathname(brew_prefix/"#{formula.name}.rb").atomic_write(s) + + keg = Keg.new(formula.prefix) + tab = Tab.for_keg(keg) + tab.installed_as_dependency = installed_as_dependency + tab.installed_on_request = installed_on_request + tab.write end build_bottle_postinstall if build_bottle? @@ -348,8 +385,8 @@ class FormulaInstaller raise UnsatisfiedRequirements, fatals end - def install_requirement_default_formula?(req, dependent, build) - return false unless req.default_formula? + def install_requirement_formula?(req, dependent, build) + return false unless req.to_dependency return true unless req.satisfied? return false if req.run? install_bottle_for?(dependent, build) || build_bottle? @@ -368,7 +405,7 @@ class FormulaInstaller Requirement.prune elsif req.build? && install_bottle_for?(dependent, build) Requirement.prune - elsif install_requirement_default_formula?(req, dependent, build) + elsif install_requirement_formula?(req, dependent, build) dep = req.to_dependency deps.unshift(dep) formulae.unshift(dep.to_formula) @@ -461,6 +498,8 @@ class FormulaInstaller fi.build_from_source = ARGV.build_formula_from_source?(df) fi.verbose = verbose? && !quieter? fi.debug = debug? + fi.installed_as_dependency = true + fi.installed_on_request = false fi.prelude oh1 "Installing #{formula.full_name} dependency: #{Formatter.identifier(dep.name)}" fi.install @@ -524,7 +563,7 @@ class FormulaInstaller def summary s = "" s << "#{Emoji.install_badge} " if Emoji.enabled? - s << "#{formula.prefix}: #{formula.prefix.abv}" + s << "#{formula.prefix.resolved_path}: #{formula.prefix.abv}" s << ", built in #{pretty_duration build_time}" if build_time s end @@ -786,6 +825,9 @@ class FormulaInstaller tab.poured_from_bottle = true tab.time = Time.now.to_i tab.head = HOMEBREW_REPOSITORY.git_head + tab.source["path"] = formula.specified_path.to_s + tab.installed_as_dependency = installed_as_dependency + tab.installed_on_request = installed_on_request tab.write end diff --git a/Library/Homebrew/formula_support.rb b/Library/Homebrew/formula_support.rb index e4f800364..dcb995a6b 100644 --- a/Library/Homebrew/formula_support.rb +++ b/Library/Homebrew/formula_support.rb @@ -29,27 +29,32 @@ class KegOnlyReason def to_s return @explanation unless @explanation.empty? case @reason - when :provided_by_macos, :provided_by_osx then <<-EOS -macOS already provides this software and installing another version in -parallel can cause all kinds of trouble. -EOS - when :shadowed_by_macos, :shadowed_by_osx then <<-EOS -macOS provides similar software and installing this software in -parallel can cause all kinds of trouble. -EOS - when :provided_pre_mountain_lion then <<-EOS -macOS already provides this software in versions before Mountain Lion. -EOS - when :provided_pre_mavericks then <<-EOS -macOS already provides this software in versions before Mavericks. -EOS - when :provided_pre_el_capitan then <<-EOS -macOS already provides this software in versions before El Capitan. -EOS - when :provided_until_xcode43 - "Xcode provides this software prior to version 4.3." - when :provided_until_xcode5 - "Xcode provides this software prior to version 5." + when :versioned_formula then <<-EOS.undent + This is an alternate version of another formula. + EOS + when :provided_by_macos, :provided_by_osx then <<-EOS.undent + macOS already provides this software and installing another version in + parallel can cause all kinds of trouble. + EOS + when :shadowed_by_macos, :shadowed_by_osx then <<-EOS.undent + macOS provides similar software and installing this software in + parallel can cause all kinds of trouble. + EOS + when :provided_pre_mountain_lion then <<-EOS.undent + macOS already provides this software in versions before Mountain Lion. + EOS + when :provided_pre_mavericks then <<-EOS.undent + macOS already provides this software in versions before Mavericks. + EOS + when :provided_pre_el_capitan then <<-EOS.undent + macOS already provides this software in versions before El Capitan. + EOS + when :provided_until_xcode43 then <<-EOS.undent + Xcode provides this software prior to version 4.3. + EOS + when :provided_until_xcode5 then <<-EOS.undent + Xcode provides this software prior to version 5. + EOS else @reason end.strip diff --git a/Library/Homebrew/formula_versions.rb b/Library/Homebrew/formula_versions.rb index 28c2a3be8..34b766fde 100644 --- a/Library/Homebrew/formula_versions.rb +++ b/Library/Homebrew/formula_versions.rb @@ -15,6 +15,7 @@ class FormulaVersions @repository = formula.tap.path @entry_name = @path.relative_path_from(repository).to_s @max_depth = options[:max_depth] + @current_formula = formula end def rev_list(branch) @@ -64,25 +65,33 @@ class FormulaVersions attributes.each do |attribute| attributes_map[attribute] ||= {} + # Set the attributes for the current formula in case it's not been + # committed yet. + set_attribute_map(attributes_map[attribute], @current_formula, attribute) end rev_list(branch) do |rev| formula_at_revision(rev) do |f| attributes.each do |attribute| - map = attributes_map[attribute] - if f.stable - map[:stable] ||= {} - map[:stable][f.stable.version] ||= [] - map[:stable][f.stable.version] << f.send(attribute) - end - next unless f.devel - map[:devel] ||= {} - map[:devel][f.devel.version] ||= [] - map[:devel][f.devel.version] << f.send(attribute) + set_attribute_map(attributes_map[attribute], f, attribute) end end end attributes_map end + + private + + def set_attribute_map(map, f, attribute) + if f.stable + map[:stable] ||= {} + map[:stable][f.stable.version] ||= [] + map[:stable][f.stable.version] << f.send(attribute) + end + return unless f.devel + map[:devel] ||= {} + map[:devel][f.devel.version] ||= [] + map[:devel][f.devel.version] << f.send(attribute) + end end diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb index 90e0dc2d4..25df57cdc 100644 --- a/Library/Homebrew/formulary.rb +++ b/Library/Homebrew/formulary.rb @@ -186,6 +186,8 @@ class Formulary name = new_name new_name = @tap.core_tap? ? name : "#{@tap}/#{name}" elsif (new_tap_name = @tap.tap_migrations[name]) + new_tap_user, new_tap_repo, = new_tap_name.split("/") + new_tap_name = "#{new_tap_user}/#{new_tap_repo}" new_tap = Tap.fetch new_tap_name new_tap.install unless new_tap.installed? new_tapped_name = "#{new_tap_name}/#{name}" @@ -333,7 +335,9 @@ class Formulary return TapLoader.new(ref, from: from) end - return FromPathLoader.new(ref) if File.extname(ref) == ".rb" + if File.extname(ref) == ".rb" && Pathname.new(ref).expand_path.exist? + return FromPathLoader.new(ref) + end formula_with_that_name = core_path(ref) if formula_with_that_name.file? @@ -376,6 +380,11 @@ class Formulary return TapLoader.new(possible_tap_newname_formulae.first, from: from) end + possible_keg_formula = Pathname.new("#{HOMEBREW_PREFIX}/opt/#{ref}/.brew/#{ref}.rb") + if possible_keg_formula.file? + return FormulaLoader.new(ref, possible_keg_formula) + end + possible_cached_formula = Pathname.new("#{HOMEBREW_CACHE_FORMULA}/#{ref}.rb") if possible_cached_formula.file? return FormulaLoader.new(ref, possible_cached_formula) diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb index eabc4c164..031178421 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -26,14 +26,7 @@ RUBY_BIN = RUBY_PATH.dirname HOMEBREW_USER_AGENT_CURL = ENV["HOMEBREW_USER_AGENT_CURL"] HOMEBREW_USER_AGENT_RUBY = "#{ENV["HOMEBREW_USER_AGENT"]} ruby/#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}".freeze - -HOMEBREW_CURL_ARGS = [ - "--fail", - "--progress-bar", - "--remote-time", - "--location", - "--user-agent", HOMEBREW_USER_AGENT_CURL -].freeze +HOMEBREW_USER_AGENT_FAKE_SAFARI = "Mozilla/5.0 (#{ENV["HOMEBREW_SYSTEM"]}; #{ENV["HOMEBREW_PROCESSOR"]} #{ENV["HOMEBREW_OS_VERSION"]}) AppleWebKit/602.3.12 (KHTML, like Gecko) Version/10.0.2 Safari/602.3.12".freeze require "tap_constants" diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb index 1de4ce1f0..837968615 100644 --- a/Library/Homebrew/keg.rb +++ b/Library/Homebrew/keg.rb @@ -87,11 +87,23 @@ class Keg mime-info pixmaps sounds postgresql ].freeze - # Will return some kegs, and some dependencies, if they're present. + # Given an array of kegs, this method will try to find some other kegs + # that depend on them. + # + # If it does, it returns: + # - some kegs in the passed array that have installed dependents + # - some installed dependents of those kegs. + # + # If it doesn't, it returns nil. + # + # Note that nil will be returned if the only installed dependents + # in the passed kegs are other kegs in the array. + # # For efficiency, we don't bother trying to get complete data. def self.find_some_installed_dependents(kegs) # First, check in the tabs of installed Formulae. kegs.each do |keg| + # Don't include dependencies of kegs that were in the given array. dependents = keg.installed_dependents - kegs dependents.map! { |d| "#{d.name} #{d.version}" } return [keg], dependents if dependents.any? @@ -105,11 +117,27 @@ class Keg # # This happens after the initial dependency check because it's sloooow. remaining_formulae = Formula.installed.select do |f| - f.installed_kegs.any? { |k| Tab.for_keg(k).runtime_dependencies.nil? } + installed_kegs = f.installed_kegs + + # Don't include dependencies of kegs that were in the given array. + next false if (installed_kegs - kegs).empty? + + installed_kegs.any? { |k| Tab.for_keg(k).runtime_dependencies.nil? } end keg_names = kegs.map(&:name) - kegs_by_source = kegs.group_by { |k| [k.name, Tab.for_keg(k).tap] } + kegs_by_source = kegs.group_by do |keg| + begin + # First, attempt to resolve the keg to a formula + # to get up-to-date name and tap information. + f = keg.to_formula + [f.name, f.tap] + rescue FormulaUnavailableError + # If the formula for the keg can't be found, + # fall back to the information in the tab. + [keg.name, Tab.for_keg(keg).tap] + end + end remaining_formulae.each do |dependent| required = dependent.missing_dependencies(hide: keg_names) @@ -119,7 +147,7 @@ class Keg next unless f_kegs f_kegs.sort_by(&:version).last - end + end.compact next unless required_kegs.any? @@ -139,10 +167,21 @@ class Keg raise NotAKegError, "#{path} is not inside a keg" end + def self.all + Formula.racks.flat_map(&:subdirs).map { |d| new(d) } + end + attr_reader :path, :name, :linked_keg_record, :opt_record protected :path + extend Forwardable + + def_delegators :path, + :to_s, :hash, :abv, :disk_usage, :file_count, :directory?, :exist?, :/, + :join, :rename, :find + def initialize(path) + path = path.resolved_path if path.to_s.start_with?("#{HOMEBREW_PREFIX}/opt/") raise "#{path} is not a valid keg" unless path.parent.parent.realpath == HOMEBREW_CELLAR.realpath raise "#{path} is not a directory" unless path.directory? @path = path @@ -151,19 +190,11 @@ class Keg @opt_record = HOMEBREW_PREFIX/"opt/#{name}" end - def to_s - path.to_s - end - def rack path.parent end - if Pathname.method_defined?(:to_path) - alias to_path to_s - else - alias to_str to_s - end + alias to_path to_s def inspect "#<#{self.class.name}:#{path}>" @@ -174,30 +205,6 @@ class Keg end alias eql? == - def hash - path.hash - end - - def abv - path.abv - end - - def disk_usage - path.disk_usage - end - - def file_count - path.file_count - end - - def directory? - path.directory? - end - - def exist? - path.exist? - end - def empty_installation? Pathname.glob("#{path}/**/*") do |file| next if file.directory? @@ -210,18 +217,6 @@ class Keg true end - def /(other) - path / other - end - - def join(*args) - path.join(*args) - end - - def rename(*args) - path.rename(*args) - end - def linked? linked_keg_record.symlink? && linked_keg_record.directory? && @@ -334,10 +329,6 @@ class Keg Pathname.glob("#{app_prefix}/{,libexec/}*.app") end - def app_installed? - !apps.empty? - end - def elisp_installed? return false unless (path/"share/emacs/site-lisp"/name).exist? (path/"share/emacs/site-lisp"/name).children.any? { |f| %w[.el .elc].include? f.extname } @@ -353,22 +344,24 @@ class Keg end def installed_dependents - Formula.installed.flat_map(&:installed_kegs).select do |keg| + return [] unless optlinked? + tap = Tab.for_keg(self).source["tap"] + Keg.all.select do |keg| tab = Tab.for_keg(keg) - next if tab.runtime_dependencies.nil? # no dependency information saved. + next if tab.runtime_dependencies.nil? tab.runtime_dependencies.any? do |dep| # Resolve formula rather than directly comparing names # in case of conflicts between formulae from different taps. - dep_formula = Formulary.factory(dep["full_name"]) - dep_formula == to_formula && dep["version"] == version.to_s + begin + dep_formula = Formulary.factory(dep["full_name"]) + dep_formula == to_formula + rescue FormulaUnavailableError + next "#{tap}/#{name}" == dep["full_name"] + end end end end - def find(*args, &block) - path.find(*args, &block) - end - def oldname_opt_record @oldname_opt_record ||= if (opt_dir = HOMEBREW_PREFIX/"opt").directory? opt_dir.subdirs.detect do |dir| @@ -559,7 +552,7 @@ class Keg if src.symlink? || src.file? Find.prune if File.basename(src) == ".DS_Store" - Find.prune if src.realpath == dst + Find.prune if src.resolved_path == dst # Don't link pyc or pyo files because Python overwrites these # cached object files and next time brew wants to link, the # file is in the way. diff --git a/Library/Homebrew/manpages/brew-cask.1.md b/Library/Homebrew/manpages/brew-cask.1.md index feab9f76e..a2c9c8c16 100644 --- a/Library/Homebrew/manpages/brew-cask.1.md +++ b/Library/Homebrew/manpages/brew-cask.1.md @@ -104,9 +104,6 @@ names, and other aspects of this manual are still subject to change. Uninstall the given Cask. With `--force`, uninstall even if the Cask does not appear to be present. - * `update`: - For convenience. `brew cask update` is a synonym for `brew update`. - * `zap` <token> [ <token> ... ]: Unconditionally remove _all_ files associated with the given Cask. @@ -123,6 +120,13 @@ names, and other aspects of this manual are still subject to change. **`zap` may remove files which are shared between applications.** +## INTERNAL COMMANDS + + * `_appcast_checkpoint` [--calculate] [ <token> ... | <URL> ... ]: + Given a `token`, returns the current appcast checkpoint, or calculates + the appcast checkpoint if the `--calculate` flag is specified. + Given a `URL`, calculates the appcast checkpoint for it. + ## OPTIONS To make these options persistent, see the ENVIRONMENT section, below. diff --git a/Library/Homebrew/manpages/brew.1.md.erb b/Library/Homebrew/manpages/brew.1.md.erb index 7412d0a69..a7f099e9d 100644 --- a/Library/Homebrew/manpages/brew.1.md.erb +++ b/Library/Homebrew/manpages/brew.1.md.erb @@ -31,7 +31,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note * `install` <formula>: Install <formula>. - * `remove` <formula>: + * `uninstall` <formula>: Uninstall <formula>. * `update`: @@ -76,7 +76,7 @@ scripts that reside somewhere in the `PATH`, named `brew-`<cmdname> or to create your own commands without modifying Homebrew's internals. Instructions for creating your own commands can be found in the docs: -<https://github.com/Homebrew/brew/blob/master/docs/External-Commands.md> +<http://docs.brew.sh/External-Commands.html> ## SPECIFYING FORMULAE @@ -197,7 +197,7 @@ can take several different forms: *Default:* the number of available CPU cores. * `HOMEBREW_NO_ANALYTICS`: - If set, Homebrew will not send analytics. See: <https://github.com/Homebrew/brew/blob/master/docs/Analytics.md#analytics> + If set, Homebrew will not send analytics. See: <http://docs.brew.sh/Analytics.html> * `HOMEBREW_NO_AUTO_UPDATE`: If set, Homebrew will not auto-update before running `brew install`, diff --git a/Library/Homebrew/official_taps.rb b/Library/Homebrew/official_taps.rb index a220c9239..f2afea614 100644 --- a/Library/Homebrew/official_taps.rb +++ b/Library/Homebrew/official_taps.rb @@ -1,18 +1,15 @@ OFFICIAL_TAPS = %w[ apache completions - devel-only dupes emacs fuse games - gui nginx php python science tex - versions x11 ].freeze diff --git a/Library/Homebrew/os.rb b/Library/Homebrew/os.rb index f6fe1eb81..dae843407 100644 --- a/Library/Homebrew/os.rb +++ b/Library/Homebrew/os.rb @@ -15,7 +15,7 @@ module OS require "os/mac" # Don't tell people to report issues on unsupported versions of macOS. if !OS::Mac.prerelease? && !OS::Mac.outdated_release? - ISSUES_URL = "https://git.io/brew-troubleshooting".freeze + ISSUES_URL = "http://docs.brew.sh/Troubleshooting.html".freeze end PATH_OPEN = "/usr/bin/open".freeze # compatibility diff --git a/Library/Homebrew/os/mac.rb b/Library/Homebrew/os/mac.rb index b2f0515a0..9468a6c1e 100644 --- a/Library/Homebrew/os/mac.rb +++ b/Library/Homebrew/os/mac.rb @@ -152,13 +152,13 @@ module OS end STANDARD_COMPILERS = { - "2.0" => { gcc_40_build: 4061 }, - "2.5" => { gcc_40_build: 5370 }, - "3.1.4" => { gcc_40_build: 5493, gcc_42_build: 5577 }, - "3.2.6" => { gcc_40_build: 5494, gcc_42_build: 5666, clang: "1.7", clang_build: 77 }, - "4.0" => { gcc_40_build: 5494, gcc_42_build: 5666, clang: "2.0", clang_build: 137 }, - "4.0.1" => { gcc_40_build: 5494, gcc_42_build: 5666, clang: "2.0", clang_build: 137 }, - "4.0.2" => { gcc_40_build: 5494, gcc_42_build: 5666, clang: "2.0", clang_build: 137 }, + "2.0" => { gcc_4_0_build: 4061 }, + "2.5" => { gcc_4_0_build: 5370 }, + "3.1.4" => { gcc_4_0_build: 5493, gcc_4_2_build: 5577 }, + "3.2.6" => { gcc_4_0_build: 5494, gcc_4_2_build: 5666, clang: "1.7", clang_build: 77 }, + "4.0" => { gcc_4_0_build: 5494, gcc_4_2_build: 5666, clang: "2.0", clang_build: 137 }, + "4.0.1" => { gcc_4_0_build: 5494, gcc_4_2_build: 5666, clang: "2.0", clang_build: 137 }, + "4.0.2" => { gcc_4_0_build: 5494, gcc_4_2_build: 5666, clang: "2.0", clang_build: 137 }, "4.2" => { clang: "3.0", clang_build: 211 }, "4.3" => { clang: "3.1", clang_build: 318 }, "4.3.1" => { clang: "3.1", clang_build: 318 }, diff --git a/Library/Homebrew/os/mac/xcode.rb b/Library/Homebrew/os/mac/xcode.rb index 8e51fc6b6..aa4504a17 100644 --- a/Library/Homebrew/os/mac/xcode.rb +++ b/Library/Homebrew/os/mac/xcode.rb @@ -3,8 +3,9 @@ module OS module Xcode module_function - V4_BUNDLE_ID = "com.apple.dt.Xcode".freeze - V3_BUNDLE_ID = "com.apple.Xcode".freeze + DEFAULT_BUNDLE_PATH = Pathname.new("/Applications/Xcode.app").freeze + BUNDLE_ID = "com.apple.dt.Xcode".freeze + OLD_BUNDLE_ID = "com.apple.Xcode".freeze def latest_version case MacOS.version @@ -51,9 +52,9 @@ module OS begin dir = MacOS.active_developer_dir - if dir.empty? || dir == CLT::MAVERICKS_PKG_PATH || !File.directory?(dir) + if dir.empty? || dir == CLT::PKG_PATH || !File.directory?(dir) path = bundle_path - path.join("Contents", "Developer") if path + path/"Contents/Developer" if path else # Use cleanpath to avoid pathological trailing slash Pathname.new(dir).cleanpath @@ -67,11 +68,14 @@ module OS Pathname.new("#{prefix}/Toolchains/XcodeDefault.xctoolchain") end - # Ask Spotlight where Xcode is. If the user didn't install the - # helper tools and installed Xcode in a non-conventional place, this - # is our only option. See: https://superuser.com/questions/390757 def bundle_path - MacOS.app_with_bundle_id(V4_BUNDLE_ID, V3_BUNDLE_ID) + # Use the default location if it exists. + return DEFAULT_BUNDLE_PATH if DEFAULT_BUNDLE_PATH.exist? + + # Ask Spotlight where Xcode is. If the user didn't install the + # helper tools and installed Xcode in a non-conventional place, this + # is our only option. See: https://superuser.com/questions/390757 + MacOS.app_with_bundle_id(BUNDLE_ID, OLD_BUNDLE_ID) end def installed? @@ -182,7 +186,7 @@ module OS FROM_XCODE_PKG_ID = "com.apple.pkg.DeveloperToolsCLI".freeze MAVERICKS_PKG_ID = "com.apple.pkg.CLTools_Executables".freeze MAVERICKS_NEW_PKG_ID = "com.apple.pkg.CLTools_Base".freeze # obsolete - MAVERICKS_PKG_PATH = "/Library/Developer/CommandLineTools".freeze + PKG_PATH = "/Library/Developer/CommandLineTools".freeze # Returns true even if outdated tools are installed, e.g. # tools from Xcode 4.x on 10.9 @@ -222,7 +226,7 @@ module OS def minimum_version case MacOS.version when "10.12" then "8.0.0" - else "4.0.0" + else "1.0.0" end end @@ -237,7 +241,7 @@ module OS return false if MacOS.version < :lion if MacOS.version >= :mavericks - version = Utils.popen_read("#{MAVERICKS_PKG_PATH}/usr/bin/clang --version") + version = Utils.popen_read("#{PKG_PATH}/usr/bin/clang --version") else version = Utils.popen_read("/usr/bin/clang --version") end @@ -261,7 +265,7 @@ module OS [MAVERICKS_PKG_ID, MAVERICKS_NEW_PKG_ID, STANDALONE_PKG_ID, FROM_XCODE_PKG_ID].find do |id| if MacOS.version >= :mavericks - next unless File.exist?("#{MAVERICKS_PKG_PATH}/usr/bin/clang") + next unless File.exist?("#{PKG_PATH}/usr/bin/clang") end version = MacOS.pkgutil_info(id)[/version: (.+)$/, 1] return version if version diff --git a/Library/Homebrew/os/mac/xquartz.rb b/Library/Homebrew/os/mac/xquartz.rb index 674e50c50..b82772faf 100644 --- a/Library/Homebrew/os/mac/xquartz.rb +++ b/Library/Homebrew/os/mac/xquartz.rb @@ -5,6 +5,8 @@ module OS module XQuartz module_function + # TODO: confirm this path when you have internet + DEFAULT_BUNDLE_PATH = Pathname.new("Applications/Utilities/XQuartz.app").freeze FORGE_BUNDLE_ID = "org.macosforge.xquartz.X11".freeze APPLE_BUNDLE_ID = "org.x.X11".freeze FORGE_PKG_ID = "org.macosforge.xquartz.pkg".freeze @@ -56,6 +58,11 @@ module OS end def bundle_path + # Use the default location if it exists. + return DEFAULT_BUNDLE_PATH if DEFAULT_BUNDLE_PATH.exist? + + # Ask Spotlight where XQuartz is. If the user didn't install XQuartz + # in the conventional place, this is our only option. MacOS.app_with_bundle_id(FORGE_BUNDLE_ID, APPLE_BUNDLE_ID) end diff --git a/Library/Homebrew/requirement.rb b/Library/Homebrew/requirement.rb index fe1a3c020..49108ca75 100644 --- a/Library/Homebrew/requirement.rb +++ b/Library/Homebrew/requirement.rb @@ -15,6 +15,7 @@ class Requirement @default_formula = self.class.default_formula @cask ||= self.class.cask @download ||= self.class.download + @formula = nil tags.each do |tag| next unless tag.is_a? Hash @cask ||= tag[:cask] @@ -56,7 +57,14 @@ class Requirement def satisfied? result = self.class.satisfy.yielder { |p| instance_eval(&p) } @satisfied_result = result - result ? true : false + return false unless result + + if parent = satisfied_result_parent + parent.to_s =~ %r{(#{Regexp.escape(HOMEBREW_CELLAR)}|#{Regexp.escape(HOMEBREW_PREFIX)}/opt)/([\w+-.@]+)} + @formula = $2 + end + + true end # Overriding #fatal? is deprecated. @@ -69,6 +77,11 @@ class Requirement self.class.default_formula || false end + def satisfied_result_parent + return unless @satisfied_result.is_a?(Pathname) + @satisfied_result.resolved_path.parent + end + # Overriding #modify_build_environment is deprecated. # Pass a block to the env DSL method instead. # Note: #satisfied? should be called before invoking this method @@ -81,11 +94,8 @@ class Requirement # satisfy { which("executable") } # work, even under superenv where "executable" wouldn't normally be on the # PATH. - # This is undocumented magic and it should be removed, but we need to add - # a way to declare path-based requirements that work with superenv first. - return unless @satisfied_result.is_a?(Pathname) - parent = @satisfied_result.parent - + parent = satisfied_result_parent + return unless parent return if ENV["PATH"].split(File::PATH_SEPARATOR).include?(parent.to_s) ENV.append_path("PATH", parent) end @@ -111,13 +121,15 @@ class Requirement "#<#{self.class.name}: #{name.inspect} #{tags.inspect}>" end + def formula + @formula || self.class.default_formula + end + def to_dependency - f = self.class.default_formula - raise "No default formula defined for #{inspect}" if f.nil? - if f =~ HOMEBREW_TAP_FORMULA_REGEX - TapDependency.new(f, tags, method(:modify_build_environment), name) - else - Dependency.new(f, tags, method(:modify_build_environment), name) + if formula =~ HOMEBREW_TAP_FORMULA_REGEX + TapDependency.new(formula, tags, method(:modify_build_environment), name) + elsif formula + Dependency.new(formula, tags, method(:modify_build_environment), name) end end diff --git a/Library/Homebrew/requirements/perl_requirement.rb b/Library/Homebrew/requirements/perl_requirement.rb index 06e36ac0d..70eb2a36c 100644 --- a/Library/Homebrew/requirements/perl_requirement.rb +++ b/Library/Homebrew/requirements/perl_requirement.rb @@ -10,7 +10,7 @@ class PerlRequirement < Requirement satisfy(build_env: false) do which_all("perl").detect do |perl| - perl_version = Utils.popen_read(perl, "--version")[/\(v(\d+\.\d+)(?:\.\d+)?\)/, 1] + perl_version = Utils.popen_read(perl, "--version")[/v(\d+\.\d+)(?:\.\d+)?/, 1] next unless perl_version Version.create(perl_version.to_s) >= Version.create(@version) end diff --git a/Library/Homebrew/system_config.rb b/Library/Homebrew/system_config.rb index 9c7a8d1b0..043f60919 100644 --- a/Library/Homebrew/system_config.rb +++ b/Library/Homebrew/system_config.rb @@ -6,12 +6,12 @@ require "development_tools" class SystemConfig class << self - def gcc_42 - @gcc_42 ||= DevelopmentTools.gcc_42_build_version if DevelopmentTools.installed? + def gcc_4_2 + @gcc_4_2 ||= DevelopmentTools.gcc_4_2_build_version if DevelopmentTools.installed? end - def gcc_40 - @gcc_40 ||= DevelopmentTools.gcc_40_build_version if DevelopmentTools.installed? + def gcc_4_0 + @gcc_4_0 ||= DevelopmentTools.gcc_4_0_build_version if DevelopmentTools.installed? end def clang @@ -143,8 +143,8 @@ class SystemConfig f.puts "HOMEBREW_BOTTLE_DOMAIN: #{BottleSpecification::DEFAULT_DOMAIN}" f.puts hardware if hardware f.puts "Homebrew Ruby: #{describe_homebrew_ruby}" - f.puts "GCC-4.0: build #{gcc_40}" unless gcc_40.null? - f.puts "GCC-4.2: build #{gcc_42}" unless gcc_42.null? + f.puts "GCC-4.0: build #{gcc_4_0}" unless gcc_4_0.null? + f.puts "GCC-4.2: build #{gcc_4_2}" unless gcc_4_2.null? f.puts "Clang: #{clang.null? ? "N/A" : "#{clang} build #{clang_build}"}" f.puts "Git: #{describe_git}" f.puts "Perl: #{describe_perl}" diff --git a/Library/Homebrew/tab.rb b/Library/Homebrew/tab.rb index 40626bad1..fd59539df 100644 --- a/Library/Homebrew/tab.rb +++ b/Library/Homebrew/tab.rb @@ -25,6 +25,8 @@ class Tab < OpenStruct "unused_options" => build.unused_options.as_flags, "tabfile" => formula.prefix.join(FILENAME), "built_as_bottle" => build.bottle?, + "installed_as_dependency" => false, + "installed_on_request" => true, "poured_from_bottle" => false, "time" => Time.now.to_i, "source_modified_time" => formula.source_modified_time.to_i, @@ -168,9 +170,12 @@ class Tab < OpenStruct def self.empty attributes = { + "homebrew_version" => HOMEBREW_VERSION, "used_options" => [], "unused_options" => [], "built_as_bottle" => false, + "installed_as_dependency" => false, + "installed_on_request" => true, "poured_from_bottle" => false, "time" => nil, "source_modified_time" => 0, @@ -242,6 +247,17 @@ class Tab < OpenStruct super || DevelopmentTools.default_compiler end + def parsed_homebrew_version + return Version::NULL if homebrew_version.nil? + Version.new(homebrew_version) + end + + def runtime_dependencies + # Homebrew versions prior to 1.1.6 generated incorrect runtime dependency + # lists. + super unless parsed_homebrew_version < "1.1.6" + end + def cxxstdlib # Older tabs won't have these values, so provide sensible defaults lib = stdlib.to_sym if stdlib @@ -301,6 +317,8 @@ class Tab < OpenStruct "unused_options" => unused_options.as_flags, "built_as_bottle" => built_as_bottle, "poured_from_bottle" => poured_from_bottle, + "installed_as_dependency" => installed_as_dependency, + "installed_on_request" => installed_on_request, "changed_files" => changed_files && changed_files.map(&:to_s), "time" => time, "source_modified_time" => source_modified_time.to_i, diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb index 68b21ac60..4b59f2344 100644 --- a/Library/Homebrew/tap.rb +++ b/Library/Homebrew/tap.rb @@ -292,7 +292,11 @@ class Tap # path to the directory of all {Formula} files for this {Tap}. def formula_dir - @formula_dir ||= [path/"Formula", path/"HomebrewFormula", path].detect(&:directory?) + @formula_dir ||= potential_formula_dirs.detect(&:directory?) + end + + def potential_formula_dirs + @potential_formula_dirs ||= [path/"Formula", path/"HomebrewFormula", path].freeze end # path to the directory of all {Cask} files for this {Tap}. diff --git a/Library/Homebrew/test/ARGV_test.rb b/Library/Homebrew/test/ARGV_test.rb index 6805e0c62..e93d09c39 100644 --- a/Library/Homebrew/test/ARGV_test.rb +++ b/Library/Homebrew/test/ARGV_test.rb @@ -3,6 +3,7 @@ require "extend/ARGV" class ArgvExtensionTests < Homebrew::TestCase def setup + super @argv = [].extend(HomebrewArgvExtension) end @@ -21,8 +22,6 @@ class ArgvExtensionTests < Homebrew::TestCase keg.mkpath @argv << "mxcl" assert_equal 1, @argv.kegs.length - ensure - keg.parent.rmtree end def test_argv_named diff --git a/Library/Homebrew/test/ENV_test.rb b/Library/Homebrew/test/ENV_test.rb index 6c0e68a9e..cbfd01e25 100644 --- a/Library/Homebrew/test/ENV_test.rb +++ b/Library/Homebrew/test/ENV_test.rb @@ -31,6 +31,7 @@ end module SharedEnvTests def setup + super @env = {}.extend(EnvActivation) end @@ -133,7 +134,7 @@ module SharedEnvTests end def test_switching_compilers_updates_compiler - [:clang, :gcc, :gcc_4_0].each do |compiler| + [:clang, :gcc_4_2, :gcc_4_0].each do |compiler| @env.send(compiler) assert_equal compiler, @env.compiler end diff --git a/Library/Homebrew/test/audit_test.rb b/Library/Homebrew/test/audit_test.rb index 2725f906e..60cf27610 100644 --- a/Library/Homebrew/test/audit_test.rb +++ b/Library/Homebrew/test/audit_test.rb @@ -6,13 +6,10 @@ require "dev-cmd/audit" class FormulaTextTests < Homebrew::TestCase def setup + super @dir = mktmpdir end - def teardown - FileUtils.rm_rf @dir - end - def formula_text(name, body = nil, options = {}) path = Pathname.new "#{@dir}/#{name}.rb" path.open("w") do |f| @@ -58,13 +55,10 @@ end class FormulaAuditorTests < Homebrew::TestCase def setup + super @dir = mktmpdir end - def teardown - FileUtils.rm_rf @dir - end - def formula_auditor(name, text, options = {}) path = Pathname.new "#{@dir}/#{name}.rb" path.open("w") do |f| @@ -249,7 +243,7 @@ class FormulaAuditorTests < Homebrew::TestCase needs_compat require "compat/formula_specialties" - ARGV.stubs(:homebrew_developer?).returns false + ENV.delete("HOMEBREW_DEVELOPER") fa = shutup do formula_auditor "foo", <<-EOS.undent class Foo < GithubGistFormula @@ -266,7 +260,7 @@ class FormulaAuditorTests < Homebrew::TestCase needs_compat require "compat/formula_specialties" - ARGV.stubs(:homebrew_developer?).returns false + ENV.delete("HOMEBREW_DEVELOPER") fa = formula_auditor "foo", <<-EOS.undent class Foo < ScriptFileFormula url "http://example.com/foo-1.0.tgz" @@ -281,7 +275,7 @@ class FormulaAuditorTests < Homebrew::TestCase needs_compat require "compat/formula_specialties" - ARGV.stubs(:homebrew_developer?).returns false + ENV.delete("HOMEBREW_DEVELOPER") fa = formula_auditor "foo", <<-EOS.undent class Foo < AmazonWebServicesFormula url "http://example.com/foo-1.0.tgz" @@ -367,13 +361,10 @@ class FormulaAuditorTests < Homebrew::TestCase end EOS - original_value = ENV["HOMEBREW_NO_GITHUB_API"] ENV["HOMEBREW_NO_GITHUB_API"] = "1" fa.audit_github_repository assert_equal [], fa.problems - ensure - ENV["HOMEBREW_NO_GITHUB_API"] = original_value end def test_audit_caveats @@ -429,8 +420,8 @@ class FormulaAuditorTests < Homebrew::TestCase fa.audit_homepage assert_equal ["The homepage should start with http or https " \ - "(URL is #{fa.formula.homepage}).", "The homepage is not reachable " \ - "(curl exit code #{$?.exitstatus})"], fa.problems + "(URL is #{fa.formula.homepage}).", "The homepage #{fa.formula.homepage} is not reachable " \ + "(HTTP status code 000)"], fa.problems formula_homepages = { "bar" => "http://www.freedesktop.org/wiki/bar", diff --git a/Library/Homebrew/test/bottle_collector_test.rb b/Library/Homebrew/test/bottle_collector_test.rb index d75e29ec8..5879da92c 100644 --- a/Library/Homebrew/test/bottle_collector_test.rb +++ b/Library/Homebrew/test/bottle_collector_test.rb @@ -3,6 +3,7 @@ require "utils/bottles" class BottleCollectorTests < Homebrew::TestCase def setup + super @collector = Utils::Bottles::Collector.new end diff --git a/Library/Homebrew/test/bottle_hooks_test.rb b/Library/Homebrew/test/bottle_hooks_test.rb index 3535d80ef..fd890192f 100644 --- a/Library/Homebrew/test/bottle_hooks_test.rb +++ b/Library/Homebrew/test/bottle_hooks_test.rb @@ -17,6 +17,7 @@ class BottleHookTests < Homebrew::TestCase end def setup + super @fi = FormulaInstaller.new FormulaDouble.new end @@ -43,5 +44,6 @@ class BottleHookTests < Homebrew::TestCase def teardown Homebrew::Hooks::Bottles.reset_hooks + super end end diff --git a/Library/Homebrew/test/build_environment_test.rb b/Library/Homebrew/test/build_environment_test.rb index 73a1c95f7..54b9cb2b1 100644 --- a/Library/Homebrew/test/build_environment_test.rb +++ b/Library/Homebrew/test/build_environment_test.rb @@ -3,6 +3,7 @@ require "build_environment" class BuildEnvironmentTests < Homebrew::TestCase def setup + super @env = BuildEnvironment.new end diff --git a/Library/Homebrew/test/build_options_test.rb b/Library/Homebrew/test/build_options_test.rb index e460d25cc..05e7ccd94 100644 --- a/Library/Homebrew/test/build_options_test.rb +++ b/Library/Homebrew/test/build_options_test.rb @@ -4,6 +4,7 @@ require "options" class BuildOptionsTests < Homebrew::TestCase def setup + super args = Options.create(%w[--with-foo --with-bar --without-qux]) opts = Options.create(%w[--with-foo --with-bar --without-baz --without-qux]) @build = BuildOptions.new(args, opts) diff --git a/Library/Homebrew/test/caveats_test.rb b/Library/Homebrew/test/caveats_test.rb index 9eaac5792..3a582b907 100644 --- a/Library/Homebrew/test/caveats_test.rb +++ b/Library/Homebrew/test/caveats_test.rb @@ -4,6 +4,7 @@ require "caveats" class CaveatsTests < Homebrew::TestCase def setup + super @f = formula { url "foo-1.0" } @c = Caveats.new @f end diff --git a/Library/Homebrew/test/checksum_verification_test.rb b/Library/Homebrew/test/checksum_verification_test.rb index 9017b528d..4c674edd2 100644 --- a/Library/Homebrew/test/checksum_verification_test.rb +++ b/Library/Homebrew/test/checksum_verification_test.rb @@ -17,10 +17,6 @@ class ChecksumVerificationTests < Homebrew::TestCase end end - def teardown - @_f.clear_cache - end - def test_good_sha256 formula do sha256 TESTBALL_SHA256 diff --git a/Library/Homebrew/test/cleaner_test.rb b/Library/Homebrew/test/cleaner_test.rb index ac108421c..05a91b90b 100644 --- a/Library/Homebrew/test/cleaner_test.rb +++ b/Library/Homebrew/test/cleaner_test.rb @@ -6,14 +6,11 @@ class CleanerTests < Homebrew::TestCase include FileUtils def setup + super @f = formula("cleaner_test") { url "foo-1.0" } @f.prefix.mkpath end - def teardown - @f.rack.rmtree if @f.rack.exist? - end - def test_clean_file @f.bin.mkpath @f.lib.mkpath diff --git a/Library/Homebrew/test/cleanup_test.rb b/Library/Homebrew/test/cleanup_test.rb index bb8e1cdc6..8a292933a 100644 --- a/Library/Homebrew/test/cleanup_test.rb +++ b/Library/Homebrew/test/cleanup_test.rb @@ -14,14 +14,14 @@ end class CleanupTests < Homebrew::TestCase def setup + super @ds_store = Pathname.new "#{HOMEBREW_PREFIX}/Library/.DS_Store" FileUtils.touch @ds_store end def teardown FileUtils.rm_f @ds_store - ARGV.delete "--dry-run" - ARGV.delete "--prune=all" + super end def test_cleanup @@ -55,9 +55,6 @@ class CleanupTests < Homebrew::TestCase refute_predicate f1, :installed? refute_predicate f2, :installed? assert_predicate f3, :installed? - ensure - [f1, f2, f3].each(&:clear_cache) - f3.rack.rmtree end def test_cleanup_logs diff --git a/Library/Homebrew/test/commands_test.rb b/Library/Homebrew/test/commands_test.rb index d44d2da0e..5f5dc9586 100644 --- a/Library/Homebrew/test/commands_test.rb +++ b/Library/Homebrew/test/commands_test.rb @@ -13,6 +13,7 @@ end class CommandsTests < Homebrew::TestCase def setup + super @cmds = [ # internal commands HOMEBREW_LIBRARY_PATH/"cmd/rbcmd.rb", @@ -28,6 +29,7 @@ class CommandsTests < Homebrew::TestCase def teardown @cmds.each(&:unlink) + super end def test_internal_commands @@ -45,8 +47,6 @@ class CommandsTests < Homebrew::TestCase end def test_external_commands - env = ENV.to_hash - mktmpdir do |dir| %w[brew-t1 brew-t2.rb brew-t3.py].each do |file| path = "#{dir}/#{file}" @@ -65,8 +65,6 @@ class CommandsTests < Homebrew::TestCase "Executable files with a non Ruby extension shoudn't be included" refute cmds.include?("t4"), "Non-executable files shouldn't be included" end - ensure - ENV.replace(env) end def test_internal_command_path diff --git a/Library/Homebrew/test/compiler_selector_test.rb b/Library/Homebrew/test/compiler_selector_test.rb index b1591bdbe..aa1a6f97e 100644 --- a/Library/Homebrew/test/compiler_selector_test.rb +++ b/Library/Homebrew/test/compiler_selector_test.rb @@ -31,6 +31,7 @@ class CompilerSelectorTests < Homebrew::TestCase end def setup + super @f = Double.new @cc = :clang @versions = CompilerVersions.new diff --git a/Library/Homebrew/test/dependencies_test.rb b/Library/Homebrew/test/dependencies_test.rb index db3b78226..c5444fcbc 100644 --- a/Library/Homebrew/test/dependencies_test.rb +++ b/Library/Homebrew/test/dependencies_test.rb @@ -5,6 +5,7 @@ require "requirements" class DependenciesTests < Homebrew::TestCase def setup + super @deps = Dependencies.new end @@ -89,6 +90,7 @@ end class RequirementsTests < Homebrew::TestCase def setup + super @reqs = Requirements.new end diff --git a/Library/Homebrew/test/dependency_collector_test.rb b/Library/Homebrew/test/dependency_collector_test.rb index 1c7f70118..c63d04637 100644 --- a/Library/Homebrew/test/dependency_collector_test.rb +++ b/Library/Homebrew/test/dependency_collector_test.rb @@ -11,11 +11,13 @@ class DependencyCollectorTests < Homebrew::TestCase end def setup + super @d = DependencyCollector.new end def teardown DependencyCollector.clear_cache + super end def test_dependency_creation diff --git a/Library/Homebrew/test/dependency_expansion_test.rb b/Library/Homebrew/test/dependency_expansion_test.rb index 9d6de35e2..de743ce03 100644 --- a/Library/Homebrew/test/dependency_expansion_test.rb +++ b/Library/Homebrew/test/dependency_expansion_test.rb @@ -9,6 +9,7 @@ class DependencyExpansionTests < Homebrew::TestCase end def setup + super @foo = build_dep(:foo) @bar = build_dep(:bar) @baz = build_dep(:baz) diff --git a/Library/Homebrew/test/dependency_test.rb b/Library/Homebrew/test/dependency_test.rb index 65255995e..404f26d79 100644 --- a/Library/Homebrew/test/dependency_test.rb +++ b/Library/Homebrew/test/dependency_test.rb @@ -3,6 +3,7 @@ require "dependency" class DependableTests < Homebrew::TestCase def setup + super @tags = ["foo", "bar", :build] @dep = Struct.new(:tags).new(@tags).extend(Dependable) end @@ -118,6 +119,11 @@ class DependencyTests < Homebrew::TestCase end class TapDependencyTests < Homebrew::TestCase + def test_tap + dep = TapDependency.new("foo/bar/dog") + assert_equal Tap.new("foo", "bar"), dep.tap + end + def test_option_names dep = TapDependency.new("foo/bar/dog") assert_equal %w[dog], dep.option_names diff --git a/Library/Homebrew/test/descriptions_test.rb b/Library/Homebrew/test/descriptions_test.rb index de38fdbd1..baeeb7b19 100644 --- a/Library/Homebrew/test/descriptions_test.rb +++ b/Library/Homebrew/test/descriptions_test.rb @@ -3,6 +3,8 @@ require "descriptions" class DescriptionsTest < Homebrew::TestCase def setup + super + @descriptions_hash = {} @descriptions = Descriptions.new(@descriptions_hash) @@ -12,6 +14,7 @@ class DescriptionsTest < Homebrew::TestCase def teardown $stdout = @old_stdout + super end def test_single_core_formula diff --git a/Library/Homebrew/test/diagnostic_test.rb b/Library/Homebrew/test/diagnostic_test.rb index c9bb524b0..7a1fb25f7 100644 --- a/Library/Homebrew/test/diagnostic_test.rb +++ b/Library/Homebrew/test/diagnostic_test.rb @@ -5,14 +5,10 @@ require "diagnostic" class DiagnosticChecksTest < Homebrew::TestCase def setup - @env = ENV.to_hash + super @checks = Homebrew::Diagnostic::Checks.new end - def teardown - ENV.replace(@env) - end - def test_inject_file_list assert_equal "foo:\n", @checks.inject_file_list([], "foo:\n") @@ -103,8 +99,6 @@ class DiagnosticChecksTest < Homebrew::TestCase assert_match "/usr/bin occurs before #{HOMEBREW_PREFIX}/bin", @checks.check_user_path_1 - ensure - bin.rmtree end def test_check_user_path_bin diff --git a/Library/Homebrew/test/download_strategies_test.rb b/Library/Homebrew/test/download_strategies_test.rb index 87218fb12..40236b420 100644 --- a/Library/Homebrew/test/download_strategies_test.rb +++ b/Library/Homebrew/test/download_strategies_test.rb @@ -2,11 +2,12 @@ require "testing_env" require "download_strategy" class ResourceDouble - attr_reader :url, :specs, :version + attr_reader :url, :specs, :version, :mirrors def initialize(url = "http://example.com/foo.tar.gz", specs = {}) @url = url @specs = specs + @mirrors = [] end end @@ -14,6 +15,7 @@ class AbstractDownloadStrategyTests < Homebrew::TestCase include FileUtils def setup + super @name = "foo" @resource = ResourceDouble.new @strategy = AbstractDownloadStrategy.new(@name, @resource) @@ -60,10 +62,86 @@ class VCSDownloadStrategyTests < Homebrew::TestCase end end +class GitHubPrivateRepositoryDownloadStrategyTests < Homebrew::TestCase + def setup + super + resource = ResourceDouble.new("https://github.com/owner/repo/archive/1.1.5.tar.gz") + ENV["HOMEBREW_GITHUB_API_TOKEN"] = "token" + GitHub.stubs(:repository).returns {} + @strategy = GitHubPrivateRepositoryDownloadStrategy.new("foo", resource) + end + + def test_set_github_token + assert_equal "token", @strategy.instance_variable_get(:@github_token) + end + + def test_parse_url_pattern + assert_equal "owner", @strategy.instance_variable_get(:@owner) + assert_equal "repo", @strategy.instance_variable_get(:@repo) + assert_equal "archive/1.1.5.tar.gz", @strategy.instance_variable_get(:@filepath) + end + + def test_download_url + expected = "https://token@github.com/owner/repo/archive/1.1.5.tar.gz" + assert_equal expected, @strategy.download_url + end +end + +class GitHubPrivateRepositoryReleaseDownloadStrategyTests < Homebrew::TestCase + def setup + super + resource = ResourceDouble.new("https://github.com/owner/repo/releases/download/tag/foo_v0.1.0_darwin_amd64.tar.gz") + ENV["HOMEBREW_GITHUB_API_TOKEN"] = "token" + GitHub.stubs(:repository).returns {} + @strategy = GitHubPrivateRepositoryReleaseDownloadStrategy.new("foo", resource) + end + + def test_parse_url_pattern + assert_equal "owner", @strategy.instance_variable_get(:@owner) + assert_equal "repo", @strategy.instance_variable_get(:@repo) + assert_equal "tag", @strategy.instance_variable_get(:@tag) + assert_equal "foo_v0.1.0_darwin_amd64.tar.gz", @strategy.instance_variable_get(:@filename) + end + + def test_download_url + @strategy.stubs(:resolve_asset_id).returns(456) + expected = "https://token@api.github.com/repos/owner/repo/releases/assets/456" + assert_equal expected, @strategy.download_url + end + + def test_resolve_asset_id + release_metadata = { + "assets" => [ + { + "id" => 123, + "name" => "foo_v0.1.0_linux_amd64.tar.gz", + }, + { + "id" => 456, + "name" => "foo_v0.1.0_darwin_amd64.tar.gz", + }, + ], + } + @strategy.stubs(:fetch_release_metadata).returns(release_metadata) + assert_equal 456, @strategy.send(:resolve_asset_id) + end + + def test_fetch_release_metadata + expected_release_url = "https://api.github.com/repos/owner/repo/releases/tags/tag" + github_mock = MiniTest::Mock.new + github_mock.expect :call, {}, [expected_release_url] + GitHub.stub :open, github_mock do + @strategy.send(:fetch_release_metadata) + end + github_mock.verify + end +end + class GitDownloadStrategyTests < Homebrew::TestCase include FileUtils def setup + super resource = ResourceDouble.new("https://github.com/homebrew/foo") @commit_id = 1 @strategy = GitDownloadStrategy.new("baz", resource) @@ -71,10 +149,6 @@ class GitDownloadStrategyTests < Homebrew::TestCase mkpath @cached_location end - def teardown - rmtree @cached_location - end - def git_commit_all shutup do system "git", "add", "--all" @@ -83,28 +157,14 @@ class GitDownloadStrategyTests < Homebrew::TestCase end end - def using_git_env - 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 - yield - ensure - ENV.replace(initial_env) - end - def setup_git_repo - using_git_env do - @cached_location.cd do - shutup do - system "git", "init" - system "git", "remote", "add", "origin", "https://github.com/Homebrew/homebrew-foo" - end - touch "README" - git_commit_all + @cached_location.cd do + shutup do + system "git", "init" + system "git", "remote", "add", "origin", "https://github.com/Homebrew/homebrew-foo" end + touch "README" + git_commit_all end end @@ -118,18 +178,16 @@ class GitDownloadStrategyTests < Homebrew::TestCase def test_source_modified_time setup_git_repo - assert_equal 1_242_860_651, @strategy.source_modified_time.to_i + assert_equal 1_485_115_153, @strategy.source_modified_time.to_i end def test_last_commit setup_git_repo - using_git_env do - @cached_location.cd do - touch "LICENSE" - git_commit_all - end + @cached_location.cd do + touch "LICENSE" + git_commit_all end - assert_equal "c50c79b", @strategy.last_commit + assert_equal "f68266e", @strategy.last_commit end def test_fetch_last_commit @@ -140,21 +198,19 @@ class GitDownloadStrategyTests < Homebrew::TestCase resource.instance_variable_set(:@version, Version.create("HEAD")) @strategy = GitDownloadStrategy.new("baz", resource) - using_git_env do - remote_repo.cd do - shutup do - system "git", "init" - system "git", "remote", "add", "origin", "https://github.com/Homebrew/homebrew-foo" - end - touch "README" - git_commit_all - touch "LICENSE" - git_commit_all + remote_repo.cd do + shutup do + system "git", "init" + system "git", "remote", "add", "origin", "https://github.com/Homebrew/homebrew-foo" end + touch "README" + git_commit_all + touch "LICENSE" + git_commit_all end @strategy.shutup! - assert_equal "c50c79b", @strategy.fetch_last_commit + assert_equal "f68266e", @strategy.fetch_last_commit ensure remote_repo.rmtree if remote_repo.directory? end @@ -162,6 +218,7 @@ end class DownloadStrategyDetectorTests < Homebrew::TestCase def setup + super @d = DownloadStrategyDetector.new end diff --git a/Library/Homebrew/test/emoji_test.rb b/Library/Homebrew/test/emoji_test.rb new file mode 100644 index 000000000..ea68db8f6 --- /dev/null +++ b/Library/Homebrew/test/emoji_test.rb @@ -0,0 +1,11 @@ +require "testing_env" +require "emoji" + +class EmojiTest < Homebrew::TestCase + def test_install_badge + assert_equal "🍺", Emoji.install_badge + + ENV["HOMEBREW_INSTALL_BADGE"] = "foo" + assert_equal "foo", Emoji.install_badge + end +end diff --git a/Library/Homebrew/test/formula_installer_test.rb b/Library/Homebrew/test/formula_installer_test.rb index 652548bd7..c99b2de74 100644 --- a/Library/Homebrew/test/formula_installer_test.rb +++ b/Library/Homebrew/test/formula_installer_test.rb @@ -84,13 +84,10 @@ class InstallTests < Homebrew::TestCase cc_arg = "--cc=clang" ARGV << cc_arg - begin - temporary_install(TestballBottle.new) do |f| - tab = Tab.for_formula(f) - assert_equal "clang", tab.compiler - end - ensure - ARGV.delete_if { |x| x == cc_arg } + + temporary_install(TestballBottle.new) do |f| + tab = Tab.for_formula(f) + assert_equal "clang", tab.compiler end end end @@ -128,11 +125,7 @@ class FormulaInstallerTests < Homebrew::TestCase fi = FormulaInstaller.new(dependent) assert_raises(CannotInstallFormulaError) { fi.check_install_sanity } ensure - dependency.unpin dependency_keg.unlink - dependency_keg.uninstall - dependency.clear_cache - dep_path.unlink Formulary::FORMULAE.delete(dep_path) end end diff --git a/Library/Homebrew/test/formula_lock_test.rb b/Library/Homebrew/test/formula_lock_test.rb index 80ee9dd25..13244555d 100644 --- a/Library/Homebrew/test/formula_lock_test.rb +++ b/Library/Homebrew/test/formula_lock_test.rb @@ -3,13 +3,14 @@ require "formula_lock" class FormulaLockTests < Homebrew::TestCase def setup + super @lock = FormulaLock.new("foo") @lock.lock end def teardown @lock.unlock - HOMEBREW_LOCK_DIR.children.each(&:unlink) + super end def test_locking_file_with_existing_lock_raises_error diff --git a/Library/Homebrew/test/formula_pin_test.rb b/Library/Homebrew/test/formula_pin_test.rb index 297d7703e..7e3c7efa0 100644 --- a/Library/Homebrew/test/formula_pin_test.rb +++ b/Library/Homebrew/test/formula_pin_test.rb @@ -21,6 +21,7 @@ class FormulaPinTests < Homebrew::TestCase end def setup + super @f = FormulaDouble.new @pin = FormulaPin.new(@f) @f.rack.mkpath @@ -47,8 +48,4 @@ class FormulaPinTests < Homebrew::TestCase refute_predicate @pin, :pinned? refute_predicate HOMEBREW_PINNED_KEGS, :directory? end - - def teardown - @f.rack.rmtree - end end diff --git a/Library/Homebrew/test/formula_test.rb b/Library/Homebrew/test/formula_test.rb index a6db1b57f..ecdd1847b 100644 --- a/Library/Homebrew/test/formula_test.rb +++ b/Library/Homebrew/test/formula_test.rb @@ -176,8 +176,6 @@ class FormulaTests < Homebrew::TestCase prefix.mkpath FileUtils.touch prefix+Tab::FILENAME assert_predicate f, :any_version_installed? - ensure - f.rack.rmtree end def test_migration_needed @@ -203,9 +201,6 @@ class FormulaTests < Homebrew::TestCase newname_prefix.mkpath refute_predicate f, :migration_needed? - ensure - oldname_prefix.parent.rmtree - newname_prefix.parent.rmtree end def test_installed? @@ -240,8 +235,6 @@ class FormulaTests < Homebrew::TestCase prefix = HOMEBREW_CELLAR+f.name+f.head.version prefix.mkpath assert_equal prefix, f.installed_prefix - ensure - f.rack.rmtree end def test_installed_prefix_devel_installed @@ -255,8 +248,6 @@ class FormulaTests < Homebrew::TestCase prefix = HOMEBREW_CELLAR+f.name+f.devel.version prefix.mkpath assert_equal prefix, f.installed_prefix - ensure - f.rack.rmtree end def test_installed_prefix_stable_installed @@ -270,8 +261,6 @@ class FormulaTests < Homebrew::TestCase prefix = HOMEBREW_CELLAR+f.name+f.version prefix.mkpath assert_equal prefix, f.installed_prefix - ensure - f.rack.rmtree end def test_installed_prefix_outdated_stable_head_installed @@ -289,8 +278,6 @@ class FormulaTests < Homebrew::TestCase tab.write assert_equal HOMEBREW_CELLAR/"#{f.name}/#{f.version}", f.installed_prefix - ensure - f.rack.rmtree end def test_installed_prefix_outdated_devel_head_installed @@ -311,8 +298,6 @@ class FormulaTests < Homebrew::TestCase tab.write assert_equal HOMEBREW_CELLAR/"#{f.name}/#{f.version}", f.installed_prefix - ensure - f.rack.rmtree end def test_installed_prefix_head @@ -358,8 +343,6 @@ class FormulaTests < Homebrew::TestCase prefix = HOMEBREW_CELLAR/"#{f.name}/HEAD-222222_2" assert_equal prefix, f.latest_head_prefix - ensure - f.rack.rmtree end def test_equality @@ -543,8 +526,6 @@ class FormulaTests < Homebrew::TestCase end def test_update_head_version - initial_env = ENV.to_hash - f = formula do head "foo", using: :git end @@ -552,12 +533,6 @@ class FormulaTests < Homebrew::TestCase cached_location = f.head.downloader.cached_location cached_location.mkpath - %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 - cached_location.cd do FileUtils.touch "LICENSE" shutup do @@ -569,9 +544,6 @@ class FormulaTests < Homebrew::TestCase f.update_head_version assert_equal Version.create("HEAD-5658946"), f.head.version - ensure - ENV.replace(initial_env) - cached_location.rmtree end def test_legacy_options @@ -651,12 +623,80 @@ class FormulaTests < Homebrew::TestCase f4 = formula("f4") do url "f4-1.0" - depends_on "f3" + depends_on "f1" end + stub_formula_loader f4 - assert_equal %w[f3], f4.deps.map(&:name) - assert_equal %w[f1 f2 f3], f4.recursive_dependencies.map(&:name) - assert_equal %w[f2 f3], f4.runtime_dependencies.map(&:name) + f5 = formula("f5") do + url "f5-1.0" + depends_on "f3" => :build + depends_on "f4" + end + + assert_equal %w[f3 f4], f5.deps.map(&:name) + assert_equal %w[f1 f2 f3 f4], f5.recursive_dependencies.map(&:name) + assert_equal %w[f1 f4], f5.runtime_dependencies.map(&:name) + end + + def test_runtime_dependencies_with_optional_deps_from_tap + tap_loader = mock + tap_loader.stubs(:get_formula).raises(RuntimeError, "tried resolving tap formula") + Formulary.stubs(:loader_for).with("foo/bar/f1", from: nil).returns(tap_loader) + + stub_formula_loader formula("f2") { url "f2-1.0" }, "baz/qux/f2" + + f3 = formula("f3") do + url "f3-1.0" + depends_on "foo/bar/f1" => :optional + depends_on "baz/qux/f2" + end + + # f1 shouldn't be loaded by default. + # If it is, an exception will be raised. + assert_equal %w[baz/qux/f2], f3.runtime_dependencies.map(&:name) + + # If --with-f1, f1 should be loaded. + stub_formula_loader formula("f1") { url "f1-1.0" }, "foo/bar/f1" + f3.build = BuildOptions.new(Options.create(%w[--with-f1]), f3.options) + assert_equal %w[foo/bar/f1 baz/qux/f2], f3.runtime_dependencies.map(&:name) + end + + def test_requirements + f1 = formula("f1") do + url "f1-1" + + depends_on :python + depends_on x11: :recommended + depends_on xcode: ["1.0", :optional] + end + stub_formula_loader f1 + + python = PythonRequirement.new + x11 = X11Requirement.new("x11", [:recommended]) + xcode = XcodeRequirement.new(["1.0", :optional]) + + # Default block should filter out deps that aren't being used + assert_equal Set[python, x11], Set.new(f1.recursive_requirements) + + f1.build = BuildOptions.new(["--with-xcode", "--without-x11"], f1.options) + assert_equal Set[python, xcode], Set.new(f1.recursive_requirements) + f1.build = f1.stable.build + + f2 = formula("f2") do + url "f2-1" + depends_on "f1" + end + + assert_equal Set[python, x11], Set.new(f2.recursive_requirements) + + # Empty block should allow all requirements + assert_equal Set[python, x11, xcode], Set.new(f2.recursive_requirements {}) + + # Requirements can be pruned + requirements = f2.recursive_requirements do |_dependent, requirement| + Requirement.prune if requirement.is_a?(PythonRequirement) + end + assert_equal Set[x11, xcode], Set.new(requirements) end def test_to_hash @@ -703,9 +743,6 @@ class FormulaTests < Homebrew::TestCase assert_equal f3.installed_kegs.sort_by(&:version)[0..1], f3.eligible_kegs_for_cleanup.sort_by(&:version) - ensure - [f1, f2, f3].each(&:clear_cache) - f3.rack.rmtree end def test_eligible_kegs_for_cleanup_keg_pinned @@ -727,10 +764,6 @@ class FormulaTests < Homebrew::TestCase assert_predicate f3, :installed? assert_equal [Keg.new(f2.prefix)], shutup { f3.eligible_kegs_for_cleanup } - ensure - f1.unpin - [f1, f2, f3].each(&:clear_cache) - f3.rack.rmtree end def test_eligible_kegs_for_cleanup_head_installed @@ -753,8 +786,6 @@ class FormulaTests < Homebrew::TestCase eligible_kegs = f.installed_kegs - [Keg.new(f.prefix("HEAD-111111_1"))] assert_equal eligible_kegs, f.eligible_kegs_for_cleanup - ensure - f.rack.rmtree end def test_pour_bottle @@ -806,6 +837,8 @@ class AliasChangeTests < Homebrew::TestCase end def setup + super + alias_name = "bar" @alias_path = "#{CoreTap.instance.alias_dir}/#{alias_name}" @@ -874,6 +907,8 @@ class OutdatedVersionsTests < Homebrew::TestCase attr_reader :f, :old_formula, :new_formula def setup + super + @f = formula do url "foo" version "1.20" @@ -889,11 +924,6 @@ class OutdatedVersionsTests < Homebrew::TestCase @old_alias_target_prefix = HOMEBREW_CELLAR/"#{old_formula.name}/1.0" end - def teardown - formulae = [@f, @old_formula, @new_formula] - formulae.map(&:rack).select(&:exist?).each(&:rmtree) - end - def alias_path "#{@f.tap.alias_dir}/bar" end @@ -1058,13 +1088,12 @@ class OutdatedVersionsTests < Homebrew::TestCase outdated_stable_prefix = HOMEBREW_CELLAR.join("testball/1.0") head_prefix_a = HOMEBREW_CELLAR.join("testball/HEAD") head_prefix_b = HOMEBREW_CELLAR.join("testball/HEAD-aaaaaaa_1") - head_prefix_c = HOMEBREW_CELLAR.join("testball/HEAD-5658946") + head_prefix_c = HOMEBREW_CELLAR.join("testball/HEAD-18a7103") setup_tab_for_prefix(outdated_stable_prefix) tab_a = setup_tab_for_prefix(head_prefix_a, versions: { "stable" => "1.0" }) setup_tab_for_prefix(head_prefix_b) - initial_env = ENV.to_hash testball_repo = HOMEBREW_PREFIX.join("testball_repo") testball_repo.mkdir @@ -1074,12 +1103,6 @@ class OutdatedVersionsTests < Homebrew::TestCase head "file://#{testball_repo}", using: :git end - %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 - testball_repo.cd do FileUtils.touch "LICENSE" shutup do @@ -1104,13 +1127,7 @@ class OutdatedVersionsTests < Homebrew::TestCase reset_outdated_kegs assert_predicate f.outdated_kegs(fetch_head: true), :empty? ensure - ENV.replace(initial_env) testball_repo.rmtree if testball_repo.exist? - outdated_stable_prefix.rmtree if outdated_stable_prefix.exist? - head_prefix_b.rmtree if head_prefix.exist? - head_prefix_c.rmtree if head_prefix_c.exist? - FileUtils.rm_rf HOMEBREW_CACHE/"testball--git" - FileUtils.rm_rf HOMEBREW_CELLAR/"testball" end def test_outdated_kegs_version_scheme_changed @@ -1124,8 +1141,6 @@ class OutdatedVersionsTests < Homebrew::TestCase setup_tab_for_prefix(prefix, versions: { "stable" => "0.1" }) refute_predicate f.outdated_kegs, :empty? - ensure - prefix.rmtree end def test_outdated_kegs_mixed_version_schemes @@ -1153,8 +1168,6 @@ class OutdatedVersionsTests < Homebrew::TestCase prefix_d = HOMEBREW_CELLAR.join("testball/20141011") setup_tab_for_prefix(prefix_d, versions: { "stable" => "20141009", "version_scheme" => 3 }) assert_predicate f.outdated_kegs, :empty? - ensure - f.rack.rmtree end def test_outdated_kegs_head_with_version_scheme @@ -1174,7 +1187,5 @@ class OutdatedVersionsTests < Homebrew::TestCase setup_tab_for_prefix(head_prefix, versions: { "stable" => "1.0", "version_scheme" => 2 }) assert_predicate f.outdated_kegs, :empty? - ensure - head_prefix.rmtree end end diff --git a/Library/Homebrew/test/formulary_test.rb b/Library/Homebrew/test/formulary_test.rb index 3d88c8407..ea7ecf8d0 100644 --- a/Library/Homebrew/test/formulary_test.rb +++ b/Library/Homebrew/test/formulary_test.rb @@ -16,6 +16,7 @@ end class FormularyFactoryTest < Homebrew::TestCase def setup + super @name = "testball_bottle" @path = CoreTap.new.formula_dir/"#{@name}.rb" @bottle_dir = Pathname.new("#{TEST_FIXTURE_DIR}/bottles") @@ -39,10 +40,6 @@ class FormularyFactoryTest < Homebrew::TestCase EOS end - def teardown - @path.unlink - end - def test_factory assert_kind_of Formula, Formulary.factory(@name) end @@ -61,8 +58,6 @@ class FormularyFactoryTest < Homebrew::TestCase path.write "class Wrong#{Formulary.class_s(name)} < Formula\nend\n" assert_raises(FormulaClassUnavailableError) { Formulary.factory(name) } - ensure - path.unlink end def test_factory_from_path @@ -90,8 +85,6 @@ class FormularyFactoryTest < Homebrew::TestCase result = Formulary.factory("foo") assert_kind_of Formula, result assert_equal alias_path.to_s, result.alias_path - ensure - alias_dir.rmtree end def test_factory_from_rack_and_from_keg @@ -107,9 +100,6 @@ class FormularyFactoryTest < Homebrew::TestCase assert_kind_of Tab, f.build ensure keg.unlink - keg.uninstall - formula.clear_cache - formula.bottle.clear_cache end def test_load_from_contents @@ -121,13 +111,12 @@ class FormularyFactoryTest < Homebrew::TestCase (HOMEBREW_CELLAR/@name).mkpath assert_equal HOMEBREW_CELLAR/@name, Formulary.to_rack(@name) assert_raises(TapFormulaUnavailableError) { Formulary.to_rack("a/b/#{@name}") } - ensure - FileUtils.rm_rf HOMEBREW_CELLAR/@name end end class FormularyTapFactoryTest < Homebrew::TestCase def setup + super @name = "foo" @tap = Tap.new "homebrew", "foo" @path = @tap.path/"#{@name}.rb" @@ -139,10 +128,6 @@ class FormularyTapFactoryTest < Homebrew::TestCase @path.write @code end - def teardown - @tap.path.rmtree - end - def test_factory_tap_formula assert_kind_of Formula, Formulary.factory(@name) end @@ -173,6 +158,7 @@ end class FormularyTapPriorityTest < Homebrew::TestCase def setup + super @name = "foo" @core_path = CoreTap.new.formula_dir/"#{@name}.rb" @tap = Tap.new "homebrew", "foo" @@ -186,11 +172,6 @@ class FormularyTapPriorityTest < Homebrew::TestCase @tap_path.write code end - def teardown - @core_path.unlink - @tap.path.rmtree - end - def test_find_with_priority_core_formula formula = Formulary.find_with_priority(@name) assert_kind_of Formula, formula diff --git a/Library/Homebrew/test/gpg2_requirement_test.rb b/Library/Homebrew/test/gpg2_requirement_test.rb index fa7fc9ea4..3297c2851 100644 --- a/Library/Homebrew/test/gpg2_requirement_test.rb +++ b/Library/Homebrew/test/gpg2_requirement_test.rb @@ -4,6 +4,7 @@ require "fileutils" class GPG2RequirementTests < Homebrew::TestCase def setup + super @dir = Pathname.new(mktmpdir) (@dir/"bin/gpg").write <<-EOS.undent #!/bin/bash @@ -14,11 +15,11 @@ class GPG2RequirementTests < Homebrew::TestCase def teardown FileUtils.rm_rf @dir + super end def test_satisfied - with_environment("PATH" => @dir/"bin") do - assert_predicate GPG2Requirement.new, :satisfied? - end + ENV["PATH"] = @dir/"bin" + assert_predicate GPG2Requirement.new, :satisfied? end end diff --git a/Library/Homebrew/test/gpg_test.rb b/Library/Homebrew/test/gpg_test.rb index 0374bdab4..ea4372549 100644 --- a/Library/Homebrew/test/gpg_test.rb +++ b/Library/Homebrew/test/gpg_test.rb @@ -3,18 +3,16 @@ require "gpg" class GpgTest < Homebrew::TestCase def setup + super skip "GPG Unavailable" unless Gpg.available? @dir = Pathname.new(mktmpdir) end def test_create_test_key Dir.chdir(@dir) do - with_environment("HOME" => @dir) do - shutup { Gpg.create_test_key(@dir) } - assert_predicate @dir/".gnupg/secring.gpg", :exist? - end + ENV["HOME"] = @dir + shutup { Gpg.create_test_key(@dir) } + assert_predicate @dir/".gnupg/secring.gpg", :exist? end - ensure - @dir.rmtree end end diff --git a/Library/Homebrew/test/hardware_test.rb b/Library/Homebrew/test/hardware_test.rb index 2bea5387d..69f881a60 100644 --- a/Library/Homebrew/test/hardware_test.rb +++ b/Library/Homebrew/test/hardware_test.rb @@ -8,7 +8,7 @@ class HardwareTests < Homebrew::TestCase if Hardware::CPU.intel? def test_hardware_intel_family - families = [:core, :core2, :penryn, :nehalem, :arrandale, :sandybridge, :ivybridge, :haswell, :broadwell, :skylake, :dunno] + families = [:core, :core2, :penryn, :nehalem, :arrandale, :sandybridge, :ivybridge, :haswell, :broadwell, :skylake, :kabylake, :dunno] assert_includes families, Hardware::CPU.family end end diff --git a/Library/Homebrew/test/install_test.rb b/Library/Homebrew/test/install_test.rb index e047c0030..da6c1863f 100644 --- a/Library/Homebrew/test/install_test.rb +++ b/Library/Homebrew/test/install_test.rb @@ -73,13 +73,6 @@ class IntegrationCommandTestInstall < IntegrationCommandTestCase 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 @@ -105,15 +98,11 @@ class IntegrationCommandTestInstall < IntegrationCommandTestCase # 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", + assert_match "#{HOMEBREW_CELLAR}/testball1/HEAD-d5eb689", cmd("install", "testball1", "--HEAD", "--ignore-dependencies") + assert_match "testball1-HEAD-d5eb689 already installed", cmd("install", "testball1", "--HEAD", "--ignore-dependencies") - assert_match "#{HOMEBREW_CELLAR}/testball1/HEAD-2ccdf4f", cmd("unlink", "testball1") + assert_match "#{HOMEBREW_CELLAR}/testball1/HEAD-d5eb689", 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 diff --git a/Library/Homebrew/test/keg_test.rb b/Library/Homebrew/test/keg_test.rb index 2c91027e5..bd4232038 100644 --- a/Library/Homebrew/test/keg_test.rb +++ b/Library/Homebrew/test/keg_test.rb @@ -2,7 +2,7 @@ require "testing_env" require "keg" require "stringio" -class LinkTests < Homebrew::TestCase +class LinkTestCase < Homebrew::TestCase include FileUtils def setup_test_keg(name, version) @@ -20,6 +20,8 @@ class LinkTests < Homebrew::TestCase end def setup + super + @keg = setup_test_keg("foo", "1.0") @dst = HOMEBREW_PREFIX.join("bin", "helloworld") @nonexistent = Pathname.new("/some/nonexistent/path") @@ -34,15 +36,17 @@ class LinkTests < Homebrew::TestCase end def teardown - @kegs.each do |keg| - keg.unlink - keg.uninstall - end - + @kegs.each(&:unlink) $stdout = @old_stdout - - rmtree HOMEBREW_PREFIX/"bin" rmtree HOMEBREW_PREFIX/"lib" + super + end +end + +class LinkTests < LinkTestCase + def test_all + Formula.clear_racks_cache + assert_equal [@keg], Keg.all end def test_empty_installation @@ -294,8 +298,6 @@ class LinkTests < Homebrew::TestCase assert_equal 2, lib.children.length ensure a.unlink - a.uninstall - b.uninstall end def test_removes_broken_symlinks_that_conflict_with_directories @@ -311,11 +313,10 @@ class LinkTests < Homebrew::TestCase keg.link ensure keg.unlink - keg.uninstall end end -class InstalledDependantsTests < LinkTests +class InstalledDependantsTests < LinkTestCase def stub_formula_name(name) f = formula(name) { url "foo-1.0" } stub_formula_loader f @@ -333,6 +334,7 @@ class InstalledDependantsTests < LinkTests def setup super @dependent = setup_test_keg("bar", "1.0") + @keg.link end def alter_tab(keg = @dependent) @@ -341,24 +343,55 @@ class InstalledDependantsTests < LinkTests tab.write end - def dependencies(deps) + # 1.1.6 is the earliest version of Homebrew that generates correct runtime + # dependency lists in tabs. + def dependencies(deps, homebrew_version: "1.1.6") alter_tab do |tab| + tab.homebrew_version = homebrew_version tab.tabfile = @dependent.join("INSTALL_RECEIPT.json") tab.runtime_dependencies = deps end end + def unreliable_dependencies(deps) + # 1.1.5 is (hopefully!) the last version of Homebrew that generates + # incorrect runtime dependency lists in tabs. + dependencies(deps, homebrew_version: "1.1.5") + end + # Test with a keg whose formula isn't known. # This can happen if e.g. a formula is installed # from a file path or URL. def test_unknown_formula Formulary.unstub(:loader_for) - dependencies [] - alter_tab { |t| t.source["path"] = nil } - assert_empty @keg.installed_dependents + alter_tab(@keg) do |t| + t.source["tap"] = "some/tap" + t.source["path"] = nil + end + + dependencies [{ "full_name" => "some/tap/foo", "version" => "1.0" }] + assert_equal [@dependent], @keg.installed_dependents + assert_equal [[@keg], ["bar 1.0"]], Keg.find_some_installed_dependents([@keg]) + + dependencies nil + # It doesn't make sense for a keg with no formula to have any dependents, + # so that can't really be tested. assert_nil Keg.find_some_installed_dependents([@keg]) end + def test_a_dependency_with_no_tap_in_tab + @tap_dep = setup_test_keg("baz", "1.0") + + alter_tab(@keg) { |t| t.source["tap"] = nil } + + dependencies nil + Formula["bar"].class.depends_on "foo" + Formula["bar"].class.depends_on "baz" + + result = Keg.find_some_installed_dependents([@keg, @tap_dep]) + assert_equal [[@keg, @tap_dep], ["bar"]], result + end + def test_no_dependencies_anywhere dependencies nil assert_empty @keg.installed_dependents @@ -372,6 +405,27 @@ class InstalledDependantsTests < LinkTests assert_equal [[@keg], ["bar"]], Keg.find_some_installed_dependents([@keg]) end + def test_uninstalling_dependent_and_dependency + dependencies nil + Formula["bar"].class.depends_on "foo" + assert_empty @keg.installed_dependents + assert_nil Keg.find_some_installed_dependents([@keg, @dependent]) + end + + def test_renamed_dependency + dependencies nil + + stub_formula_loader Formula["foo"], "homebrew/core/foo-old" + renamed_path = HOMEBREW_CELLAR/"foo-old" + (HOMEBREW_CELLAR/"foo").rename(renamed_path) + renamed_keg = Keg.new(renamed_path.join("1.0")) + + Formula["bar"].class.depends_on "foo" + + result = Keg.find_some_installed_dependents([renamed_keg]) + assert_equal [[renamed_keg], ["bar"]], result + end + def test_empty_dependencies_in_tab dependencies [] assert_empty @keg.installed_dependents @@ -380,8 +434,8 @@ class InstalledDependantsTests < LinkTests def test_same_name_different_version_in_tab dependencies [{ "full_name" => "foo", "version" => "1.1" }] - assert_empty @keg.installed_dependents - assert_nil Keg.find_some_installed_dependents([@keg]) + assert_equal [@dependent], @keg.installed_dependents + assert_equal [[@keg], ["bar 1.0"]], Keg.find_some_installed_dependents([@keg]) end def test_different_name_same_version_in_tab @@ -396,4 +450,26 @@ class InstalledDependantsTests < LinkTests assert_equal [@dependent], @keg.installed_dependents assert_equal [[@keg], ["bar 1.0"]], Keg.find_some_installed_dependents([@keg]) end + + def test_fallback_for_old_versions + unreliable_dependencies [{ "full_name" => "baz", "version" => "1.0" }] + Formula["bar"].class.depends_on "foo" + assert_empty @keg.installed_dependents + assert_equal [[@keg], ["bar"]], Keg.find_some_installed_dependents([@keg]) + end + + def test_nonoptlinked + @keg.remove_opt_record + dependencies [{ "full_name" => "foo", "version" => "1.0" }] + assert_empty @keg.installed_dependents + assert_nil Keg.find_some_installed_dependents([@keg]) + end + + def test_keg_only + @keg.unlink + Formula["foo"].class.keg_only "a good reason" + dependencies [{ "full_name" => "foo", "version" => "1.1" }] # different version + assert_equal [@dependent], @keg.installed_dependents + assert_equal [[@keg], ["bar 1.0"]], Keg.find_some_installed_dependents([@keg]) + end end diff --git a/Library/Homebrew/test/language_python_test.rb b/Library/Homebrew/test/language_python_test.rb index d1e3867f7..aa0a7d51d 100644 --- a/Library/Homebrew/test/language_python_test.rb +++ b/Library/Homebrew/test/language_python_test.rb @@ -4,6 +4,7 @@ require "resource" class LanguagePythonTests < Homebrew::TestCase def setup + super @dir = Pathname.new(mktmpdir) resource = stub("resource", stage: true) formula_bin = @dir/"formula_bin" @@ -14,10 +15,6 @@ class LanguagePythonTests < Homebrew::TestCase @venv = Language::Python::Virtualenv::Virtualenv.new(@formula, @dir, "python") end - def teardown - FileUtils.rm_rf @dir - end - def test_virtualenv_creation @formula.expects(:resource).with("homebrew-virtualenv").returns( mock("resource", stage: true) diff --git a/Library/Homebrew/test/migrator_test.rb b/Library/Homebrew/test/migrator_test.rb index 8a2b6ad63..012ea12bb 100644 --- a/Library/Homebrew/test/migrator_test.rb +++ b/Library/Homebrew/test/migrator_test.rb @@ -10,6 +10,7 @@ end class MigratorErrorsTests < Homebrew::TestCase def setup + super @new_f = Testball.new("newname") @new_f.oldname = "oldname" @old_f = Testball.new("oldname") @@ -31,8 +32,6 @@ class MigratorErrorsTests < Homebrew::TestCase tab.source["tap"] = "homebrew/core" tab.write assert_raises(Migrator::MigratorDifferentTapsError) { Migrator.new(@new_f) } - ensure - keg.parent.rmtree end end @@ -40,6 +39,8 @@ class MigratorTests < Homebrew::TestCase include FileUtils def setup + super + @new_f = Testball.new("newname") @new_f.oldname = "oldname" @@ -69,30 +70,16 @@ class MigratorTests < Homebrew::TestCase end def teardown - @old_pin.unlink if @old_pin.symlink? - - if @old_keg_record.parent.symlink? - @old_keg_record.parent.unlink - elsif @old_keg_record.directory? + if !@old_keg_record.parent.symlink? && @old_keg_record.directory? @keg.unlink - @keg.uninstall end if @new_keg_record.directory? new_keg = Keg.new(@new_keg_record) new_keg.unlink - new_keg.uninstall end - @old_keg_record.parent.rmtree if @old_keg_record.parent.directory? - @new_keg_record.parent.rmtree if @new_keg_record.parent.directory? - - rmtree HOMEBREW_PREFIX/"bin" - rmtree HOMEBREW_PREFIX/"opt" if (HOMEBREW_PREFIX/"opt").directory? - # What to do with pin? - @new_f.unpin - - HOMEBREW_LOCK_DIR.children.each(&:unlink) + super end def test_move_cellar diff --git a/Library/Homebrew/test/options_test.rb b/Library/Homebrew/test/options_test.rb index e7189a604..f38ec4415 100644 --- a/Library/Homebrew/test/options_test.rb +++ b/Library/Homebrew/test/options_test.rb @@ -15,6 +15,7 @@ end class OptionTests < Homebrew::TestCase def setup + super @option = Option.new("foo") end @@ -43,6 +44,7 @@ end class DeprecatedOptionTests < Homebrew::TestCase def setup + super @deprecated_option = DeprecatedOption.new("foo", "bar") end @@ -68,6 +70,7 @@ end class OptionsTests < Homebrew::TestCase def setup + super @options = Options.new end diff --git a/Library/Homebrew/test/os/mac/bottle_collector_test.rb b/Library/Homebrew/test/os/mac/bottle_collector_test.rb index 2f88050ae..e9ae9b753 100644 --- a/Library/Homebrew/test/os/mac/bottle_collector_test.rb +++ b/Library/Homebrew/test/os/mac/bottle_collector_test.rb @@ -3,6 +3,7 @@ require "utils/bottles" class OSMacBottleCollectorTests < Homebrew::TestCase def setup + super @collector = Utils::Bottles::Collector.new end diff --git a/Library/Homebrew/test/os/mac/dependency_collector_test.rb b/Library/Homebrew/test/os/mac/dependency_collector_test.rb index 4fdf3ebe4..1033df9ab 100644 --- a/Library/Homebrew/test/os/mac/dependency_collector_test.rb +++ b/Library/Homebrew/test/os/mac/dependency_collector_test.rb @@ -7,11 +7,13 @@ class OSMacDependencyCollectorTests < Homebrew::TestCase end def setup + super @d = DependencyCollector.new end def teardown DependencyCollector.clear_cache + super end def test_tar_needs_xz_dependency diff --git a/Library/Homebrew/test/os/mac/diagnostic_test.rb b/Library/Homebrew/test/os/mac/diagnostic_test.rb index 655aa1d46..704235b01 100644 --- a/Library/Homebrew/test/os/mac/diagnostic_test.rb +++ b/Library/Homebrew/test/os/mac/diagnostic_test.rb @@ -5,14 +5,10 @@ require "diagnostic" class OSMacDiagnosticChecksTest < Homebrew::TestCase def setup - @env = ENV.to_hash + super @checks = Homebrew::Diagnostic::Checks.new end - def teardown - ENV.replace(@env) - end - def test_check_for_other_package_managers MacOS.stubs(:macports_or_fink).returns ["fink"] assert_match "You have MacPorts or Fink installed:", @@ -20,7 +16,7 @@ class OSMacDiagnosticChecksTest < Homebrew::TestCase end def test_check_for_unsupported_macos - ARGV.stubs(:homebrew_developer?).returns false + ENV.delete("HOMEBREW_DEVELOPER") OS::Mac.stubs(:prerelease?).returns true assert_match "We do not provide support for this pre-release version.", @checks.check_for_unsupported_macos diff --git a/Library/Homebrew/test/os/mac/keg_test.rb b/Library/Homebrew/test/os/mac/keg_test.rb index e79cbc921..d1103415d 100644 --- a/Library/Homebrew/test/os/mac/keg_test.rb +++ b/Library/Homebrew/test/os/mac/keg_test.rb @@ -6,6 +6,8 @@ class OSMacLinkTests < Homebrew::TestCase include FileUtils def setup + super + keg = HOMEBREW_CELLAR.join("foo", "1.0") keg.join("bin").mkpath @@ -28,12 +30,12 @@ class OSMacLinkTests < Homebrew::TestCase def teardown @keg.unlink - @keg.uninstall $stdout = @old_stdout - rmtree HOMEBREW_PREFIX/"bin" rmtree HOMEBREW_PREFIX/"lib" + + super end def test_mach_o_files_skips_hardlinks @@ -48,7 +50,6 @@ class OSMacLinkTests < Homebrew::TestCase assert_equal 1, keg.mach_o_files.size ensure keg.unlink - keg.uninstall end def test_mach_o_files_isnt_confused_by_symlinks @@ -64,6 +65,5 @@ class OSMacLinkTests < Homebrew::TestCase assert_equal 1, keg.mach_o_files.size ensure keg.unlink - keg.uninstall end end diff --git a/Library/Homebrew/test/os/mac/mach_test.rb b/Library/Homebrew/test/os/mac/mach_test.rb index a42f7316b..ed0424be6 100644 --- a/Library/Homebrew/test/os/mac/mach_test.rb +++ b/Library/Homebrew/test/os/mac/mach_test.rb @@ -109,6 +109,7 @@ end class ArchitectureListExtensionTests < MachOPathnameTests def setup + super @archs = [:i386, :x86_64, :ppc7400, :ppc64].extend(ArchitectureListExtension) end @@ -157,11 +158,13 @@ class TextExecutableTests < Homebrew::TestCase attr_reader :pn def setup + super @pn = HOMEBREW_PREFIX.join("an_executable") end def teardown HOMEBREW_PREFIX.join("an_executable").unlink + super end def test_simple_shebang diff --git a/Library/Homebrew/test/os/mac/version_test.rb b/Library/Homebrew/test/os/mac/version_test.rb index f702c7097..ba4217691 100644 --- a/Library/Homebrew/test/os/mac/version_test.rb +++ b/Library/Homebrew/test/os/mac/version_test.rb @@ -4,6 +4,7 @@ require "os/mac/version" class OSMacVersionTests < Homebrew::TestCase def setup + super @v = MacOS::Version.new("10.7") end diff --git a/Library/Homebrew/test/patch_test.rb b/Library/Homebrew/test/patch_test.rb index 62624720e..f5a61398a 100644 --- a/Library/Homebrew/test/patch_test.rb +++ b/Library/Homebrew/test/patch_test.rb @@ -111,6 +111,7 @@ end class ExternalPatchTests < Homebrew::TestCase def setup + super @p = ExternalPatch.new(:p1) { url "file:///my.patch" } end diff --git a/Library/Homebrew/test/patching_test.rb b/Library/Homebrew/test/patching_test.rb index ac14c8e1e..3dacc0818 100644 --- a/Library/Homebrew/test/patching_test.rb +++ b/Library/Homebrew/test/patching_test.rb @@ -20,11 +20,6 @@ class PatchingTests < Homebrew::TestCase end end - def teardown - @_f.clear_cache - @_f.patchlist.each { |p| p.clear_cache if p.external? } - end - def assert_patched(formula) shutup do formula.brew do diff --git a/Library/Homebrew/test/pathname_test.rb b/Library/Homebrew/test/pathname_test.rb index 2f6360719..b48a26fbd 100644 --- a/Library/Homebrew/test/pathname_test.rb +++ b/Library/Homebrew/test/pathname_test.rb @@ -7,16 +7,12 @@ module PathnameTestExtension include FileUtils def setup + super @src = Pathname.new(mktmpdir) @dst = Pathname.new(mktmpdir) @file = @src/"foo" @dir = @src/"bar" end - - def teardown - rmtree(@src) - rmtree(@dst) - end end class PathnameTests < Homebrew::TestCase diff --git a/Library/Homebrew/test/resource_test.rb b/Library/Homebrew/test/resource_test.rb index c1b526cb2..d982a7c33 100644 --- a/Library/Homebrew/test/resource_test.rb +++ b/Library/Homebrew/test/resource_test.rb @@ -3,6 +3,7 @@ require "resource" class ResourceTests < Homebrew::TestCase def setup + super @resource = Resource.new("test") end diff --git a/Library/Homebrew/test/sandbox_test.rb b/Library/Homebrew/test/sandbox_test.rb index 2a062cb10..a633defce 100644 --- a/Library/Homebrew/test/sandbox_test.rb +++ b/Library/Homebrew/test/sandbox_test.rb @@ -3,26 +3,23 @@ require "sandbox" class SandboxTest < Homebrew::TestCase def setup + super skip "sandbox not implemented" unless Sandbox.available? @sandbox = Sandbox.new @dir = Pathname.new(mktmpdir) @file = @dir/"foo" end - def teardown - @dir.rmtree - end - def test_formula? f = formula { url "foo-1.0" } f2 = formula { url "bar-1.0" } f2.stubs(:tap).returns(Tap.fetch("test/tap")) - ARGV.stubs(:sandbox?).returns true + ENV["HOMEBREW_SANDBOX"] = "1" assert Sandbox.formula?(f), "Formulae should be sandboxed if --sandbox was passed." - ARGV.stubs(:sandbox?).returns false + ENV.delete("HOMEBREW_SANDBOX") assert Sandbox.formula?(f), "Formulae should be sandboxed if in a sandboxed tap." refute Sandbox.formula?(f2), @@ -30,7 +27,7 @@ class SandboxTest < Homebrew::TestCase end def test_test? - ARGV.stubs(:no_sandbox?).returns false + ENV.delete("HOMEBREW_NO_SANDBOX") assert Sandbox.test?, "Tests should be sandboxed unless --no-sandbox was passed." end @@ -50,7 +47,7 @@ class SandboxTest < Homebrew::TestCase def test_complains_on_failure Utils.expects(popen_read: "foo") - ARGV.stubs(verbose?: true) + ENV["HOMEBREW_VERBOSE"] = "1" out, _err = capture_io do assert_raises(ErrorDuringExecution) { @sandbox.exec "false" } end @@ -64,7 +61,7 @@ class SandboxTest < Homebrew::TestCase bar EOS Utils.expects(popen_read: with_bogus_error) - ARGV.stubs(verbose?: true) + ENV["HOMEBREW_VERBOSE"] = "1" out, _err = capture_io do assert_raises(ErrorDuringExecution) { @sandbox.exec "false" } end diff --git a/Library/Homebrew/test/shell_test.rb b/Library/Homebrew/test/shell_test.rb index 877acb5c8..a32d09863 100644 --- a/Library/Homebrew/test/shell_test.rb +++ b/Library/Homebrew/test/shell_test.rb @@ -37,7 +37,6 @@ class ShellSmokeTest < Homebrew::TestCase end def prepend_path_shell(shell, path, fragment) - original_shell = ENV["SHELL"] ENV["SHELL"] = shell prepend_message = Utils::Shell.prepend_path_in_shell_profile(path) @@ -45,8 +44,6 @@ class ShellSmokeTest < Homebrew::TestCase prepend_message.start_with?(fragment), "#{shell}: expected #{prepend_message} to match #{fragment}" ) - - ENV["SHELL"] = original_shell end def test_prepend_path_in_shell_profile diff --git a/Library/Homebrew/test/software_spec_test.rb b/Library/Homebrew/test/software_spec_test.rb index d9226f8c3..026265a4a 100644 --- a/Library/Homebrew/test/software_spec_test.rb +++ b/Library/Homebrew/test/software_spec_test.rb @@ -3,6 +3,7 @@ require "software_spec" class SoftwareSpecTests < Homebrew::TestCase def setup + super @spec = SoftwareSpec.new end @@ -136,6 +137,7 @@ end class HeadSoftwareSpecTests < Homebrew::TestCase def setup + super @spec = HeadSoftwareSpec.new end @@ -150,6 +152,7 @@ end class BottleSpecificationTests < Homebrew::TestCase def setup + super @spec = BottleSpecification.new end diff --git a/Library/Homebrew/test/stdlib_test.rb b/Library/Homebrew/test/stdlib_test.rb index ee53e7c8c..f193ae71e 100644 --- a/Library/Homebrew/test/stdlib_test.rb +++ b/Library/Homebrew/test/stdlib_test.rb @@ -4,9 +4,11 @@ require "cxxstdlib" class CxxStdlibTests < Homebrew::TestCase def setup + super @clang = CxxStdlib.create(:libstdcxx, :clang) @gcc = CxxStdlib.create(:libstdcxx, :gcc) - @gcc4 = CxxStdlib.create(:libstdcxx, :gcc_4_0) + @gcc40 = CxxStdlib.create(:libstdcxx, :gcc_4_0) + @gcc42 = CxxStdlib.create(:libstdcxx, :gcc_4_2) @gcc48 = CxxStdlib.create(:libstdcxx, "gcc-4.8") @gcc49 = CxxStdlib.create(:libstdcxx, "gcc-4.9") @lcxx = CxxStdlib.create(:libcxx, :clang) @@ -15,7 +17,7 @@ class CxxStdlibTests < Homebrew::TestCase def test_apple_libstdcxx_intercompatibility assert @clang.compatible_with?(@gcc) - assert @clang.compatible_with?(@gcc4) + assert @clang.compatible_with?(@gcc42) end def test_compatibility_same_compilers_and_type @@ -42,7 +44,7 @@ class CxxStdlibTests < Homebrew::TestCase def test_apple_compiler_reporting assert_predicate @clang, :apple_compiler? assert_predicate @gcc, :apple_compiler? - assert_predicate @gcc4, :apple_compiler? + assert_predicate @gcc42, :apple_compiler? refute_predicate @gcc48, :apple_compiler? end diff --git a/Library/Homebrew/test/support/fixtures/receipt.json b/Library/Homebrew/test/support/fixtures/receipt.json index b20626bbe..a57d6d80d 100644 --- a/Library/Homebrew/test/support/fixtures/receipt.json +++ b/Library/Homebrew/test/support/fixtures/receipt.json @@ -1,4 +1,5 @@ { + "homebrew_version": "1.1.6", "used_options": [ "--with-foo", "--without-bar" diff --git a/Library/Homebrew/test/support/helper/env.rb b/Library/Homebrew/test/support/helper/env.rb deleted file mode 100644 index 904a1d4c7..000000000 --- a/Library/Homebrew/test/support/helper/env.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Test - module Helper - module Env - def with_environment(partial_env) - old = ENV.to_hash - ENV.update partial_env - begin - yield - ensure - ENV.replace old - end - end - end - end -end diff --git a/Library/Homebrew/test/support/helper/integration_command_test_case.rb b/Library/Homebrew/test/support/helper/integration_command_test_case.rb index b79fdd6e0..a36b56691 100644 --- a/Library/Homebrew/test/support/helper/integration_command_test_case.rb +++ b/Library/Homebrew/test/support/helper/integration_command_test_case.rb @@ -6,40 +6,12 @@ require "test/support/helper/test_case" class IntegrationCommandTestCase < Homebrew::TestCase def setup + super @cmd_id_index = 0 # Assign unique IDs to invocations of `cmd_output`. (HOMEBREW_PREFIX/"bin").mkpath FileUtils.touch HOMEBREW_PREFIX/"bin/brew" end - def teardown - coretap = CoreTap.new - paths_to_delete = [ - HOMEBREW_LINKED_KEGS, - HOMEBREW_PINNED_KEGS, - HOMEBREW_CELLAR.children, - HOMEBREW_CACHE.children, - HOMEBREW_LOCK_DIR.children, - HOMEBREW_LOGS.children, - HOMEBREW_TEMP.children, - HOMEBREW_PREFIX/".git", - HOMEBREW_PREFIX/"bin", - HOMEBREW_PREFIX/"share", - HOMEBREW_PREFIX/"opt", - HOMEBREW_PREFIX/"Caskroom", - HOMEBREW_LIBRARY/"Taps/caskroom", - HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-bundle", - HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-foo", - HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-services", - HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-shallow", - HOMEBREW_REPOSITORY/".git", - coretap.path/".git", - coretap.alias_dir, - coretap.formula_dir.children, - coretap.path/"formula_renames.json", - ].flatten - FileUtils.rm_rf paths_to_delete - end - def needs_test_cmd_taps return if ENV["HOMEBREW_TEST_OFFICIAL_CMD_TAPS"] skip "HOMEBREW_TEST_OFFICIAL_CMD_TAPS is not set" @@ -106,16 +78,20 @@ class IntegrationCommandTestCase < Homebrew::TestCase def cmd(*args) output = cmd_output(*args) status = $?.exitstatus - puts "\n'brew #{args.join " "}' output: #{output}" if status.nonzero? - assert_equal 0, status + assert_equal 0, status, <<-EOS.undent + `brew #{args.join " "}` exited with non-zero status! + #{output} + EOS output end def cmd_fail(*args) output = cmd_output(*args) status = $?.exitstatus - $stderr.puts "\n'brew #{args.join " "}'" if status.zero? - refute_equal 0, status + refute_equal 0, status, <<-EOS.undent + `brew #{args.join " "}` exited with zero status! + #{output} + EOS output end diff --git a/Library/Homebrew/test/support/helper/lifecycle_enforcer.rb b/Library/Homebrew/test/support/helper/lifecycle_enforcer.rb new file mode 100644 index 000000000..413f8b11e --- /dev/null +++ b/Library/Homebrew/test/support/helper/lifecycle_enforcer.rb @@ -0,0 +1,22 @@ +module Test + module Helper + module LifecycleEnforcer + def setup + @__setup_called = true + super + end + + def teardown + @__teardown_called = true + super + end + + def after_teardown + assert @__setup_called, "Expected setup to call `super` but didn't" + assert @__teardown_called, "Expected teardown to call `super` but didn't" + + super + end + end + end +end diff --git a/Library/Homebrew/test/support/helper/test_case.rb b/Library/Homebrew/test/support/helper/test_case.rb index 60c91e7bb..ab97ef758 100644 --- a/Library/Homebrew/test/support/helper/test_case.rb +++ b/Library/Homebrew/test/support/helper/test_case.rb @@ -1,17 +1,60 @@ module Homebrew class TestCase < ::Minitest::Test - require "test/support/helper/env" require "test/support/helper/fs_leak_logger" + require "test/support/helper/lifecycle_enforcer" require "test/support/helper/shutup" require "test/support/helper/version_assertions" - include Test::Helper::Env include Test::Helper::FSLeakLogger + include Test::Helper::LifecycleEnforcer include Test::Helper::Shutup include Test::Helper::VersionAssertions TEST_SHA1 = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef".freeze TEST_SHA256 = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef".freeze + def setup + super + + @__argv = ARGV.dup + @__env = ENV.to_hash # dup doesn't work on ENV + end + + def teardown + ARGV.replace(@__argv) + ENV.replace(@__env) + + Tab.clear_cache + + coretap = CoreTap.new + paths_to_delete = [ + HOMEBREW_LINKED_KEGS, + HOMEBREW_PINNED_KEGS, + HOMEBREW_CELLAR.children, + HOMEBREW_CACHE.children, + HOMEBREW_LOCK_DIR.children, + HOMEBREW_LOGS.children, + HOMEBREW_TEMP.children, + HOMEBREW_PREFIX/".git", + HOMEBREW_PREFIX/"bin", + HOMEBREW_PREFIX/"share", + HOMEBREW_PREFIX/"opt", + HOMEBREW_PREFIX/"Caskroom", + HOMEBREW_LIBRARY/"Taps/caskroom", + HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-bundle", + HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-foo", + HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-services", + HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-shallow", + HOMEBREW_REPOSITORY/".git", + coretap.path/".git", + coretap.alias_dir, + coretap.formula_dir.children, + coretap.path/"formula_renames.json", + ].flatten + FileUtils.rm_rf paths_to_delete + + super + end + def formula(name = "formula_name", path = Formulary.core_path(name), spec = :stable, alias_path: nil, &block) @_f = Class.new(Formula, &block).new(name, path, spec, alias_path: alias_path) end diff --git a/Library/Homebrew/test/tab_test.rb b/Library/Homebrew/test/tab_test.rb index 5d83b5907..f6f55348d 100644 --- a/Library/Homebrew/test/tab_test.rb +++ b/Library/Homebrew/test/tab_test.rb @@ -4,6 +4,8 @@ require "formula" class TabTests < Homebrew::TestCase def setup + super + @used = Options.create(%w[--with-foo --without-bar]) @unused = Options.create(%w[--with-baz --without-qux]) @@ -32,6 +34,8 @@ class TabTests < Homebrew::TestCase def test_defaults tab = Tab.empty + + assert_equal HOMEBREW_VERSION, tab.homebrew_version assert_empty tab.unused_options assert_empty tab.used_options assert_nil tab.changed_files @@ -69,6 +73,49 @@ class TabTests < Homebrew::TestCase assert_predicate tab, :universal? end + def test_parsed_homebrew_version + tab = Tab.new + assert_same Version::NULL, tab.parsed_homebrew_version + + tab = Tab.new(homebrew_version: "1.2.3") + assert_equal "1.2.3", tab.parsed_homebrew_version + assert tab.parsed_homebrew_version < "1.2.3-1-g12789abdf" + assert_kind_of Version, tab.parsed_homebrew_version + + tab.homebrew_version = "1.2.4-567-g12789abdf" + assert tab.parsed_homebrew_version > "1.2.4" + assert tab.parsed_homebrew_version > "1.2.4-566-g21789abdf" + assert tab.parsed_homebrew_version < "1.2.4-568-g01789abdf" + + tab = Tab.new(homebrew_version: "2.0.0-134-gabcdefabc-dirty") + assert tab.parsed_homebrew_version > "2.0.0" + assert tab.parsed_homebrew_version > "2.0.0-133-g21789abdf" + assert tab.parsed_homebrew_version < "2.0.0-135-g01789abdf" + end + + def test_runtime_dependencies + tab = Tab.new + assert_nil tab.runtime_dependencies + + tab.homebrew_version = "1.1.6" + assert_nil tab.runtime_dependencies + + tab.runtime_dependencies = [] + refute_nil tab.runtime_dependencies + + tab.homebrew_version = "1.1.5" + assert_nil tab.runtime_dependencies + + tab.homebrew_version = "1.1.7" + refute_nil tab.runtime_dependencies + + tab.homebrew_version = "1.1.10" + refute_nil tab.runtime_dependencies + + tab.runtime_dependencies = [{ "full_name" => "foo", "version" => "1.0" }] + refute_nil tab.runtime_dependencies + end + def test_cxxstdlib assert_equal :clang, @tab.cxxstdlib.compiler assert_equal :libcxx, @tab.cxxstdlib.type @@ -215,16 +262,13 @@ end class TabLoadingTests < Homebrew::TestCase def setup + super @f = formula { url "foo-1.0" } @f.prefix.mkpath @path = @f.prefix.join(Tab::FILENAME) @path.write TEST_FIXTURE_DIR.join("receipt.json").read end - def teardown - @f.rack.rmtree - end - def test_for_keg tab = Tab.for_keg(@f.prefix) assert_equal @path, tab.tabfile diff --git a/Library/Homebrew/test/tap_test.rb b/Library/Homebrew/test/tap_test.rb index b950cd166..578326cea 100644 --- a/Library/Homebrew/test/tap_test.rb +++ b/Library/Homebrew/test/tap_test.rb @@ -16,7 +16,7 @@ class IntegrationCommandTestTap < IntegrationCommandTestCase end assert_match "homebrew/foo", cmd("tap") - assert_match "homebrew/versions", cmd("tap", "--list-official") + assert_match "homebrew/science", cmd("tap", "--list-official") assert_match "2 taps", cmd("tap-info") assert_match "https://github.com/Homebrew/homebrew-foo", cmd("tap-info", "homebrew/foo") assert_match "https://github.com/Homebrew/homebrew-foo", cmd("tap-info", "--json=v1", "--installed") @@ -34,6 +34,7 @@ class TapTest < Homebrew::TestCase include FileUtils def setup + super @path = Tap::TAP_DIRECTORY/"homebrew/homebrew-foo" @path.mkpath @tap = Tap.new("Homebrew", "foo") @@ -65,13 +66,6 @@ class TapTest < Homebrew::TestCase end def setup_git_repo - 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 - @path.cd do shutup do system "git", "init" @@ -80,12 +74,6 @@ class TapTest < Homebrew::TestCase system "git", "commit", "-m", "init" end end - ensure - ENV.replace(env) - end - - def teardown - @path.rmtree end def test_fetch @@ -162,17 +150,15 @@ class TapTest < Homebrew::TestCase assert_raises(TapUnavailableError) { Tap.new("Homebrew", "bar").remote } refute_predicate @tap, :custom_remote? - version_tap = Tap.new("Homebrew", "versions") - version_tap.path.mkpath - version_tap.path.cd do + services_tap = Tap.new("Homebrew", "services") + services_tap.path.mkpath + services_tap.path.cd do shutup do system "git", "init" - system "git", "remote", "add", "origin", "https://github.com/Homebrew/homebrew-versions" + system "git", "remote", "add", "origin", "https://github.com/Homebrew/homebrew-services" end end - refute_predicate version_tap, :private? - ensure - version_tap.path.rmtree if version_tap + refute_predicate services_tap, :private? end def test_remote_not_git_repo @@ -189,10 +175,10 @@ class TapTest < Homebrew::TestCase touch @path/"README" setup_git_repo - assert_equal "e1893a6bd191ba895c71b652ff8376a6114c7fa7", @tap.git_head - assert_equal "e189", @tap.git_short_head - assert_match "years ago", @tap.git_last_commit - assert_equal "2009-05-21", @tap.git_last_commit_date + assert_equal "0453e16c8e3fac73104da50927a86221ca0740c2", @tap.git_head + assert_equal "0453", @tap.git_short_head + assert_match(/\A\d+ .+ ago\Z/, @tap.git_last_commit) + assert_equal "2017-01-22", @tap.git_last_commit_date end def test_private_remote @@ -256,8 +242,6 @@ class TapTest < Homebrew::TestCase refute_predicate tap, :installed? refute_predicate HOMEBREW_PREFIX/"share/man/man1/brew-tap-cmd.1", :exist? refute_predicate HOMEBREW_PREFIX/"share/man/man1", :exist? - ensure - (HOMEBREW_PREFIX/"share").rmtree if (HOMEBREW_PREFIX/"share").exist? end def test_pin_and_unpin @@ -285,6 +269,7 @@ class CoreTapTest < Homebrew::TestCase include FileUtils def setup + super @repo = CoreTap.new end @@ -322,8 +307,5 @@ class CoreTapTest < Homebrew::TestCase assert_equal ["bar"], @repo.aliases assert_equal @repo.alias_table, "bar" => "foo" assert_equal @repo.alias_reverse_table, "foo" => ["bar"] - ensure - @formula_file.unlink - @repo.alias_dir.rmtree end end diff --git a/Library/Homebrew/test/uninstall_test.rb b/Library/Homebrew/test/uninstall_test.rb index 5c53988f2..2f8bf4fff 100644 --- a/Library/Homebrew/test/uninstall_test.rb +++ b/Library/Homebrew/test/uninstall_test.rb @@ -3,15 +3,21 @@ require "cmd/uninstall" class UninstallTests < Homebrew::TestCase def setup + super + @dependency = formula("dependency") { url "f-1" } @dependent = formula("dependent") do url "f-1" depends_on "dependency" end - [@dependency, @dependent].each { |f| f.installed_prefix.mkpath } + [@dependency, @dependent].each do |f| + f.installed_prefix.mkpath + Keg.new(f.installed_prefix).optlink + end tab = Tab.empty + tab.homebrew_version = "1.1.6" tab.tabfile = @dependent.installed_prefix/Tab::FILENAME tab.runtime_dependencies = [ { "full_name" => "dependency", "version" => "1" }, @@ -24,7 +30,7 @@ class UninstallTests < Homebrew::TestCase def teardown Homebrew.failed = false - [@dependency, @dependent].each { |f| f.rack.rmtree } + super end def handle_unsatisfied_dependents @@ -52,8 +58,6 @@ class UninstallTests < Homebrew::TestCase assert_empty handle_unsatisfied_dependents refute_predicate Homebrew, :failed? end - ensure - ARGV.delete("--ignore-dependencies") end end diff --git a/Library/Homebrew/test/update_report_test.rb b/Library/Homebrew/test/update_report_test.rb index 6b6cec6ce..32c3e36d0 100644 --- a/Library/Homebrew/test/update_report_test.rb +++ b/Library/Homebrew/test/update_report_test.rb @@ -24,6 +24,7 @@ class ReportTests < Homebrew::TestCase end def setup + super @tap = CoreTap.new @reporter = ReporterMock.new(@tap) @hub = ReporterHub.new diff --git a/Library/Homebrew/test/utils_test.rb b/Library/Homebrew/test/utils_test.rb index 146f57b49..1f2fb7b55 100644 --- a/Library/Homebrew/test/utils_test.rb +++ b/Library/Homebrew/test/utils_test.rb @@ -5,13 +5,12 @@ require "utils/shell" class UtilTests < Homebrew::TestCase def setup + super @dir = Pathname.new(mktmpdir) - @env = ENV.to_hash end - def teardown - @dir.rmtree - ENV.replace @env + def esc(code) + /(\e\[\d+m)*\e\[#{code}m/ end def test_ofail @@ -27,11 +26,29 @@ class UtilTests < Homebrew::TestCase end def test_pretty_installed + $stdout.stubs(:tty?).returns true + ENV.delete("HOMEBREW_NO_EMOJI") + tty_with_emoji_output = /\A#{esc 1}foo #{esc 32}✔#{esc 0}\Z/ + assert_match tty_with_emoji_output, pretty_installed("foo") + + ENV["HOMEBREW_NO_EMOJI"] = "1" + tty_no_emoji_output = /\A#{esc 1}foo \(installed\)#{esc 0}\Z/ + assert_match tty_no_emoji_output, pretty_installed("foo") + $stdout.stubs(:tty?).returns false assert_equal "foo", pretty_installed("foo") end def test_pretty_uninstalled + $stdout.stubs(:tty?).returns true + ENV.delete("HOMEBREW_NO_EMOJI") + tty_with_emoji_output = /\A#{esc 1}foo #{esc 31}✘#{esc 0}\Z/ + assert_match tty_with_emoji_output, pretty_uninstalled("foo") + + ENV["HOMEBREW_NO_EMOJI"] = "1" + tty_no_emoji_output = /\A#{esc 1}foo \(uninstalled\)#{esc 0}\Z/ + assert_match tty_no_emoji_output, pretty_uninstalled("foo") + $stdout.stubs(:tty?).returns false assert_equal "foo", pretty_uninstalled("foo") end @@ -212,11 +229,11 @@ class UtilTests < Homebrew::TestCase end def test_odeprecated - ARGV.stubs(:homebrew_developer?).returns false + ENV.delete("HOMEBREW_DEVELOPER") e = assert_raises(MethodDeprecatedError) do odeprecated("method", "replacement", caller: ["#{HOMEBREW_LIBRARY}/Taps/homebrew/homebrew-core/"], - die: true) + disable: true) end assert_match "method", e.message assert_match "replacement", e.message diff --git a/Library/Homebrew/test/versions_test.rb b/Library/Homebrew/test/versions_test.rb index a6e922178..b6814b1d1 100644 --- a/Library/Homebrew/test/versions_test.rb +++ b/Library/Homebrew/test/versions_test.rb @@ -185,8 +185,6 @@ class VersionParsingTests < Homebrew::TestCase d = HOMEBREW_CELLAR/"foo-0.1.9" d.mkpath assert_equal version("0.1.9"), d.version - ensure - d.unlink end def test_no_version diff --git a/Library/Homebrew/utils.rb b/Library/Homebrew/utils.rb index 4ad97c7d4..70d2787d9 100644 --- a/Library/Homebrew/utils.rb +++ b/Library/Homebrew/utils.rb @@ -11,6 +11,7 @@ require "utils/hash" require "utils/inreplace" require "utils/popen" require "utils/tty" +require "time" def ohai(title, *sput) title = Tty.truncate(title) if $stdout.tty? && !ARGV.verbose? @@ -44,24 +45,32 @@ def odie(error) exit 1 end -def odeprecated(method, replacement = nil, options = {}) - verb = if options[:die] - "disabled" - else - "deprecated" - end - +def odeprecated(method, replacement = nil, disable: false, disable_on: nil, caller: send(:caller)) replacement_message = if replacement "Use #{replacement} instead." else "There is no replacement." end + unless disable_on.nil? + if disable_on > Time.now + will_be_disabled_message = " and will be disabled on #{disable_on.strftime("%Y-%m-%d")}" + else + disable = true + end + end + + verb = if disable + "disabled" + else + "deprecated#{will_be_disabled_message}" + end + # Try to show the most relevant location in message, i.e. (if applicable): # - Location in a formula. # - Location outside of 'compat/'. # - Location of caller of deprecated method (if all else fails). - backtrace = options.fetch(:caller, caller) + backtrace = caller tap_message = nil caller_message = backtrace.detect do |line| next unless line =~ %r{^#{Regexp.escape HOMEBREW_LIBRARY}/Taps/([^/]+/[^/]+)/} @@ -80,7 +89,7 @@ def odeprecated(method, replacement = nil, options = {}) #{caller_message}#{tap_message} EOS - if ARGV.homebrew_developer? || options[:die] || + if ARGV.homebrew_developer? || disable || Homebrew.raise_deprecation_exceptions? raise MethodDeprecatedError, message else @@ -89,7 +98,7 @@ def odeprecated(method, replacement = nil, options = {}) end def odisabled(method, replacement = nil, options = {}) - options = { die: true, caller: caller }.merge(options) + options = { disable: true, caller: caller }.merge(options) odeprecated(method, replacement, options) end @@ -97,7 +106,7 @@ def pretty_installed(f) if !$stdout.tty? f.to_s elsif Emoji.enabled? - "#{Tty.bold}#{f} #{Formatter.success(Emoji.tick)}#{Tty.reset}" + "#{Tty.bold}#{f} #{Formatter.success("✔")}#{Tty.reset}" else Formatter.success("#{Tty.bold}#{f} (installed)#{Tty.reset}") end @@ -107,7 +116,7 @@ def pretty_uninstalled(f) if !$stdout.tty? f.to_s elsif Emoji.enabled? - "#{Tty.bold}#{f} #{Formatter.error(Emoji.cross)}#{Tty.reset}" + "#{Tty.bold}#{f} #{Formatter.error("✘")}#{Tty.reset}" else Formatter.error("#{Tty.bold}#{f} (uninstalled)#{Tty.reset}") end diff --git a/Library/Homebrew/utils/analytics.rb b/Library/Homebrew/utils/analytics.rb index cc7ad54d2..7dd54d3f1 100644 --- a/Library/Homebrew/utils/analytics.rb +++ b/Library/Homebrew/utils/analytics.rb @@ -35,7 +35,7 @@ module Utils end # Send analytics. Don't send or store any personally identifiable information. - # https://github.com/Homebrew/brew/blob/master/docs/Analytics.md + # http://docs.brew.sh/Analytics.html # https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide # https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters if ENV["HOMEBREW_ANALYTICS_DEBUG"] diff --git a/Library/Homebrew/utils/analytics.sh b/Library/Homebrew/utils/analytics.sh index 0f188fe9b..35f91eabc 100644 --- a/Library/Homebrew/utils/analytics.sh +++ b/Library/Homebrew/utils/analytics.sh @@ -107,7 +107,7 @@ report-analytics-screenview-command() { ) # Send analytics. Don't send or store any personally identifiable information. - # https://github.com/Homebrew/brew/blob/master/docs/Analytics.md + # http://docs.brew.sh/Analytics.html # https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide#screenView # https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters if [[ -z "$HOMEBREW_ANALYTICS_DEBUG" ]] diff --git a/Library/Homebrew/utils/curl.rb b/Library/Homebrew/utils/curl.rb index 00c3a591c..5a40ae846 100644 --- a/Library/Homebrew/utils/curl.rb +++ b/Library/Homebrew/utils/curl.rb @@ -1,27 +1,41 @@ require "pathname" require "open3" -def curl_args(extra_args = []) +def curl_args(options = {}) curl = Pathname.new ENV["HOMEBREW_CURL"] curl = Pathname.new "/usr/bin/curl" unless curl.exist? raise "#{curl} is not executable" unless curl.exist? && curl.executable? - flags = HOMEBREW_CURL_ARGS - flags -= ["--progress-bar"] if ARGV.verbose? + args = [ + curl.to_s, + "--remote-time", + "--location", + ] - args = [curl.to_s] + flags + extra_args - args << "--verbose" if ENV["HOMEBREW_CURL_VERBOSE"] - args << "--silent" if !$stdout.tty? || ENV["TRAVIS"] + case options[:user_agent] + when :browser + args << "--user-agent" << HOMEBREW_USER_AGENT_FAKE_SAFARI + else + args << "--user-agent" << HOMEBREW_USER_AGENT_CURL + end + + unless options[:show_output] + args << "--progress-bar" unless ARGV.verbose? + args << "--verbose" if ENV["HOMEBREW_CURL_VERBOSE"] + args << "--fail" + args << "--silent" if !$stdout.tty? || ENV["TRAVIS"] + end + + args += options[:extra_args] if options[:extra_args] args end def curl(*args) - safe_system(*curl_args(args)) + safe_system(*curl_args(extra_args: args)) end def curl_output(*args) - curl_args = curl_args(args) - curl_args -= ["--fail", "--silent"] + curl_args = curl_args(extra_args: args, show_output: true) Open3.popen3(*curl_args) do |_, stdout, stderr, wait_thread| [stdout.read, stderr.read, wait_thread.value] end diff --git a/Library/Homebrew/utils/inreplace.rb b/Library/Homebrew/utils/inreplace.rb index c7557ab41..b4c219f06 100644 --- a/Library/Homebrew/utils/inreplace.rb +++ b/Library/Homebrew/utils/inreplace.rb @@ -1,9 +1,10 @@ module Utils class InreplaceError < RuntimeError def initialize(errors) - super errors.inject("inreplace failed\n") do |s, (path, errs)| + formatted_errors = errors.inject("inreplace failed\n") do |s, (path, errs)| s << "#{path}:\n" << errs.map { |e| " #{e}\n" }.join end + super formatted_errors end end |
