Merge remote-tracking branch 'origin/master' into insecure_audit
This commit is contained in:
commit
13a3a57fa8
7
.gitignore
vendored
7
.gitignore
vendored
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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!
|
||||
|
||||
@ -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" ;;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
@ -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
|
||||
|
||||
@ -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.}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
@ -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?
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
require "tap"
|
||||
|
||||
module Hbc
|
||||
module Locations
|
||||
def self.included(base)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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?
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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?)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 " "}"
|
||||
|
||||
@ -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) }
|
||||
|
||||
@ -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"
|
||||
|
||||
6
Library/Homebrew/compat/ENV/shared.rb
Normal file
6
Library/Homebrew/compat/ENV/shared.rb
Normal file
@ -0,0 +1,6 @@
|
||||
module SharedEnvExtension
|
||||
def j1
|
||||
odeprecated "ENV.j1", "ENV.deparallelize"
|
||||
deparallelize
|
||||
end
|
||||
end
|
||||
27
Library/Homebrew/compat/ENV/std.rb
Normal file
27
Library/Homebrew/compat/ENV/std.rb
Normal 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
|
||||
47
Library/Homebrew/compat/ENV/super.rb
Normal file
47
Library/Homebrew/compat/ENV/super.rb
Normal 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
|
||||
@ -1 +1,2 @@
|
||||
require "compat/hbc/cask_loader"
|
||||
require "compat/hbc/cli/update"
|
||||
|
||||
23
Library/Homebrew/compat/hbc/cli/update.rb
Normal file
23
Library/Homebrew/compat/hbc/cli/update.rb
Normal 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
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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 }
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
[
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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?
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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]
|
||||
|
||||
@ -47,6 +47,8 @@ module Hardware
|
||||
:haswell
|
||||
when 0x3d, 0x47, 0x4f, 0x56
|
||||
:broadwell
|
||||
when 0x8e
|
||||
:kabylake
|
||||
else
|
||||
cpu_family_model
|
||||
end
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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")
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
#
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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`,
|
||||
|
||||
@ -1,18 +1,15 @@
|
||||
OFFICIAL_TAPS = %w[
|
||||
apache
|
||||
completions
|
||||
devel-only
|
||||
dupes
|
||||
emacs
|
||||
fuse
|
||||
games
|
||||
gui
|
||||
nginx
|
||||
php
|
||||
python
|
||||
science
|
||||
tex
|
||||
versions
|
||||
x11
|
||||
].freeze
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 },
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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}"
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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}.
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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
Loading…
x
Reference in New Issue
Block a user