Merge remote-tracking branch 'origin/master' into cache-optimization

This commit is contained in:
AndrewMcBurney 2018-04-09 13:49:58 -04:00
commit dcdd16237c
321 changed files with 2904 additions and 2937 deletions

View File

@ -26,6 +26,9 @@ Layout/CaseIndentation:
Layout/EmptyLineBetweenDefs:
AllowAdjacentOneLineDefs: true
Layout/EndAlignment:
EnforcedStyleAlignWith: variable
Layout/IndentArray:
EnforcedStyle: special_inside_parentheses
@ -52,9 +55,6 @@ Lint/AmbiguousBlockAssociation:
Lint/AssignmentInCondition:
Enabled: false
Lint/EndAlignment:
EnforcedStyleAlignWith: variable
# so many of these in formulae and can't be autocorrected
Lint/ParenthesesAsGroupedExpression:
Enabled: false
@ -205,7 +205,10 @@ Style/TernaryParentheses:
EnforcedStyle: require_parentheses_when_complex
# makes diffs nicer
Style/TrailingCommaInLiteral:
Style/TrailingCommaInArrayLiteral:
EnforcedStyleForMultiline: comma
Style/TrailingCommaInHashLiteral:
EnforcedStyleForMultiline: comma
Style/TrailingCommaInArguments:
@ -215,6 +218,10 @@ Style/TrailingCommaInArguments:
Naming/VariableNumber:
Enabled: false
# doesn't make sense for Homebrew/brew but does for taps
Naming/UncommunicativeMethodParamName:
Enabled: true
Style/WordArray:
MinSize: 4

View File

@ -68,6 +68,10 @@ Naming/PredicateName:
- 'compat/**/*'
NameWhitelist: is_32_bit?, is_64_bit?
# f meaning formulae is pretty standard
Naming/UncommunicativeMethodParamName:
Enabled: false
Style/BlockDelimiters:
Exclude:
- '**/*_spec.rb'

View File

@ -14,12 +14,13 @@ end
require "pathname"
HOMEBREW_LIBRARY_PATH = Pathname.new(__FILE__).realpath.parent
require "English"
unless $LOAD_PATH.include?(HOMEBREW_LIBRARY_PATH.to_s)
$LOAD_PATH.unshift(HOMEBREW_LIBRARY_PATH.to_s)
end
require "global"
require "tap"
if ARGV == %w[--version] || ARGV == %w[-v]
puts "Homebrew #{HOMEBREW_VERSION}"

View File

@ -32,7 +32,7 @@ onoe() {
fi
if [[ $# -eq 0 ]]
then
/bin/cat >&2
cat >&2
else
echo "$*" >&2
fi

View File

@ -44,9 +44,9 @@ class Build
def expand_reqs
formula.recursive_requirements do |dependent, req|
build = effective_build_options_for(dependent)
if (req.optional? || req.recommended?) && build.without?(req)
if req.prune_from_option?(build)
Requirement.prune
elsif req.build? && dependent != formula
elsif req.prune_if_build_and_not_dependent?(dependent, formula)
Requirement.prune
end
end
@ -55,9 +55,9 @@ class Build
def expand_deps
formula.recursive_dependencies do |dependent, dep|
build = effective_build_options_for(dependent)
if (dep.optional? || dep.recommended?) && build.without?(dep)
if dep.prune_from_option?(build)
Dependency.prune
elsif dep.build? && dependent != formula
elsif dep.prune_if_build_and_not_dependent?(dependent, formula)
Dependency.prune
elsif dep.build?
Dependency.keep_but_prune_recursive_deps

View File

@ -1,4 +1,3 @@
require "set"
class BuildEnvironment
def initialize(*settings)

View File

@ -1,5 +1,4 @@
require "hardware"
require "utils"
require "hbc/artifact"
require "hbc/audit"

View File

@ -1,4 +1,3 @@
require "pathname"
require "timeout"
require "hbc/artifact/abstract_artifact"

View File

@ -33,6 +33,9 @@ module Hbc
check_download
check_single_pre_postflight
check_single_uninstall_zap
check_untrusted_pkg
check_github_releases_appcast
check_latest_with_appcast
self
rescue StandardError => e
odebug "#{e.message}\n#{e.backtrace.join("\n")}"
@ -50,6 +53,18 @@ module Hbc
private
def check_untrusted_pkg
odebug "Auditing pkg stanza: allow_untrusted"
return if @cask.sourcefile_path.nil?
tap = @cask.tap
return if tap.nil? || tap.user != "caskroom"
return unless cask.artifacts.any? { |k| k.is_a?(Hbc::Artifact::Pkg) && k.stanza_options.key?(:allow_untrusted) }
add_warning "allow_untrusted is not permitted in official Homebrew-Cask taps"
end
def check_single_pre_postflight
odebug "Auditing preflight and postflight stanzas"
@ -95,7 +110,7 @@ module Hbc
def check_version_and_checksum
return if @cask.sourcefile_path.nil?
tap = Tap.select { |t| t.cask_file?(@cask.sourcefile_path) }.first
tap = @cask.tap
return if tap.nil?
return if commit_range.nil?
@ -214,6 +229,20 @@ module Hbc
end
end
def check_latest_with_appcast
return unless cask.version.latest?
return unless cask.appcast
add_warning "Casks with an appcast should not use version :latest"
end
def check_github_releases_appcast
return if cask.appcast
return unless cask.url.to_s =~ %r{github.com/([^/]+)/([^/]+)/releases/download/(\S+)}
add_warning "Cask uses GitHub releases, please add an appcast. See https://github.com/caskroom/homebrew-cask/blob/master/doc/cask_language_reference/stanzas/appcast.md"
end
def check_url
return unless cask.url
check_download_url_format

View File

@ -1,3 +1,5 @@
require "uri"
module Hbc
module CaskLoader
class FromContentLoader
@ -95,14 +97,14 @@ module Hbc
class FromTapPathLoader < FromPathLoader
def self.can_load?(ref)
ref.to_s.match?(HOMEBREW_TAP_PATH_REGEX) && super
super && !Tap.from_path(ref).nil?
end
attr_reader :tap
def initialize(tap_path)
@tap = Tap.from_path(tap_path)
super tap_path
def initialize(path)
@tap = Tap.from_path(path)
super(path)
end
private

View File

@ -124,6 +124,7 @@ module Hbc
BUNDLE_PATH
PATH
SHELL
HOMEBREW_CASK_OPTS
]
locale_variables = ENV.keys.grep(/^(?:LC_\S+|LANG|LANGUAGE)\Z/).sort

View File

@ -1,5 +1,3 @@
require "tmpdir"
require "hbc/container/base"
module Hbc

View File

@ -1,4 +1,3 @@
require "tmpdir"
require "hbc/container/base"

View File

@ -1,4 +1,3 @@
require "set"
require "tempfile"
require "hbc/container/base"

View File

@ -1,4 +1,3 @@
require "tmpdir"
require "hbc/container/base"

View File

@ -1,4 +1,3 @@
require "tmpdir"
require "hbc/container/base"

View File

@ -1,4 +1,3 @@
require "tmpdir"
require "hbc/container/base"

View File

@ -1,4 +1,3 @@
require "tmpdir"
require "hbc/container/base"

View File

@ -1,4 +1,3 @@
require "tmpdir"
require "hbc/container/base"

View File

@ -1,4 +1,3 @@
require "tmpdir"
require "hbc/container/base"

View File

@ -1,4 +1,3 @@
require "tmpdir"
require "hbc/container/base"

View File

@ -154,7 +154,7 @@ module Hbc
end
def ext
Pathname.new(@url).extname[/[^?]+/]
Pathname.new(@url).extname[/[^?&]+/]
end
end

View File

@ -1,4 +1,3 @@
require "set"
require "locale"
require "hbc/artifact"

View File

@ -90,7 +90,7 @@ module Hbc
brew cask install java
EOS
elsif java_version.include?("9") || java_version.include?("+")
elsif java_version.include?("10") || java_version.include?("+")
<<~EOS
#{@cask} requires Java #{java_version}. You can install the latest version with

View File

@ -14,7 +14,7 @@ module Hbc
def initialize(signature, parameters = {})
@parameters = parameters
@signature = URI(signature)
@signature = URI(signature) unless signature == :embedded
parameters.each do |hkey, hvalue|
raise "invalid 'gpg' parameter: '#{hkey.inspect}'" unless VALID_PARAMETERS.include?(hkey)
writer_method = "#{hkey}=".to_sym

View File

@ -1,4 +1,3 @@
require "tap"
module Hbc
module Locations

View File

@ -1,4 +1,3 @@
require "set"
require "os/mac/version"

View File

@ -33,6 +33,7 @@ module Hbc
def set_ownership(paths, user: current_user, group: "staff")
full_paths = remove_nonexistent(paths)
return if full_paths.empty?
ohai "Changing ownership of paths required by #{@cask}; your password may be necessary"
@command.run!("/usr/sbin/chown", args: ["-R", "--", "#{user}:#{group}"] + full_paths,
sudo: true)
end

View File

@ -49,7 +49,7 @@ module Hbc
end
def verify
return unless available?
return unless available? && cask.gpg.signature != :embedded
import_key
sig = fetch_sig

View File

@ -1,4 +1,3 @@
require "forwardable"
require "language/python"
class Caveats
@ -25,7 +24,6 @@ class Caveats
caveats << function_completion_caveats(:zsh)
caveats << function_completion_caveats(:fish)
caveats << plist_caveats
caveats << python_caveats
caveats << elisp_caveats
caveats.compact.join("\n")
end
@ -108,53 +106,6 @@ class Caveats
end
end
def python_caveats
return unless keg
return unless keg.python_site_packages_installed?
s = nil
homebrew_site_packages = Language::Python.homebrew_site_packages
user_site_packages = Language::Python.user_site_packages "python"
pth_file = user_site_packages/"homebrew.pth"
instructions = <<~EOS.gsub(/^/, " ")
mkdir -p #{user_site_packages}
echo 'import site; site.addsitedir("#{homebrew_site_packages}")' >> #{pth_file}
EOS
if f.keg_only?
keg_site_packages = f.opt_prefix/"lib/python2.7/site-packages"
unless Language::Python.in_sys_path?("python", keg_site_packages)
s = <<~EOS
If you need Python to find bindings for this keg-only formula, run:
echo #{keg_site_packages} >> #{homebrew_site_packages/f.name}.pth
EOS
s += instructions unless Language::Python.reads_brewed_pth_files?("python")
end
return s
end
return if Language::Python.reads_brewed_pth_files?("python")
if !Language::Python.in_sys_path?("python", homebrew_site_packages)
s = <<~EOS
Python modules have been installed and Homebrew's site-packages is not
in your Python sys.path, so you will not be able to import the modules
this formula installed. If you plan to develop with these modules,
please run:
EOS
s += instructions
elsif keg.python_pth_files_installed?
s = <<~EOS
This formula installed .pth files to Homebrew's site-packages and your
Python isn't configured to process them, so you will not be able to
import the modules this formula installed. If you plan to develop
with these modules, please run:
EOS
s += instructions
end
s
end
def elisp_caveats
return if f.keg_only?
return unless keg

View File

@ -13,6 +13,6 @@ class Checksum
delegate [:empty?, :to_s] => :@hexdigest
def ==(other)
hash_type == other.hash_type && hexdigest == other.hexdigest
hash_type == other&.hash_type && hexdigest == other.hexdigest
end
end

View File

@ -122,7 +122,7 @@ module Homebrew
lockfiles = candidates.select(&:file?)
lockfiles.each do |file|
next unless file.readable?
file.open.flock(File::LOCK_EX | File::LOCK_NB) && file.unlink
file.open(File::RDWR).flock(File::LOCK_EX | File::LOCK_NB) && file.unlink
end
end

View File

@ -0,0 +1,78 @@
require "optparse"
require "ostruct"
module Homebrew
module CLI
class Parser
def self.parse(&block)
new(&block).parse
end
def initialize(&block)
@parser = OptionParser.new
@parsed_args = OpenStruct.new
# undefine tap to allow --tap argument
@parsed_args.instance_eval { undef tap }
instance_eval(&block)
end
def switch(*names, description: nil, env: nil)
description = option_to_description(*names) if description.nil?
names, env = common_switch(*names) if names.first.is_a?(Symbol)
@parser.on(*names, description) do
enable_switch(*names)
end
enable_switch(*names) if !env.nil? && !ENV["HOMEBREW_#{env.to_s.upcase}"].nil?
end
def comma_array(name, description: nil)
description = option_to_description(name) if description.nil?
@parser.on(name, OptionParser::REQUIRED_ARGUMENT, Array, description) do |list|
@parsed_args[option_to_name(name)] = list
end
end
def flag(name, description: nil, required: false)
if required
option_required = OptionParser::REQUIRED_ARGUMENT
else
option_required = OptionParser::OPTIONAL_ARGUMENT
end
description = option_to_description(name) if description.nil?
@parser.on(name, description, option_required) do |option_value|
@parsed_args[option_to_name(name)] = option_value
end
end
def option_to_name(name)
name.sub(/\A--?/, "").tr("-", "_")
end
def option_to_description(*names)
names.map { |name| name.to_s.sub(/\A--?/, "").tr("-", " ") }.sort.last
end
def parse(cmdline_args = ARGV)
@parser.parse!(cmdline_args)
@parsed_args
end
private
def enable_switch(*names)
names.each do |name|
@parsed_args["#{option_to_name(name)}?"] = true
end
end
def common_switch(name)
case name
when :quiet then [["-q", "--quiet"], :quiet]
when :verbose then [["-v", "--verbose"], :verbose]
when :debug then [["-d", "--debug"], :debug]
else name
end
end
end
end
end

View File

@ -4,8 +4,6 @@
#: * `--repository` <user>`/`<repo>:
#: Display where tap <user>`/`<repo>'s directory is located.
require "tap"
module Homebrew
module_function

View File

@ -12,7 +12,6 @@
#: deleted. If you want to delete those too: `rm -rf $(brew --cache)`
require "cleanup"
require "utils"
module Homebrew
module_function

View File

@ -17,7 +17,8 @@
#:
#: By default, `deps` shows required and recommended dependencies for
#: <formulae>. To include the `:build` type dependencies, pass `--include-build`.
#: Similarly, pass `--include-optional` to include `:optional` dependencies.
#: Similarly, pass `--include-optional` to include `:optional` dependencies or
#: `--include-test` to include (non-recursive) `:test` dependencies.
#: To skip `:recommended` type dependencies, pass `--skip-recommended`.
#: To include requirements in addition to dependencies, pass `--include-requirements`.
#:
@ -30,8 +31,8 @@
#: If `--installed` is passed, output a tree for every installed formula.
#:
#: The <filters> placeholder is any combination of options `--include-build`,
#: `--include-optional`, `--skip-recommended`, and `--include-requirements` as
#: documented above.
#: `--include-optional`, `--include-test`, `--skip-recommended`, and
#: `--include-requirements` as documented above.
#:
#: If `--annotate` is passed, the build, optional, and recommended dependencies
#: are marked as such in the output.
@ -42,7 +43,8 @@
#: dependencies of that formula.
#:
#: The <filters> placeholder is any combination of options `--include-build`,
#: `--include-optional`, and `--skip-recommended` as documented above.
#: `--include-optional`, `--include-test`, and `--skip-recommended` as
#: documented above.
# The undocumented `--for-each` option will switch into the mode used by `deps --all`,
# but only list dependencies for specified formula, one specified formula per line.
@ -73,29 +75,39 @@ module Homebrew
raise FormulaUnspecifiedError if ARGV.named.empty?
puts_deps_tree ARGV.formulae, !ARGV.one?
end
return
elsif mode.all?
puts_deps Formula.sort
elsif ARGV.named.empty?
return
elsif !ARGV.named.empty? && mode.for_each?
puts_deps ARGV.formulae
return
end
@only_installed_arg = ARGV.include?("--installed") &&
!ARGV.include?("--include-build") &&
!ARGV.include?("--include-test") &&
!ARGV.include?("--include-optional") &&
!ARGV.include?("--skip-recommended")
if ARGV.named.empty?
raise FormulaUnspecifiedError unless mode.installed?
puts_deps Formula.installed.sort
elsif mode.for_each?
puts_deps ARGV.formulae
else
all_deps = deps_for_formulae(ARGV.formulae, !ARGV.one?, &(mode.union? ? :| : :&))
all_deps = condense_requirements(all_deps)
all_deps = all_deps.select(&:installed?) if mode.installed?
all_deps = all_deps.map(&method(:dep_display_name)).uniq
all_deps.sort! unless mode.topo_order?
puts all_deps
return
end
all_deps = deps_for_formulae(ARGV.formulae, !ARGV.one?, &(mode.union? ? :| : :&))
all_deps = condense_requirements(all_deps)
all_deps.select!(&:installed?) if mode.installed?
all_deps.map!(&method(:dep_display_name))
all_deps.uniq!
all_deps.sort! unless mode.topo_order?
puts all_deps
end
def condense_requirements(deps)
if ARGV.include?("--include-requirements")
deps
else
deps.select { |dep| dep.is_a? Dependency }
end
return deps if ARGV.include?("--include-requirements")
deps.select { |dep| dep.is_a? Dependency }
end
def dep_display_name(dep)
@ -106,58 +118,33 @@ module Homebrew
# This shouldn't happen, but we'll put something here to help debugging
"::#{dep.name}"
end
elsif ARGV.include?("--full-name")
dep.to_formula.full_name
else
ARGV.include?("--full-name") ? dep.to_formula.full_name : dep.name
dep.name
end
if ARGV.include?("--annotate")
str = "#{str} [build]" if dep.build?
str = "#{str} [test]" if dep.test?
str = "#{str} [optional" if dep.optional?
str = "#{str} [recommended]" if dep.recommended?
end
str
end
def deps_for_formula(f, recursive = false)
includes = []
ignores = []
if ARGV.include?("--include-build")
includes << "build?"
else
ignores << "build?"
end
if ARGV.include?("--include-optional")
includes << "optional?"
else
ignores << "optional?"
end
ignores << "recommended?" if ARGV.include?("--skip-recommended")
includes, ignores = argv_includes_ignores(ARGV)
deps = f.runtime_dependencies if @only_installed_arg
if recursive
deps = f.recursive_dependencies do |dependent, dep|
if dep.recommended?
Dependency.prune if ignores.include?("recommended?") || dependent.build.without?(dep)
elsif dep.optional?
Dependency.prune if !includes.include?("optional?") && !dependent.build.with?(dep)
elsif dep.build?
Dependency.prune unless includes.include?("build?")
end
end
reqs = f.recursive_requirements do |dependent, req|
if req.recommended?
Requirement.prune if ignores.include?("recommended?") || dependent.build.without?(req)
elsif req.optional?
Requirement.prune if !includes.include?("optional?") && !dependent.build.with?(req)
elsif req.build?
Requirement.prune unless includes.include?("build?")
end
end
deps ||= recursive_includes(Dependency, f, includes, ignores)
reqs = recursive_includes(Requirement, f, includes, ignores)
else
deps = f.deps.reject do |dep|
ignores.any? { |ignore| dep.send(ignore) } && includes.none? { |include| dep.send(include) }
end
reqs = f.requirements.reject do |req|
ignores.any? { |ignore| req.send(ignore) } && includes.none? { |include| req.send(include) }
end
deps ||= reject_ignores(f.deps, ignores, includes)
reqs = reject_ignores(f.requirements, ignores, includes)
end
deps + reqs.to_a
@ -171,7 +158,8 @@ module Homebrew
formulae.each do |f|
deps = deps_for_formula(f)
deps = condense_requirements(deps)
deps = deps.sort_by(&:name).map(&method(:dep_display_name))
deps.sort_by!(&:name)
deps.map!(&method(:dep_display_name))
puts "#{f.full_name}: #{deps.join(" ")}"
end
end
@ -189,32 +177,39 @@ module Homebrew
reqs = f.requirements
deps = f.deps
dependables = reqs + deps
dependables = dependables.reject(&:optional?) unless ARGV.include?("--include-optional")
dependables = dependables.reject(&:build?) unless ARGV.include?("--include-build")
dependables = dependables.reject(&:recommended?) if ARGV.include?("--skip-recommended")
dependables.reject!(&:optional?) unless ARGV.include?("--include-optional")
dependables.reject!(&:build?) unless ARGV.include?("--include-build")
dependables.reject!(&:test?) unless ARGV.include?("--include-test")
dependables.reject!(&:recommended?) if ARGV.include?("--skip-recommended")
max = dependables.length - 1
@dep_stack.push f.name
dependables.each_with_index do |dep, i|
next if !ARGV.include?("--include-requirements") && dep.is_a?(Requirement)
tree_lines = if i == max
"└──"
else
"├──"
end
display_s = "#{tree_lines} #{dep_display_name(dep)}"
is_circular = @dep_stack.include?(dep.name)
display_s = "#{display_s} (CIRCULAR DEPENDENCY)" if is_circular
puts "#{prefix}#{display_s}"
next if !recursive || is_circular
prefix_addition = if i == max
" "
else
""
end
if dep.is_a? Dependency
recursive_deps_tree(Formulary.factory(dep.name), prefix + prefix_addition, true)
end
end
@dep_stack.pop
end
end

View File

@ -28,7 +28,6 @@ module Homebrew
slow_checks = %w[
check_for_broken_symlinks
check_missing_deps
check_for_linked_keg_only_brews
]
methods = (checks.all.sort - slow_checks) + slow_checks
else

View File

@ -113,14 +113,14 @@ module Homebrew
url = "https://api.github.com/gists"
data = { "public" => true, "files" => files, "description" => description }
scopes = GitHub::CREATE_GIST_SCOPES
GitHub.open(url, data: data, scopes: scopes)["html_url"]
GitHub.open_api(url, data: data, scopes: scopes)["html_url"]
end
def create_issue(repo, title, body)
url = "https://api.github.com/repos/#{repo}/issues"
data = { "title" => title, "body" => body }
scopes = GitHub::CREATE_ISSUE_SCOPES
GitHub.open(url, data: data, scopes: scopes)["html_url"]
scopes = GitHub::CREATE_ISSUE_FORK_OR_PR_SCOPES
GitHub.open_api(url, data: data, scopes: scopes)["html_url"]
end
def gist_logs

View File

@ -1,7 +1,7 @@
HOMEBREW_HELP = <<~EOS.freeze
Example usage:
brew search [TEXT|/REGEX/]
brew (info|home|options) [FORMULA...]
brew info [FORMULA...]
brew install FORMULA...
brew update
brew upgrade [FORMULA...]
@ -11,17 +11,17 @@ HOMEBREW_HELP = <<~EOS.freeze
Troubleshooting:
brew config
brew doctor
brew install -vd FORMULA
brew install --verbose --debug FORMULA
Developers:
Contributing:
brew create [URL [--no-fetch]]
brew edit [FORMULA...]
https://docs.brew.sh/Formula-Cookbook
Further help:
man brew
brew commands
brew help [COMMAND]
brew home
man brew
https://docs.brew.sh
EOS
# NOTE Keep the lenth of vanilla --help less than 25 lines!
@ -74,14 +74,13 @@ module Homebrew
end
def command_help(path)
help_lines = path.read.lines.grep(/^#:/)
help_lines = command_help_lines(path)
if help_lines.empty?
opoo "No help text in: #{path}" if ARGV.homebrew_developer?
HOMEBREW_HELP
else
help_lines.map do |line|
line.slice(2..-1)
.sub(/^ \* /, "#{Tty.bold}brew#{Tty.reset} ")
line.sub(/^ \* /, "#{Tty.bold}brew#{Tty.reset} ")
.gsub(/`(.*?)`/, "#{Tty.bold}\\1#{Tty.reset}")
.gsub(%r{<([^\s]+?://[^\s]+?)>}) { |url| Formatter.url(url) }
.gsub(/<(.*?)>/, "#{Tty.underline}\\1#{Tty.reset}")

View File

@ -1,4 +1,4 @@
#: * `install` [`--debug`] [`--env=`(`std`|`super`)] [`--ignore-dependencies`|`--only-dependencies`] [`--cc=`<compiler>] [`--build-from-source`|`--force-bottle`] [`--devel`|`--HEAD`] [`--keep-tmp`] [`--build-bottle`] [`--force`] [`--verbose`] <formula> [<options> ...]:
#: * `install` [`--debug`] [`--env=`(`std`|`super`)] [`--ignore-dependencies`|`--only-dependencies`] [`--cc=`<compiler>] [`--build-from-source`|`--force-bottle`] [`--include-test`] [`--devel`|`--HEAD`] [`--keep-tmp`] [`--build-bottle`] [`--force`] [`--verbose`] <formula> [<options> ...]:
#: Install <formula>.
#:
#: <formula> is usually the name of the formula to install, but it can be specified
@ -36,6 +36,9 @@
#: current or newest version of macOS, even if it would not normally be used
#: for installation.
#:
#: If `--include-test` is passed, install testing dependencies. These are only
#: needed by formulae maintainers to run `brew test`.
#:
#: If `--devel` is passed, and <formula> defines it, install the development version.
#:
#: If `--HEAD` is passed, and <formula> defines it, install the HEAD version,
@ -68,7 +71,6 @@ require "missing_formula"
require "diagnostic"
require "cmd/search"
require "formula_installer"
require "tap"
require "hardware"
require "development_tools"
@ -159,9 +161,12 @@ module Homebrew
#{f.full_name} #{optlinked_version} is already installed
To upgrade to #{f.version}, run `brew upgrade #{f.name}`
EOS
elsif ARGV.only_deps?
formulae << f
else
opoo <<~EOS
#{f.full_name} #{f.pkg_version} is already installed
#{f.full_name} #{f.pkg_version} is already installed and up-to-date
To reinstall #{f.pkg_version}, run `brew reinstall #{f.name}`
EOS
end
elsif (ARGV.build_head? && new_head_installed) || prefix_installed
@ -185,11 +190,19 @@ module Homebrew
EOS
elsif !f.linked? || f.keg_only?
msg = <<~EOS
#{msg}, it's just not linked.
#{msg}, it's just not linked
You can use `brew link #{f}` to link this version.
EOS
elsif ARGV.only_deps?
msg = nil
formulae << f
else
msg = <<~EOS
#{msg} and up-to-date
To reinstall #{f.pkg_version}, run `brew reinstall #{f.name}`
EOS
end
opoo msg
opoo msg if msg
elsif !f.any_version_installed? && old_formula = f.old_installed_formulae.first
msg = "#{old_formula.full_name} #{old_formula.installed_version} already installed"
if !old_formula.linked? && !old_formula.keg_only?
@ -249,10 +262,10 @@ module Homebrew
return
end
query = query_regexp(e.name)
regex = query_regexp(e.name)
ohai "Searching for similarly named formulae..."
formulae_search_results = search_formulae(query)
formulae_search_results = search_formulae(regex)
case formulae_search_results.length
when 0
ofail "No similarly named formulae found."
@ -269,7 +282,7 @@ module Homebrew
# Do not search taps if the formula name is qualified
return if e.name.include?("/")
ohai "Searching taps..."
taps_search_results = search_taps(query)
taps_search_results = search_taps(e.name)
case taps_search_results.length
when 0
ofail "No formulae found in taps."
@ -344,7 +357,7 @@ module Homebrew
rescue FormulaInstallationAlreadyAttemptedError
# We already attempted to install f as part of the dependency tree of
# another formula. In that case, don't generate an error, just move on.
return
nil
rescue CannotInstallFormulaError => e
ofail e.message
end

View File

@ -3,22 +3,24 @@
require "formula"
require "tab"
require "set"
module Homebrew
module_function
def leaves
installed = Formula.installed.sort
deps_of_installed = Set.new
installed.each do |f|
deps = f.runtime_dependencies.map { |d| d.to_formula.full_name }
deps_of_installed.merge(deps)
deps_of_installed = installed.flat_map do |f|
f.runtime_dependencies.map do |dep|
begin
dep.to_formula.full_name
rescue FormulaUnavailableError
dep.name
end
end
end
installed.each do |f|
puts f.full_name unless deps_of_installed.include? f.full_name
end
leaves = installed.map(&:full_name) - deps_of_installed
leaves.each(&method(:puts))
end
end

View File

@ -1,67 +0,0 @@
#: @hide_from_man_page
#: * `linkapps` [`--local`] [<formulae>]:
#: Find installed formulae that provide `.app`-style macOS apps and symlink them
#: 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.
require "keg"
require "formula"
module Homebrew
module_function
def linkapps
odeprecated "'brew linkapps'"
target_dir = linkapps_target(local: ARGV.include?("--local"))
unless target_dir.directory?
opoo "#{target_dir} does not exist, stopping."
puts "Run `mkdir #{target_dir}` first."
exit 1
end
if ARGV.named.empty?
kegs = Formula.racks.map do |rack|
keg = rack.subdirs.map { |d| Keg.new(d) }
next if keg.empty?
keg.detect(&:linked?) || keg.max_by(&:version)
end
else
kegs = ARGV.kegs
end
link_count = 0
kegs.each do |keg|
keg.apps.each do |app|
puts "Linking: #{app}"
target_app = target_dir/app.basename
if target_app.exist? && !target_app.symlink?
onoe "#{target_app} already exists, skipping."
next
end
# We prefer system `ln` over `FileUtils.ln_sf` because the latter seems
# to have weird failure conditions (that were observed in the past).
system "ln", "-sf", app, target_dir
link_count += 1
end
end
if link_count.zero?
puts "No apps linked to #{target_dir}" if ARGV.verbose?
else
puts "Linked #{Formatter.pluralize(link_count, "app")} to #{target_dir}"
end
end
def linkapps_target(opts = {})
local = opts.fetch(:local, false)
Pathname.new(local ? "~/Applications" : "/Applications").expand_path
end
end

View File

@ -1,15 +1,12 @@
#: * `prune` [`--dry-run`]:
#: Remove dead symlinks from the Homebrew prefix. This is generally not
#: needed, but can be useful when doing DIY installations. Also remove broken
#: app symlinks from `/Applications` and `~/Applications` that were previously
#: created by `brew linkapps`.
#: needed, but can be useful when doing DIY installations.
#:
#: If `--dry-run` or `-n` is passed, show what would be removed, but do not
#: actually remove anything.
require "keg"
require "cmd/tap"
require "cmd/unlinkapps"
module Homebrew
module_function
@ -49,17 +46,15 @@ module Homebrew
end
end
unless ARGV.dry_run?
if ObserverPathnameExtension.total.zero?
puts "Nothing pruned" if ARGV.verbose?
else
n, d = ObserverPathnameExtension.counts
print "Pruned #{n} symbolic links "
print "and #{d} directories " if d.positive?
puts "from #{HOMEBREW_PREFIX}"
end
end
return if ARGV.dry_run?
unlinkapps_prune(dry_run: ARGV.dry_run?, quiet: true)
if ObserverPathnameExtension.total.zero?
puts "Nothing pruned" if ARGV.verbose?
else
n, d = ObserverPathnameExtension.counts
print "Pruned #{n} symbolic links "
print "and #{d} directories " if d.positive?
puts "from #{HOMEBREW_PREFIX}"
end
end
end

View File

@ -47,7 +47,7 @@ module Homebrew
fi.install
fi.finish
rescue FormulaInstallationAlreadyAttemptedError
return
nil
rescue Exception # rubocop:disable Lint/RescueException
ignore_interrupts { restore_backup(keg, keg_was_linked) }
raise

View File

@ -15,8 +15,6 @@
require "formula"
require "missing_formula"
require "utils"
require "official_taps"
require "descriptions"
module Homebrew
@ -110,15 +108,22 @@ module Homebrew
$stderr.puts Formatter.headline("Searching taps on GitHub...", color: :blue)
end
valid_dirnames = ["Formula", "HomebrewFormula", "Casks", "."].freeze
matches = GitHub.search_code(user: ["Homebrew", "caskroom"], filename: query, extension: "rb")
matches = begin
GitHub.search_code(
user: ["Homebrew", "caskroom"],
path: ["Formula", "HomebrewFormula", "Casks", "."],
filename: query,
extension: "rb",
)
rescue GitHub::Error => error
opoo "Error searching on GitHub: #{error}\n"
[]
end
matches.map do |match|
dirname, filename = File.split(match["path"])
next unless valid_dirnames.include?(dirname)
filename = File.basename(match["path"], ".rb")
tap = Tap.fetch(match["repository"]["full_name"])
next if tap.installed? && match["repository"]["owner"]["login"] != "caskroom"
"#{tap.name}/#{File.basename(filename, ".rb")}"
"#{tap.name}/#{filename}"
end.compact
end

View File

@ -11,13 +11,14 @@
#: If `--display-cop-names` is passed, include the RuboCop cop name for each
#: violation in the output.
#:
#: If `--rspec` is passed, install and use the RuboCop RSpec gem.
#:
#: Passing `--only-cops=`<cops> will check for violations of only the listed
#: RuboCop <cops>, while `--except-cops=`<cops> will skip checking the listed
#: <cops>. For either option <cops> should be a comma-separated list of cop names.
#:
#: Exits with a non-zero status if any style violations are found.
require "utils"
require "json"
require "open3"
@ -83,6 +84,11 @@ module Homebrew
args << "--parallel"
end
if ARGV.include?("--rspec")
Homebrew.install_gem! "rubocop-rspec"
args += %w[--require rubocop-rspec]
end
if options[:except_cops]
options[:except_cops].map! { |cop| RuboCop::Cop::Cop.registry.qualified_cop_name(cop.to_s, "") }
cops_to_exclude = options[:except_cops].select do |cop|

View File

@ -1,5 +1,5 @@
#: * `switch` <name> <version>:
#: Symlink all of the specific <version> of <name>'s install to Homebrew prefix.
#: * `switch` <formula> <version>:
#: Symlink all of the specific <version> of <formula>'s install to Homebrew prefix.
require "formula"
require "keg"
@ -9,14 +9,15 @@ module Homebrew
module_function
def switch
if ARGV.named.length != 2
onoe "Usage: brew switch <name> <version>"
name = ARGV.first
usage = "Usage: brew switch <formula> <version>"
unless name
onoe usage
exit 1
end
name = ARGV.shift
version = ARGV.shift
rack = Formulary.to_rack(name)
unless rack.directory?
@ -24,13 +25,21 @@ module Homebrew
exit 2
end
# Does the target version exist?
versions = rack.subdirs
.map { |d| Keg.new(d).version }
.sort
.join(", ")
version = ARGV[1]
if !version || ARGV.named.length > 2
onoe usage
puts "#{name} installed versions: #{versions}"
exit 1
end
unless (rack/version).directory?
onoe "#{name} does not have a version \"#{version}\" in the Cellar."
versions = rack.subdirs.map { |d| Keg.new(d).version }.sort
puts "Versions available: #{versions.join(", ")}"
puts "#{name} installed versions: #{versions}"
exit 3
end

View File

@ -15,8 +15,6 @@
#: See the docs for examples of using the JSON output:
#: <https://docs.brew.sh/Querying-Brew>
require "tap"
module Homebrew
module_function

View File

@ -2,8 +2,6 @@
#: Pin <tap>, prioritizing its formulae over core when formula names are supplied
#: by the user. See also `tap-unpin`.
require "tap"
module Homebrew
module_function

View File

@ -1,8 +1,6 @@
#: * `tap-unpin` <tap>:
#: Unpin <tap> so its formulae are no longer prioritized. See also `tap-pin`.
require "tap"
module Homebrew
module_function

View File

@ -25,14 +25,9 @@
#: * `tap` `--repair`:
#: Migrate tapped formulae from symlink-based to directory-based structure.
#:
#: * `tap` `--list-official`:
#: List all official taps.
#:
#: * `tap` `--list-pinned`:
#: List all pinned taps.
require "tap"
module Homebrew
module_function
@ -40,8 +35,7 @@ module Homebrew
if ARGV.include? "--repair"
Tap.each(&:link_completions_and_manpages)
elsif ARGV.include? "--list-official"
require "official_taps"
puts OFFICIAL_TAPS.map { |t| "homebrew/#{t}" }
odeprecated("brew tap --list-official")
elsif ARGV.include? "--list-pinned"
puts Tap.select(&:pinned?).map(&:name)
elsif ARGV.named.empty?

View File

@ -1,79 +0,0 @@
#: @hide_from_man_page
#: * `unlinkapps` [`--local`] [`--dry-run`] [<formulae>]:
#: 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.
require "cmd/linkapps"
module Homebrew
module_function
def unlinkapps
odeprecated "'brew unlinkapps'"
target_dir = linkapps_target(local: ARGV.include?("--local"))
unlinkapps_from_dir(target_dir, dry_run: ARGV.dry_run?)
end
def unlinkapps_prune(opts = {})
opts = opts.merge(prune: true)
unlinkapps_from_dir(linkapps_target(local: false), opts)
unlinkapps_from_dir(linkapps_target(local: true), opts)
end
def unlinkapps_from_dir(target_dir, opts = {})
return unless target_dir.directory?
dry_run = opts.fetch(:dry_run, false)
quiet = opts.fetch(:quiet, false)
apps = Pathname.glob("#{target_dir}/*.app").select do |app|
unlinkapps_unlink?(app, opts)
end
ObserverPathnameExtension.reset_counts!
app_kind = opts.fetch(:prune, false) ? " (broken link)" : ""
apps.each do |app|
app.extend(ObserverPathnameExtension)
if dry_run
puts "Would unlink#{app_kind}: #{app}"
else
puts "Unlinking#{app_kind}: #{app}" unless quiet
app.unlink
end
end
return if dry_run
if ObserverPathnameExtension.total.zero?
puts "No apps unlinked from #{target_dir}" if ARGV.verbose?
else
n = ObserverPathnameExtension.total
puts "Unlinked #{Formatter.pluralize(n, "app")} from #{target_dir}"
end
end
UNLINKAPPS_PREFIXES = %W[
#{HOMEBREW_CELLAR}/
#{HOMEBREW_PREFIX}/opt/
].freeze
def unlinkapps_unlink?(target_app, opts = {})
# Skip non-symlinks and symlinks that don't point into the Homebrew prefix.
app = target_app.readlink.to_s if target_app.symlink?
return false unless app&.start_with?(*UNLINKAPPS_PREFIXES)
if opts.fetch(:prune, false)
!File.exist?(app) # Remove only broken symlinks in prune mode.
elsif ARGV.named.empty?
true
else
ARGV.kegs.any? { |keg| app.start_with?("#{keg}/", "#{keg.opt_record}/") }
end
end
end

View File

@ -1,8 +1,6 @@
#: * `untap` <tap>:
#: Remove a tapped repository.
require "tap"
module Homebrew
module_function

View File

@ -7,13 +7,12 @@ require "migrator"
require "formulary"
require "descriptions"
require "cleanup"
require "utils"
module Homebrew
module_function
def update_preinstall_header
@header_already_printed ||= begin
@update_preinstall_header ||= begin
ohai "Auto-updated Homebrew!" if ARGV.include?("--preinstall")
true
end

View File

@ -23,15 +23,8 @@ git() {
}
git_init_if_necessary() {
if [[ -n "$HOMEBREW_MACOS" ]] || [[ -n "$HOMEBREW_FORCE_HOMEBREW_ORG" ]]
then
BREW_OFFICIAL_REMOTE="https://github.com/Homebrew/brew"
CORE_OFFICIAL_REMOTE="https://github.com/Homebrew/homebrew-core"
elif [[ -n "$HOMEBREW_LINUX" ]]
then
BREW_OFFICIAL_REMOTE="https://github.com/Linuxbrew/brew"
CORE_OFFICIAL_REMOTE="https://github.com/Linuxbrew/homebrew-core"
fi
BREW_OFFICIAL_REMOTE="https://github.com/Homebrew/brew"
CORE_OFFICIAL_REMOTE="https://github.com/Homebrew/homebrew-core"
safe_cd "$HOMEBREW_REPOSITORY"
if [[ ! -d ".git" ]]

View File

@ -1,17 +1,21 @@
#: * `upgrade` [<install-options>] [`--cleanup`] [`--fetch-HEAD`] [<formulae>]:
#: * `upgrade` [<install-options>] [`--cleanup`] [`--fetch-HEAD`] [`--ignore-pinned`] [<formulae>]:
#: Upgrade outdated, unpinned brews (with existing install options).
#:
#: Options for the `install` command are also valid here.
#:
#: If `--cleanup` is specified then remove previously installed <formula> version(s).
#: If `--cleanup` is specified or `HOMEBREW_UPGRADE_CLEANUP` is set then remove
#: previously installed <formula> version(s).
#:
#: If `--fetch-HEAD` is passed, fetch the upstream repository to detect if
#: the HEAD installation of the formula is outdated. Otherwise, the
#: repository's HEAD will be checked for updates when a new stable or devel
#: version has been released.
#:
#: If <formulae> are given, upgrade only the specified brews (but do so even
#: if they are pinned; see `pin`, `unpin`).
#: If `--ignore-pinned` is passed, set a 0 exit code even if pinned formulae
#: are not upgraded.
#:
#: If <formulae> are given, upgrade only the specified brews (unless they
#: are pinned; see `pin`, `unpin`).
require "cmd/install"
require "cleanup"
@ -25,7 +29,7 @@ module Homebrew
Homebrew.perform_preinstall_checks
odeprecated "'brew upgrade --all'", "'brew upgrade'" if ARGV.include?("--all")
odisabled "'brew upgrade --all'", "'brew upgrade'" if ARGV.include?("--all")
if ARGV.named.empty?
outdated = Formula.installed.select do |f|
@ -54,16 +58,23 @@ module Homebrew
outdated -= pinned
formulae_to_install = outdated.map(&:latest_formula)
if !pinned.empty? && !ARGV.include?("--ignore-pinned")
ofail "Not upgrading #{Formatter.pluralize(pinned.length, "pinned package")}:"
puts pinned.map { |f| "#{f.full_specified_name} #{f.pkg_version}" } * ", "
end
if formulae_to_install.empty?
oh1 "No packages to upgrade"
else
oh1 "Upgrading #{Formatter.pluralize(formulae_to_install.length, "outdated package")}, with result:"
puts formulae_to_install.map { |f| "#{f.full_specified_name} #{f.pkg_version}" } * ", "
end
unless pinned.empty?
onoe "Not upgrading #{Formatter.pluralize(pinned.length, "pinned package")}:"
puts pinned.map { |f| "#{f.full_specified_name} #{f.pkg_version}" } * ", "
formulae_upgrades = formulae_to_install.map do |f|
if f.optlinked?
"#{f.full_specified_name} #{Keg.new(f.opt_prefix).version} -> #{f.pkg_version}"
else
"#{f.full_specified_name} #{f.pkg_version}"
end
end
puts formulae_upgrades.join(", ")
end
# Sort keg_only before non-keg_only formulae to avoid any needless conflicts
@ -82,7 +93,7 @@ module Homebrew
Migrator.migrate_if_needed(f)
begin
upgrade_formula(f)
next unless ARGV.include?("--cleanup")
next if !ARGV.include?("--cleanup") && !ENV["HOMEBREW_UPGRADE_CLEANUP"]
next unless f.installed?
Homebrew::Cleanup.cleanup_formula f
rescue UnsatisfiedRequirements => e
@ -139,7 +150,7 @@ module Homebrew
rescue FormulaInstallationAlreadyAttemptedError
# We already attempted to upgrade f as part of the dependency tree of
# another formula. In that case, don't generate an error, just move on.
return
nil
rescue CannotInstallFormulaError => e
ofail e
rescue BuildError => e

View File

@ -1,4 +1,4 @@
#: * `uses` [`--installed`] [`--recursive`] [`--include-build`] [`--include-optional`] [`--skip-recommended`] [`--devel`|`--HEAD`] <formulae>:
#: * `uses` [`--installed`] [`--recursive`] [`--include-build`] [`--include-test`] [`--include-optional`] [`--skip-recommended`] [`--devel`|`--HEAD`] <formulae>:
#: Show the formulae that specify <formulae> as a dependency. When given
#: multiple formula arguments, show the intersection of formulae that use
#: <formulae>.
@ -9,10 +9,12 @@
#:
#: By default, `uses` shows all formulae that specify <formulae> as a required
#: or recommended dependency. To include the `:build` type dependencies, pass
#: `--include-build`. Similarly, pass `--include-optional` to include `:optional`
#: dependencies. To skip `:recommended` type dependencies, pass `--skip-recommended`.
#: `--include-build`, to include the `:test` type dependencies, pass
#: `--include-test` and to include `:optional` dependencies pass
#: `--include-optional`. To skip `:recommended` type dependencies, pass
#: `--skip-recommended`.
#:
#: By default, `uses` shows usages of <formulae> by stable builds. To find
#: By default, `uses` shows usage of <formulae> by stable builds. To find
#: cases where <formulae> is used by development or HEAD build, pass
#: `--devel` or `--HEAD`.
@ -40,80 +42,31 @@ module Homebrew
formulae = ARGV.include?("--installed") ? Formula.installed : Formula
recursive = ARGV.flag? "--recursive"
includes = []
ignores = []
if ARGV.include? "--include-build"
includes << "build?"
else
ignores << "build?"
end
if ARGV.include? "--include-optional"
includes << "optional?"
else
ignores << "optional?"
end
ignores << "recommended?" if ARGV.include? "--skip-recommended"
only_installed_arg = ARGV.include?("--installed") &&
!ARGV.include?("--include-build") &&
!ARGV.include?("--include-test") &&
!ARGV.include?("--include-optional") &&
!ARGV.include?("--skip-recommended")
includes, ignores = argv_includes_ignores(ARGV)
uses = formulae.select do |f|
used_formulae.all? do |ff|
begin
if recursive
deps = f.recursive_dependencies do |dependent, dep|
if dep.recommended?
Dependency.prune if ignores.include?("recommended?") || dependent.build.without?(dep)
elsif dep.optional?
Dependency.prune if !includes.include?("optional?") && !dependent.build.with?(dep)
elsif dep.build?
Dependency.prune unless includes.include?("build?")
end
# If a tap isn't installed, we can't find the dependencies of one
# its formulae, and an exception will be thrown if we try.
if dep.is_a?(TapDependency) && !dep.tap.installed?
Dependency.keep_but_prune_recursive_deps
end
end
dep_formulae = deps.flat_map do |dep|
begin
dep.to_formula
rescue
[]
end
end
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?
ignores.include?("recommended?") || dependent.build.without?(req)
elsif req.optional?
!includes.include?("optional?") && !dependent.build.with?(req)
elsif req.build?
!includes.include?("build?")
end
end
reqs = reqs_by_formula.map(&:last)
deps = f.runtime_dependencies if only_installed_arg
deps ||= if recursive
recursive_includes(Dependency, f, includes, ignores)
else
deps = f.deps.reject do |dep|
ignores.any? { |ignore| dep.send(ignore) } && includes.none? { |include| dep.send(include) }
end
reqs = f.requirements.reject do |req|
ignores.any? { |ignore| req.send(ignore) } && includes.none? { |include| req.send(include) }
end
reject_ignores(f.deps, ignores, includes)
end
next true if deps.any? do |dep|
deps.any? do |dep|
begin
dep.to_formula.full_name == ff.full_name
rescue
dep.name == ff.name
end
end
reqs.any? { |req| req.name == ff.name }
rescue FormulaUnavailableError
# Silently ignore this case as we don't care about things used in
# taps that aren't currently tapped.

View File

@ -47,7 +47,15 @@ fetch() {
local sha
local temporary_path
curl_args=(
curl_args=()
# do not load .curlrc unless requested (must be the first argument)
if [[ -n "$HOMEBREW_CURLRC" ]]
then
curl_args[${#curl_args[*]}]="-q"
fi
curl_args+=(
--fail
--remote-time
--location
@ -114,10 +122,10 @@ EOS
if [[ -x "/usr/bin/shasum" ]]
then
sha="$(/usr/bin/shasum -a 256 "$CACHED_LOCATION" | cut -d' ' -f1)"
elif [[ -x "$(which sha256sum)" ]]
elif [[ -x "$(type -P sha256sum)" ]]
then
sha="$(sha256sum "$CACHED_LOCATION" | cut -d' ' -f1)"
elif [[ -x "$(which ruby)" ]]
elif [[ -x "$(type -P ruby)" ]]
then
sha="$(ruby <<EOSCRIPT
require 'digest/sha2'

View File

@ -1,31 +1,10 @@
require "compat/fails_with_llvm"
require "compat/tap"
require "compat/hbc"
require "compat/formula"
require "compat/formula_specialties"
require "compat/formula_support"
require "compat/global"
require "compat/hardware"
require "compat/macos"
require "compat/md5"
require "compat/sha1"
require "compat/requirements"
require "compat/version"
require "compat/download_strategy"
require "compat/keg"
require "compat/pathname"
require "compat/dependency_collector"
require "compat/language/haskell"
require "compat/xcode"
require "compat/software_spec"
require "compat/utils"
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"
require "compat/utils/shell"
require "compat/extend/string"
require "compat/gpg"
require "compat/dependable"

View File

@ -1,5 +0,0 @@
module HomebrewArgvExtension
def build_32_bit?
odisabled "ARGV.build_32_bit?"
end
end

View File

@ -1,10 +1,9 @@
module SharedEnvExtension
def j1
odeprecated "ENV.j1", "ENV.deparallelize"
deparallelize
odisabled "ENV.j1", "ENV.deparallelize"
end
def java_cache
odeprecated "ENV.java_cache"
odisabled "ENV.java_cache"
end
end

View File

@ -1,25 +0,0 @@
module Stdenv
def fast
odisabled "ENV.fast"
end
def O4
odisabled "ENV.O4"
end
def Og
odisabled "ENV.Og"
end
def gcc_4_0_1
odisabled "ENV.gcc_4_0_1", "ENV.gcc_4_0"
end
def gcc
odisabled "ENV.gcc", "ENV.gcc_4_2"
end
def libpng
odisabled "ENV.libpng", "ENV.x11"
end
end

View File

@ -1,45 +0,0 @@
module Superenv
def fast
odisabled "ENV.fast"
end
def O4
odisabled "ENV.O4"
end
def Og
odisabled "ENV.Og"
end
def gcc_4_0_1
odisabled "ENV.gcc_4_0_1", "ENV.gcc_4_0"
end
def gcc
odisabled "ENV.gcc", "ENV.gcc_4_2"
end
def libxml2
odisabled "ENV.libxml2"
end
def minimal_optimization
odisabled "ENV.minimal_optimization"
end
def no_optimization
odisabled "ENV.no_optimization"
end
def enable_warnings
odisabled "ENV.enable_warnings"
end
def macosxsdk
odisabled "ENV.macosxsdk"
end
def remove_macosxsdk
odisabled "ENV.remove_macosxsdk"
end
end

View File

@ -1,9 +0,0 @@
class BuildOptions
def build_32_bit?
odisabled "build.build_32_bit?"
end
def build_bottle?
odisabled "build.build_bottle?", "build.bottle?"
end
end

View File

@ -0,0 +1,6 @@
module Dependable
def run?
odeprecated "Dependable#run?"
tags.include? :run
end
end

View File

@ -9,57 +9,42 @@ class DependencyCollector
def parse_string_spec(spec, tags)
if (tag = tags.first) && LANGUAGE_MODULES.include?(tag)
odeprecated "'depends_on ... => #{tag.inspect}'"
LanguageModuleRequirement.new(tag, spec, tags[1])
else
super
odisabled "'depends_on ... => #{tag.inspect}'"
end
if tags.include?(:run)
odeprecated "'depends_on ... => :run'"
end
super
end
def parse_symbol_spec(spec, tags)
case spec
when :clt
odeprecated "'depends_on :clt'"
odisabled "'depends_on :clt'"
when :tex
odeprecated "'depends_on :tex'"
TeXRequirement.new(tags)
when :autoconf, :automake, :bsdmake, :libtool
output_deprecation(spec)
autotools_dep(spec, tags)
when :cairo, :fontconfig, :freetype, :libpng, :pixman
output_deprecation(spec)
Dependency.new(spec.to_s, tags)
when :ant, :expat
output_deprecation(spec)
Dependency.new(spec.to_s, tags)
odisabled "'depends_on :tex'"
when :libltdl
tags << :run
output_deprecation("libtool")
Dependency.new("libtool", tags)
output_disabled(spec, "libtool")
when :apr
output_deprecation(spec, "apr-util")
Dependency.new("apr-util", tags)
output_disabled(spec, "apr-util")
when :fortran
output_deprecation(spec, "gcc")
Dependency.new("gcc", tags)
output_disabled(spec, "gcc")
when :gpg
output_deprecation(spec, "gnupg")
Dependency.new("gnupg", tags)
output_disabled(spec, "gnupg")
when :hg
output_deprecation(spec, "mercurial")
Dependency.new("mercurial", tags)
output_disabled(spec, "mercurial")
when :mpi
output_deprecation(spec, "open-mpi")
Dependency.new("open-mpi", tags)
output_disabled(spec, "open-mpi")
when :python, :python2
output_deprecation(spec, "python@2")
Dependency.new("python@2", tags)
output_disabled(spec, "python@2")
when :python3
output_deprecation(spec, "python")
Dependency.new("python", tags)
when :emacs, :mysql, :perl, :postgresql, :rbenv, :ruby
output_deprecation(spec)
Dependency.new(spec.to_s, tags)
output_disabled(spec, "python")
when :ant, :autoconf, :automake, :bsdmake, :cairo, :emacs, :expat,
:fontconfig, :freetype, :libtool, :libpng, :mysql, :perl, :pixman,
:postgresql, :rbenv, :ruby
output_disabled(spec)
else
super
end
@ -67,14 +52,9 @@ class DependencyCollector
private
def autotools_dep(spec, tags)
tags << :build unless tags.include? :run
Dependency.new(spec.to_s, tags)
end
def output_deprecation(dependency, new_dependency = dependency)
odeprecated "'depends_on :#{dependency}'",
"'depends_on \"#{new_dependency}\"'"
def output_disabled(dependency, new_dependency = dependency)
odisabled "'depends_on :#{dependency}'",
"'depends_on \"#{new_dependency}\"'"
end
end

View File

@ -1,7 +1,6 @@
class String
def undent
odeprecated "<<-EOS.undent", "<<~EOS"
gsub(/^[ \t]{#{(slice(/^[ \t]+/) || '').length}}/, "")
odisabled "<<-EOS.undent", "<<~EOS"
end
alias unindent undent

View File

@ -1,9 +0,0 @@
class Formula
def fails_with_llvm(_msg = nil, _data = nil)
odisabled "Formula#fails_with_llvm in install"
end
def self.fails_with_llvm(_msg = nil, _data = {})
odisabled "Formula.fails_with_llvm"
end
end

View File

@ -1,74 +1,11 @@
module FormulaCompat
def x11_installed?
odisabled "Formula#x11_installed?", "MacOS::X11.installed?"
end
def snow_leopard_64?
odisabled "Formula#snow_leopard_64?", "MacOS.prefer_64_bit?"
end
end
class Formula
include FormulaCompat
extend FormulaCompat
def std_cmake_parameters
odisabled "Formula#std_cmake_parameters", "Formula#std_cmake_args"
end
def cxxstdlib_check(_)
odisabled "Formula#cxxstdlib_check in install",
"Formula.cxxstdlib_check outside install"
end
def self.bottle_sha1(*)
odisabled "Formula.bottle_sha1"
end
def self.all
odisabled "Formula.all", "Formula.map"
end
def self.canonical_name(_)
odisabled "Formula.canonical_name", "Formulary.canonical_name"
end
def self.class_s(_)
odisabled "Formula.class_s", "Formulary.class_s"
end
def self.factory(_)
odisabled "Formula.factory", "Formulary.factory"
end
def self.require_universal_deps
odisabled "Formula.require_universal_deps"
end
def self.path(_)
odisabled "Formula.path", "Formulary.core_path"
end
DATA = :DATA
def patches
# Don't print deprecation warning because this method is inherited
# when used.
{}
end
def python(_options = {}, &_)
odisabled "Formula#python"
end
alias python2 python
alias python3 python
def startup_plist
odisabled "Formula#startup_plist", "Formula#plist"
end
def rake(*args)
odeprecated "FileUtils#rake", "system \"rake\""
system "rake", *args
def rake(*)
odisabled "FileUtils#rake", "system \"rake\""
end
end

View File

@ -1,23 +0,0 @@
class ScriptFileFormula < Formula
def install
odisabled "ScriptFileFormula#install", "Formula#install"
end
end
class GithubGistFormula < ScriptFileFormula
def self.url(_val)
odisabled "GithubGistFormula.url", "Formula.url"
end
end
class AmazonWebServicesFormula < Formula
def install
odisabled "AmazonWebServicesFormula#install", "Formula#install"
end
alias standard_install install
# Use this method to generate standard caveats.
def standard_instructions(_, _)
odisabled "AmazonWebServicesFormula#standard_instructions", "Formula#caveats"
end
end

View File

@ -5,11 +5,9 @@ class KegOnlyReason
def to_s
case @reason
when :provided_by_osx
odeprecated "keg_only :provided_by_osx", "keg_only :provided_by_macos"
@reason = :provided_by_macos
odisabled "keg_only :provided_by_osx", "keg_only :provided_by_macos"
when :shadowed_by_osx
odeprecated "keg_only :shadowed_by_osx", "keg_only :shadowed_by_macos"
@reason = :shadowed_by_macos
odisabled "keg_only :shadowed_by_osx", "keg_only :shadowed_by_macos"
end
super

View File

@ -1,15 +0,0 @@
module Homebrew
module_function
def method_missing(method, *args, &block)
if instance_methods.include?(method)
odisabled "#{self}##{method}", "'module_function' or 'def self.#{method}' to convert it to a class method"
end
super
end
def respond_to_missing?(method, include_private = false)
return true if method_defined?(method)
super(method, include_private)
end
end

View File

@ -1,27 +1,24 @@
require "utils"
module Gpg
module_function
def executable
odeprecated "Gpg.executable", 'which "gpg"'
which "gpg"
odisabled "Gpg.executable", 'which "gpg"'
end
def available?
odeprecated "Gpg.available?", 'which "gpg"'
File.executable?(executable.to_s)
odisabled "Gpg.available?", 'which "gpg"'
end
def create_test_key(_)
odeprecated "Gpg.create_test_key"
odisabled "Gpg.create_test_key"
end
def cleanup_test_processes!
odeprecated "Gpg.cleanup_test_processes!"
odisabled "Gpg.cleanup_test_processes!"
end
def test(_)
odeprecated "Gpg.test"
odisabled "Gpg.test"
end
end

View File

@ -1,35 +0,0 @@
module Hardware
class << self
def is_32_bit?
odisabled "Hardware.is_32_bit?", "Hardware::CPU.is_32_bit?"
end
def is_64_bit?
odisabled "Hardware.is_64_bit?", "Hardware::CPU.is_64_bit?"
end
def bits
odisabled "Hardware.bits", "Hardware::CPU.bits"
end
def cpu_type
odisabled "Hardware.cpu_type", "Hardware::CPU.type"
end
def cpu_family
odisabled "Hardware.cpu_family", "Hardware::CPU.family"
end
def intel_family
odisabled "Hardware.intel_family", "Hardware::CPU.family"
end
def ppc_family
odisabled "Hardware.ppc_family", "Hardware::CPU.family"
end
def processor_count
odisabled "Hardware.processor_count", "Hardware::CPU.cores"
end
end
end

View File

@ -1,19 +0,0 @@
require "json"
module Utils
module JSON
module_function
def load(_)
odisabled "Utils::JSON.load", "JSON.parse"
end
def dump(_)
odisabled "Utils::JSON.dump", "JSON.generate"
end
def stringify_keys(_)
odisabled "Utils::JSON.stringify_keys"
end
end
end

View File

@ -1,5 +0,0 @@
class Keg
def fname
odisabled "Keg#fname", "Keg#name"
end
end

View File

@ -1,9 +0,0 @@
module Language
module Haskell
module Cabal
def cabal_clean_lib
odisabled "Language::Haskell::Cabal#cabal_clean_lib"
end
end
end
end

View File

@ -1,124 +0,0 @@
require "development_tools"
if OS.mac?
MACOS_FULL_VERSION = OS::Mac.full_version.to_s.freeze
MACOS_VERSION = OS::Mac.version.to_s.freeze
end
module OS
module Mac
module_function
def xcode_folder
odisabled "MacOS.xcode_folder", "MacOS::Xcode.folder"
end
def xcode_prefix
odisabled "MacOS.xcode_prefix", "MacOS::Xcode.prefix"
end
def xcode_installed?
odisabled "MacOS.xcode_installed?", "MacOS::Xcode.installed?"
end
def xcode_version
odisabled "MacOS.xcode_version", "MacOS::Xcode.version"
end
def clt_installed?
odisabled "MacOS.clt_installed?", "MacOS::CLT.installed?"
end
def clt_version?
odisabled "MacOS.clt_version?", "MacOS::CLT.version"
end
def x11_installed?
odisabled "MacOS.x11_installed?", "MacOS::X11.installed?"
end
def x11_prefix
odisabled "MacOS.x11_prefix", "MacOS::X11.prefix"
end
def leopard?
odisabled "MacOS.leopard?", "'MacOS.version == :leopard'"
end
def snow_leopard?
odisabled "MacOS.snow_leopard?", "'MacOS.version >= :snow_leopard'"
end
def snow_leopard_or_newer?
odisabled "MacOS.snow_leopard_or_newer?", "'MacOS.version >= :snow_leopard'"
end
def lion?
odisabled "MacOS.lion?", "'MacOS.version >= :lion'"
end
def lion_or_newer?
odisabled "MacOS.lion_or_newer?", "'MacOS.version >= :lion'"
end
def mountain_lion?
odisabled "MacOS.mountain_lion?", "'MacOS.version >= :mountain_lion'"
end
def mountain_lion_or_newer?
odisabled "MacOS.mountain_lion_or_newer?", "'MacOS.version >= :mountain_lion'"
end
def macports_or_fink_installed?
odisabled "MacOS.macports_or_fink_installed?", "!MacOS.macports_or_fink.empty?"
end
def locate(_)
odisabled "MacOS.locate", "DevelopmentTools.locate"
end
def default_cc
odisabled "MacOS.default_cc", "DevelopmentTools.default_cc"
end
def default_compiler
odisabled "MacOS.default_compiler", "DevelopmentTools.default_compiler"
end
def gcc_40_build_version
odisabled "MacOS.gcc_40_build_version", "DevelopmentTools.gcc_4_0_build_version"
end
def gcc_4_0_build_version
odisabled "MacOS.gcc_4_0_build_version", "DevelopmentTools.gcc_4_0_build_version"
end
def gcc_42_build_version
odisabled "MacOS.gcc_42_build_version", "DevelopmentTools.gcc_4_2_build_version"
end
def gcc_build_version
odisabled "MacOS.gcc_build_version", "DevelopmentTools.gcc_4_2_build_version"
end
def llvm_build_version
odisabled "MacOS.llvm_build_version"
end
def clang_version
odisabled "MacOS.clang_version", "DevelopmentTools.clang_version"
end
def clang_build_version
odisabled "MacOS.clang_build_version", "DevelopmentTools.clang_build_version"
end
def has_apple_developer_tools?
odisabled "MacOS.has_apple_developer_tools?", "DevelopmentTools.installed?"
end
def release
odisabled "MacOS.release", "MacOS.version"
end
end
end

View File

@ -1,23 +0,0 @@
class Formula
def self.md5(_val)
odisabled "Formula.md5", "Formula.sha256"
end
end
class SoftwareSpec
def md5(_val)
odisabled "SoftwareSpec#md5", "SoftwareSpec#sha256"
end
end
class Resource
def md5(_val)
odisabled "Resource#md5", "Resource#sha256"
end
end
class Pathname
def md5
odisabled "Pathname#md5", "Pathname#sha256"
end
end

View File

@ -1,9 +0,0 @@
class Pathname
def cp(_)
odisabled "Pathname#cp", "FileUtils.cp"
end
def chmod_R(_)
odisabled "Pathname#chmod_R", "FileUtils.chmod_R"
end
end

View File

@ -1,123 +1,107 @@
require "requirements"
require "compat/requirements/language_module_requirement"
class CVSRequirement < Requirement
fatal true
satisfy do
odeprecated("CVSRequirement", "'depends_on \"cvs\"'")
which "cvs"
odisabled("CVSRequirement", "'depends_on \"cvs\"'")
end
end
class EmacsRequirement < Requirement
fatal true
satisfy do
odeprecated("EmacsRequirement", "'depends_on \"emacs\"'")
which "emacs"
odisabled("EmacsRequirement", "'depends_on \"emacs\"'")
end
end
class FortranRequirement < Requirement
fatal true
satisfy do
odeprecated("FortranRequirement", "'depends_on \"gcc\"'")
which "gfortran"
odisabled("FortranRequirement", "'depends_on \"gcc\"'")
end
end
class GitRequirement < Requirement
fatal true
satisfy do
odeprecated("GitRequirement", "'depends_on \"git\"'")
which "git"
odisabled("GitRequirement", "'depends_on \"git\"'")
end
end
class GPG2Requirement < Requirement
fatal true
satisfy do
odeprecated("GPG2Requirement", "'depends_on \"gnupg\"'")
which "gpg"
odisabled("GPG2Requirement", "'depends_on \"gnupg\"'")
end
end
class MercurialRequirement < Requirement
fatal true
satisfy do
odeprecated("MercurialRequirement", "'depends_on \"mercurial\"'")
which "hg"
odisabled("MercurialRequirement", "'depends_on \"mercurial\"'")
end
end
class MPIRequirement < Requirement
fatal true
satisfy do
odeprecated("MPIRequirement", "'depends_on \"open-mpi\"'")
which "mpicc"
odisabled("MPIRequirement", "'depends_on \"open-mpi\"'")
end
end
class MysqlRequirement < Requirement
fatal true
satisfy do
odeprecated("MysqlRequirement", "'depends_on \"mysql\"'")
which "mysql_config"
odisabled("MysqlRequirement", "'depends_on \"mysql\"'")
end
end
class PerlRequirement < Requirement
fatal true
satisfy do
odeprecated("PerlRequirement", "'depends_on \"perl\"'")
which "perl"
odisabled("PerlRequirement", "'depends_on \"perl\"'")
end
end
class PostgresqlRequirement < Requirement
fatal true
satisfy do
odeprecated("PostgresqlRequirement", "'depends_on \"postgresql\"'")
which "pg_config"
odisabled("PostgresqlRequirement", "'depends_on \"postgresql\"'")
end
end
class PythonRequirement < Requirement
fatal true
satisfy do
odeprecated("PythonRequirement", "'depends_on \"python@2\"'")
which "python2"
odisabled("PythonRequirement", "'depends_on \"python@2\"'")
end
end
class Python3Requirement < Requirement
fatal true
satisfy do
odeprecated("Python3Requirement", "'depends_on \"python\"'")
which "python"
odisabled("Python3Requirement", "'depends_on \"python\"'")
end
end
class RbenvRequirement < Requirement
fatal true
satisfy do
odeprecated("RbenvRequirement", "'depends_on \"rbenv\"'")
which "rbenv"
odisabled("RbenvRequirement", "'depends_on \"rbenv\"'")
end
end
class RubyRequirement < Requirement
fatal true
satisfy do
odeprecated("RubyRequirement", "'depends_on \"ruby\"'")
which "ruby"
odisabled("RubyRequirement", "'depends_on \"ruby\"'")
end
end
class SubversionRequirement < Requirement
fatal true
satisfy do
odeprecated("SubversionRequirement", "'depends_on \"subversion\"'")
which "svn"
odisabled("SubversionRequirement", "'depends_on \"subversion\"'")
end
end
@ -126,8 +110,7 @@ class TeXRequirement < Requirement
cask "mactex"
download "https://www.tug.org/mactex/"
satisfy do
odeprecated("TeXRequirement")
which("tex") || which("latex")
odisabled("TeXRequirement")
end
end

View File

@ -1,63 +0,0 @@
require "requirement"
class LanguageModuleRequirement < Requirement
fatal true
def initialize(language, module_name, import_name = nil)
@language = language
@module_name = module_name
@import_name = import_name || module_name
super([language, module_name, import_name])
end
satisfy(build_env: false) { quiet_system(*the_test) }
def message
s = <<~EOS
Unsatisfied dependency: #{@module_name}
Homebrew does not provide special #{@language.to_s.capitalize} dependencies; install with:
`#{command_line} #{@module_name}`
EOS
unless [:python, :perl, :ruby].include? @language
s += <<~EOS
You may need to: `brew install #{@language}`
EOS
end
s
end
def the_test
case @language
when :lua
["/usr/bin/env", "luarocks-5.2", "show", @import_name.to_s]
when :lua51
["/usr/bin/env", "luarocks-5.1", "show", @import_name.to_s]
when :perl
["/usr/bin/env", "perl", "-e", "use #{@import_name}"]
when :python
["/usr/bin/env", "python2", "-c", "import #{@import_name}"]
when :python3
["/usr/bin/env", "python", "-c", "import #{@import_name}"]
when :ruby
["/usr/bin/env", "ruby", "-rubygems", "-e", "require '#{@import_name}'"]
end
end
def command_line
case @language
when :lua then "luarocks-5.2 install"
when :lua51 then "luarocks-5.1 install"
when :perl then "cpan -i"
when :python then "pip3 install"
when :python3 then "pip install"
when :ruby then "gem install"
end
end
def display_s
"#{@module_name} (#{@language} module)"
end
end

View File

@ -1,29 +0,0 @@
class Formula
def self.sha1(_val)
odisabled "Formula.sha1", "Formula.sha256"
end
end
class SoftwareSpec
def sha1(_val)
odisabled "SoftwareSpec#sha1", "SoftwareSpec#sha256"
end
end
class Resource
def sha1(_val)
odisabled "Resource#sha1", "Resource#sha256"
end
end
class BottleSpecification
def sha1(_val)
odisabled "BottleSpecification#sha1", "BottleSpecification#sha256"
end
end
class Pathname
def sha1
odisabled "Pathname#sha1", "Pathname#sha256"
end
end

View File

@ -1,5 +0,0 @@
class BottleSpecification
def revision(*)
odisabled "BottleSpecification.revision", "BottleSpecification.rebuild"
end
end

View File

@ -1,5 +0,0 @@
class Tab < OpenStruct
def build_32_bit?
odisabled "Tab.build_32_bit?"
end
end

View File

@ -1,7 +0,0 @@
require "tap"
class Tap
def core_formula_repository?
odisabled "Tap#core_formula_repository?", "Tap#core_tap?"
end
end

View File

@ -1,15 +0,0 @@
module Tty
module_function
def white
odisabled "Tty.white", "Tty.reset.bold"
end
end
def puts_columns(_)
odisabled "puts_columns", "puts Formatter.columns"
end
def plural(_, _)
odisabled "#plural", "Formatter.pluralize"
end

View File

@ -1,7 +0,0 @@
module Utils
module Shell
def self.shell_profile
odisabled "Utils::Shell.shell_profile", "Utils::Shell.profile"
end
end
end

View File

@ -1,5 +0,0 @@
class Version
def slice(*)
odisabled "Version#slice", "Version#to_s.slice"
end
end

View File

@ -1,11 +0,0 @@
module OS
module Mac
module Xcode
module_function
def provides_autotools?
odisabled "OS::Mac::Xcode.provides_autotools?"
end
end
end
end

View File

@ -2,8 +2,6 @@ unless ENV["HOMEBREW_BREW_FILE"]
raise "HOMEBREW_BREW_FILE was not exported! Please call bin/brew directly!"
end
require "constants"
# Path to `bin/brew` main executable in HOMEBREW_PREFIX
HOMEBREW_BREW_FILE = Pathname.new(ENV["HOMEBREW_BREW_FILE"])

View File

@ -1,5 +1,5 @@
# frozen_string_literal: true
# RuboCop version used for `brew style` and `brew cask style`
HOMEBREW_RUBOCOP_VERSION = "0.52.1"
HOMEBREW_RUBOCOP_CASK_VERSION = "~> 0.16.0" # has to be updated when RuboCop version changes
HOMEBREW_RUBOCOP_VERSION = "0.54.0"
HOMEBREW_RUBOCOP_CASK_VERSION = "~> 0.18.0" # has to be updated when RuboCop version changes

View File

@ -1,7 +1,9 @@
require "options"
module Dependable
RESERVED_TAGS = [:build, :optional, :recommended, :run, :linked].freeze
# :run and :linked are no longer used but keep them here to avoid them being
# misused in future.
RESERVED_TAGS = [:build, :optional, :recommended, :run, :test, :linked].freeze
def build?
tags.include? :build
@ -15,12 +17,12 @@ module Dependable
tags.include? :recommended
end
def run?
tags.include? :run
def test?
tags.include? :test
end
def required?
!build? && !optional? && !recommended?
!build? && !test? && !optional? && !recommended?
end
def option_tags
@ -30,4 +32,15 @@ module Dependable
def options
Options.create(option_tags)
end
def prune_from_option?(build)
return if !optional? && !recommended?
build.without?(self)
end
def prune_if_build_and_not_dependent?(dependent, formula = nil)
return false unless build?
return dependent.installed? unless formula
dependent != formula
end
end

View File

@ -52,3 +52,81 @@ class Requirements < DelegateClass(Set)
"#<#{self.class.name}: {#{to_a.join(", ")}}>"
end
end
module Homebrew
module_function
def argv_includes_ignores(argv)
includes = []
ignores = []
if argv.include? "--include-build"
includes << "build?"
else
ignores << "build?"
end
if argv.include? "--include-test"
includes << "test?"
else
ignores << "test?"
end
if argv.include? "--include-optional"
includes << "optional?"
else
ignores << "optional?"
end
ignores << "recommended?" if ARGV.include? "--skip-recommended"
[includes, ignores]
end
def recursive_includes(klass, formula, includes, ignores)
type = if klass == Dependency
:dependencies
elsif klass == Requirement
:requirements
else
raise ArgumentError, "Invalid class argument: #{klass}"
end
formula.send("recursive_#{type}") do |dependent, dep|
if dep.recommended?
if ignores.include?("recommended?") || dependent.build.without?(dep)
klass.prune
end
elsif dep.test?
if includes.include?("test?")
if type == :dependencies
Dependency.keep_but_prune_recursive_deps
end
else
klass.prune
end
elsif dep.optional?
if !includes.include?("optional?") && !dependent.build.with?(dep)
klass.prune
end
elsif dep.build?
klass.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 type == :dependencies &&
dep.is_a?(TapDependency) &&
!dep.tap.installed?
Dependency.keep_but_prune_recursive_deps
end
end
end
def reject_ignores(dependables, ignores, includes)
dependables.reject do |dep|
next false unless ignores.any? { |ignore| dep.send(ignore) }
includes.none? { |include| dep.send(include) }
end
end
end

View File

@ -83,6 +83,9 @@ class Dependency
deps.each do |dep|
next if dependent.name == dep.name
# we only care about one level of test dependencies.
next if dep.test? && @expand_stack.length > 1
case action(dependent, dep, &block)
when :prune
next
@ -143,8 +146,9 @@ class Dependency
private
def merge_tags(deps)
options = deps.flat_map(&:option_tags).uniq
merge_necessity(deps) + merge_temporality(deps) + options
other_tags = deps.flat_map(&:option_tags).uniq
other_tags << :test if deps.flat_map(&:tags).include?(:test)
merge_necessity(deps) + merge_temporality(deps) + other_tags
end
def merge_necessity(deps)
@ -159,13 +163,9 @@ class Dependency
end
def merge_temporality(deps)
if deps.all?(&:build?)
[:build]
elsif deps.all?(&:run?)
[:run]
else
[] # Means both build and runtime dependency.
end
# Means both build and runtime dependency.
return [] unless deps.all?(&:build?)
[:build]
end
end
end

View File

@ -2,7 +2,6 @@ require "dependency"
require "dependencies"
require "requirement"
require "requirements"
require "set"
require "extend/cachable"
## A dependency is a formula that another formula needs to install.

View File

@ -1,4 +1,3 @@
require "set"
require "formula"
require "formula_versions"

View File

@ -39,30 +39,44 @@
require "formula"
require "formula_versions"
require "utils"
require "utils/curl"
require "extend/ENV"
require "formula_cellar_checks"
require "official_taps"
require "cmd/search"
require "cmd/style"
require "date"
require "missing_formula"
require "digest"
require "cli_parser"
module Homebrew
module_function
def audit
inject_dump_stats!(FormulaAuditor, /^audit_/) if ARGV.switch? "D"
args = Homebrew::CLI::Parser.parse do
switch "--strict"
switch "--online"
switch "--new-formula"
switch "--fix"
switch "--display-cop-names"
switch "--display-filename"
switch "-D", "--audit-debug", description: "Activates debugging and profiling"
switch :verbose
switch :debug
comma_array "--only"
comma_array "--except"
comma_array "--only-cops"
comma_array "--except-cops"
end
Homebrew.auditing = true
inject_dump_stats!(FormulaAuditor, /^audit_/) if args.audit_debug?
formula_count = 0
problem_count = 0
new_formula = ARGV.include? "--new-formula"
strict = new_formula || ARGV.include?("--strict")
online = new_formula || ARGV.include?("--online")
new_formula = args.new_formula?
strict = new_formula || args.strict?
online = new_formula || args.online?
ENV.activate_extensions!
ENV.setup_build_environment
@ -75,35 +89,36 @@ module Homebrew
files = ARGV.resolved_formulae.map(&:path)
end
only_cops = ARGV.value("only-cops").to_s.split(",")
except_cops = ARGV.value("except-cops").to_s.split(",")
only_cops = args.only_cops
except_cops = args.except_cops
if !only_cops.empty? && !except_cops.empty?
if only_cops && except_cops
odie "--only-cops and --except-cops cannot be used simultaneously!"
elsif (!only_cops.empty? || !except_cops.empty?) && (strict || ARGV.value("only"))
elsif (only_cops || except_cops) && (strict || args.only)
odie "--only-cops/--except-cops and --strict/--only cannot be used simultaneously"
end
options = { fix: ARGV.flag?("--fix"), realpath: true }
options = { fix: args.fix?, realpath: true }
if !only_cops.empty?
if only_cops
options[:only_cops] = only_cops
ARGV.push("--only=style")
elsif new_formula
args.only = ["style"]
elsif args.new_formula?
nil
elsif strict
options[:except_cops] = [:NewFormulaAudit]
elsif !except_cops.empty?
elsif except_cops
options[:except_cops] = except_cops
elsif !strict
options[:only_cops] = [:FormulaAudit]
end
options[:display_cop_names] = args.display_cop_names?
# Check style in a single batch run up front for performance
style_results = check_style_json(files, options)
ff.sort.each do |f|
options = { new_formula: new_formula, strict: strict, online: online }
options = { new_formula: new_formula, strict: strict, online: online, only: args.only, except: args.except }
options[:style_offenses] = style_results.file_offenses(f.path)
fa = FormulaAuditor.new(f, options)
fa.audit
@ -113,7 +128,7 @@ module Homebrew
formula_count += 1
problem_count += fa.problems.size
problem_lines = fa.problems.map { |p| "* #{p.chomp.gsub("\n", "\n ")}" }
if ARGV.include? "--display-filename"
if args.display_filename?
puts problem_lines.map { |s| "#{f.path}: #{s}" }
else
puts "#{f.full_name}:", problem_lines.map { |s| " #{s}" }
@ -172,28 +187,14 @@ class FormulaAuditor
attr_reader :formula, :text, :problems
BUILD_TIME_DEPS = %w[
autoconf
automake
boost-build
bsdmake
cmake
godep
imake
intltool
libtool
pkg-config
scons
smake
sphinx-doc
swig
].freeze
def initialize(formula, options = {})
@formula = formula
@new_formula = options[:new_formula]
@strict = options[:strict]
@online = options[:online]
@display_cop_names = options[:display_cop_names]
@only = options[:only]
@except = options[:except]
# Accept precomputed style offense results, for efficiency
@style_offenses = options[:style_offenses]
# Allow the actual official-ness of a formula to be overridden, for testing purposes
@ -205,9 +206,8 @@ class FormulaAuditor
def audit_style
return unless @style_offenses
display_cop_names = ARGV.include?("--display-cop-names")
@style_offenses.each do |offense|
problem offense.to_s(display_cop_name: display_cop_names)
problem offense.to_s(display_cop_name: @display_cop_names)
end
end
@ -377,17 +377,12 @@ class FormulaAuditor
problem "Dependency #{dep} does not define option #{opt.name.inspect}"
end
case dep.name
when "git"
if dep.name == "git"
problem "Don't use git as a dependency (it's always available)"
when *BUILD_TIME_DEPS
next if dep.build? || dep.run?
problem <<~EOS
#{dep} dependency should be
depends_on "#{dep}" => :build
Or if it is indeed a runtime dependency
depends_on "#{dep}" => :run
EOS
end
if dep.tags.include?(:run)
problem "Dependency '#{dep.name}' is marked as :run. Remove :run; it is a no-op."
end
end
end
@ -569,6 +564,7 @@ class FormulaAuditor
gtk-doc 1.25
libart 2.3.21
pygtkglext 1.1.0
libepoxy 1.5.0
].each_slice(2).to_a.map do |formula, version|
[formula, version.split(".")[0..1].join(".")]
end
@ -740,6 +736,10 @@ class FormulaAuditor
problem "Use \#{pkgshare} instead of \#{share}/#{formula.name}"
end
if line =~ /depends_on .+ if build\.with(out)?\?\(?["']\w+["']\)?/
problem "`Use :optional` or `:recommended` instead of `#{Regexp.last_match(0)}`"
end
return unless line =~ %r{share(\s*[/+]\s*)(['"])#{Regexp.escape(formula.name)}(?:\2|/)}
problem "Use pkgshare instead of (share#{Regexp.last_match(1)}\"#{formula.name}\")"
end
@ -789,17 +789,17 @@ class FormulaAuditor
end
def audit
only_audits = ARGV.value("only").to_s.split(",")
except_audits = ARGV.value("except").to_s.split(",")
if !only_audits.empty? && !except_audits.empty?
only_audits = @only
except_audits = @except
if only_audits && except_audits
odie "--only and --except cannot be used simultaneously!"
end
methods.map(&:to_s).grep(/^audit_/).each do |audit_method_name|
name = audit_method_name.gsub(/^audit_/, "")
if !only_audits.empty?
if only_audits
next unless only_audits.include?(name)
elsif !except_audits.empty?
elsif except_audits
next if except_audits.include?(name)
end
send(audit_method_name)
@ -949,13 +949,13 @@ class ResourceAuditor
problem http_content_problem
end
elsif strategy <= GitDownloadStrategy
unless Utils.git_remote_exists url
unless Utils.git_remote_exists? url
problem "The URL #{url} is not a valid git URL"
end
elsif strategy <= SubversionDownloadStrategy
next unless DevelopmentTools.subversion_handles_most_https_certificates?
next unless Utils.svn_available?
unless Utils.svn_remote_exists url
unless Utils.svn_remote_exists? url
problem "The URL #{url} is not a valid svn URL"
end
end

View File

@ -34,9 +34,9 @@ require "utils/bottles"
require "tab"
require "keg"
require "formula_versions"
require "cli_parser"
require "utils/inreplace"
require "erb"
require "extend/pathname"
BOTTLE_ERB = <<-EOS.freeze
bottle do
@ -68,6 +68,26 @@ MAXIMUM_STRING_MATCHES = 100
module Homebrew
module_function
def bottle
@args = Homebrew::CLI::Parser.parse do
switch "--merge"
switch "--skip-relocation"
switch "--force-core-tap"
switch "--no-rebuild"
switch "--keep-old"
switch "--write"
switch "--no-commit"
switch "--json"
switch :verbose
flag "--root-url"
end
return merge if @args.merge?
ARGV.resolved_formulae.each do |f|
bottle_formula f
end
end
def keg_contain?(string, keg, ignores)
@put_string_exists_header, @put_filenames = nil
@ -93,7 +113,7 @@ module Homebrew
linked_libraries = Keg.file_linked_libraries(file, string)
result ||= !linked_libraries.empty?
if ARGV.verbose?
if @args.verbose?
print_filename.call(string, file) unless linked_libraries.empty?
linked_libraries.each do |lib|
puts " #{Tty.bold}-->#{Tty.reset} links to #{lib}"
@ -116,7 +136,7 @@ module Homebrew
end
end
next unless ARGV.verbose? && !text_matches.empty?
next unless @args.verbose? && !text_matches.empty?
print_filename.call(string, file)
text_matches.first(MAXIMUM_STRING_MATCHES).each do |match, offset|
puts " #{Tty.bold}-->#{Tty.reset} match '#{match}' at offset #{Tty.bold}0x#{offset}#{Tty.reset}"
@ -137,7 +157,7 @@ module Homebrew
absolute_symlinks_start_with_string << pn if link.to_s.start_with?(string)
end
if ARGV.verbose?
if @args.verbose?
unless absolute_symlinks_start_with_string.empty?
opoo "Absolute symlink starting with #{string}:"
absolute_symlinks_start_with_string.each do |pn|
@ -160,7 +180,7 @@ module Homebrew
end
unless tap = f.tap
unless ARGV.include?("--force-core-tap")
unless @args.force_core_tap?
return ofail "Formula not from core or any taps: #{f.full_name}"
end
@ -179,9 +199,9 @@ module Homebrew
return ofail "Formula has no stable version: #{f.full_name}" unless f.stable
if ARGV.include?("--no-rebuild") || !f.tap
if @args.no_rebuild? || !f.tap
rebuild = 0
elsif ARGV.include? "--keep-old"
elsif @args.keep_old?
rebuild = f.bottle_specification.rebuild
else
ohai "Determining #{f.full_name} bottle rebuild..."
@ -214,7 +234,7 @@ module Homebrew
begin
keg.delete_pyc_files!
unless ARGV.include? "--skip-relocation"
unless @args.skip_relocation?
changed_files = keg.replace_locations_with_placeholders
end
@ -265,7 +285,7 @@ module Homebrew
end
relocatable = true
if ARGV.include? "--skip-relocation"
if @args.skip_relocation?
skip_relocation = true
else
relocatable = false if keg_contain?(prefix_check, keg, ignores)
@ -278,23 +298,21 @@ module Homebrew
end
skip_relocation = relocatable && !keg.require_relocation?
end
puts if !relocatable && ARGV.verbose?
puts if !relocatable && @args.verbose?
rescue Interrupt
ignore_interrupts { bottle_path.unlink if bottle_path.exist? }
raise
ensure
ignore_interrupts do
original_tab&.write
unless ARGV.include? "--skip-relocation"
unless @args.skip_relocation?
keg.replace_placeholders_with_locations changed_files
end
end
end
end
root_url = ARGV.value("root-url")
# Use underscored version for legacy reasons. Remove at some point.
root_url ||= ARGV.value("root_url")
root_url = @args.root_url
bottle = BottleSpecification.new
bottle.tap = tap
@ -314,7 +332,7 @@ module Homebrew
bottle.sha256 sha256 => Utils::Bottles.tag
old_spec = f.bottle_specification
if ARGV.include?("--keep-old") && !old_spec.checksums.empty?
if @args.keep_old? && !old_spec.checksums.empty?
mismatches = [:root_url, :prefix, :cellar, :rebuild].reject do |key|
old_spec.send(key) == bottle.send(key)
end
@ -340,7 +358,7 @@ module Homebrew
puts "./#{filename}"
puts output
return unless ARGV.include? "--json"
return unless @args.json?
json = {
f.full_name => {
"formula" => {
@ -371,7 +389,7 @@ module Homebrew
end
def merge
write = ARGV.include? "--write"
write = @args.write?
bottles_hash = ARGV.named.reduce({}) do |hash, json_file|
deep_merge_hashes hash, JSON.parse(IO.read(json_file))
@ -400,7 +418,7 @@ module Homebrew
Utils::Inreplace.inreplace(path) do |s|
if s.include? "bottle do"
update_or_add = "update"
if ARGV.include? "--keep-old"
if @args.keep_old?
mismatches = []
bottle_block_contents = s[/ bottle do(.+?)end\n/m, 1]
bottle_block_contents.lines.each do |line|
@ -443,7 +461,7 @@ module Homebrew
string = s.sub!(/ bottle do.+?end\n/m, output)
odie "Bottle block update failed!" unless string
else
if ARGV.include? "--keep-old"
if @args.keep_old?
odie "--keep-old was passed but there was no existing bottle block!"
end
puts output
@ -472,7 +490,7 @@ module Homebrew
end
end
unless ARGV.include? "--no-commit"
unless @args.no_commit?
if ENV["HOMEBREW_GIT_NAME"]
ENV["GIT_AUTHOR_NAME"] =
ENV["GIT_COMMITTER_NAME"] =
@ -498,14 +516,4 @@ module Homebrew
end
end
end
def bottle
if ARGV.include? "--merge"
merge
else
ARGV.resolved_formulae.each do |f|
bottle_formula f
end
end
end
end

View File

@ -131,6 +131,9 @@ module Homebrew
ENV[env] = homebrew_env
end
gh_api_errors = [GitHub::AuthenticationFailedError, GitHub::HTTPNotFoundError,
GitHub::RateLimitExceededError, GitHub::Error, JSON::ParserError].freeze
formula = ARGV.formulae.first
if formula
@ -314,73 +317,41 @@ module Homebrew
end
end
unless Formula["hub"].any_version_installed?
if ARGV.dry_run?
ohai "brew install hub"
else
safe_system "brew", "install", "hub"
end
end
formula.path.parent.cd do
branch = "#{formula.name}-#{new_formula_version}"
git_dir = Utils.popen_read("git rev-parse --git-dir").chomp
shallow = !git_dir.empty? && File.exist?("#{git_dir}/shallow")
hub_args = []
git_final_checkout_args = []
if ARGV.include?("--no-browse")
git_final_checkout_args << "--quiet"
else
hub_args << "--browse"
end
if ARGV.dry_run?
ohai "hub fork # read $HUB_REMOTE"
ohai "fork repository with GitHub API"
ohai "git fetch --unshallow origin" if shallow
ohai "git checkout --no-track -b #{branch} origin/master"
ohai "git commit --no-edit --verbose --message='#{formula.name} #{new_formula_version}#{devel_message}' -- #{formula.path}"
ohai "git push --set-upstream $HUB_REMOTE #{branch}:#{branch}"
ohai "hub pull-request #{hub_args.join(" ")} -m '#{formula.name} #{new_formula_version}#{devel_message}'"
ohai "create pull request with GitHub API"
ohai "git checkout -"
else
reply = IO.popen(["hub", "fork"], "r+", err: "/dev/null") do |io|
reader = Thread.new { io.read }
sleep 1
io.close_write
reader.value
end
if reply.to_s.include? "username:"
begin
response = GitHub.create_fork(formula.tap.full_name)
# GitHub API responds immediately but fork takes a few seconds to be ready.
sleep 3
rescue *gh_api_errors => e
formula.path.atomic_write(backup_file) unless ARGV.dry_run?
git_path = "$(brew --repo #{formula.tap})" if formula.tap
git_path ||= formula.path.parent
odie <<~EOS
Retry after configuring hub by running:
hub -C "#{git_path}" fork
Or setting HOMEBREW_GITHUB_TOKEN with at least 'public_repo' scope.
EOS
odie "Unable to fork: #{e.message}!"
end
remote = reply[/remote:? (\S+)/, 1]
# repeat for hub 2.2 backwards compatibility:
remote = Utils.popen_read("hub", "fork", err: :out)[/remote:? (\S+)/, 1] if remote.to_s.empty?
if remote.to_s.empty?
formula.path.atomic_write(backup_file) unless ARGV.dry_run?
odie "cannot get remote from 'hub'!"
end
remote_url = response.fetch("clone_url")
username = response.fetch("owner").fetch("login")
safe_system "git", "fetch", "--unshallow", "origin" if shallow
safe_system "git", "checkout", "--no-track", "-b", branch, "origin/master"
safe_system "git", "commit", "--no-edit", "--verbose",
"--message=#{formula.name} #{new_formula_version}#{devel_message}",
"--", formula.path
safe_system "git", "push", "--set-upstream", remote, "#{branch}:#{branch}"
safe_system "git", "push", "--set-upstream", remote_url, "#{branch}:#{branch}"
safe_system "git", "checkout", "--quiet", "-"
pr_message = <<~EOS
#{formula.name} #{new_formula_version}#{devel_message}
Created with `brew bump-formula-pr`.
EOS
user_message = ARGV.value("message")
@ -391,8 +362,19 @@ module Homebrew
#{user_message}
EOS
end
safe_system "hub", "pull-request", *hub_args, "-m", pr_message
safe_system "git", "checkout", *git_final_checkout_args, "-"
pr_title = "#{formula.name} #{new_formula_version}#{devel_message}"
begin
url = GitHub.create_pull_request(formula.tap.full_name, pr_title,
"#{username}:#{branch}", "master", pr_message)["html_url"]
if ARGV.include?("--no-browse")
puts url
else
exec_browser url
end
rescue *gh_api_errors => e
odie "Unable to open pull request: #{e.message}!"
end
end
end
end

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