diff options
| -rw-r--r-- | Library/Homebrew/brew.sh | 20 | ||||
| -rw-r--r-- | Library/Homebrew/cask/lib/hbc/cli/search.rb | 5 | ||||
| -rw-r--r-- | Library/Homebrew/dev-cmd/audit.rb | 49 | ||||
| -rw-r--r-- | Library/Homebrew/extend/os/linux/hardware/cpu.rb | 6 | ||||
| -rw-r--r-- | Library/Homebrew/os/mac/linkage_checker.rb | 7 | ||||
| -rw-r--r-- | Library/Homebrew/rubocops.rb | 1 | ||||
| -rw-r--r-- | Library/Homebrew/rubocops/urls_cop.rb | 90 | ||||
| -rw-r--r-- | Library/Homebrew/system_config.rb | 9 | ||||
| -rw-r--r-- | Library/Homebrew/test/cask/cli/search_spec.rb | 31 | ||||
| -rw-r--r-- | Library/Homebrew/test/rubocops/urls_cop_spec.rb | 54 | ||||
| -rw-r--r-- | Library/Homebrew/test/spec_helper.rb | 2 | ||||
| -rw-r--r-- | Library/Homebrew/test/support/helper/output_as_tty.rb | 84 |
12 files changed, 291 insertions, 67 deletions
diff --git a/Library/Homebrew/brew.sh b/Library/Homebrew/brew.sh index 638e9dc19..35e3eaa02 100644 --- a/Library/Homebrew/brew.sh +++ b/Library/Homebrew/brew.sh @@ -110,22 +110,32 @@ then then HOMEBREW_CURL="$HOMEBREW_PREFIX/opt/curl/bin/curl" fi + + if [[ -z "$HOMEBREW_CACHE" ]] + then + HOMEBREW_CACHE="$HOME/Library/Caches/Homebrew" + fi else HOMEBREW_PROCESSOR="$(uname -m)" HOMEBREW_PRODUCT="${HOMEBREW_SYSTEM}brew" [[ -n "$HOMEBREW_LINUX" ]] && HOMEBREW_OS_VERSION="$(lsb_release -sd 2>/dev/null)" : "${HOMEBREW_OS_VERSION:=$(uname -r)}" HOMEBREW_OS_USER_AGENT_VERSION="$HOMEBREW_OS_VERSION" + + if [[ -z "$HOMEBREW_CACHE" ]] + then + if [[ -n "$XDG_CACHE_HOME" ]] + then + HOMEBREW_CACHE="$XDG_CACHE_HOME/Homebrew" + else + HOMEBREW_CACHE="$HOME/.cache/Homebrew" + fi + fi fi HOMEBREW_USER_AGENT="$HOMEBREW_PRODUCT/$HOMEBREW_USER_AGENT_VERSION ($HOMEBREW_SYSTEM; $HOMEBREW_PROCESSOR $HOMEBREW_OS_USER_AGENT_VERSION)" HOMEBREW_CURL_VERSION="$("$HOMEBREW_CURL" --version 2>/dev/null | head -n1 | /usr/bin/awk '{print $1"/"$2}')" HOMEBREW_USER_AGENT_CURL="$HOMEBREW_USER_AGENT $HOMEBREW_CURL_VERSION" -if [[ -z "$HOMEBREW_CACHE" ]] -then - HOMEBREW_CACHE="$HOME/Library/Caches/Homebrew" -fi - # Declared in bin/brew export HOMEBREW_BREW_FILE export HOMEBREW_PREFIX diff --git a/Library/Homebrew/cask/lib/hbc/cli/search.rb b/Library/Homebrew/cask/lib/hbc/cli/search.rb index 9d1a16f15..643d18d55 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/search.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/search.rb @@ -46,6 +46,11 @@ module Hbc end def self.render_results(exact_match, partial_matches, remote_matches, search_term) + unless $stdout.tty? + puts [*exact_match, *partial_matches, *remote_matches] + return + end + if !exact_match && partial_matches.empty? puts "No Cask found for \"#{search_term}\"." return diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index 4bcfdd128..327c3e811 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -1282,56 +1282,7 @@ class ResourceAuditor end def audit_urls - # Check GNU urls; doesn't apply to mirrors - if url =~ %r{^(?:https?|ftp)://ftpmirror.gnu.org/(.*)} - problem "Please use \"https://ftp.gnu.org/gnu/#{Regexp.last_match(1)}\" instead of #{url}." - end - - # Fossies upstream requests they aren't used as primary URLs - # https://github.com/Homebrew/homebrew-core/issues/14486#issuecomment-307753234 - if url =~ %r{^https?://fossies\.org/} - problem "Please don't use fossies.org in the url (using as a mirror is fine)" - end - - if mirrors.include?(url) - problem "URL should not be duplicated as a mirror: #{url}" - end - urls = [url] + mirrors - - # Check a variety of SSL/TLS URLs that don't consistently auto-redirect - # or are overly common errors that need to be reduced & fixed over time. - urls.each do |p| - case p - when %r{^http://ftp\.gnu\.org/}, - %r{^http://ftpmirror\.gnu\.org/}, - %r{^http://download\.savannah\.gnu\.org/}, - %r{^http://download-mirror\.savannah\.gnu\.org/}, - %r{^http://[^/]*\.apache\.org/}, - %r{^http://code\.google\.com/}, - %r{^http://fossies\.org/}, - %r{^http://mirrors\.kernel\.org/}, - %r{^http://(?:[^/]*\.)?bintray\.com/}, - %r{^http://tools\.ietf\.org/}, - %r{^http://launchpad\.net/}, - %r{^http://github\.com/}, - %r{^http://bitbucket\.org/}, - %r{^http://anonscm\.debian\.org/}, - %r{^http://cpan\.metacpan\.org/}, - %r{^http://hackage\.haskell\.org/}, - %r{^http://(?:[^/]*\.)?archive\.org}, - %r{^http://(?:[^/]*\.)?freedesktop\.org}, - %r{^http://(?:[^/]*\.)?mirrorservice\.org/} - problem "Please use https:// for #{p}" - when %r{^http://search\.mcpan\.org/CPAN/(.*)}i - problem "#{p} should be `https://cpan.metacpan.org/#{Regexp.last_match(1)}`" - when %r{^(http|ftp)://ftp\.gnome\.org/pub/gnome/(.*)}i - problem "#{p} should be `https://download.gnome.org/#{Regexp.last_match(2)}`" - when %r{^git://anonscm\.debian\.org/users/(.*)}i - problem "#{p} should be `https://anonscm.debian.org/git/users/#{Regexp.last_match(1)}`" - end - end - # Prefer HTTP/S when possible over FTP protocol due to possible firewalls. urls.each do |p| case p diff --git a/Library/Homebrew/extend/os/linux/hardware/cpu.rb b/Library/Homebrew/extend/os/linux/hardware/cpu.rb index 177db6139..8bf67bec8 100644 --- a/Library/Homebrew/extend/os/linux/hardware/cpu.rb +++ b/Library/Homebrew/extend/os/linux/hardware/cpu.rb @@ -84,7 +84,7 @@ module Hardware @features ||= flags[1..-1].map(&:intern) end - %w[aes altivec avx avx2 lm ssse3 sse4 sse4_2].each do |flag| + %w[aes altivec avx avx2 lm ssse3 sse4_2].each do |flag| define_method(flag + "?") { flags.include? flag } end @@ -92,6 +92,10 @@ module Hardware flags.include?("pni") || flags.include?("sse3") end + def sse4? + flags.include? "sse4_1" + end + alias is_64_bit? lm? def bits diff --git a/Library/Homebrew/os/mac/linkage_checker.rb b/Library/Homebrew/os/mac/linkage_checker.rb index f332c2d7a..786827852 100644 --- a/Library/Homebrew/os/mac/linkage_checker.rb +++ b/Library/Homebrew/os/mac/linkage_checker.rb @@ -118,9 +118,12 @@ class LinkageChecker # Whether or not dylib is a harmless broken link, meaning that it's # okay to skip (and not report) as broken. def harmless_broken_link?(dylib) - # libgcc_s_ppc64 is referenced by programs that use the Java Service Wrapper, + # libgcc_s_* is referenced by programs that use the Java Service Wrapper, # and is harmless on x86(_64) machines - ["/usr/lib/libgcc_s_ppc64.1.dylib"].include?(dylib) + [ + "/usr/lib/libgcc_s_ppc64.1.dylib", + "/opt/local/lib/libgcc/libgcc_s.1.dylib", + ].include?(dylib) end # Display a list of things. diff --git a/Library/Homebrew/rubocops.rb b/Library/Homebrew/rubocops.rb index f673720a6..7d104ad9e 100644 --- a/Library/Homebrew/rubocops.rb +++ b/Library/Homebrew/rubocops.rb @@ -9,3 +9,4 @@ require_relative "./rubocops/checksum_cop" require_relative "./rubocops/legacy_patches_cop" require_relative "./rubocops/conflicts_cop" require_relative "./rubocops/options_cop" +require_relative "./rubocops/urls_cop" diff --git a/Library/Homebrew/rubocops/urls_cop.rb b/Library/Homebrew/rubocops/urls_cop.rb new file mode 100644 index 000000000..830b68ead --- /dev/null +++ b/Library/Homebrew/rubocops/urls_cop.rb @@ -0,0 +1,90 @@ +require_relative "./extend/formula_cop" + +module RuboCop + module Cop + module FormulaAudit + # This cop audits urls and mirrors in Formulae + class Urls < FormulaCop + def audit_formula(_node, _class_node, _parent_class_node, body_node) + urls = find_every_method_call_by_name(body_node, :url) + mirrors = find_every_method_call_by_name(body_node, :mirror) + + # GNU urls; doesn't apply to mirrors + gnu_pattern = %r{^(?:https?|ftp)://ftpmirror.gnu.org/(.*)} + audit_urls(urls, gnu_pattern) do |match, url| + problem "Please use \"https://ftp.gnu.org/gnu/#{match[1]}\" instead of #{url}." + end + + # Fossies upstream requests they aren't used as primary URLs + # https://github.com/Homebrew/homebrew-core/issues/14486#issuecomment-307753234 + fossies_pattern = %r{^https?://fossies\.org/} + audit_urls(urls, fossies_pattern) do + problem "Please don't use fossies.org in the url (using as a mirror is fine)" + end + + audit_urls(mirrors, /.*/) do |_, mirror| + urls.each do |url| + url_string = string_content(parameters(url).first) + next unless url_string.eql?(mirror) + problem "URL should not be duplicated as a mirror: #{url_string}" + end + end + + urls += mirrors + + # Check a variety of SSL/TLS URLs that don't consistently auto-redirect + # or are overly common errors that need to be reduced & fixed over time. + http_to_https_patterns = Regexp.union([%r{^http://ftp\.gnu\.org/}, + %r{^http://ftpmirror\.gnu\.org/}, + %r{^http://download\.savannah\.gnu\.org/}, + %r{^http://download-mirror\.savannah\.gnu\.org/}, + %r{^http://[^/]*\.apache\.org/}, + %r{^http://code\.google\.com/}, + %r{^http://fossies\.org/}, + %r{^http://mirrors\.kernel\.org/}, + %r{^http://(?:[^/]*\.)?bintray\.com/}, + %r{^http://tools\.ietf\.org/}, + %r{^http://launchpad\.net/}, + %r{^http://github\.com/}, + %r{^http://bitbucket\.org/}, + %r{^http://anonscm\.debian\.org/}, + %r{^http://cpan\.metacpan\.org/}, + %r{^http://hackage\.haskell\.org/}, + %r{^http://(?:[^/]*\.)?archive\.org}, + %r{^http://(?:[^/]*\.)?freedesktop\.org}, + %r{^http://(?:[^/]*\.)?mirrorservice\.org/}]) + audit_urls(urls, http_to_https_patterns) do |_, url| + problem "Please use https:// for #{url}" + end + + cpan_pattern = %r{^http://search\.mcpan\.org/CPAN/(.*)}i + audit_urls(urls, cpan_pattern) do |match, url| + problem "#{url} should be `https://cpan.metacpan.org/#{match[1]}`" + end + + gnome_pattern = %r{^(http|ftp)://ftp\.gnome\.org/pub/gnome/(.*)}i + audit_urls(urls, gnome_pattern) do |match, url| + problem "#{url} should be `https://download.gnome.org/#{match[2]}`" + end + + debian_pattern = %r{^git://anonscm\.debian\.org/users/(.*)}i + audit_urls(urls, debian_pattern) do |match, url| + problem "#{url} should be `https://anonscm.debian.org/git/users/#{match[1]}`" + end + end + + private + + def audit_urls(urls, regex) + urls.each do |url_node| + url_string_node = parameters(url_node).first + url_string = string_content(url_string_node) + match_object = regex_match_group(url_string_node, regex) + offending_node(url_string_node.parent) if match_object + yield match_object, url_string if match_object + end + end + end + end + end +end diff --git a/Library/Homebrew/system_config.rb b/Library/Homebrew/system_config.rb index f89c79306..5663295c2 100644 --- a/Library/Homebrew/system_config.rb +++ b/Library/Homebrew/system_config.rb @@ -77,7 +77,14 @@ class SystemConfig end def describe_python - python = which "python" + python = begin + python_path = PATH.new(ENV["HOMEBREW_PATH"]) + .prepend(Formula["python"].opt_libexec/"bin") + which "python", python_path + rescue FormulaUnavailableError + which "python" + end + return "N/A" if python.nil? python_binary = Utils.popen_read python, "-c", "import sys; sys.stdout.write(sys.executable)" python_binary = Pathname.new(python_binary).realpath diff --git a/Library/Homebrew/test/cask/cli/search_spec.rb b/Library/Homebrew/test/cask/cli/search_spec.rb index 00fcf7382..f43610767 100644 --- a/Library/Homebrew/test/cask/cli/search_spec.rb +++ b/Library/Homebrew/test/cask/cli/search_spec.rb @@ -1,60 +1,73 @@ describe Hbc::CLI::Search, :cask do + before(:each) do + allow(Tty).to receive(:width).and_return(0) + end + it "lists the available Casks that match the search term" do expect { Hbc::CLI::Search.run("local") - }.to output(<<-EOS.undent).to_stdout + }.to output(<<-EOS.undent).to_stdout.as_tty ==> Partial Matches local-caffeine local-transmission EOS end + it "outputs a plain list when stdout is not a TTY" do + expect { + Hbc::CLI::Search.run("local") + }.to output(<<-EOS.undent).to_stdout + local-caffeine + local-transmission + EOS + end + it "shows that there are no Casks matching a search term that did not result in anything" do expect { Hbc::CLI::Search.run("foo-bar-baz") - }.to output("No Cask found for \"foo-bar-baz\".\n").to_stdout + }.to output("No Cask found for \"foo-bar-baz\".\n").to_stdout.as_tty end it "lists all available Casks with no search term" do expect { Hbc::CLI::Search.run - }.to output(/local-caffeine/).to_stdout + }.to output(/local-caffeine/).to_stdout.as_tty end it "ignores hyphens in search terms" do expect { Hbc::CLI::Search.run("lo-cal-caffeine") - }.to output(/local-caffeine/).to_stdout + }.to output(/local-caffeine/).to_stdout.as_tty end it "ignores hyphens in Cask tokens" do expect { Hbc::CLI::Search.run("localcaffeine") - }.to output(/local-caffeine/).to_stdout + }.to output(/local-caffeine/).to_stdout.as_tty end it "accepts multiple arguments" do expect { Hbc::CLI::Search.run("local caffeine") - }.to output(/local-caffeine/).to_stdout + }.to output(/local-caffeine/).to_stdout.as_tty end it "accepts a regexp argument" do expect { Hbc::CLI::Search.run("/^local-c[a-z]ffeine$/") - }.to output("==> Regexp Matches\nlocal-caffeine\n").to_stdout + }.to output("==> Regexp Matches\nlocal-caffeine\n").to_stdout.as_tty end it "Returns both exact and partial matches" do expect { Hbc::CLI::Search.run("test-opera") - }.to output(/^==> Exact Match\ntest-opera\n==> Partial Matches\ntest-opera-mail/).to_stdout + }.to output(/^==> Exact Match\ntest-opera\n==> Partial Matches\ntest-opera-mail/).to_stdout.as_tty end it "does not search the Tap name" do expect { Hbc::CLI::Search.run("caskroom") - }.to output(/^No Cask found for "caskroom"\.\n/).to_stdout + }.to output(/^No Cask found for "caskroom"\.\n/).to_stdout.as_tty end it "doesn't highlight packages that aren't installed" do diff --git a/Library/Homebrew/test/rubocops/urls_cop_spec.rb b/Library/Homebrew/test/rubocops/urls_cop_spec.rb new file mode 100644 index 000000000..2e56dbf03 --- /dev/null +++ b/Library/Homebrew/test/rubocops/urls_cop_spec.rb @@ -0,0 +1,54 @@ +require "rubocop" +require "rubocop/rspec/support" +require_relative "../../extend/string" +require_relative "../../rubocops/urls_cop" + +describe RuboCop::Cop::FormulaAudit::Urls do + subject(:cop) { described_class.new } + + context "When auditing urls" do + it "with offenses" do + formulas = [{ + "url" => "https://ftpmirror.gnu.org/lightning/lightning-2.1.0.tar.gz", + "msg" => 'Please use "https://ftp.gnu.org/gnu/lightning/lightning-2.1.0.tar.gz" instead of https://ftpmirror.gnu.org/lightning/lightning-2.1.0.tar.gz.', + "col" => 2, + }, { + "url" => "https://fossies.org/linux/privat/monit-5.23.0.tar.gz", + "msg" => "Please don't use fossies.org in the url (using as a mirror is fine)", + "col" => 2, + }, { + "url" => "http://tools.ietf.org/tools/rfcmarkup/rfcmarkup-1.119.tgz", + "msg" => "Please use https:// for http://tools.ietf.org/tools/rfcmarkup/rfcmarkup-1.119.tgz", + "col" => 2, + }, { + "url" => "http://search.mcpan.org/CPAN/authors/id/Z/ZE/ZEFRAM/Perl4-CoreLibs-0.003.tar.gz", + "msg" => "http://search.mcpan.org/CPAN/authors/id/Z/ZE/ZEFRAM/Perl4-CoreLibs-0.003.tar.gz should be `https://cpan.metacpan.org/authors/id/Z/ZE/ZEFRAM/Perl4-CoreLibs-0.003.tar.gz`", + "col" => 2, + }, { + "url" => "http://ftp.gnome.org/pub/GNOME/binaries/mac/banshee/banshee-2.macosx.intel.dmg", + "msg" => "http://ftp.gnome.org/pub/GNOME/binaries/mac/banshee/banshee-2.macosx.intel.dmg should be `https://download.gnome.org/binaries/mac/banshee/banshee-2.macosx.intel.dmg`", + "col" => 2, + }] + + formulas.each do |formula| + source = <<-EOS.undent + class Foo < Formula + desc "foo" + url "#{formula["url"]}" + end + EOS + expected_offenses = [{ message: formula["msg"], + severity: :convention, + line: 3, + column: formula["col"], + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses.reverse).each do |expected, actual| + expect_offense(expected, actual) + end + end + end + end +end diff --git a/Library/Homebrew/test/spec_helper.rb b/Library/Homebrew/test/spec_helper.rb index b1a028d9d..222f85fc4 100644 --- a/Library/Homebrew/test/spec_helper.rb +++ b/Library/Homebrew/test/spec_helper.rb @@ -23,6 +23,7 @@ require "test/support/helper/shutup" require "test/support/helper/fixtures" require "test/support/helper/formula" require "test/support/helper/mktmpdir" +require "test/support/helper/output_as_tty" require "test/support/helper/rubocop" require "test/support/helper/spec/shared_context/homebrew_cask" if OS.mac? @@ -47,6 +48,7 @@ RSpec.configure do |config| config.include(Test::Helper::Fixtures) config.include(Test::Helper::Formula) config.include(Test::Helper::MkTmpDir) + config.include(Test::Helper::OutputAsTTY) config.include(Test::Helper::RuboCop) config.before(:each, :needs_compat) do diff --git a/Library/Homebrew/test/support/helper/output_as_tty.rb b/Library/Homebrew/test/support/helper/output_as_tty.rb new file mode 100644 index 000000000..aa9da73cc --- /dev/null +++ b/Library/Homebrew/test/support/helper/output_as_tty.rb @@ -0,0 +1,84 @@ +require "delegate" + +module Test + module Helper + module OutputAsTTY + # This is a custom wrapper for the `output` matcher, + # used for testing output to a TTY: + # + # expect { + # print "test" if $stdout.tty? + # }.to output("test").to_stdout.as_tty + # + # expect { + # # command + # }.to output(...).to_stderr.as_tty.with_color + # + class Output < SimpleDelegator + def matches?(block) + return super(block) unless @tty + + colored_tty_block = lambda do + instance_eval("$#{@output}").extend(Module.new do + def tty? + true + end + + alias_method :isatty, :tty? + end) + block.call + end + + return super(colored_tty_block) if @colors + + uncolored_tty_block = lambda do + instance_eval <<-EOS + begin + captured_stream = StringIO.new + + original_stream = $#{@output} + $#{@output} = captured_stream + + colored_tty_block.call + ensure + $#{@output} = original_stream + $#{@output}.print Tty.strip_ansi(captured_stream.string) + end + EOS + end + + super(uncolored_tty_block) + end + + def to_stdout + @output = :stdout + super + self + end + + def to_stderr + @output = :stderr + super + self + end + + def as_tty + @tty = true + return self if [:stdout, :stderr].include?(@output) + raise "`as_tty` can only be chained to `stdout` or `stderr`." + end + + def with_color + @colors = true + return self if @tty + raise "`with_color` can only be chained to `as_tty`." + end + end + + def output(*args) + core_matcher = super(*args) + Output.new(core_matcher) + end + end + end +end |
