aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Library/Homebrew/brew.sh20
-rw-r--r--Library/Homebrew/cask/lib/hbc/cli/search.rb5
-rw-r--r--Library/Homebrew/dev-cmd/audit.rb49
-rw-r--r--Library/Homebrew/extend/os/linux/hardware/cpu.rb6
-rw-r--r--Library/Homebrew/os/mac/linkage_checker.rb7
-rw-r--r--Library/Homebrew/rubocops.rb1
-rw-r--r--Library/Homebrew/rubocops/urls_cop.rb90
-rw-r--r--Library/Homebrew/system_config.rb9
-rw-r--r--Library/Homebrew/test/cask/cli/search_spec.rb31
-rw-r--r--Library/Homebrew/test/rubocops/urls_cop_spec.rb54
-rw-r--r--Library/Homebrew/test/spec_helper.rb2
-rw-r--r--Library/Homebrew/test/support/helper/output_as_tty.rb84
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