Merge remote-tracking branch 'origin/master' into insecure_audit

This commit is contained in:
David Broder-Rodgers 2017-01-30 18:31:52 +00:00
commit 13a3a57fa8
199 changed files with 1953 additions and 1236 deletions

7
.gitignore vendored
View File

@ -38,6 +38,13 @@
!/docs
!/manpages
# Ignore generated documentation site
/docs/_site
/docs/.bundle
/docs/bin
/docs/vendor
/docs/Gemfile.lock
# Unignore our shell completion
!/completions

View File

@ -5,7 +5,7 @@ First time contributing to Homebrew? Read our [Code of Conduct](https://github.c
* run `brew update` (twice)
* run and read `brew doctor`
* read [the Troubleshooting Checklist](https://github.com/Homebrew/brew/blob/master/docs/Troubleshooting.md#troubleshooting)
* read [the Troubleshooting Checklist](http://docs.brew.sh/Troubleshooting.html)
* open an issue on the formula's repository or on Homebrew/brew if it's not a formula-specific issue
### Propose a feature

View File

@ -1,6 +1,6 @@
BSD 2-Clause License
Copyright (c) 2009-2016, Homebrew contributors
Copyright (c) 2009-present, Homebrew contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@ -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:

View File

@ -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!

View File

@ -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" ;;

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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.}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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?

View File

@ -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

View File

@ -1,3 +1,5 @@
require "tap"
module Hbc
module Locations
def self.included(base)

View File

@ -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

View File

@ -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

View File

@ -39,18 +39,18 @@ 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"))
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
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"))
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
end
it "exits with a status of 1 when something goes wrong" do
allow(described_class).to receive(:lookup_command).and_raise(Hbc::CaskError)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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?

View File

@ -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"

View File

@ -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

View File

@ -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?)

View File

@ -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

View File

@ -94,6 +94,11 @@ 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
@ -102,6 +107,11 @@ module Homebrew
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 " "}"

View File

@ -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
reqs = f.recursive_requirements do |dependent, req|
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_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) }

View File

@ -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"

View File

@ -0,0 +1,6 @@
module SharedEnvExtension
def j1
odeprecated "ENV.j1", "ENV.deparallelize"
deparallelize
end
end

View File

@ -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

View File

@ -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

View File

@ -1 +1,2 @@
require "compat/hbc/cask_loader"
require "compat/hbc/cli/update"

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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 }

View File

@ -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"

View File

@ -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
[

View File

@ -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

View File

@ -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"

View File

@ -34,15 +34,11 @@ class DevelopmentTools
end
def default_compiler
if default_cc =~ /^gcc/
:gcc
else
:clang
end
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

View File

@ -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

View File

@ -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

View File

@ -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?

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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]

View File

@ -47,6 +47,8 @@ module Hardware
:haswell
when 0x3d, 0x47, 0x4f, 0x56
:broadwell
when 0x8e
:kabylake
else
cpu_family_model
end

View File

@ -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

View File

@ -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

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.
#

View File

@ -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

View File

@ -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
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
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
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
when :provided_pre_mavericks then <<-EOS.undent
macOS already provides this software in versions before Mavericks.
EOS
when :provided_pre_el_capitan then <<-EOS
when :provided_pre_el_capitan then <<-EOS.undent
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 :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

View File

@ -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

View File

@ -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)

View File

@ -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"

View File

@ -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
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,20 +344,22 @@ 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.
begin
dep_formula = Formulary.factory(dep["full_name"])
dep_formula == to_formula && dep["version"] == version.to_s
dep_formula == to_formula
rescue FormulaUnavailableError
next "#{tap}/#{name}" == dep["full_name"]
end
end
end
def find(*args, &block)
path.find(*args, &block)
end
def oldname_opt_record
@ -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.

View File

@ -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.

View File

@ -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`,

View File

@ -1,18 +1,15 @@
OFFICIAL_TAPS = %w[
apache
completions
devel-only
dupes
emacs
fuse
games
gui
nginx
php
python
science
tex
versions
x11
].freeze

View File

@ -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

View File

@ -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 },

View File

@ -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
def bundle_path
# 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
def bundle_path
MacOS.app_with_bundle_id(V4_BUNDLE_ID, V3_BUNDLE_ID)
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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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}"

View File

@ -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,

View File

@ -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}.

View File

@ -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

View File

@ -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

View File

@ -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",

View File

@ -3,6 +3,7 @@ require "utils/bottles"
class BottleCollectorTests < Homebrew::TestCase
def setup
super
@collector = Utils::Bottles::Collector.new
end

Some files were not shown because too many files have changed in this diff Show More