Merge branch 'master' into brew-info-display-casks

This commit is contained in:
Zach Auten 2019-02-18 03:26:43 -05:00
commit 648c8e4672
388 changed files with 4347 additions and 5229 deletions

20
.gitignore vendored
View File

@ -17,6 +17,7 @@
/Library/Homebrew/test/fs_leak_log
/Library/Homebrew/vendor/portable-ruby
/Library/Taps
/Library/PinnedTaps
# Ignore Bundler files
**/.bundle/bin
@ -24,6 +25,7 @@
**/vendor/bundle
**/vendor/ruby
**/vendor/bundle-standalone/ruby/*/bin
**/vendor/bundle-standalone/ruby/*/build_info/
**/vendor/bundle-standalone/ruby/*/cache
**/vendor/bundle-standalone/ruby/*/extensions
**/vendor/bundle-standalone/ruby/*/gems/*/*
@ -92,15 +94,33 @@
# Ignore rubocop's (and other) dependencies we don't wish to vendor
**/vendor/bundle-standalone/ruby/*/gems/ast-*/
**/vendor/bundle-standalone/ruby/*/gems/connection_pool-*/lib
**/vendor/bundle-standalone/ruby/*/gems/domain_name-*/lib
**/vendor/bundle-standalone/ruby/*/gems/http-cookie-*/lib
**/vendor/bundle-standalone/ruby/*/gems/jaro_winkler-*/
**/vendor/bundle-standalone/ruby/*/gems/mime-types-data-*/lib
**/vendor/bundle-standalone/ruby/*/gems/mime-types-*/lib
**/vendor/bundle-standalone/ruby/*/gems/mini_portile2-*/lib
**/vendor/bundle-standalone/ruby/*/gems/minitest-*/lib
**/vendor/bundle-standalone/ruby/*/gems/net-http-digest_auth-*/lib
**/vendor/bundle-standalone/ruby/*/gems/net-http-persistent-*/lib
**/vendor/bundle-standalone/ruby/*/gems/nokogiri-*/lib
**/vendor/bundle-standalone/ruby/*/gems/ntlm-http-*/lib
**/vendor/bundle-standalone/ruby/*/gems/parallel-*/
**/vendor/bundle-standalone/ruby/*/gems/parser-*/
**/vendor/bundle-standalone/ruby/*/gems/powerpack-*/
**/vendor/bundle-standalone/ruby/*/gems/rainbow-*/
**/vendor/bundle-standalone/ruby/*/gems/rubocop-0*/
**/vendor/bundle-standalone/ruby/*/gems/ruby-progressbar-*/
**/vendor/bundle-standalone/ruby/*/gems/unf_ext-*/lib
**/vendor/bundle-standalone/ruby/*/gems/unf-*/lib
**/vendor/bundle-standalone/ruby/*/gems/unicode-display_width-*/
**/vendor/bundle-standalone/ruby/*/gems/webrobots-*/lib
# Only include the `Mechanize::HTTP::ContentDispositionParser`.
**/vendor/bundle-standalone/ruby/*/gems/mechanize-*/lib
!**/vendor/bundle-standalone/ruby/*/gems/mechanize-*/lib/mechanize/http/content_disposition_parser.rb
!**/vendor/bundle-standalone/ruby/*/gems/mechanize-*/lib/mechanize/version.rb
# Ignore `bin` contents (again).
/bin

View File

@ -28,16 +28,14 @@ ADD . /home/linuxbrew/.linuxbrew/Homebrew
RUN cd /home/linuxbrew/.linuxbrew \
&& mkdir -p bin etc include lib opt sbin share var/homebrew/linked Cellar \
&& ln -s ../Homebrew/bin/brew /home/linuxbrew/.linuxbrew/bin/ \
&& chown -R linuxbrew: /home/linuxbrew/.linuxbrew \
&& cd /home/linuxbrew/.linuxbrew/Homebrew \
&& git remote set-url origin https://github.com/Homebrew/brew
USER linuxbrew
WORKDIR /home/linuxbrew
ENV PATH=/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:$PATH \
SHELL=/bin/bash \
USER=linuxbrew
SHELL=/bin/bash
# Install portable-ruby and tap homebrew/core.
RUN HOMEBREW_NO_ANALYTICS=1 HOMEBREW_NO_AUTO_UPDATE=1 brew tap homebrew/core \
&& chown -R linuxbrew: /home/linuxbrew/.linuxbrew \
&& rm -rf ~/.cache

View File

@ -1,3 +1,3 @@
sut:
build: .
command: brew test-bot
command: "sudo -i -u linuxbrew /home/linuxbrew/.linuxbrew/bin/brew test-bot"

View File

@ -110,7 +110,10 @@ Style/GuardClause:
Style/HashSyntax:
EnforcedStyle: hash_rockets
Exclude:
- '**/cmd/*.rb'
- '**/Guardfile'
- '**/cmd/**/*.rb'
- '**/lib/**/*.rb'
- '**/spec/**/*.rb'
# ruby style guide favorite
Style/StringLiterals:

View File

@ -0,0 +1,22 @@
inherit_from: ./.rubocop.yml
NewFormulaAudit:
Enabled: true
# TODO: try to enable these
RSpec/AnyInstance:
Enabled: false
RSpec/ContextWording:
Enabled: false
RSpec/DescribeClass:
Enabled: false
RSpec/ExampleLength:
Enabled: false
RSpec/MessageSpies:
Enabled: false
# TODO: try to reduce these
RSpec/MultipleExpectations:
Max: 26
RSpec/NestedGroups:
Max: 5

View File

@ -1,4 +1,4 @@
inherit_from: ../.rubocop.yml
inherit_from: ../.rubocop_rspec.yml
AllCops:
Include:
@ -64,10 +64,10 @@ Metrics/LineLength:
IgnoredPatterns: ['#: ']
# we won't change backward compatible predicate names
# TODO: deprecate whitelisted names and move to compat
Naming/PredicateName:
Exclude:
- 'compat/**/*'
# can't rename these
NameWhitelist: is_32_bit?, is_64_bit?
# whitelist those that are standard

View File

@ -10,6 +10,9 @@ if RUBY_X < 2 || (RUBY_X == 2 && RUBY_Y < 3)
raise "Homebrew must be run under Ruby 2.3! You're running #{RUBY_VERSION}."
end
# Also define here so we can rescue regardless of location.
class MissingEnvironmentVariables < RuntimeError; end
begin
require_relative "global"
rescue MissingEnvironmentVariables => e
@ -89,13 +92,8 @@ begin
# `Homebrew.help` never returns, except for external/unknown commands.
end
# Uninstall old brew-cask if it's still around; we just use the tap now.
if cmd == "cask" && (HOMEBREW_CELLAR/"brew-cask").exist?
system(HOMEBREW_BREW_FILE, "uninstall", "--force", "brew-cask")
end
if ENV["HOMEBREW_BUILD_FROM_SOURCE"]
odeprecated("HOMEBREW_BUILD_FROM_SOURCE", "--build-from-source")
odisabled("HOMEBREW_BUILD_FROM_SOURCE", "--build-from-source")
end
if internal_cmd

View File

@ -58,7 +58,7 @@ git() {
numeric() {
# Condense the exploded argument into a single return value.
# shellcheck disable=SC2086,SC2183
printf "%01d%02d%02d%02d" ${1//./ }
printf "%01d%02d%02d%02d" ${1//[.rc]/ }
}
HOMEBREW_VERSION="$(git -C "$HOMEBREW_REPOSITORY" describe --tags --dirty --abbrev=7 2>/dev/null)"
@ -93,23 +93,14 @@ then
# Don't change this from Mac OS X to match what macOS itself does in Safari on 10.12
HOMEBREW_OS_USER_AGENT_VERSION="Mac OS X $HOMEBREW_MACOS_VERSION"
# The system Curl is too old for some modern HTTPS certificates on
# older macOS versions.
#
# Intentionally set this variable by exploding another.
# shellcheck disable=SC2086,SC2183
printf -v HOMEBREW_MACOS_VERSION_NUMERIC "%02d%02d%02d" ${HOMEBREW_MACOS_VERSION//./ }
if [[ "$HOMEBREW_MACOS_VERSION_NUMERIC" -lt "101000" ]]
then
HOMEBREW_SYSTEM_CURL_TOO_OLD="1"
HOMEBREW_FORCE_BREWED_CURL="1"
fi
# Announce pre-Mavericks deprecation now
# Refuse to run on pre-Mavericks
if [[ "$HOMEBREW_MACOS_VERSION_NUMERIC" -lt "100900" ]]
then
printf "WARNING: Your version of macOS (%s) will not be able to run Homebrew when\n" "$HOMEBREW_MACOS_VERSION" >&2
printf " version 2.0.0 is released (Q1 2019)!\n" >&2
printf "ERROR: Your version of macOS (%s) is too old to run Homebrew!" "$HOMEBREW_MACOS_VERSION" >&2
if [[ "$HOMEBREW_MACOS_VERSION_NUMERIC" -lt "100700" ]]
then
printf " For 10.4 - 10.6 support see: https://github.com/mistydemeo/tigerbrew\n" >&2
@ -117,6 +108,15 @@ then
printf "\n" >&2
fi
# The system Curl is too old for some modern HTTPS certificates on
# older macOS versions.
#
if [[ "$HOMEBREW_MACOS_VERSION_NUMERIC" -lt "101000" ]]
then
HOMEBREW_SYSTEM_CURL_TOO_OLD="1"
HOMEBREW_FORCE_BREWED_CURL="1"
fi
# The system Git on macOS versions before Sierra is too old for some Homebrew functionality we rely on.
HOMEBREW_MINIMUM_GIT_VERSION="2.14.3"
if [[ "$HOMEBREW_MACOS_VERSION_NUMERIC" -lt "101200" ]]
@ -350,6 +350,9 @@ fi
check-run-command-as-root() {
[[ "$(id -u)" = 0 ]] || return
# Allow Docker to do everything as root (as it's normal there)
[[ -f /proc/1/cgroup ]] && grep docker -q /proc/1/cgroup && return
# Homebrew Services may need `sudo` for system-wide daemons.
[[ "$HOMEBREW_COMMAND" = "services" ]] && return

View File

@ -41,7 +41,7 @@ module Homebrew
MACOSX_DEPLOYMENT_TARGET PKG_CONFIG_PATH PKG_CONFIG_LIBDIR
HOMEBREW_DEBUG HOMEBREW_MAKE_JOBS HOMEBREW_VERBOSE
HOMEBREW_SVN HOMEBREW_GIT
HOMEBREW_SDKROOT HOMEBREW_BUILD_FROM_SOURCE
HOMEBREW_SDKROOT
MAKE GIT CPP
ACLOCAL_PATH PATH CPATH
LD_LIBRARY_PATH LD_RUN_PATH LD_PRELOAD LIBRARY_PATH

View File

@ -99,22 +99,6 @@ class BuildOptions
@options - @args
end
# @private
def invalid_options
@args - @options - BuildOptions.formula_install_options
end
# @private
def invalid_option_names
invalid_options.map(&:flag).sort
end
def self.formula_install_options
@formula_install_options ||= ARGV.formula_install_option_names.map do |option_name|
Option.new option_name[2..-1]
end
end
private
def option_defined?(name)

View File

@ -94,11 +94,14 @@ module Cask
[executable, arguments]
end
attr_reader :cask, :config
attr_reader :cask
def initialize(cask)
@cask = cask
@config = cask.config
end
def config
cask.config
end
def to_s

View File

@ -2,6 +2,8 @@ require "timeout"
require "utils/user"
require "cask/artifact/abstract_artifact"
require "extend/hash_validator"
using HashValidator
module Cask
module Artifact
@ -27,6 +29,8 @@ module Cask
attr_reader :directives
def initialize(cask, directives)
directives.assert_valid_keys!(*ORDERED_DIRECTIVES)
super(cask)
directives[:signal] = [*directives[:signal]].flatten.each_slice(2).to_a
@directives = directives
@ -49,30 +53,23 @@ module Cask
private
def dispatch_uninstall_directives(**options)
ohai "Running #{stanza} process for #{@cask}; your password may be necessary"
warn_for_unknown_directives(directives)
ORDERED_DIRECTIVES.each do |directive_sym|
next unless directives.key?(directive_sym)
args = directives[directive_sym]
send("uninstall_#{directive_sym}", *(args.is_a?(Hash) ? [args] : args), **options)
dispatch_uninstall_directive(directive_sym, **options)
end
end
def dispatch_uninstall_directive(directive_sym, **options)
return unless directives.key?(directive_sym)
args = directives[directive_sym]
send("uninstall_#{directive_sym}", *(args.is_a?(Hash) ? [args] : args), **options)
end
def stanza
self.class.dsl_key
end
def warn_for_unknown_directives(directives)
unknown_keys = directives.keys - ORDERED_DIRECTIVES
return if unknown_keys.empty?
opoo "Unknown arguments to #{stanza} -- #{unknown_keys.inspect}. " \
"Running \"brew update; brew cleanup\" will likely fix it."
end
# Preserve prior functionality of script which runs first. Should rarely be needed.
# :early_script should not delete files, better defer that to :script.
# If Cask writers never need :early_script it may be removed in the future.

View File

@ -40,9 +40,13 @@ module Cask
end
ohai "Moving #{self.class.english_name} '#{source.basename}' to '#{target}'."
target.dirname.mkpath
if target.dirname.ascend.find(&:directory?).writable?
target.dirname.mkpath
else
command.run!("/bin/mkdir", args: ["-p", target.dirname], sudo: true)
end
if target.parent.writable?
if target.dirname.writable?
FileUtils.move(source, target)
else
command.run!("/bin/mv", args: [source, target], sudo: true)

View File

@ -4,7 +4,14 @@ module Cask
module Artifact
class Uninstall < AbstractUninstall
def uninstall_phase(**options)
dispatch_uninstall_directives(**options)
ORDERED_DIRECTIVES.reject { |directive_sym| directive_sym == :rmdir }
.each do |directive_sym|
dispatch_uninstall_directive(directive_sym, **options)
end
end
def post_uninstall_phase(**options)
dispatch_uninstall_directive(:rmdir, **options)
end
end
end

View File

@ -31,15 +31,21 @@ module Cask
@tap
end
def initialize(token, sourcefile_path: nil, tap: nil, config: Config.global, &block)
def initialize(token, sourcefile_path: nil, tap: nil, &block)
@token = token
@sourcefile_path = sourcefile_path
@tap = tap
@config = config
@dsl = DSL.new(self)
return unless block_given?
@block = block
self.config = Config.for_cask(self)
end
@dsl.instance_eval(&block)
def config=(config)
@config = config
@dsl = DSL.new(self)
return unless @block
@dsl.instance_eval(&@block)
@dsl.language_eval
end
@ -77,6 +83,14 @@ module Cask
metadata_master_container_path.join(*installed_version, "Casks", "#{token}.rb")
end
def config_path
metadata_master_container_path/"config.json"
end
def caskroom_path
@caskroom_path ||= Caskroom.path.join(token)
end
def outdated?(greedy = false)
!outdated_versions(greedy).empty?
end
@ -133,7 +147,7 @@ module Cask
end,
"caveats" => caveats,
"depends_on" => depends_on,
"conflicts_with" => conflicts_with.to_a,
"conflicts_with" => conflicts_with,
"container" => container,
"auto_updates" => auto_updates,
}

View File

@ -9,6 +9,7 @@ require "cask/cmd/options"
require "cask/cmd/abstract_command"
require "cask/cmd/audit"
require "cask/cmd/automerge"
require "cask/cmd/cat"
require "cask/cmd/create"
require "cask/cmd/doctor"
@ -186,7 +187,10 @@ module Cask
end
def process_options(*args)
all_args = Shellwords.shellsplit(ENV["HOMEBREW_CASK_OPTS"] || "") + args
exclude_regex = /^\-\-#{Regexp.union(*Config::DEFAULT_DIRS.keys.map(&Regexp.public_method(:escape)))}=/
all_args = Shellwords.shellsplit(ENV.fetch("HOMEBREW_CASK_OPTS", ""))
.reject { |arg| arg.match?(exclude_regex) } + args
non_options = []

View File

@ -0,0 +1,124 @@
# frozen_string_literal: true
require "cask/cmd/abstract_internal_command"
require "tap"
require "utils/formatter"
require "utils/github"
module Cask
class Cmd
class Automerge < AbstractInternalCommand
OFFICIAL_CASK_TAPS = [
"homebrew/cask",
"homebrew/cask-drivers",
"homebrew/cask-eid",
"homebrew/cask-fonts",
"homebrew/cask-versions",
].freeze
def run
taps = OFFICIAL_CASK_TAPS.map(&Tap.public_method(:fetch))
access = taps.all? { |tap| GitHub.write_access?(tap.full_name) }
raise "This command may only be run by Homebrew maintainers." unless access
Homebrew.install_gem! "git_diff"
require "git_diff"
failed = []
taps.each do |tap|
open_pull_requests = GitHub.pull_requests(tap.full_name, state: :open, base: "master")
open_pull_requests.each do |pr|
next unless passed_ci(pr)
next unless check_diff(pr)
number = pr["number"]
sha = pr.dig("head", "sha")
print "#{Formatter.url(pr["html_url"])} "
retried = false
begin
GitHub.merge_pull_request(
tap.full_name,
number: number, sha: sha,
merge_method: :squash,
commit_message: "Squashed and auto-merged via `brew cask automerge`."
)
puts "#{Tty.bold}#{Formatter.success("")}#{Tty.reset}"
rescue
unless retried
retried = true
sleep 5
retry
end
puts "#{Tty.bold}#{Formatter.error("")}#{Tty.reset}"
failed << pr["html_url"]
end
end
end
return if failed.empty?
$stderr.puts
raise CaskError, "Failed merging the following PRs:\n#{failed.join("\n")}"
end
def passed_ci(pr)
statuses = GitHub.open_api(pr["statuses_url"])
latest_pr_status = statuses.select { |status| status["context"] == "continuous-integration/travis-ci/pr" }
.max_by { |status| Time.parse(status["updated_at"]) }
latest_pr_status&.fetch("state") == "success"
end
def check_diff(pr)
diff_url = pr["diff_url"]
output, _, status = curl_output("--location", diff_url)
return false unless status.success?
diff = GitDiff.from_string(output)
diff_is_single_cask(diff) && diff_only_version_or_checksum_changed(diff)
end
def diff_is_single_cask(diff)
return false unless diff.files.count == 1
file = diff.files.first
return false unless file.a_path == file.b_path
file.a_path.match?(%r{\ACasks/[^/]+\.rb\Z})
end
def diff_only_version_or_checksum_changed(diff)
lines = diff.files.flat_map(&:hunks).flat_map(&:lines)
additions = lines.select(&:addition?)
deletions = lines.select(&:deletion?)
changed_lines = deletions + additions
return false if additions.count != deletions.count
return false if additions.count > 2
changed_lines.all? { |line| diff_line_is_version(line.to_s) || diff_line_is_sha256(line.to_s) }
end
def diff_line_is_sha256(line)
line.match?(/\A[+-]\s*sha256 '[0-9a-f]{64}'\Z/)
end
def diff_line_is_version(line)
line.match?(/\A[+-]\s*version '[^']+'\Z/)
end
def self.help
"automatically merge “simple” Cask pull requests"
end
end
end
end

View File

@ -17,7 +17,7 @@ module Cask
def cask_path
casks.first.sourcefile_path
rescue CaskInvalidError
rescue CaskInvalidError, CaskUnreadableError
path = CaskLoader.path(args.first)
return path if path.file?

View File

@ -1,3 +1,5 @@
require "cask/config"
module Cask
class Cmd
class Upgrade < AbstractCommand
@ -44,13 +46,17 @@ module Cask
old_cask = CaskLoader.load(old_cask.installed_caskfile)
old_config = old_cask.config
old_cask_installer =
Installer.new(old_cask, binaries: binaries?,
verbose: verbose?,
force: force?,
upgrade: true)
new_cask = CaskLoader.load(old_cask.to_s)
new_cask = CaskLoader.load(old_cask.token)
new_cask.config = Config.global.merge(old_config)
new_cask_installer =
Installer.new(new_cask, binaries: binaries?,

View File

@ -1,12 +1,11 @@
require "json"
require "extend/hash_validator"
using HashValidator
module Cask
class Config
def self.global
@global ||= new
end
attr_reader :binarydir
def initialize(
DEFAULT_DIRS = {
appdir: "/Applications",
prefpanedir: "~/Library/PreferencePanes",
qlplugindir: "~/Library/QuickLook",
@ -19,47 +18,91 @@ module Cask
audio_unit_plugindir: "~/Library/Audio/Plug-Ins/Components",
vst_plugindir: "~/Library/Audio/Plug-Ins/VST",
vst3_plugindir: "~/Library/Audio/Plug-Ins/VST3",
screen_saverdir: "~/Library/Screen Savers"
)
screen_saverdir: "~/Library/Screen Savers",
}.freeze
self.appdir = appdir
self.prefpanedir = prefpanedir
self.qlplugindir = qlplugindir
self.dictionarydir = dictionarydir
self.fontdir = fontdir
self.colorpickerdir = colorpickerdir
self.servicedir = servicedir
self.input_methoddir = input_methoddir
self.internet_plugindir = internet_plugindir
self.audio_unit_plugindir = audio_unit_plugindir
self.vst_plugindir = vst_plugindir
self.vst3_plugindir = vst3_plugindir
self.screen_saverdir = screen_saverdir
# `binarydir` is not customisable.
@binarydir = HOMEBREW_PREFIX/"bin"
def self.global
@global ||= new
end
[
:appdir,
:prefpanedir,
:qlplugindir,
:dictionarydir,
:fontdir,
:colorpickerdir,
:servicedir,
:input_methoddir,
:internet_plugindir,
:audio_unit_plugindir,
:vst_plugindir,
:vst3_plugindir,
:screen_saverdir,
].each do |dir|
attr_reader dir
def self.clear
@global = nil
end
def self.for_cask(cask)
if cask.config_path.exist?
from_file(cask.config_path)
else
global
end
end
def self.from_file(path)
config = begin
JSON.parse(File.read(path))
rescue JSON::ParserError => e
raise e, "Cannot parse #{path}: #{e}", e.backtrace
end
new(
default: config.fetch("default", {}),
env: config.fetch("env", {}),
explicit: config.fetch("explicit", {}),
)
end
def self.canonicalize(config)
config.map { |k, v| [k.to_sym, Pathname(v).expand_path] }.to_h
end
attr_accessor :explicit
def initialize(default: nil, env: nil, explicit: {})
@default = self.class.canonicalize(default) if default
@env = self.class.canonicalize(env) if env
@explicit = self.class.canonicalize(explicit)
@env&.assert_valid_keys!(*DEFAULT_DIRS.keys)
@explicit.assert_valid_keys!(*DEFAULT_DIRS.keys)
end
def default
@default ||= self.class.canonicalize(DEFAULT_DIRS)
end
def env
@env ||= self.class.canonicalize(
Shellwords.shellsplit(ENV.fetch("HOMEBREW_CASK_OPTS", ""))
.select { |arg| arg.include?("=") }
.map { |arg| arg.split("=", 2) }
.map { |(flag, value)| [flag.sub(/^\-\-/, ""), value] },
)
end
def binarydir
@binarydir ||= HOMEBREW_PREFIX/"bin"
end
DEFAULT_DIRS.keys.each do |dir|
define_method(dir) do
explicit.fetch(dir, env.fetch(dir, default.fetch(dir)))
end
define_method(:"#{dir}=") do |path|
instance_variable_set(:"@#{dir}", Pathname(path).expand_path)
explicit[dir] = Pathname(path).expand_path
end
end
def merge(other)
self.class.new(explicit: other.explicit.merge(explicit))
end
def to_json(*args)
{
default: default,
env: env,
explicit: explicit,
}.to_json(*args)
end
end
end

View File

@ -57,7 +57,6 @@ module Cask
:appcast,
:artifacts,
:auto_updates,
:caskroom_path,
:caveats,
:conflicts_with,
:container,
@ -226,7 +225,7 @@ module Cask
end
def caskroom_path
@caskroom_path ||= Caskroom.path.join(token)
@cask.caskroom_path
end
def staged_path

View File

@ -1,29 +1,28 @@
require "extend/hash_validator"
using HashValidator
module Cask
class DSL
class ConflictsWith
VALID_KEYS = Set.new [
class ConflictsWith < DelegateClass(Hash)
VALID_KEYS = [
:formula,
:cask,
:macos,
:arch,
:x11,
:java,
]
].freeze
attr_reader *VALID_KEYS
def initialize(**pairs)
pairs.assert_valid_keys!(*VALID_KEYS)
def initialize(pairs = {})
@pairs = pairs
super(Hash[pairs.map { |k, v| [k, Set.new([*v])] }])
VALID_KEYS.each do |key|
instance_variable_set("@#{key}", Set.new)
end
self.default = Set.new
end
pairs.each do |key, value|
raise "invalid conflicts_with key: '#{key.inspect}'" unless VALID_KEYS.include?(key)
instance_variable_set("@#{key}", instance_variable_get("@#{key}").merge([*value]))
end
def to_json(generator)
Hash[map { |k, v| [k, v.to_a] }].to_json(generator)
end
end
end

View File

@ -136,7 +136,9 @@ module Cask
Actual: #{Formatter.error(actual.to_s)}
File: #{path}
To retry an incomplete download, remove the file above.
To retry an incomplete download, remove the file above. If the issue persists, visit:
https://github.com/Homebrew/homebrew-cask/blob/master/doc/reporting_bugs/checksum_does_not_match_error.md
EOS
end
end

View File

@ -4,6 +4,7 @@ require "formula_installer"
require "unpack_strategy"
require "cask/cask_dependencies"
require "cask/config"
require "cask/download"
require "cask/staged"
require "cask/verify"
@ -39,7 +40,7 @@ module Cask
end
attr_predicate :binaries?, :force?, :skip_cask_deps?, :require_sha?,
:upgrade?, :verbose?, :installed_as_dependency?,
:reinstall?, :upgrade?, :verbose?, :installed_as_dependency?,
:quarantine?
def self.print_caveats(cask)
@ -79,7 +80,9 @@ module Cask
def install
odebug "Cask::Installer#install"
if @cask.installed? && !force? && !@reinstall && !upgrade?
old_config = @cask.config
if @cask.installed? && !force? && !reinstall? && !upgrade?
raise CaskAlreadyInstalledError, @cask
end
@ -87,11 +90,14 @@ module Cask
print_caveats
fetch
uninstall_existing_cask if @reinstall
uninstall_existing_cask if reinstall?
oh1 "Installing Cask #{Formatter.identifier(@cask)}"
opoo "macOS's Gatekeeper has been disabled for this Cask" unless quarantine?
stage
@cask.config = Config.global.merge(old_config)
install_artifacts
unless @cask.tap&.private?
@ -104,7 +110,7 @@ module Cask
def check_conflicts
return unless @cask.conflicts_with
@cask.conflicts_with.cask.each do |conflicting_cask|
@cask.conflicts_with[:cask].each do |conflicting_cask|
begin
conflicting_cask = CaskLoader.load(conflicting_cask)
if conflicting_cask.installed?
@ -209,6 +215,8 @@ module Cask
artifact.install_phase(command: @command, verbose: verbose?, force: force?)
already_installed_artifacts.unshift(artifact)
end
save_config_file
rescue => e
begin
already_installed_artifacts.each do |artifact|
@ -217,6 +225,13 @@ module Cask
odebug "Reverting installation of artifact of class #{artifact.class}"
artifact.uninstall_phase(command: @command, verbose: verbose?, force: force?)
end
already_installed_artifacts.each do |artifact|
next unless artifact.respond_to?(:post_uninstall_phase)
odebug "Reverting installation of artifact of class #{artifact.class}"
artifact.post_uninstall_phase(command: @command, verbose: verbose?, force: force?)
end
ensure
purge_versioned_files
raise e
@ -375,13 +390,23 @@ module Cask
old_savedir&.rmtree
end
def save_config_file
@cask.config_path.atomic_write(@cask.config.to_json)
end
def uninstall
oh1 "Uninstalling Cask #{Formatter.identifier(@cask)}"
uninstall_artifacts(clear: true)
remove_config_file unless reinstall? || upgrade?
purge_versioned_files
purge_caskroom_path if force?
end
def remove_config_file
FileUtils.rm_f @cask.config_path
@cask.config_path.parent.rmdir_if_possible
end
def start_upgrade
oh1 "Starting upgrade for Cask #{Formatter.identifier(@cask)}"
@ -425,9 +450,18 @@ module Cask
artifacts.each do |artifact|
next unless artifact.respond_to?(:uninstall_phase)
odebug "Un-installing artifact of class #{artifact.class}"
odebug "Uninstalling artifact of class #{artifact.class}"
artifact.uninstall_phase(command: @command, verbose: verbose?, skip: clear, force: force?, upgrade: upgrade?)
end
artifacts.each do |artifact|
next unless artifact.respond_to?(:post_uninstall_phase)
odebug "Post-uninstalling artifact of class #{artifact.class}"
artifact.post_uninstall_phase(
command: @command, verbose: verbose?, skip: clear, force: force?, upgrade: upgrade?,
)
end
end
def zap

View File

@ -88,10 +88,12 @@ class Cleaner
Find.prune if @f.skip_clean? path
next if path.symlink? || path.directory?
next if path.directory?
if path.extname == ".la"
path.unlink
elsif path.symlink?
# Skip it.
elsif path.basename.to_s == "perllocal.pod"
# Both this file & the .packlist one below are completely unnecessary
# to package & causes pointless conflict with other formulae. They are

View File

@ -52,7 +52,7 @@ module CleanupRefinement
return true if symlink? && !exist?
mtime < days.days.ago
mtime < days.days.ago && ctime < days.days.ago
end
def stale?(scrub = false)
@ -112,6 +112,8 @@ module CleanupRefinement
def stale_cask?(scrub)
return false unless name = basename.to_s[/\A(.*?)\-\-/, 1]
return if dirname.basename.to_s != "Cask"
cask = begin
Cask::CaskLoader.load(name)
rescue Cask::CaskUnavailableError
@ -124,7 +126,10 @@ module CleanupRefinement
return true if scrub && !cask.versions.include?(cask.version)
return mtime < CLEANUP_DEFAULT_DAYS.days.ago if cask.version.latest?
if cask.version.latest?
return mtime < CLEANUP_DEFAULT_DAYS.days.ago &&
ctime < CLEANUP_DEFAULT_DAYS.days.ago
end
false
end
@ -155,7 +160,6 @@ module Homebrew
def self.install_formula_clean!(f)
return if ENV["HOMEBREW_NO_INSTALL_CLEANUP"]
return unless ENV["HOMEBREW_INSTALL_CLEANUP"]
cleanup = Cleanup.new
if cleanup.periodic_clean_due?
@ -167,7 +171,6 @@ module Homebrew
def periodic_clean_due?
return false if ENV["HOMEBREW_NO_INSTALL_CLEANUP"]
return unless ENV["HOMEBREW_INSTALL_CLEANUP"]
return true unless PERIODIC_CLEAN_FILE.exist?
PERIODIC_CLEAN_FILE.mtime < CLEANUP_DEFAULT_DAYS.days.ago
@ -177,25 +180,32 @@ module Homebrew
return false unless periodic_clean_due?
ohai "`brew cleanup` has not been run in #{CLEANUP_DEFAULT_DAYS} days, running now..."
clean!
clean!(quiet: true, periodic: true)
end
def clean!
def clean!(quiet: false, periodic: false)
if args.empty?
Formula.installed.sort_by(&:name).each do |formula|
cleanup_formula(formula)
cleanup_formula(formula, quiet: quiet)
end
cleanup_cache
cleanup_logs
cleanup_portable_ruby
cleanup_lockfiles
return if dry_run?
cleanup_old_cache_db
rm_ds_store
prune_prefix_symlinks_and_directories
HOMEBREW_CACHE.mkpath
FileUtils.touch PERIODIC_CLEAN_FILE
unless dry_run?
cleanup_old_cache_db
rm_ds_store
HOMEBREW_CACHE.mkpath
FileUtils.touch PERIODIC_CLEAN_FILE
end
# Cleaning up Ruby needs to be done last to avoid requiring additional
# files afterwards. Additionally, don't allow it on periodic cleans to
# avoid having to try to do a `brew install` when we've just deleted
# the running Ruby process...
return if periodic
cleanup_portable_ruby
else
args.each do |arg|
formula = begin
@ -220,8 +230,9 @@ module Homebrew
@unremovable_kegs ||= []
end
def cleanup_formula(formula)
formula.eligible_kegs_for_cleanup.each(&method(:cleanup_keg))
def cleanup_formula(formula, quiet: false)
formula.eligible_kegs_for_cleanup(quiet: quiet)
.each(&method(:cleanup_keg))
cleanup_cache(Pathname.glob(cache/"#{formula.name}--*"))
rm_ds_store([formula.rack])
cleanup_lockfiles(FormulaLock.new(formula.name).path)
@ -274,6 +285,8 @@ module Homebrew
# Skip incomplete downloads which are still in progress.
next
end
elsif download.directory?
FileUtils.rm_rf download
else
download.unlink
end
@ -310,12 +323,12 @@ module Homebrew
if dry_run?
puts "Would remove: #{path} (#{path.abv})"
@disk_cleanup_size += disk_usage
else
puts "Removing: #{path}... (#{path.abv})"
yield
@disk_cleanup_size += disk_usage - path.disk_usage
end
@disk_cleanup_size += disk_usage
end
def cleanup_lockfiles(*lockfiles)

View File

@ -5,7 +5,7 @@ require "set"
module Homebrew
module CLI
class Parser
attr_reader :processed_options
attr_reader :processed_options, :hide_from_man_page
def self.parse(args = ARGV, &block)
new(&block).parse(args)
@ -27,8 +27,10 @@ module Homebrew
Homebrew.args.instance_eval { undef tap }
@constraints = []
@conflicts = []
@switch_sources = {}
@processed_options = []
@desc_line_length = 43
@hide_from_man_page = false
instance_eval(&block)
post_initialize
end
@ -50,15 +52,16 @@ module Homebrew
end
process_option(*names, description)
@parser.on(*names, *wrap_option_desc(description)) do
enable_switch(*names)
enable_switch(*names, from: :args)
end
names.each do |name|
set_constraints(name, required_for: required_for, depends_on: depends_on)
end
enable_switch(*names) if !env.nil? && !ENV["HOMEBREW_#{env.to_s.upcase}"].nil?
enable_switch(*names, from: :env) if !env.nil? && !ENV["HOMEBREW_#{env.to_s.upcase}"].nil?
end
alias switch_option switch
def usage_banner(text)
@parser.banner = "#{text}\n"
@ -147,14 +150,42 @@ module Homebrew
.gsub(/\*(.*?)\*/m, "#{Tty.underline}\\1#{Tty.reset}")
end
def formula_options
ARGV.formulae.each do |f|
next if f.options.empty?
f.options.each do |o|
name = o.flag
description = "`#{f.name}`: #{o.description}"
if name.end_with? "="
flag name, description: description
else
switch name, description: description
end
end
end
rescue FormulaUnavailableError
[]
end
def hide_from_man_page!
@hide_from_man_page = true
end
private
def enable_switch(*names)
def enable_switch(*names, from:)
names.each do |name|
@switch_sources[option_to_name(name)] = from
Homebrew.args["#{option_to_name(name)}?"] = true
end
end
def disable_switch(*names)
names.each do |name|
Homebrew.args.delete_field("#{option_to_name(name)}?")
end
end
# These are common/global switches accessible throughout Homebrew
def common_switch(name)
Homebrew::CLI::Parser.global_options.fetch(name, name)
@ -202,7 +233,13 @@ module Homebrew
next if violations.count < 2
raise OptionConflictError, violations.map(&method(:name_to_option))
env_var_options = violations.select do |option|
@switch_sources[option_to_name(option)] == :env_var
end
select_cli_arg = violations.count - env_var_options.count == 1
raise OptionConflictError, violations.map(&method(:name_to_option)) unless select_cli_arg
env_var_options.each(&method(:disable_switch))
end
end

View File

@ -1,15 +1,29 @@
#: * `--cache`:
#: Display Homebrew's download cache. See also `HOMEBREW_CACHE`.
#:
#: * `--cache` [`--build-from-source`|`-s`] [`--force-bottle`] <formula>:
#: Display the file or directory used to cache <formula>.
require "fetch"
require "cli_parser"
module Homebrew
module_function
def __cache_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`--cache` [<options>] [<formula>]
Display Homebrew's download cache. See also `HOMEBREW_CACHE`.
If <formula> is provided, display the file or directory used to cache <formula>.
EOS
switch "-s", "--build-from-source",
description: "Show the cache file used when building from source."
switch "--force-bottle",
description: "Show the cache file used when pouring a bottle."
conflicts "--build-from-source", "--force-bottle"
end
end
def __cache
__cache_args.parse
if ARGV.named.empty?
puts HOMEBREW_CACHE
else

View File

@ -1,15 +1,25 @@
#: * `--cellar`:
#: Display Homebrew's Cellar path. *Default:* `$(brew --prefix)/Cellar`, or if
#: that directory doesn't exist, `$(brew --repository)/Cellar`.
#:
#: * `--cellar` <formula>:
#: Display the location in the cellar where <formula> would be installed,
#: without any sort of versioned directory as the last path.
require "cli_parser"
module Homebrew
module_function
def __cellar_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`--cache` [<formula>]
Display Homebrew's Cellar path. *Default:* `$(brew --prefix)/Cellar`, or if
that directory doesn't exist, `$(brew --repository)/Cellar`.
If <formula> is provided, display the location in the cellar where <formula>
would be installed, without any sort of versioned directory as the last path.
EOS
end
end
def __cellar
__cellar_args.parse
if ARGV.named.empty?
puts HOMEBREW_CELLAR
else

View File

@ -1,36 +1,46 @@
#: * `--env` [`--shell=`(<shell>|`auto`)|`--plain`]:
#: Show a summary of the Homebrew build environment as a plain list.
#:
#: Pass `--shell=`<shell> to generate a list of environment variables for the
#: specified shell, or `--shell=auto` to detect the current shell.
#:
#: If the command's output is sent through a pipe and no shell is specified,
#: the list is formatted for export to `bash`(1) unless `--plain` is passed.
require "extend/ENV"
require "build_environment"
require "utils/shell"
require "cli_parser"
module Homebrew
module_function
def __env_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`--env` [<options>]
Show a summary of the Homebrew build environment as a plain list.
If the command's output is sent through a pipe and no shell is specified,
the list is formatted for export to `bash`(1) unless `--plain` is passed.
EOS
flag "--shell=",
description: "Generate a list of environment variables for the specified shell, " \
"or `--shell=auto` to detect the current shell."
switch "--plain",
description: "Plain output even when piped."
end
end
def __env
__env_args.parse
ENV.activate_extensions!
ENV.deps = ARGV.formulae if superenv?
ENV.setup_build_environment
ENV.universal_binary if ARGV.build_universal?
shell_value = ARGV.value("shell")
if ARGV.include?("--plain")
shell = nil
elsif shell_value.nil?
shell = if args.plain?
nil
elsif args.shell.nil?
# legacy behavior
shell = :bash unless $stdout.tty?
elsif shell_value == "auto"
shell = Utils::Shell.parent || Utils::Shell.preferred
elsif shell_value
shell = Utils::Shell.from_path(shell_value)
:bash unless $stdout.tty?
elsif args.shell == "auto"
Utils::Shell.parent || Utils::Shell.preferred
elsif args.shell
Utils::Shell.from_path(args.shell)
end
env_keys = build_env_keys(ENV)

View File

@ -1,13 +1,25 @@
#: * `--prefix`:
#: Display Homebrew's install path. *Default:* `/usr/local` on macOS and `/home/linuxbrew/.linuxbrew` on Linux
#:
#: * `--prefix` <formula>:
#: Display the location in the cellar where <formula> is or would be installed.
require "cli_parser"
module Homebrew
module_function
def __prefix_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`--prefix` [<formula>]
Display Homebrew's install path. *Default:* `/usr/local` on macOS and
`/home/linuxbrew/.linuxbrew` on Linux.
If <formula> is provided, display the location in the cellar where <formula>
is or would be installed.
EOS
end
end
def __prefix
__prefix_args.parse
if ARGV.named.empty?
puts HOMEBREW_PREFIX
else

View File

@ -1,13 +1,23 @@
#: * `--repository`:
#: Display where Homebrew's `.git` directory is located.
#:
#: * `--repository` <user>`/`<repo>:
#: Display where tap <user>`/`<repo>'s directory is located.
require "cli_parser"
module Homebrew
module_function
def __repository_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`--repository` [<user>`/`<repo>]
Display where Homebrew's `.git` directory is located.
If <user>`/`<repo> are provided, display where tap <user>`/`<repo>'s directory is located.
EOS
end
end
def __repository
__repository_args.parse
if ARGV.named.empty?
puts HOMEBREW_REPOSITORY
else

View File

@ -1,10 +1,22 @@
#: * `--version`:
#: Print the version number of Homebrew to standard output and exit.
require "cli_parser"
module Homebrew
module_function
def __version_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`--version`
Print the version number of Homebrew, Homebrew/homebrew-core and Homebrew/homebrew-cask
(if tapped) to standard output and exit.
EOS
end
end
def __version
__version_args.parse
odie "This command does not take arguments." if ARGV.any?
puts "Homebrew #{HOMEBREW_VERSION}"

View File

@ -1,22 +1,32 @@
#: * `analytics` [`state`]:
#: Display anonymous user behaviour analytics state.
#: Read more at <https://docs.brew.sh/Analytics>.
#:
#: * `analytics` (`on`|`off`):
#: Turn on/off Homebrew's analytics.
#:
#: * `analytics` `regenerate-uuid`:
#: Regenerate UUID used in Homebrew's analytics.
require "cli_parser"
module Homebrew
module_function
def analytics_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`analytics` (`on`|`off`) [`state`] [`regenerate-uuid`]
If `on`|`off` is passed, turn Homebrew's analytics on or off respectively.
If `state` is passed, display anonymous user behaviour analytics state.
Read more at <https://docs.brew.sh/Analytics>.
If `regenerate-uuid` is passed, regenerate UUID used in Homebrew's analytics.
EOS
switch :verbose
switch :debug
end
end
def analytics
analytics_args.parse
config_file = HOMEBREW_REPOSITORY/".git/config"
raise UsageError if ARGV.named.size > 1
raise UsageError if args.remaining.size > 1
case ARGV.named.first
case args.remaining.first
when nil, "state"
analyticsdisabled =
Utils.popen_read("git config --file=#{config_file} --get homebrew.analyticsdisabled").chomp

View File

@ -1,16 +1,26 @@
#: * `cat` <formula>:
#: Display the source to <formula>.
require "cli_parser"
module Homebrew
module_function
def cat_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`cat` <formula>
Display the source of <formula>.
EOS
end
end
def cat
cat_args.parse
# do not "fix" this to support multiple arguments, the output would be
# unparsable, if the user wants to cat multiple formula they can call
# brew cat multiple times.
formulae = ARGV.formulae
raise FormulaUnspecifiedError if formulae.empty?
raise "`brew cat` doesn't support multiple arguments" if formulae.size > 1
raise "`brew cat` doesn't support multiple arguments" if args.remaining.size > 1
cd HOMEBREW_REPOSITORY
exec "cat", formulae.first.path, *ARGV.options_only

View File

@ -1,17 +1,3 @@
#: * `cleanup` [`--prune=`<days>] [`--dry-run`] [`-s`] [<formulae>|<casks>]:
#: Remove stale lock files and outdated downloads for formulae and casks,
#: and remove old versions of installed formulae. If arguments are specified,
#: only do this for the specified formulae and casks.
#:
#: If `--prune=`<days> is specified, remove all cache files older than <days>.
#:
#: If `--dry-run` or `-n` is passed, show what would be removed, but do not
#: actually remove anything.
#:
#: If `-s` is passed, scrub the cache, including downloads for even the latest
#: versions. Note downloads for any installed formula or cask will still not
#: be deleted. If you want to delete those too: `rm -rf "$(brew --cache)"`
require "cleanup"
require "cli_parser"
@ -21,8 +7,7 @@ module Homebrew
def cleanup_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`cleanup` [<options>] [<formulae>|<casks>]
`cleanup` [<options>] [<formula>|<cask>]
Remove stale lock files and outdated downloads for formulae and casks,
and remove old versions of installed formulae. If arguments are specified,
@ -37,6 +22,8 @@ module Homebrew
description: "Scrub the cache, including downloads for even the latest versions. "\
"Note downloads for any installed formula or cask will still not be deleted. "\
"If you want to delete those too: `rm -rf \"$(brew --cache)\"`"
switch "--prune-prefix",
description: "Only prune the symlinks and directories from the prefix and remove no other files."
switch :verbose
switch :debug
end
@ -46,6 +33,10 @@ module Homebrew
cleanup_args.parse
cleanup = Cleanup.new(*args.remaining, dry_run: args.dry_run?, scrub: args.s?, days: args.prune&.to_i)
if args.prune_prefix?
cleanup.prune_prefix_symlinks_and_directories
return
end
cleanup.clean!

View File

@ -1,15 +1,26 @@
#: * `command` <cmd>:
#: Display the path to the file which is used when invoking `brew` <cmd>.
require "commands"
require "cli_parser"
module Homebrew
module_function
def command
abort "This command requires a command argument" if ARGV.empty?
def command_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`command` <cmd>
cmd = HOMEBREW_INTERNAL_COMMAND_ALIASES.fetch(ARGV.first, ARGV.first)
Display the path to the file which is used when invoking `brew` <cmd>.
EOS
switch :verbose
switch :debug
end
end
def command
command_args.parse
abort "This command requires a command argument" if args.remaining.empty?
cmd = HOMEBREW_INTERNAL_COMMAND_ALIASES.fetch(args.remaining.first, args.remaining.first)
path = Commands.path(cmd)

View File

@ -1,18 +1,33 @@
#: * `commands` [`--quiet` [`--include-aliases`]]:
#: Show a list of built-in and external commands.
#:
#: If `--quiet` is passed, list only the names of commands without the header.
#: With `--include-aliases`, the aliases of internal commands will be included.
require "cli_parser"
module Homebrew
module_function
def commands_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`commands` [<options>]
Show a list of built-in and external commands.
EOS
switch "--quiet",
description: "List only the names of commands without the header."
switch "--include-aliases",
depends_on: "--quiet",
description: "Include the aliases of internal commands."
switch :verbose
switch :debug
end
end
def commands
if ARGV.include? "--quiet"
commands_args.parse
if args.quiet?
cmds = internal_commands
cmds += external_commands
cmds += internal_developer_commands
cmds += HOMEBREW_INTERNAL_COMMAND_ALIASES.keys if ARGV.include? "--include-aliases"
cmds += HOMEBREW_INTERNAL_COMMAND_ALIASES.keys if args.include_aliases?
puts Formatter.columns(cmds.sort)
return
end

View File

@ -1,14 +1,26 @@
#: * `config`:
#: Show Homebrew and system configuration useful for debugging. If you file
#: a bug report, you will likely be asked for this information if you do not
#: provide it.
require "system_config"
require "cli_parser"
module Homebrew
module_function
def config_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`config`
Show Homebrew and system configuration useful for debugging. If you file
a bug report, you will likely be asked for this information if you do not
provide it.
EOS
switch :verbose
switch :debug
end
end
def config
config_args.parse
raise UsageError unless args.remaining.empty?
SystemConfig.dump_verbose_config
end
end

View File

@ -1,104 +1,96 @@
#: * `deps` [`--1`] [`-n`] [`--union`] [`--full-name`] [`--installed`] [`--include-build`] [`--include-optional`] [`--skip-recommended`] [`--include-requirements`] <formulae>:
#: Show dependencies for <formulae>. When given multiple formula arguments,
#: show the intersection of dependencies for <formulae>.
#:
#: If `--1` is passed, only show dependencies one level down, instead of
#: recursing.
#:
#: If `-n` is passed, show dependencies in topological order.
#:
#: If `--union` is passed, show the union of dependencies for <formulae>,
#: instead of the intersection.
#:
#: If `--full-name` is passed, list dependencies by their full name.
#:
#: If `--installed` is passed, only list those dependencies that are
#: currently installed.
#:
#: 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 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`.
#:
#: * `deps` `--tree` [`--1`] [<filters>] [`--annotate`] (<formulae>|`--installed`):
#: Show dependencies as a tree. When given multiple formula arguments, output
#: individual trees for every formula.
#:
#: If `--1` is passed, only one level of children is displayed.
#:
#: If `--installed` is passed, output a tree for every installed formula.
#:
#: The <filters> placeholder is any combination of options `--include-build`,
#: `--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.
#:
#: * `deps` [<filters>] (`--installed`|`--all`):
#: Show dependencies for installed or all available formulae. Every line of
#: output starts with the formula name, followed by a colon and all direct
#: dependencies of that formula.
#:
#: The <filters> placeholder is any combination of options `--include-build`,
#: `--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.
# This is used for debugging the `--installed`/`--all` display mode.
# encoding: UTF-8
require "formula"
require "ostruct"
require "cli_parser"
module Homebrew
module_function
def deps_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`deps` [<options>] <formula>
Show dependencies for <formula>. When given multiple formula arguments,
show the intersection of dependencies for <formula>.
EOS
switch "--1",
description: "Only show dependencies one level down, instead of recursing."
switch "-n",
description: "Show dependencies in topological order."
switch "--union",
description: "Show the union of dependencies for <formula>, instead of the intersection."
switch "--full-name",
description: "List dependencies by their full name."
switch "--installed",
description: "Only list those dependencies that are currently installed."
switch "--all",
description: "List all the dependencies for all available formulae."
switch "--include-build",
description: "Show `:build` type dependencies for <formula>."
switch "--include-optional",
description: "Show `:optional` dependencies for <formula>."
switch "--include-test",
description: "Show `:test` dependencies for <formula> (non-recursive)."
switch "--skip-recommended",
description: "Skip `:recommended` type dependencies for <formula>."
switch "--include-requirements",
description: "Include requirements in addition to dependencies for <formula>."
switch "--tree",
description: "Show dependencies as a tree. When given multiple formula arguments "\
"output individual trees for every formula."
switch "--for-each",
description: "Switch into the mode used by `deps --all`, but only list dependencies "\
"for specified formula one specified formula per line. This is used for "\
"debugging the `--installed`/`--all` display mode."
switch :verbose
switch :debug
conflicts "--installed", "--all"
formula_options
end
end
def deps
deps_args.parse
mode = OpenStruct.new(
installed?: ARGV.include?("--installed"),
tree?: ARGV.include?("--tree"),
all?: ARGV.include?("--all"),
topo_order?: ARGV.include?("-n"),
union?: ARGV.include?("--union"),
for_each?: ARGV.include?("--for-each"),
installed?: args.installed?,
tree?: args.tree?,
all?: args.all?,
topo_order?: args.n?,
union?: args.union?,
for_each?: args.for_each?,
)
if mode.tree?
if mode.installed?
puts_deps_tree Formula.installed.sort, !ARGV.one?
puts_deps_tree Formula.installed.sort, !args.send("1?")
else
raise FormulaUnspecifiedError if ARGV.named.empty?
raise FormulaUnspecifiedError if args.remaining.empty?
puts_deps_tree ARGV.formulae, !ARGV.one?
puts_deps_tree ARGV.formulae, !args.send("1?")
end
return
elsif mode.all?
puts_deps Formula.sort
return
elsif !ARGV.named.empty? && mode.for_each?
elsif !args.remaining.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")
@only_installed_arg = args.installed? &&
!args.include_build? &&
!args.include_test? &&
!args.include_optional? &&
!args.skip_recommended?
if ARGV.named.empty?
if args.remaining.empty?
raise FormulaUnspecifiedError unless mode.installed?
puts_deps Formula.installed.sort
return
end
all_deps = deps_for_formulae(ARGV.formulae, !ARGV.one?, &(mode.union? ? :| : :&))
all_deps = deps_for_formulae(ARGV.formulae, !args.send("1?"), &(mode.union? ? :| : :&))
all_deps = condense_requirements(all_deps)
all_deps.select!(&:installed?) if mode.installed?
all_deps.map!(&method(:dep_display_name))
@ -108,26 +100,26 @@ module Homebrew
end
def condense_requirements(deps)
return deps if ARGV.include?("--include-requirements")
return deps if args.include_requirements?
deps.select { |dep| dep.is_a? Dependency }
end
def dep_display_name(dep)
str = if dep.is_a? Requirement
if ARGV.include?("--include-requirements")
if args.include_requirements?
":#{dep.display_s}"
else
# This shouldn't happen, but we'll put something here to help debugging
"::#{dep.name}"
end
elsif ARGV.include?("--full-name")
elsif args.full_name?
dep.to_formula.full_name
else
dep.name
end
if ARGV.include?("--annotate")
if args.annotate?
str = "#{str} [build]" if dep.build?
str = "#{str} [test]" if dep.test?
str = "#{str} [optional]" if dep.optional?
@ -180,14 +172,14 @@ module Homebrew
reqs = f.requirements
deps = f.deps
dependables = reqs + deps
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")
dependables.reject!(&:optional?) unless args.include_optional?
dependables.reject!(&:build?) unless args.include_build?
dependables.reject!(&:test?) unless args.include_test?
dependables.reject!(&:recommended?) if args.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)
next if !args.include_requirements? && dep.is_a?(Requirement)
tree_lines = if i == max
"└──"

View File

@ -1,13 +1,3 @@
#: * `desc` <formula>:
#: Display <formula>'s name and one-line description.
#:
#: * `desc` [`--search`|`--name`|`--description`] (<text>|`/`<text>`/`):
#: Search both name and description (`--search` or `-s`), just the names
#: (`--name` or `-n`), or just the descriptions (`--description` or `-d`) for
#: <text>. If <text> is flanked by slashes, it is interpreted as a regular
#: expression. Formula descriptions are cached; the cache is created on the
#: first search, making that search slower than subsequent ones.
require "descriptions"
require "search"
require "description_cache_store"
@ -37,6 +27,7 @@ module Homebrew
description: "Search just the descriptions for provided <text>. If <text> is flanked by slashes, "\
"it is interpreted as a regular expression."
switch :verbose
conflicts "--search=", "--name=", "--description="
end
end

View File

@ -1,13 +1,3 @@
#: * `diy` [`--name=`<name>] [`--version=`<version>]:
#: Automatically determine the installation prefix for non-Homebrew software.
#:
#: Using the output from this command, you can install your own software into
#: the Cellar and then link it into Homebrew's prefix with `brew link`.
#:
#: The options `--name=`<name> and `--version=`<version> each take an argument
#: and allow you to explicitly set the name and version of the package you are
#: installing.
require "formula"
require "cli_parser"

View File

@ -1,14 +1,3 @@
#: * `doctor`:
#: Check your system for potential problems. Doctor exits with a non-zero status
#: if any potential problems are found. Please note that these warnings are just
#: used to help the Homebrew maintainers with debugging if you file an issue. If
#: everything you use Homebrew for is working fine: please don't worry or file
#: an issue; just ignore this.
# Undocumented options:
# `-D` activates debugging and profiling of the audit methods (not the same as `--debug`)
# `--list-checks` lists all audit methods
require "diagnostic"
require "cli_parser"

View File

@ -1,37 +1,52 @@
#: * `fetch` [`--force`] [`--retry`] [`-v`] [`--devel`|`--HEAD`] [`--deps`] [`--build-from-source`|`--force-bottle`] <formulae>:
#: Download the source packages for the given <formulae>.
#: For tarballs, also print SHA-256 checksums.
#:
#: If `--HEAD` or `--devel` is passed, fetch that version instead of the
#: stable version.
#:
#: If `-v` is passed, do a verbose VCS checkout, if the URL represents a VCS.
#: This is useful for seeing if an existing VCS cache has been updated.
#:
#: If `--force` (or `-f`) is passed, remove a previously cached version and re-fetch.
#:
#: If `--retry` is passed, retry if a download fails or re-download if the
#: checksum of a previously cached version no longer matches.
#:
#: If `--deps` is passed, also download dependencies for any listed <formulae>.
#:
#: If `--build-from-source` (or `-s`) is passed, download the source rather than a
#: bottle.
#:
#: 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"
require "fetch"
require "cli_parser"
module Homebrew
module_function
def fetch_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`fetch` [<options>] <formula>
Download the source packages for the given <formula>.
For tarballs, also print SHA-256 checksums.
EOS
switch "--HEAD",
description: "Fetch HEAD version instead of stable version."
switch "--devel",
description: "Fetch development version instead of stable version."
switch :verbose,
description: "Do a verbose VCS checkout, if the URL represents a VCS. This is useful for "\
"seeing if an existing VCS cache has been updated."
switch :force,
description: "Remove a previously cached version and re-fetch."
switch "--retry",
description: "Retry if a download fails or re-download if the checksum of a previously cached "\
"version no longer matches."
switch "--deps",
description: "Download dependencies for any listed <formula>."
switch "-s", "--build-from-source",
description: "Download the source for rather than a bottle."
switch "--build-bottle",
description: "Download the source (for eventual bottling) rather than a bottle."
switch "--force-bottle",
description: "Download a bottle if it exists for the current or newest version of macOS, "\
"even if it would not be used during installation."
switch :verbose
switch :debug
conflicts "--devel", "--HEAD"
conflicts "--build-from-source", "--build-bottle", "--force-bottle"
end
end
def fetch
fetch_args.parse
raise FormulaUnspecifiedError if ARGV.named.empty?
if ARGV.include? "--deps"
if args.deps?
bucket = []
ARGV.formulae.each do |f|
bucket << f
@ -100,7 +115,7 @@ module Homebrew
def retry_fetch?(f)
@fetch_failed ||= Set.new
if ARGV.include?("--retry") && @fetch_failed.add?(f)
if args.retry? && @fetch_failed.add?(f)
ohai "Retrying download"
f.clear_cache
true
@ -111,7 +126,7 @@ module Homebrew
end
def fetch_fetchable(f)
f.clear_cache if ARGV.force?
f.clear_cache if args.force?
already_fetched = f.cached_download.exist?

View File

@ -1,28 +1,41 @@
#: * `gist-logs` [`--new-issue`|`-n`] [`--private`|`-p`] <formula>:
#: Upload logs for a failed build of <formula> to a new Gist.
#:
#: <formula> is usually the name of the formula to install, but it can be specified
#: in several different ways. See [SPECIFYING FORMULAE](#specifying-formulae).
#:
#: If `--with-hostname` is passed, include the hostname in the Gist.
#:
#: If `--new-issue` is passed, automatically create a new issue in the appropriate
#: GitHub repository as well as creating the Gist.
#:
#: If `--private` is passed, the Gist will be marked private and will not
#: appear in listings but will be accessible with the link.
#:
#: If no logs are found, an error message is presented.
require "formula"
require "install"
require "system_config"
require "stringio"
require "socket"
require "cli_parser"
module Homebrew
module_function
def gist_logs_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`gist-logs` [<options>] <formula>
Upload logs for a failed build of <formula> to a new Gist.
<formula> is usually the name of the formula to install, but it can be specified
in several different ways.
If no logs are found, an error message is presented.
EOS
switch "--with-hostname",
description: "Include the hostname in the Gist."
switch "-n", "--new-issue",
description: "Automatically create a new issue in the appropriate GitHub repository as "\
"well as creating the Gist."
switch "-p", "--private",
description: "The Gist will be marked private and will not appear in listings but will "\
"be accessible with the link."
switch :verbose
switch :debug
end
end
def gistify_logs(f)
gist_logs_args.parse
files = load_logs(f.logs)
build_time = f.logs.ctime
timestamp = build_time.strftime("%Y-%m-%d_%H-%M-%S")
@ -60,7 +73,7 @@ module Homebrew
end
url = create_gist(files, descr)
if ARGV.include?("--new-issue") || ARGV.switch?("n")
if args.new_issue?
url = create_issue(f.tap, "#{f.name} failed to build on #{MacOS.full_version}", url)
end
@ -72,7 +85,7 @@ module Homebrew
s = <<~EOS
Homebrew build logs for #{f.full_name} on #{OS_VERSION}
EOS
if ARGV.include?("--with-hostname")
if args.with_hostname?
hostname = Socket.gethostname
s << "Host: #{hostname}\n"
end
@ -114,7 +127,7 @@ module Homebrew
end
def create_private?
ARGV.include?("--private") || ARGV.switch?("p")
args.private?
end
def create_gist(files, description)
@ -134,6 +147,8 @@ module Homebrew
def gist_logs
raise FormulaUnspecifiedError if ARGV.resolved_formulae.length != 1
Install.perform_preinstall_checks(all_fatal: true)
Install.perform_build_from_source_checks(all_fatal: true)
gistify_logs(ARGV.resolved_formulae.first)
end
end

View File

@ -1,9 +1,3 @@
#: * `home`:
#: Open Homebrew's own homepage in a browser.
#:
#: * `home` <formula>:
#: Open <formula>'s homepage in a browser.
require "cli_parser"
module Homebrew

View File

@ -1,39 +1,3 @@
#: * `info`:
#: Display brief statistics for your Homebrew installation.
#:
#: * `info` `--analytics` [`--days=`<days>] [`--category=`<category>]:
#: Display Homebrew analytics data (provided neither `HOMEBREW_NO_ANALYTICS`
#: or `HOMEBREW_NO_GITHUB_API` are set)
#:
#: The value for `days` must be `30`, `90` or `365`. The default is `30`.
#:
#: The value for `category` must be `install`, `install-on-request`,
#: `build-error` or `os-version`. The default is `install`.
#:
#: * `info` <formula> [`--analytics`]:
#: Display information about <formula> and analytics data (provided neither
#: `HOMEBREW_NO_ANALYTICS` or `HOMEBREW_NO_GITHUB_API` are set)
#:
#: Pass `--verbose` to see more verbose analytics data.
#:
#: Pass `--analytics` to see only more verbose analytics data instead of
#: formula information.
#:
#: * `info` `--github` <formula>:
#: Open a browser to the GitHub History page for <formula>.
#:
#: To view formula history locally: `brew log -p` <formula>
#:
#: * `info` `--json[=`<version>] (`--all`|`--installed`|<formulae>):
#: Print a JSON representation of <formulae>. Currently the default and
#: only accepted value for <version> is `v1`.
#:
#: Pass `--all` to get information on all formulae, or `--installed` to get
#: information on all installed formulae.
#:
#: See the docs for examples of using the JSON output:
#: <https://docs.brew.sh/Querying-Brew>
require "missing_formula"
require "caveats"
require "cli_parser"
@ -49,7 +13,7 @@ module Homebrew
def info_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`info [<formulae>]`
`info` [<formula>]
Display brief statistics for your Homebrew installation.
EOS
@ -67,7 +31,7 @@ module Homebrew
description: "Open a browser to the GitHub History page for provided <formula>. "\
"To view formula history locally: `brew log -p` <formula>"
flag "--json",
description: "Print a JSON representation of <formulae>. Currently the default and only accepted "\
description: "Print a JSON representation of <formula>. Currently the default and only accepted "\
"value for <version> is `v1`. See the docs for examples of using the JSON "\
"output: <https://docs.brew.sh/Querying-Brew>"
switch "--all",
@ -79,6 +43,7 @@ module Homebrew
switch :verbose,
description: "See more verbose analytics data."
switch :debug
conflicts "--all", "--installed"
end
end

View File

@ -1,98 +1,97 @@
#: * `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`] [`--display-times`] <formula> [<options> ...]:
#: Install <formula>.
#:
#: <formula> is usually the name of the formula to install, but it can be specified
#: in several different ways. See [SPECIFYING FORMULAE](#specifying-formulae).
#:
#: If `--debug` (or `-d`) is passed and brewing fails, open an interactive debugging
#: session with access to IRB or a shell inside the temporary build directory.
#:
#: If `--env=std` is passed, use the standard build environment instead of superenv.
#:
#: If `--env=super` is passed, use superenv even if the formula specifies the
#: standard build environment.
#:
#: If `--ignore-dependencies` is passed, skip installing any dependencies of
#: any kind. If they are not already present, the formula will probably fail
#: to install.
#:
#: If `--only-dependencies` is passed, install the dependencies with specified
#: options but do not install the specified formula.
#:
#: If `--cc=`<compiler> is passed, attempt to compile using <compiler>.
#: <compiler> should be the name of the compiler's executable, for instance
#: `gcc-7` for GCC 7. In order to use LLVM's clang, use `llvm_clang`.
#: To specify the Apple-provided clang, use `clang`.
#: This parameter will only accept compilers that are provided by Homebrew or
#: bundled with macOS. Please do not file issues if you encounter errors
#: while using this flag.
#:
#: If `--build-from-source` (or `-s`) is passed, compile the specified <formula> from
#: source even if a bottle is provided. Dependencies will still be installed
#: from bottles if they are available.
#:
#: If `HOMEBREW_BUILD_FROM_SOURCE` is set, regardless of whether `--build-from-source` was
#: passed, then both <formula> and the dependencies installed as part of this process
#: are built from source even if bottles are available.
#:
#: 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 `--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,
#: aka master, trunk, unstable.
#:
#: If `--keep-tmp` is passed, the temporary files created during installation
#: are not deleted.
#:
#: If `--build-bottle` is passed, prepare the formula for eventual bottling
#: during installation.
#:
#: If `--force` (or `-f`) is passed, install without checking for previously
#: installed keg-only or non-migrated versions
#:
#: If `--verbose` (or `-v`) is passed, print the verification and postinstall steps.
#:
#: If `--display-times` is passed, install times for each formula are printed
#: at the end of the run.
#:
#: Installation options specific to <formula> may be appended to the command,
#: and can be listed with `brew options` <formula>.
#:
#: * `install` `--interactive` [`--git`] <formula>:
#: If `--interactive` (or `-i`) is passed, download and patch <formula>, then
#: open a shell. This allows the user to run `./configure --help` and
#: otherwise determine how to turn the software package into a Homebrew
#: formula.
#:
#: If `--git` (or `-g`) is passed, Homebrew will create a Git repository, useful for
#: creating patches to the software.
require "missing_formula"
require "formula_installer"
require "development_tools"
require "install"
require "search"
require "cleanup"
require "cli_parser"
module Homebrew
module_function
extend Search
def install
raise FormulaUnspecifiedError if ARGV.named.empty?
def install_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`install` [<options>] <formula>
if ARGV.include? "--head"
raise "Specify `--HEAD` in uppercase to build from trunk."
Install <formula>.
<formula> is usually the name of the formula to install, but it can be specified
in several different ways.
Unless `HOMEBREW_NO_INSTALL_CLEANUP` is set, `brew cleanup` will be run for the installed formulae or, every 30 days, for all formulae.
EOS
switch :debug,
description: "If brewing fails, open an interactive debugging session with access to IRB "\
"or a shell inside the temporary build directory"
flag "--env=",
description: "If `std` is passed, use the standard build environment instead of superenv."\
"If `super` is passed, use superenv even if the formula specifies the "\
"standard build environment."
switch "--ignore-dependencies",
description: "Skip installing any dependencies of any kind. If they are not already "\
"present, the formula will probably fail to install."
switch "--only-dependencies",
description: "Install the dependencies with specified options but do not install the "\
"specified formula."
flag "--cc=",
description: "Attempt to compile using provided <compiler>. <compiler> should be the "\
"name of the compiler's executable, for instance `gcc-7` for GCC 7. "\
"In order to use LLVM's clang, use `llvm_clang`. To specify the "\
"Apple-provided clang, use `clang`. This parameter will only accept "\
"compilers that are provided by Homebrew or bundled with macOS. "\
"Please do not file issues if you encounter errors while using this flag."
switch "-s", "--build-from-source",
description: "Compile the specified <formula> from source even if a bottle is provided. "\
"Dependencies will still be installed from bottles if they are available."
switch "--force-bottle",
description: "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."
switch "--include-test",
description: "Install testing dependencies required to run `brew test`."
switch "--devel",
description: "If <formula> defines it, install the development version."
switch "--HEAD",
description: "If <formula> defines it, install the HEAD version, aka. master, trunk, unstable."
switch "--fetch-HEAD",
description: "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 development version has been released."
switch "--keep-tmp",
description: "Don't delete the temporary files created during installation."
switch "--build-bottle",
description: "Prepare the formula for eventual bottling during installation."
switch "--bottle-arch=",
description: "Optimise bottles for the given architecture rather than the oldest "\
"architecture supported by the version of macOS the bottles are built on."
switch :force,
description: "Install without checking for previously installed keg-only or "\
"non-migrated versions."
switch :verbose,
description: "Print the verification and postinstall steps."
switch "--display-times",
description: "Print install times for each formula at the end of the run."
switch "-i", "--interactive",
description: "Download and patch <formula>, then open a shell. This allows the user to "\
"run `./configure --help` and otherwise determine how to turn the software "\
"package into a Homebrew package."
switch "-g", "--git",
description: "Create a Git repository, useful for creating patches to the software."
conflicts "--ignore-dependencies", "--only-dependencies"
conflicts "--devel", "--HEAD"
conflicts "--build-from-source", "--build-bottle", "--force-bottle"
formula_options
end
end
unless ARGV.force?
def install
install_args.parse
raise FormulaUnspecifiedError if args.remaining.empty?
unless args.force?
ARGV.named.each do |name|
next if File.exist?(name)
if name !~ HOMEBREW_TAP_FORMULA_REGEX && name !~ HOMEBREW_CASK_TAP_CASK_REGEX
@ -104,210 +103,210 @@ module Homebrew
end
end
begin
formulae = []
formulae = []
unless ARGV.casks.empty?
args = []
args << "--force" if ARGV.force?
args << "--debug" if ARGV.debug?
args << "--verbose" if ARGV.verbose?
unless ARGV.casks.empty?
cask_args = []
cask_args << "--force" if args.force?
cask_args << "--debug" if args.debug?
cask_args << "--verbose" if args.verbose?
ARGV.casks.each do |c|
ohai "brew cask install #{c} #{args.join " "}"
system("#{HOMEBREW_PREFIX}/bin/brew", "cask", "install", c, *args)
end
ARGV.casks.each do |c|
ohai "brew cask install #{c} #{cask_args.join " "}"
system("#{HOMEBREW_PREFIX}/bin/brew", "cask", "install", c, *cask_args)
end
end
# if the user's flags will prevent bottle only-installations when no
# developer tools are available, we need to stop them early on
FormulaInstaller.prevent_build_flags unless DevelopmentTools.installed?
ARGV.formulae.each do |f|
# head-only without --HEAD is an error
if !Homebrew.args.HEAD? && f.stable.nil? && f.devel.nil?
raise <<~EOS
#{f.full_name} is a head-only formula
Install with `brew install --HEAD #{f.full_name}`
EOS
end
# if the user's flags will prevent bottle only-installations when no
# developer tools are available, we need to stop them early on
FormulaInstaller.prevent_build_flags unless DevelopmentTools.installed?
# devel-only without --devel is an error
if !args.devel? && f.stable.nil? && f.head.nil?
raise <<~EOS
#{f.full_name} is a devel-only formula
Install with `brew install --devel #{f.full_name}`
EOS
end
ARGV.formulae.each do |f|
# head-only without --HEAD is an error
if !ARGV.build_head? && f.stable.nil? && f.devel.nil?
raise <<~EOS
#{f.full_name} is a head-only formula
Install with `brew install --HEAD #{f.full_name}`
if !(args.HEAD? || args.devel?) && f.stable.nil?
raise "#{f.full_name} has no stable download, please choose --devel or --HEAD"
end
# --HEAD, fail with no head defined
if args.head? && f.head.nil?
raise "No head is defined for #{f.full_name}"
end
# --devel, fail with no devel defined
if args.devel? && f.devel.nil?
raise "No devel block is defined for #{f.full_name}"
end
installed_head_version = f.latest_head_version
if installed_head_version &&
!f.head_version_outdated?(installed_head_version, fetch_head: args.fetch_HEAD?)
new_head_installed = true
end
prefix_installed = f.prefix.exist? && !f.prefix.children.empty?
if f.keg_only? && f.any_version_installed? && f.optlinked? && !args.force?
# keg-only install is only possible when no other version is
# linked to opt, because installing without any warnings can break
# dependencies. Therefore before performing other checks we need to be
# sure --force flag is passed.
if f.outdated?
optlinked_version = Keg.for(f.opt_prefix).version
onoe <<~EOS
#{f.full_name} #{optlinked_version} is already installed
To upgrade to #{f.version}, run `brew upgrade #{f.name}`
EOS
end
# devel-only without --devel is an error
if !ARGV.build_devel? && f.stable.nil? && f.head.nil?
raise <<~EOS
#{f.full_name} is a devel-only formula
Install with `brew install --devel #{f.full_name}`
EOS
end
if ARGV.build_stable? && f.stable.nil?
raise "#{f.full_name} has no stable download, please choose --devel or --HEAD"
end
# --HEAD, fail with no head defined
if ARGV.build_head? && f.head.nil?
raise "No head is defined for #{f.full_name}"
end
# --devel, fail with no devel defined
if ARGV.build_devel? && f.devel.nil?
raise "No devel block is defined for #{f.full_name}"
end
installed_head_version = f.latest_head_version
new_head_installed = installed_head_version &&
!f.head_version_outdated?(installed_head_version, fetch_head: ARGV.fetch_head?)
prefix_installed = f.prefix.exist? && !f.prefix.children.empty?
if f.keg_only? && f.any_version_installed? && f.optlinked? && !ARGV.force?
# keg-only install is only possible when no other version is
# linked to opt, because installing without any warnings can break
# dependencies. Therefore before performing other checks we need to be
# sure --force flag is passed.
if f.outdated?
optlinked_version = Keg.for(f.opt_prefix).version
onoe <<~EOS
#{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 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
# After we're sure that --force flag is passed for linked to opt
# keg-only we need to be sure that the version we're attempting to
# install is not already installed.
installed_version = if ARGV.build_head?
f.latest_head_version
else
f.pkg_version
end
msg = "#{f.full_name} #{installed_version} is already installed"
linked_not_equals_installed = f.linked_version != installed_version
if f.linked? && linked_not_equals_installed
msg = <<~EOS
#{msg}
The currently linked version is #{f.linked_version}
You can use `brew switch #{f} #{installed_version}` to link this version.
EOS
elsif !f.linked? || f.keg_only?
msg = <<~EOS
#{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 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?
msg = <<~EOS
#{msg}, it's just not linked.
You can use `brew link #{old_formula.full_name}` to link this version.
EOS
end
opoo msg
elsif f.migration_needed? && !ARGV.force?
# Check if the formula we try to install is the same as installed
# but not migrated one. If --force passed then install anyway.
opoo <<~EOS
#{f.oldname} already installed, it's just not migrated
You can migrate formula with `brew migrate #{f}`
Or you can force install it with `brew install #{f} --force`
EOS
else
# If none of the above is true and the formula is linked, then
# FormulaInstaller will handle this case.
elsif args.only_dependencies?
formulae << f
else
opoo <<~EOS
#{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 (args.HEAD? && new_head_installed) || prefix_installed
# After we're sure that --force flag is passed for linked to opt
# keg-only we need to be sure that the version we're attempting to
# install is not already installed.
installed_version = if args.HEAD?
f.latest_head_version
else
f.pkg_version
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)
unless tab.installed_on_request
tab.installed_on_request = true
tab.write
msg = "#{f.full_name} #{installed_version} is already installed"
linked_not_equals_installed = f.linked_version != installed_version
if f.linked? && linked_not_equals_installed
msg = <<~EOS
#{msg}
The currently linked version is #{f.linked_version}
You can use `brew switch #{f} #{installed_version}` to link this version.
EOS
elsif !f.linked? || f.keg_only?
msg = <<~EOS
#{msg}, it's just not linked
You can use `brew link #{f}` to link this version.
EOS
elsif args.only_dependencies?
msg = nil
formulae << f
else
msg = <<~EOS
#{msg} and up-to-date
To reinstall #{f.pkg_version}, run `brew reinstall #{f.name}`
EOS
end
end
return if formulae.empty?
Install.perform_preinstall_checks
formulae.each do |f|
Migrator.migrate_if_needed(f)
install_formula(f)
Cleanup.install_formula_clean!(f)
end
Homebrew.messages.display_messages
rescue FormulaUnreadableError, FormulaClassUnavailableError,
TapFormulaUnreadableError, TapFormulaClassUnavailableError => e
# Need to rescue before `FormulaUnavailableError` (superclass of this)
# is handled, as searching for a formula doesn't make sense here (the
# formula was found, but there's a problem with its implementation).
ofail e.message
rescue FormulaUnavailableError => e
if e.name == "updog"
ofail "What's updog?"
return
end
ofail e.message
if (reason = MissingFormula.reason(e.name))
$stderr.puts reason
return
end
ohai "Searching for similarly named formulae..."
formulae_search_results = search_formulae(e.name)
case formulae_search_results.length
when 0
ofail "No similarly named formulae found."
when 1
puts "This similarly named formula was found:"
puts formulae_search_results
puts "To install it, run:\n brew install #{formulae_search_results.first}"
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?
msg = <<~EOS
#{msg}, it's just not linked.
You can use `brew link #{old_formula.full_name}` to link this version.
EOS
end
opoo msg
elsif f.migration_needed? && !args.force?
# Check if the formula we try to install is the same as installed
# but not migrated one. If --force passed then install anyway.
opoo <<~EOS
#{f.oldname} already installed, it's just not migrated
You can migrate formula with `brew migrate #{f}`
Or you can force install it with `brew install #{f} --force`
EOS
else
puts "These similarly named formulae were found:"
puts Formatter.columns(formulae_search_results)
puts "To install one of them, run (for example):\n brew install #{formulae_search_results.first}"
# If none of the above is true and the formula is linked, then
# FormulaInstaller will handle this case.
formulae << f
end
# Do not search taps if the formula name is qualified
return if e.name.include?("/")
# Even if we don't install this formula mark it as no longer just
# installed as a dependency.
next unless f.opt_prefix.directory?
ohai "Searching taps..."
taps_search_results = search_taps(e.name)[:formulae]
case taps_search_results.length
when 0
ofail "No formulae found in taps."
when 1
puts "This formula was found in a tap:"
puts taps_search_results
puts "To install it, run:\n brew install #{taps_search_results.first}"
else
puts "These formulae were found in taps:"
puts Formatter.columns(taps_search_results)
puts "To install one of them, run (for example):\n brew install #{taps_search_results.first}"
keg = Keg.new(f.opt_prefix.resolved_path)
tab = Tab.for_keg(keg)
unless tab.installed_on_request
tab.installed_on_request = true
tab.write
end
end
return if formulae.empty?
Install.perform_preinstall_checks
formulae.each do |f|
Migrator.migrate_if_needed(f)
install_formula(f)
Cleanup.install_formula_clean!(f)
end
Homebrew.messages.display_messages
rescue FormulaUnreadableError, FormulaClassUnavailableError,
TapFormulaUnreadableError, TapFormulaClassUnavailableError => e
# Need to rescue before `FormulaUnavailableError` (superclass of this)
# is handled, as searching for a formula doesn't make sense here (the
# formula was found, but there's a problem with its implementation).
ofail e.message
rescue FormulaUnavailableError => e
if e.name == "updog"
ofail "What's updog?"
return
end
ofail e.message
if (reason = MissingFormula.reason(e.name))
$stderr.puts reason
return
end
ohai "Searching for similarly named formulae..."
formulae_search_results = search_formulae(e.name)
case formulae_search_results.length
when 0
ofail "No similarly named formulae found."
when 1
puts "This similarly named formula was found:"
puts formulae_search_results
puts "To install it, run:\n brew install #{formulae_search_results.first}"
else
puts "These similarly named formulae were found:"
puts Formatter.columns(formulae_search_results)
puts "To install one of them, run (for example):\n brew install #{formulae_search_results.first}"
end
# Do not search taps if the formula name is qualified
return if e.name.include?("/")
ohai "Searching taps..."
taps_search_results = search_taps(e.name)[:formulae]
case taps_search_results.length
when 0
ofail "No formulae found in taps."
when 1
puts "This formula was found in a tap:"
puts taps_search_results
puts "To install it, run:\n brew install #{taps_search_results.first}"
else
puts "These formulae were found in taps:"
puts Formatter.columns(taps_search_results)
puts "To install one of them, run (for example):\n brew install #{taps_search_results.first}"
end
end
def install_formula(f)
@ -316,12 +315,11 @@ module Homebrew
fi = FormulaInstaller.new(f)
fi.options = build_options.used_options
fi.invalid_option_names = build_options.invalid_option_names
fi.ignore_deps = ARGV.ignore_deps?
fi.only_deps = ARGV.only_deps?
fi.build_bottle = ARGV.build_bottle?
fi.interactive = ARGV.interactive?
fi.git = ARGV.git?
fi.ignore_deps = args.ignore_dependencies?
fi.only_deps = args.only_dependencies?
fi.build_bottle = args.build_bottle?
fi.interactive = args.interactive?
fi.git = args.git?
fi.prelude
fi.install
fi.finish

View File

@ -1,6 +1,3 @@
#: * `leaves`:
#: Show installed formulae that are not dependencies of another installed formula.
require "formula"
require "tab"
require "cli_parser"

View File

@ -1,17 +1,3 @@
#: * `ln`, `link` [`--overwrite`] [`--dry-run`] [`--force`] <formula>:
#: Symlink all of <formula>'s installed files into the Homebrew prefix. This
#: is done automatically when you install formulae but can be useful for DIY
#: installations.
#:
#: If `--overwrite` is passed, Homebrew will delete files which already exist in
#: the prefix while linking.
#:
#: If `--dry-run` or `-n` is passed, Homebrew will list all files which would
#: be linked or which would be deleted by `brew link --overwrite`, but will not
#: actually link or delete any files.
#:
#: If `--force` (or `-f`) is passed, Homebrew will allow keg-only formulae to be linked.
require "ostruct"
require "caveats"
require "cli_parser"
@ -22,7 +8,7 @@ module Homebrew
def link_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`ln`, `link` <options> <formula>
`ln`, `link` [<options>] <formula>
Symlink all of <formula>'s installed files into the Homebrew prefix. This
is done automatically when you install formulae but can be useful for DIY

View File

@ -1,23 +1,3 @@
#: * `list`, `ls` [`--full-name`] [`-1`] [`-l`] [`-t`] [`-r`]:
#: List all installed formulae. If `--full-name` is passed, print formulae
#: with fully-qualified names. If `--full-name` is not passed, other
#: options (i.e. `-1`, `-l`, `-t` and `-r`) are passed to `ls` which produces the actual output.
#:
#: * `list`, `ls` `--unbrewed`:
#: List all files in the Homebrew prefix not installed by Homebrew.
#:
#: * `list`, `ls` [`--verbose`] [`--versions` [`--multiple`]] [`--pinned`] [<formulae>]:
#: List the installed files for <formulae>. Combined with `--verbose`, recursively
#: list the contents of all subdirectories in each <formula>'s keg.
#:
#: If `--versions` is passed, show the version number for installed formulae,
#: or only the specified formulae if <formulae> are given. With `--multiple`,
#: only show formulae with multiple versions installed.
#:
#: If `--pinned` is passed, show the versions of pinned formulae, or only the
#: specified (pinned) formulae if <formulae> are given.
#: See also `pin`, `unpin`.
require "metafiles"
require "formula"
require "cli_parser"
@ -28,7 +8,7 @@ module Homebrew
def list_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`list`, `ls` [<options>] [`-1`] [`-l`] [`-t`] [`-r`]
`list`, `ls` [<options>]
List all installed formulae.
EOS
@ -40,13 +20,13 @@ module Homebrew
description: "List all files in the Homebrew prefix not installed by Homebrew."
switch "--versions",
description: "Show the version number for installed formulae, or only the specified "\
"formulae if <formulae> are given."
"formulae if <formula> are given."
switch "--multiple",
depends_on: "--versions",
description: "Only show formulae with multiple versions installed."
switch "--pinned",
description: "Show the versions of pinned formulae, or only the specified (pinned) "\
"formulae if <formulae> are given. See also `pin`, `unpin`."
"formulae if <formula> are given. See also `pin`, `unpin`."
# passed through to ls
switch "-1",
description: "Force output to be one entry per line. " \

View File

@ -1,13 +1,30 @@
#: * `log` [<git-log-options>] <formula> ...:
#: Show the git log for the given formulae. Options that `git-log`(1)
#: recognizes can be passed before the formula list.
require "formula"
require "cli_parser"
module Homebrew
module_function
def log_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`log` [<options>] <formula>
Show the `git log` for the given <formula>.
EOS
switch "-p", "-u", "--patch",
description: "Also output patch from commit."
switch "--stat",
description: "Also output diffstat from commit."
switch "--oneline",
description: "Output only one line per commit."
switch "-1", "--max-count=1",
description: "Output only one commit."
end
end
def log
log_args.parse
if ARGV.named.empty?
git_log HOMEBREW_REPOSITORY
else

View File

@ -1,10 +1,3 @@
#: * `migrate` [`--force`] <formulae>:
#: Migrate renamed packages to new name, where <formulae> are old names of
#: packages.
#:
#: If `--force` (or `-f`) is passed, then treat installed <formulae> and passed <formulae>
#: like if they are from same taps and migrate them anyway.
require "migrator"
require "cli_parser"
@ -14,13 +7,13 @@ module Homebrew
def migrate_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`migrate` [<options>] <formulae>
`migrate` [<options>] <formula>
Migrate renamed packages to new name, where <formulae> are old names of
Migrate renamed packages to new name, where <formula> are old names of
packages.
EOS
switch :force,
description: "Treat installed <formulae> and passed <formulae> like if they are from "\
description: "Treat installed <formula> and passed <formula> like if they are from "\
"same taps and migrate them anyway."
switch :verbose
switch :debug

View File

@ -1,12 +1,3 @@
#: * `missing` [`--hide=`<hidden>] [<formulae>]:
#: Check the given <formulae> for missing dependencies. If no <formulae> are
#: given, check all installed brews.
#:
#: If `--hide=`<hidden> is passed, act as if none of <hidden> are installed.
#: <hidden> should be a comma-separated list of formulae.
#:
#: `missing` exits with a non-zero status if any formulae are missing dependencies.
require "formula"
require "tab"
require "diagnostic"
@ -18,9 +9,9 @@ module Homebrew
def missing_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`missing` [<options>] [<formulae>]
`missing` [<options>] [<formule>]
Check the given <formulae> for missing dependencies. If no <formulae> are
Check the given <formula> for missing dependencies. If no <formula> are
given, check all installed brews.
`missing` exits with a non-zero status if any formulae are missing dependencies.

View File

@ -1,13 +1,3 @@
#: * `options` [`--compact`] (`--all`|`--installed`|<formulae>):
#: Display install options specific to <formulae>.
#:
#: If `--compact` is passed, show all options on a single line separated by
#: spaces.
#:
#: If `--all` is passed, show options for all formulae.
#:
#: If `--installed` is passed, show options for all installed formulae.
require "formula"
require "options"
require "cli_parser"
@ -18,9 +8,9 @@ module Homebrew
def options_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`options` [<options>] <formulae>
`options` [<options>] <formula>
Display install options specific to <formulae>
Display install options specific to <formula>
EOS
switch "--compact",
description: "Show all options on a single line separated by spaces."
@ -29,6 +19,7 @@ module Homebrew
switch "--installed",
description: "Show options for all installed formulae."
switch :debug
conflicts "--all", "--installed"
end
end

View File

@ -1,22 +1,3 @@
#: * `outdated` [`--quiet`|`--verbose`|`--json=`<version>] [`--fetch-HEAD`]:
#: Show formulae that have an updated version available.
#:
#: By default, version information is displayed in interactive shells, and
#: suppressed otherwise.
#:
#: If `--quiet` is passed, list only the names of outdated brews (takes
#: precedence over `--verbose`).
#:
#: If `--verbose` (or `-v`) is passed, display detailed version information.
#:
#: If `--json=`<version> is passed, the output will be in JSON format.
#: Currently the only accepted value for <version> is `v1`.
#:
#: 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.
require "formula"
require "keg"
require "cli_parser"
@ -44,8 +25,9 @@ module Homebrew
switch "--fetch-HEAD",
description: "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."
"updates when a new stable or development version has been released."
switch :debug
conflicts "--quiet", "--verbose", "--json="
end
end

View File

@ -1,7 +1,3 @@
#: * `pin` <formulae>:
#: Pin the specified <formulae>, preventing them from being upgraded when
#: issuing the `brew upgrade` <formulae> command. See also `unpin`.
require "formula"
require "cli_parser"
@ -11,10 +7,10 @@ module Homebrew
def pin_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`pin` <formulae>
`pin` <formula>
Pin the specified <formulae>, preventing them from being upgraded when
issuing the `brew upgrade` <formulae> command. See also `unpin`.
Pin the specified <formula>, preventing them from being upgraded when
issuing the `brew upgrade` <formula> command. See also `unpin`.
EOS
switch :debug
end

View File

@ -1,6 +1,3 @@
#: * `postinstall` <formula>:
#: Rerun the post-install steps for <formula>.
require "sandbox"
require "formula_installer"
require "cli_parser"

View File

@ -1,6 +1,3 @@
#: * `prune` [`--dry-run`]:
#: Deprecated. Use `brew cleanup` instead.
require "keg"
require "cli_parser"
require "cleanup"
@ -19,13 +16,13 @@ module Homebrew
description: "Show what would be removed, but do not actually remove anything."
switch :verbose
switch :debug
hide_from_man_page!
end
end
def prune
prune_args.parse
odeprecated("'brew prune'", "'brew cleanup'")
Cleanup.new(dry_run: args.dry_run?).prune_prefix_symlinks_and_directories
odisabled("'brew prune'", "'brew cleanup --prune-prefix'")
end
end

View File

@ -1,14 +1,3 @@
#: * `readall` [`--aliases`] [`--syntax`] [<taps>]:
#: Import all formulae from specified <taps> (defaults to all installed taps).
#:
#: This can be useful for debugging issues across all formulae when making
#: significant changes to `formula.rb`, testing the performance of loading
#: all formulae or to determine if any current formulae have Ruby issues.
#:
#: If `--aliases` is passed, also verify any alias symlinks in each tap.
#:
#: If `--syntax` is passed, also syntax-check all of Homebrew's Ruby files.
require "readall"
require "cli_parser"
@ -18,9 +7,9 @@ module Homebrew
def readall_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`readall` [<options>] [<taps>]
`readall` [<options>] [<tap>]
Import all formulae from specified <taps> (defaults to all installed taps).
Import all formulae from specified <tap> (defaults to all installed taps).
This can be useful for debugging issues across all formulae when making
significant changes to `formula.rb`, testing the performance of loading
all formulae or to determine if any current formulae have Ruby issues.

View File

@ -1,12 +1,3 @@
#: * `reinstall` [`--display-times`] <formula>:
#: Uninstall and then install <formula> (with existing install options).
#:
#: If `--display-times` is passed, install times for each formula are printed
#: at the end of the run.
#:
#: If `HOMEBREW_INSTALL_CLEANUP` is set then remove previously installed versions
#: of upgraded <formulae> as well as the HOMEBREW_CACHE for that formula.
require "formula_installer"
require "development_tools"
require "messages"
@ -20,19 +11,31 @@ module Homebrew
def reinstall_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`reinstall` [<option(s)>] <formula>:
`reinstall` [<options>] <formula>
Uninstall and then install <formula> (with existing install options).
Uninstall and then install <formula> (with existing and any appended install options).
If `HOMEBREW_INSTALL_CLEANUP` is set then remove previously installed versions
of upgraded <formulae> as well as the HOMEBREW_CACHE for that formula.
Unless `HOMEBREW_NO_INSTALL_CLEANUP` is set, `brew cleanup` will be run for the reinstalled formulae or, every 30 days, for all formulae.
EOS
switch :debug,
description: "If brewing fails, open an interactive debugging session with access to IRB "\
"or a shell inside the temporary build directory"
switch "-s", "--build-from-source",
description: "Compile the formula> from source even if a bottle is available."
description: "Compile <formula> from source even if a bottle is available."
switch "--force-bottle",
description: "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."
switch "--keep-tmp",
description: "Don't delete the temporary files created during installation."
switch :force,
description: "Install without checking for previously installed keg-only or "\
"non-migrated versions."
switch :verbose,
description: "Print the verification and postinstall steps."
switch "--display-times",
description: "Print install times for each formula at the end of the run."
switch :verbose
switch :debug
conflicts "--build-from-source", "--force-bottle"
formula_options
end
end

View File

@ -1,22 +1,3 @@
#: * `search`, `-S`:
#: Display all locally available formulae (including tapped ones).
#: No online search is performed.
#:
#: * `search` `--casks`:
#: Display all locally available casks (including tapped ones).
#: No online search is performed.
#:
#: * `search` [`--desc`] (<text>|`/`<text>`/`):
#: Perform a substring search of cask tokens and formula names for <text>. If <text>
#: is surrounded with slashes, then it is interpreted as a regular expression.
#: The search for <text> is extended online to `homebrew/core` and `homebrew/cask`.
#:
#: If `--desc` is passed, search formulae with a description matching <text> and
#: casks with a name matching <text>.
#:
#: * `search` (`--debian`|`--fedora`|`--fink`|`--macports`|`--opensuse`|`--ubuntu`) <text>:
#: Search for <text> in the given package manager's list.
require "formula"
require "missing_formula"
require "descriptions"
@ -41,20 +22,38 @@ module Homebrew
},
}.freeze
def search(argv = ARGV)
CLI::Parser.parse(argv) do
switch "--desc"
def search_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`search` [<options>] [<text>|`/`<text>`/`]
Perform a substring search of cask tokens and formula names for <text>. If <text>
is surrounded with slashes, then it is interpreted as a regular expression.
The search for <text> is extended online to `homebrew/core` and `homebrew/cask`.
If no <text> is passed, display all locally available formulae (including tapped ones).
No online search is performed.
EOS
switch "--casks",
description: "Display all locally available casks (including tapped ones). "\
"No online search is performed."
switch "--desc",
description: "search formulae with a description matching <text> and casks with "\
"a name matching <text>."
package_manager_switches = PACKAGE_MANAGERS.keys.map { |name| "--#{name}" }
package_manager_switches.each do |s|
switch s
switch s,
description: "Search for <text> in the given package manager's list."
end
switch "--casks"
switch :verbose
switch :debug
conflicts(*package_manager_switches)
end
end
def search
search_args.parse
if package_manager = PACKAGE_MANAGERS.find { |name,| args[:"#{name}?"] }
_, url = package_manager

View File

@ -1,19 +1,30 @@
#: * `sh` [`--env=std`]:
#: Start a Homebrew build environment shell. Uses our years-battle-hardened
#: Homebrew build logic to help your `./configure && make && make install`
#: or even your `gem install` succeed. Especially handy if you run Homebrew
#: in an Xcode-only configuration since it adds tools like `make` to your `PATH`
#: which otherwise build systems would not find.
#:
#: If `--env=std` is passed, use the standard `PATH` instead of superenv's.
require "extend/ENV"
require "formula"
require "cli_parser"
module Homebrew
module_function
def sh_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`sh` [<options>]
Start a Homebrew build environment shell. Uses our years-battle-hardened
Homebrew build logic to help your `./configure && make && make install`
or even your `gem install` succeed. Especially handy if you run Homebrew
in an Xcode-only configuration since it adds tools like `make` to your `PATH`
which otherwise build systems would not find.
EOS
flag "--env=",
description: "Use the standard `PATH` instead of superenv's, when <std> is passed"
switch :verbose
switch :debug
end
end
def sh
sh_args.parse
ENV.activate_extensions!
if superenv?

View File

@ -1,12 +1,10 @@
#: * `shellenv`:
#: Prints export statements - run them in a shell and this installation of
#: Homebrew will be included into your PATH, MANPATH, and INFOPATH.
#: * `shellenv`
#:
#: HOMEBREW_PREFIX, HOMEBREW_CELLAR and HOMEBREW_REPOSITORY are also exported
#: to save multiple queries of those variables.
#: Prints export statements - run them in a shell and this installation of Homebrew will be included into your `PATH`, `MANPATH` and `INFOPATH`.
#:
#: Consider adding evaluating the output in your dotfiles (e.g. `~/.profile`)
#: with `eval $(brew shellenv)`
#: `HOMEBREW_PREFIX`, `HOMEBREW_CELLAR` and `HOMEBREW_REPOSITORY` are also exported to save multiple queries of those variables.
#:
#: Consider adding evaluating the output in your dotfiles (e.g. `~/.profile`) with `eval $(brew shellenv)`
homebrew-shellenv() {
echo "export HOMEBREW_PREFIX=\"$HOMEBREW_PREFIX\""

View File

@ -1,22 +1,3 @@
#: * `style` [`--fix`] [`--display-cop-names`] [`--only-cops=`<cops>|`--except-cops=`<cops>] [<files>|<taps>|<formulae>]:
#: Check formulae or files for conformance to Homebrew style guidelines.
#:
#: Lists of <files>, <taps> and <formulae> may not be combined. If none are
#: provided, `style` will run style checks on the whole Homebrew library,
#: including core code and all formulae.
#:
#: If `--fix` is passed, automatically fix style violations using RuboCop's
#: auto-correct feature.
#:
#: If `--display-cop-names` is passed, include the RuboCop cop name for each
#: violation in the output.
#:
#: 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 "json"
require "open3"
require "style"
@ -28,11 +9,11 @@ module Homebrew
def style_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`style` [<options>] [<files>|<taps>|<formulae>]
`style` [<options>] [<file>|<tap>|<formula>]
Check formulae or files for conformance to Homebrew style guidelines.
Lists of <files>, <taps> and <formulae> may not be combined. If none are
Lists of <file>, <tap> and <formula> may not be combined. If none are
provided, `style` will run style checks on the whole Homebrew library,
including core code and all formulae.
EOS

View File

@ -1,14 +1,25 @@
#: * `switch` <formula> <version>:
#: Symlink all of the specific <version> of <formula>'s install to Homebrew prefix.
require "formula"
require "keg"
require "cli_parser"
module Homebrew
module_function
def switch_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`switch` <formula> <version>
Symlink all of the specific <version> of <formula>'s install to Homebrew prefix.
EOS
switch_option :verbose
switch_option :debug
end
end
def switch
name = ARGV.first
switch_args.parse
name = args.remaining.first
usage = "Usage: brew switch <formula> <version>"
@ -28,9 +39,9 @@ module Homebrew
.map { |d| Keg.new(d).version }
.sort
.join(", ")
version = ARGV.second
version = args.remaining.second
if !version || ARGV.named.length > 2
if !version || args.remaining.length > 2
onoe usage
puts "#{name} installed versions: #{versions}"
exit 1

View File

@ -1,20 +1,3 @@
#: * `tap-info`:
#: Display a brief summary of all installed taps.
#:
#: * `tap-info` (`--installed`|<taps>):
#: Display detailed information about one or more <taps>.
#:
#: Pass `--installed` to display information on all installed taps.
#:
#: * `tap-info` `--json=`<version> (`--installed`|<taps>):
#: Print a JSON representation of <taps>. Currently the only accepted value
#: for <version> is `v1`.
#:
#: Pass `--installed` to get information on installed taps.
#:
#: See the docs for examples of using the JSON output:
#: <https://docs.brew.sh/Querying-Brew>
require "cli_parser"
module Homebrew
@ -23,10 +6,10 @@ module Homebrew
def tap_info_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`tap-info` [<options>] [<taps>]
`tap-info` [<options>] [<tap>]
Display detailed information about one or more provided <taps>.
Display a brief summary of all installed taps if no <taps> are passed.
Display detailed information about one or more provided <tap>.
Display a brief summary of all installed taps if no <tap> are passed.
EOS
switch "--installed",
description: "Display information on all installed taps."

View File

@ -1,7 +1,3 @@
#: * `tap-pin` <tap>:
#: Pin <tap>, prioritizing its formulae over core when formula names are supplied
#: by the user. See also `tap-unpin`.
require "cli_parser"
module Homebrew
@ -12,7 +8,7 @@ module Homebrew
usage_banner <<~EOS
`tap-pin` <tap>
Pin <tap>, prioritizing its formulae over core when formula names are supplied
Pin <tap>, prioritising its formulae over core when formula names are supplied
by the user. See also `tap-unpin`.
EOS
switch :debug

View File

@ -1,6 +1,3 @@
#: * `tap-unpin` <tap>:
#: Unpin <tap> so its formulae are no longer prioritized. See also `tap-pin`.
require "cli_parser"
module Homebrew
@ -11,7 +8,7 @@ module Homebrew
usage_banner <<~EOS
`tap-unpin` <tap>
Unpin <tap> so its formulae are no longer prioritized. See also `tap-pin`.
Unpin <tap> so its formulae are no longer prioritised. See also `tap-pin`.
EOS
switch :debug
end

View File

@ -1,37 +1,3 @@
#: * `tap`:
#: List all installed taps.
#:
#: * `tap` [`--full`] [`--force-auto-update`] <user>`/`<repo> [<URL>]:
#: Tap a formula repository.
#:
#: With <URL> unspecified, taps a formula repository from GitHub using HTTPS.
#: Since so many taps are hosted on GitHub, this command is a shortcut for
#: `brew tap` <user>`/`<repo> `https://github.com/`<user>`/homebrew-`<repo>.
#:
#: With <URL> specified, taps a formula repository from anywhere, using
#: any transport protocol that `git` handles. The one-argument form of `tap`
#: simplifies but also limits. This two-argument command makes no
#: assumptions, so taps can be cloned from places other than GitHub and
#: using protocols other than HTTPS, e.g., SSH, GIT, HTTP, FTP(S), RSYNC.
#:
#: By default, the repository is cloned as a shallow copy (`--depth=1`), but
#: if `--full` is passed, a full clone will be used. To convert a shallow copy
#: to a full copy, you can retap passing `--full` without first untapping.
#:
#: By default, only taps hosted on GitHub are auto-updated (for performance
#: reasons). If `--force-auto-update` is passed, this tap will be auto-updated
#: even if it is not hosted on GitHub.
#:
#: `tap` is re-runnable and exits successfully if there's nothing to do.
#: However, retapping with a different <URL> will cause an exception, so first
#: `untap` if you need to modify the <URL>.
#:
#: * `tap` `--repair`:
#: Migrate tapped formulae from symlink-based to directory-based structure.
#:
#: * `tap` `--list-pinned`:
#: List all pinned taps.
require "cli_parser"
module Homebrew

View File

@ -1,12 +1,3 @@
#: * `uninstall`, `rm`, `remove` [`--force`] [`--ignore-dependencies`] <formula>:
#: Uninstall <formula>.
#:
#: If `--force` (or `-f`) is passed, and there are multiple versions of <formula>
#: installed, delete all installed versions.
#:
#: If `--ignore-dependencies` is passed, uninstalling won't fail, even if
#: formulae depending on <formula> would still be installed.
require "keg"
require "formula"
require "diagnostic"
@ -26,7 +17,7 @@ module Homebrew
switch :force,
description: "Delete all installed versions of the <formula>"
switch "--ignore-dependencies",
description: "Dont fail uninstall, even if <formula> is a dependency of any installed "\
description: "Don't fail uninstall, even if <formula> is a dependency of any installed "\
"formulae."
switch :debug
end

View File

@ -1,11 +1,3 @@
#: * `unlink` [`--dry-run`] <formula>:
#: Remove symlinks for <formula> from the Homebrew prefix. This can be useful
#: for temporarily disabling a formula:
#: `brew unlink` <formula> `&&` <commands> `&& brew link` <formula>
#:
#: If `--dry-run` or `-n` is passed, Homebrew will list all files which would
#: be unlinked, but will not actually unlink or delete any files.
require "ostruct"
require "cli_parser"

View File

@ -1,14 +1,3 @@
#: * `unpack` [`--git`|`--patch`] [`--destdir=`<path>] <formulae>:
#: Unpack the source files for <formulae> into subdirectories of the current
#: working directory. If `--destdir=`<path> is given, the subdirectories will
#: be created in the directory named by <path> instead.
#:
#: If `--patch` is passed, patches for <formulae> will be applied to the
#: unpacked source.
#:
#: If `--git` (or `-g`) is passed, a Git repository will be initialized in the unpacked
#: source. This is useful for creating patches for the software.
require "stringio"
require "formula"
require "cli_parser"
@ -19,21 +8,22 @@ module Homebrew
def unpack_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`usage` [<options>] <formulae>
`unpack` [<options>] <formula>
Unpack the source files for <formulae> into subdirectories of the current
Unpack the source files for <formula> into subdirectories of the current
working directory.
EOS
flag "--destdir=",
description: "Create subdirectories in the directory named by <path> instead."
switch "--patch",
description: "Patches for <formulae> will be applied to the unpacked source."
description: "Patches for <formula> will be applied to the unpacked source."
switch "-g", "--git",
description: "Initialize a Git repository in the unpacked source. This is useful for creating "\
description: "Initialise a Git repository in the unpacked source. This is useful for creating "\
"patches for the software."
switch :force
switch :verbose
switch :debug
conflicts "--git", "--patch"
end
end

View File

@ -1,7 +1,3 @@
#: * `unpin` <formulae>:
#: Unpin <formulae>, allowing them to be upgraded by `brew upgrade` <formulae>.
#: See also `pin`.
require "formula"
require "cli_parser"
@ -11,9 +7,9 @@ module Homebrew
def unpin_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`unpin` <formulae>
`unpin` <formula>
Unpin <formulae>, allowing them to be upgraded by `brew upgrade` <formulae>.
Unpin <formula>, allowing them to be upgraded by `brew upgrade` <formula>.
See also `pin`.
EOS
switch :verbose

View File

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

View File

@ -1,13 +1,10 @@
#: @hide_from_man_page
#: * `update_report` [`--preinstall`]:
#: The Ruby implementation of `brew update`. Never called manually.
require "formula_versions"
require "migrator"
require "formulary"
require "descriptions"
require "cleanup"
require "description_cache_store"
require "cli_parser"
module Homebrew
module_function
@ -19,7 +16,26 @@ module Homebrew
end
end
def update_report_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`update_report` [`--preinstall`]
The Ruby implementation of `brew update`. Never called manually.
EOS
switch "--preinstall",
description: "Run in 'auto-update' mode (faster, less output)."
switch :force
switch :quiet
switch :debug
switch :verbose
hide_from_man_page!
end
end
def update_report
update_report_args.parse
HOMEBREW_REPOSITORY.cd do
analytics_message_displayed =
Utils.popen_read("git", "config", "--local", "--get", "homebrew.analyticsmessage").chomp == "true"

View File

@ -1,7 +1,6 @@
#: * `update-reset` [<repositories>]:
#: Fetches and resets Homebrew and all tap repositories (or the specified
#: `repositories`) using `git`(1) to their latest `origin/master`. Note this
#: will destroy all your uncommitted or committed changes.
#: * `update-reset` [<repository>]
#:
#: Fetches and resets Homebrew and all tap repositories (or any specified `repository`) using `git`(1) to their latest `origin/master`. Note this will destroy all your uncommitted or committed changes.
homebrew-update-reset() {
local DIR
@ -36,14 +35,7 @@ homebrew-update-reset() {
[[ -d "$DIR/.git" ]] || continue
cd "$DIR" || continue
echo "==> Fetching $DIR..."
if [[ "$DIR" = "$HOMEBREW_REPOSITORY" ]]; then
latest_tag="$(git ls-remote --tags --refs -q origin | tail -n1 | cut -f2)"
git fetch --force origin --shallow-since="$latest_tag"
else
git fetch --force --tags origin
fi
git fetch --force --tags origin
echo
echo "==> Resetting $DIR..."

View File

@ -1,12 +1,9 @@
#: * `update` [`--merge`] [`--force`]:
#: Fetch the newest version of Homebrew and all formulae from GitHub using
#: `git`(1) and perform any necessary migrations.
#: * `update` [<options>]
#:
#: If `--merge` is specified then `git merge` is used to include updates
#: (rather than `git rebase`).
#: Fetch the newest version of Homebrew and all formulae from GitHub using `git`(1) and perform any necessary migrations.
#:
#: If `--force` (or `-f`) is specified then always do a slower, full update check even
#: if unnecessary.
#: --merge `git merge` is used to include updates (rather than `git rebase`).
#: --force Always do a slower, full update check (even if unnecessary).
# Don't need shellcheck to follow this `source`.
# shellcheck disable=SC1090
@ -513,7 +510,13 @@ EOS
if ! git fetch --tags --force "${QUIET_ARGS[@]}" origin \
"refs/heads/$UPSTREAM_BRANCH_DIR:refs/remotes/origin/$UPSTREAM_BRANCH_DIR"
then
echo "Fetching $DIR failed!" >>"$update_failed_file"
if [[ "$UPSTREAM_SHA_HTTP_CODE" = "404" ]]
then
TAP="${DIR#$HOMEBREW_LIBRARY/Taps/}"
echo "$TAP does not exist! Run 'brew untap $TAP'" >>"$update_failed_file"
else
echo "Fetching $DIR failed!" >>"$update_failed_file"
fi
fi
fi
) &

View File

@ -1,41 +1,62 @@
#: * `upgrade` [<install-options>] [`--fetch-HEAD`] [`--ignore-pinned`] [`--display-times`] [<formulae>]:
#: Upgrade outdated, unpinned brews (with existing install options).
#:
#: Options for the `install` command are also valid here.
#:
#: 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 `--ignore-pinned` is passed, set a 0 exit code even if pinned formulae
#: are not upgraded.
#:
#: If `--display-times` is passed, install times for each formula are printed
#: at the end of the run.
#:
#: If <formulae> are given, upgrade only the specified brews (unless they
#: are pinned; see `pin`, `unpin`).
require "install"
require "reinstall"
require "formula_installer"
require "development_tools"
require "messages"
require "cleanup"
require "cli_parser"
module Homebrew
module_function
def upgrade
# TODO: deprecate for next minor release.
if ARGV.include?("--cleanup")
ENV["HOMEBREW_INSTALL_CLEANUP"] = "1"
odeprecated("'brew upgrade --cleanup'", "'HOMEBREW_INSTALL_CLEANUP'")
elsif ENV["HOMEBREW_UPGRADE_CLEANUP"]
ENV["HOMEBREW_INSTALL_CLEANUP"] = "1"
odeprecated("'HOMEBREW_UPGRADE_CLEANUP'", "'HOMEBREW_INSTALL_CLEANUP'")
def upgrade_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`upgrade` [<options>] <formula>
Upgrade outdated, unpinned brews (with existing and any appended install options).
If <formula> are given, upgrade only the specified brews (unless they
are pinned; see `pin`, `unpin`).
Unless `HOMEBREW_NO_INSTALL_CLEANUP` is set, `brew cleanup` will be run for the upgraded formulae or, every 30 days, for all formulae.
EOS
switch :debug,
description: "If brewing fails, open an interactive debugging session with access to IRB "\
"or a shell inside the temporary build directory"
switch "-s", "--build-from-source",
description: "Compile <formula> from source even if a bottle is available."
switch "--force-bottle",
description: "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."
switch "--fetch-HEAD",
description: "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 development version has been released."
switch "--ignore-pinned",
description: "Set a 0 exit code even if pinned formulae are not upgraded."
switch "--keep-tmp",
description: "Don't delete the temporary files created during installation."
switch :force,
description: "Install without checking for previously installed keg-only or "\
"non-migrated versions."
switch :verbose,
description: "Print the verification and postinstall steps."
switch "--display-times",
description: "Print install times for each formula at the end of the run."
conflicts "--build-from-source", "--force-bottle"
formula_options
end
end
def upgrade
if ARGV.include?("--cleanup")
odisabled("'brew upgrade --cleanup'")
elsif ENV["HOMEBREW_UPGRADE_CLEANUP"]
odisabled("'HOMEBREW_UPGRADE_CLEANUP'")
end
upgrade_args.parse
FormulaInstaller.prevent_build_flags unless DevelopmentTools.installed?
@ -43,13 +64,13 @@ module Homebrew
if ARGV.named.empty?
outdated = Formula.installed.select do |f|
f.outdated?(fetch_head: ARGV.fetch_head?)
f.outdated?(fetch_head: args.fetch_HEAD?)
end
exit 0 if outdated.empty?
else
outdated = ARGV.resolved_formulae.select do |f|
f.outdated?(fetch_head: ARGV.fetch_head?)
f.outdated?(fetch_head: args.fetch_HEAD?)
end
(ARGV.resolved_formulae - outdated).each do |f|
@ -68,7 +89,7 @@ module Homebrew
outdated -= pinned
formulae_to_install = outdated.map(&:latest_formula)
if !pinned.empty? && !ARGV.include?("--ignore-pinned")
if !pinned.empty? && !args.ignore_pinned?
ofail "Not upgrading #{pinned.count} pinned #{"package".pluralize(pinned.count)}:"
puts pinned.map { |f| "#{f.full_specified_name} #{f.pkg_version}" } * ", "
end
@ -147,7 +168,7 @@ module Homebrew
fi = FormulaInstaller.new(f)
fi.options = options
fi.build_bottle = ARGV.build_bottle? || (!f.bottle_defined? && f.build.bottle?)
fi.build_bottle = args.build_bottle? || (!f.bottle_defined? && f.build.bottle?)
fi.installed_on_request = !ARGV.named.empty?
fi.link_keg ||= keg_was_linked if keg_had_linked_opt
if tab
@ -206,7 +227,7 @@ module Homebrew
next if formulae_to_upgrade.include?(f)
next if formulae_pinned.include?(f)
if f.outdated?(fetch_head: ARGV.fetch_head?)
if f.outdated?(fetch_head: args.fetch_HEAD?)
if f.pinned?
formulae_pinned << f
else
@ -250,7 +271,7 @@ module Homebrew
checker = LinkageChecker.new(keg, cache_db: db)
if checker.broken_library_linkage?
if f.outdated?(fetch_head: ARGV.fetch_head?)
if f.outdated?(fetch_head: args.fetch_HEAD?)
# Outdated formulae = pinned formulae (see function above)
formulae_pinned_and_outdated << f
else
@ -298,7 +319,7 @@ module Homebrew
return if kegs.empty?
oh1 "Checking dependents for outdated formulae" if ARGV.verbose?
oh1 "Checking dependents for outdated formulae" if args.verbose?
upgradable, pinned = upgradable_dependents(kegs, formulae).map(&:to_a)
upgradable.sort! { |a, b| depends_on(a, b) }
@ -313,7 +334,7 @@ module Homebrew
# Print the upgradable dependents.
if upgradable.empty?
ohai "No dependents to upgrade" if ARGV.verbose?
ohai "No dependents to upgrade" if args.verbose?
else
ohai "Upgrading #{upgradable.count} #{"dependent".pluralize(upgradable.count)}:"
formulae_upgrades = upgradable.map do |f|
@ -331,7 +352,7 @@ module Homebrew
# Assess the dependents tree again.
kegs = formulae_with_runtime_dependencies
oh1 "Checking dependents for broken library links" if ARGV.verbose?
oh1 "Checking dependents for broken library links" if args.verbose?
reinstallable, pinned = broken_dependents(kegs, formulae).map(&:to_a)
reinstallable.sort! { |a, b| depends_on(a, b) }
@ -346,7 +367,7 @@ module Homebrew
# Print the broken dependents.
if reinstallable.empty?
ohai "No broken dependents to reinstall" if ARGV.verbose?
ohai "No broken dependents to reinstall" if args.verbose?
else
ohai "Reinstalling #{reinstallable.count} broken #{"dependent".pluralize(reinstallable.count)} from source:"
puts reinstallable.map(&:full_specified_name).join(", ")

View File

@ -1,23 +1,3 @@
#: * `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>.
#:
#: Use `--recursive` to resolve more than one level of dependencies.
#:
#: If `--installed` is passed, only list installed formulae.
#:
#: By default, `uses` shows all formulae that specify <formulae> as a required
#: or recommended dependency. To include the `:build` type dependencies, pass
#: `--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 usage of <formulae> by stable builds. To find
#: cases where <formulae> is used by development or HEAD build, pass
#: `--devel` or `--HEAD`.
require "formula"
require "cli_parser"
@ -31,34 +11,35 @@ module Homebrew
def uses_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`uses` [<options>] <formulae>
`uses` [<options>] <formula>
Show the formulae that specify <formulae> as a dependency. When given
Show the formulae that specify <formula> as a dependency. When given
multiple formula arguments, show the intersection of formulae that use
<formulae>.
<formula>.
By default, `uses` shows all formulae that specify <formulae> as a required
By default, `uses` shows all formulae that specify <formula> as a required
or recommended dependency.
By default, `uses` shows usage of <formulae> by stable builds.
By default, `uses` shows usage of <formula> by stable builds.
EOS
switch "--recursive",
description: "Resolve more than one level of dependencies."
switch "--installed",
description: "Only list installed formulae."
switch "--include-build",
description: "Include all formulae that specify <formulae> as `:build` type dependency."
description: "Include all formulae that specify <formula> as `:build` type dependency."
switch "--include-test",
description: "Include all formulae that specify <formulae> as `:test` type dependency."
description: "Include all formulae that specify <formula> as `:test` type dependency."
switch "--include-optional",
description: "Include all formulae that specify <formulae> as `:optional` type dependency."
description: "Include all formulae that specify <formula> as `:optional` type dependency."
switch "--skip-recommended",
description: "Skip all formulae that specify <formulae> as `:recommended` type dependency."
description: "Skip all formulae that specify <formula> as `:recommended` type dependency."
switch "--devel",
description: "Show usage of <formulae> by development build."
description: "Show usage of <formula> by development build."
switch "--HEAD",
description: "Show usage of <formulae> by HEAD build."
description: "Show usage of <formula> by HEAD build."
switch :debug
conflicts "--devel", "--HEAD"
end
end

View File

@ -1,6 +1,7 @@
#: @hide_from_man_page
#: * `vendor-install` [<target>]:
#: Install vendor version of Homebrew dependencies.
#: * `vendor-install` [<target>]
#:
#: Install Homebrew's portable Ruby.
# Don't need shellcheck to follow this `source`.
# shellcheck disable=SC1090
@ -16,9 +17,9 @@ if [[ -n "$HOMEBREW_MACOS" ]]
then
if [[ "$HOMEBREW_PROCESSOR" = "Intel" ]]
then
ruby_URL="$HOMEBREW_BOTTLE_DOMAIN/bottles-portable-ruby/portable-ruby-2.3.7.leopard_64.bottle.tar.gz"
ruby_URL2="https://github.com/Homebrew/homebrew-portable-ruby/releases/download/2.3.7/portable-ruby-2.3.7.leopard_64.bottle.tar.gz"
ruby_SHA="033ac518bb14abdb1bb47d968dc9e967c3ae2035499383a21a79b49d523065d1"
ruby_URL="$HOMEBREW_BOTTLE_DOMAIN/bottles-portable-ruby/portable-ruby-2.3.7.mavericks.bottle.tar.gz"
ruby_URL2="https://github.com/Homebrew/homebrew-portable-ruby/releases/download/2.3.7/portable-ruby-2.3.7.mavericks.bottle.tar.gz"
ruby_SHA="539ae571968fc74d4ec3a839cb33edc5786c219a5e6ae7fb6a09ec5fc1b04e4e"
fi
elif [[ -n "$HOMEBREW_LINUX" ]]
then

View File

@ -1,8 +1,2 @@
require "compat/extend/os/mac/utils/bottles"
require "compat/os/mac"
require "compat/requirements/x11_requirement"
require "compat/requirements/xcode_requirement"
require "compat/cask"
require "compat/download_strategy"
require "compat/formula"
require "compat/tap"

View File

@ -1,21 +0,0 @@
require "compat/cask/cache"
require "compat/cask/cask_loader"
require "compat/cask/caskroom"
require "compat/cask/dsl"
module Cask
class << self
module Compat
def init
Cache.delete_legacy_cache
Caskroom.migrate_caskroom_from_repo_to_prefix
Caskroom.migrate_legacy_caskroom
super
end
end
prepend Compat
end
end

View File

@ -1,17 +0,0 @@
module Cask
module Cache
class << self
module Compat
def delete_legacy_cache
legacy_cache = HOMEBREW_CACHE.join("Casks")
return unless legacy_cache.exist?
ohai "Deleting legacy cache at #{legacy_cache}"
FileUtils.remove_entry_secure(legacy_cache)
end
end
prepend Compat
end
end
end

View File

@ -1,24 +0,0 @@
module Cask
module CaskLoader
class FromContentLoader; end
class FromPathLoader < FromContentLoader
module Compat
private
# TODO: can't delete this code until the merge of
# https://github.com/Homebrew/brew/pull/4730 or an equivalent.
def cask(header_token, **options, &block)
if header_token.is_a?(Hash) && header_token.key?(:v1)
odisabled %q("cask :v1 => 'token'"), %q("cask 'token'")
header_token = header_token[:v1]
end
super(header_token, **options, &block)
end
end
prepend Compat
end
end
end

View File

@ -1,49 +0,0 @@
module Cask
module Caskroom
class << self
module Compat
def migrate_legacy_caskroom
return if path.exist?
legacy_caskroom_path = Pathname.new("/opt/homebrew-cask/Caskroom")
return if path == legacy_caskroom_path
return unless legacy_caskroom_path.exist?
return if legacy_caskroom_path.symlink?
ohai "Migrating Caskroom from #{legacy_caskroom_path} to #{path}."
if path.parent.writable?
FileUtils.mv legacy_caskroom_path, path
else
opoo "#{path.parent} is not writable, sudo is needed to move the Caskroom."
SystemCommand.run("/bin/mv", args: [legacy_caskroom_path, path.parent], sudo: true)
end
ohai "Creating symlink from #{path} to #{legacy_caskroom_path}."
if legacy_caskroom_path.parent.writable?
FileUtils.ln_s path, legacy_caskroom_path
else
opoo "#{legacy_caskroom_path.parent} is not writable, sudo is needed to link the Caskroom."
SystemCommand.run("/bin/ln", args: ["-s", path, legacy_caskroom_path], sudo: true)
end
end
def migrate_caskroom_from_repo_to_prefix
repo_caskroom_path = HOMEBREW_REPOSITORY.join("Caskroom")
return if path.exist?
return unless repo_caskroom_path.directory?
ohai "Moving Caskroom from HOMEBREW_REPOSITORY to HOMEBREW_PREFIX"
if path.parent.writable?
FileUtils.mv repo_caskroom_path, path
else
opoo "#{path.parent} is not writable, sudo is needed to move the Caskroom."
SystemCommand.run("/bin/mv", args: [repo_caskroom_path, path.parent], sudo: true)
end
end
end
prepend Compat
end
end
end

View File

@ -1,22 +0,0 @@
module Cask
class DSL
module Compat
# TODO: can't delete this code until the merge of
# https://github.com/Homebrew/brew/pull/4730 or an equivalent.
def gpg(*)
odisabled "the `gpg` stanza"
end
def license(*)
odisabled "the `license` stanza"
end
def accessibility_access(*)
odisabled "the `accessibility_access` stanza"
end
end
prepend Compat
end
end

View File

@ -1,256 +0,0 @@
require "download_strategy"
# S3DownloadStrategy downloads tarballs from AWS S3.
# To use it, add `:using => :s3` to the URL section of your
# formula. This download strategy uses AWS access tokens (in the
# environment variables `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`)
# to sign the request. This strategy is good in a corporate setting,
# because it lets you use a private S3 bucket as a repo for internal
# distribution. (It will work for public buckets as well.)
class S3DownloadStrategy < CurlDownloadStrategy
def initialize(url, name, version, **meta)
odisabled("S3DownloadStrategy",
"a vendored S3DownloadStrategy in your own formula or tap (using require_relative)")
super
end
def _fetch(url:, resolved_url:)
if url !~ %r{^https?://([^.].*)\.s3\.amazonaws\.com/(.+)$} &&
url !~ %r{^s3://([^.].*?)/(.+)$}
raise "Bad S3 URL: " + url
end
bucket = Regexp.last_match(1)
key = Regexp.last_match(2)
ENV["AWS_ACCESS_KEY_ID"] = ENV["HOMEBREW_AWS_ACCESS_KEY_ID"]
ENV["AWS_SECRET_ACCESS_KEY"] = ENV["HOMEBREW_AWS_SECRET_ACCESS_KEY"]
begin
require "aws-sdk-s3"
rescue LoadError
Homebrew.install_gem! "aws-sdk-s3", "~> 1.8"
require "aws-sdk-s3"
end
begin
signer = Aws::S3::Presigner.new
s3url = signer.presigned_url :get_object, bucket: bucket, key: key
rescue Aws::Sigv4::Errors::MissingCredentialsError
ohai "AWS credentials missing, trying public URL instead."
s3url = url
end
curl_download s3url, to: temporary_path
end
end
# GitHubPrivateRepositoryDownloadStrategy downloads contents from GitHub
# Private Repository. To use it, add
# `:using => :github_private_repo` 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 GitHub 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(url, name, version, **meta)
odisabled("GitHubPrivateRepositoryDownloadStrategy",
"a vendored GitHubPrivateRepositoryDownloadStrategy in your own formula or tap (using require_relative)")
super
parse_url_pattern
set_github_token
end
def parse_url_pattern
unless match = url.match(%r{https://github.com/([^/]+)/([^/]+)/(\S+)})
raise CurlDownloadStrategyError, "Invalid url pattern for GitHub Repository."
end
_, @owner, @repo, @filepath = *match
end
def download_url
"https://#{@github_token}@github.com/#{@owner}/#{@repo}/#{@filepath}"
end
private
def _fetch(url:, resolved_url:)
curl_download download_url, to: temporary_path
end
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
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 => :github_private_release` 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 initialize(url, name, version, **meta)
odisabled("GitHubPrivateRepositoryReleaseDownloadStrategy",
"a vendored GitHubPrivateRepositoryReleaseDownloadStrategy in your own formula or tap (using require_relative)")
super
end
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
private
def _fetch(url:, resolved_url:)
# HTTP request header `Accept: application/octet-stream` is required.
# Without this, the GitHub API will respond with metadata, not binary.
curl_download download_url, "--header", "Accept: application/octet-stream", to: temporary_path
end
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_api(release_url)
end
end
# ScpDownloadStrategy downloads files using ssh via scp. To use it, add
# `:using => :scp` to the URL section of your formula or
# provide a URL starting with scp://. This strategy uses ssh credentials for
# authentication. If a public/private keypair is configured, it will not
# prompt for a password.
#
# @example
# class Abc < Formula
# url "scp://example.com/src/abc.1.0.tar.gz"
# ...
class ScpDownloadStrategy < AbstractFileDownloadStrategy
def initialize(url, name, version, **meta)
odisabled("ScpDownloadStrategy",
"a vendored ScpDownloadStrategy in your own formula or tap (using require_relative)")
super
parse_url_pattern
end
def parse_url_pattern
url_pattern = %r{scp://([^@]+@)?([^@:/]+)(:\d+)?/(\S+)}
if @url !~ url_pattern
raise ScpDownloadStrategyError, "Invalid URL for scp: #{@url}"
end
_, @user, @host, @port, @path = *@url.match(url_pattern)
end
def fetch
ohai "Downloading #{@url}"
if cached_location.exist?
puts "Already downloaded: #{cached_location}"
else
system_command! "scp", args: [scp_source, temporary_path.to_s]
ignore_interrupts { temporary_path.rename(cached_location) }
end
end
def clear_cache
super
rm_rf(temporary_path)
end
private
def scp_source
path_prefix = "/" unless @path.start_with?("~")
port_arg = "-P #{@port[1..-1]} " if @port
"#{port_arg}#{@user}#{@host}:#{path_prefix}#{@path}"
end
end
class DownloadStrategyDetector
class << self
module Compat
def detect_from_url(url)
case url
when %r{^s3://}
odisabled("s3://",
"a vendored S3DownloadStrategy in your own formula or tap (using require_relative)")
S3DownloadStrategy
when %r{^scp://}
odisabled("scp://",
"a vendored ScpDownloadStrategy in your own formula or tap (using require_relative)")
ScpDownloadStrategy
else
super(url)
end
end
def detect_from_symbol(symbol)
case symbol
when :github_private_repo
odisabled(":github_private_repo",
"a vendored GitHubPrivateRepositoryDownloadStrategy in your own formula or tap (using require_relative)")
GitHubPrivateRepositoryDownloadStrategy
when :github_private_release
odisabled(":github_private_repo",
"a vendored GitHubPrivateRepositoryReleaseDownloadStrategy in your own formula or tap "\
"(using require_relative)")
GitHubPrivateRepositoryReleaseDownloadStrategy
when :s3
odisabled(":s3",
"a vendored S3DownloadStrategy in your own formula or tap (using require_relative)")
S3DownloadStrategy
when :scp
odisabled(":scp",
"a vendored ScpDownloadStrategy in your own formula or tap (using require_relative)")
ScpDownloadStrategy
else
super(symbol)
end
end
end
prepend Compat
end
end

View File

@ -1,19 +0,0 @@
module Utils
class Bottles
class Collector
module Compat
private
def tag_without_or_later(tag)
return super unless tag.to_s.end_with?("_or_later")
odisabled "`or_later` bottles",
"bottles without `or_later` (or_later is implied now)"
tag.to_s[/(\w+)_or_later$/, 1].to_sym
end
end
prepend Compat
end
end
end

View File

@ -2,40 +2,15 @@ class Formula
module Compat
# Run `scons` using a Homebrew-installed version rather than whatever is
# in the `PATH`.
# TODO: deprecate
def scons(*args)
odeprecated("scons", 'system "scons"')
system Formulary.factory("scons").opt_bin/"scons", *args
def scons(*)
odisabled("scons", 'system "scons"')
end
# Run `make` 3.81 or newer.
# Uses the system make on Leopard and newer, and the
# path to the actually-installed make on Tiger or older.
# TODO: deprecate
def make(*args)
odeprecated("make", 'system "make"')
if Utils.popen_read("/usr/bin/make", "--version")
.match(/Make (\d\.\d+)/)[1] > "3.80"
make_path = "/usr/bin/make"
else
make = Formula["make"].opt_bin/"make"
make_path = if make.exist?
make.to_s
else
(Formula["make"].opt_bin/"gmake").to_s
end
end
if superenv?
make_name = File.basename(make_path)
with_env(HOMEBREW_MAKE: make_name) do
system "make", *args
end
else
system make_path, *args
end
def make(*)
odisabled("make", 'system "make"')
end
end

View File

@ -3,7 +3,7 @@ module OS
class << self
module Compat
def prefer_64_bit?
odeprecated("MacOS.prefer_64_bit?")
odisabled("MacOS.prefer_64_bit?")
Hardware::CPU.is_64_bit?
end
end

View File

@ -1,15 +0,0 @@
require "requirement"
class X11Requirement < Requirement
module Compat
def initialize(tags = [])
if tags.first.to_s.match?(/(\d\.)+\d/)
odisabled('depends_on :x11 => "X.Y.Z"')
end
super(tags)
end
end
prepend Compat
end

View File

@ -1,21 +0,0 @@
require "requirement"
class XcodeRequirement < Requirement
module Compat
def initialize(tags = [])
@version = if tags.first.to_s.match?(/(\d\.)+\d/)
tags.shift
else
tags.find do |tag|
next unless tag.to_s.match?(/(\d\.)+\d/)
odisabled('depends_on :xcode => [..., "X.Y.Z"]')
tags.delete(tag)
end
end
super(tags)
end
end
prepend Compat
end

View File

@ -1,47 +0,0 @@
class Tap
module Compat
def initialize(user, repo)
super
return unless user == "caskroom"
old_initial_revision_var = "HOMEBREW_UPDATE_BEFORE#{repo_var}"
old_current_revision_var = "HOMEBREW_UPDATE_AFTER#{repo_var}"
new_user = "Homebrew"
new_repo = (repo == "cask") ? repo : "cask-#{repo}"
old_name = name
old_path = path
old_remote = path.git_origin
clear_cache
super(new_user, new_repo)
return unless old_path.directory?
new_initial_revision_var = "HOMEBREW_UPDATE_BEFORE#{repo_var}"
new_current_revision_var = "HOMEBREW_UPDATE_AFTER#{repo_var}"
ENV[new_initial_revision_var] ||= ENV[old_initial_revision_var]
ENV[new_current_revision_var] ||= ENV[old_current_revision_var]
new_name = name
new_path = path
new_remote = default_remote
ohai "Migrating tap #{old_name} to #{new_name}..." if $stdout.tty?
if old_path.git?
puts "Changing remote from #{old_remote} to #{new_remote}..." if $stdout.tty?
old_path.git_origin = new_remote
end
puts "Moving #{old_path} to #{new_path}..." if $stdout.tty?
path.dirname.mkpath
FileUtils.mv old_path, new_path
end
end
prepend Compat
end

View File

@ -4,7 +4,6 @@ module CompilerConstants
GNU_GCC_REGEXP = /^gcc-(4\.9|[5-8])$/.freeze
COMPILER_SYMBOL_MAP = {
"gcc" => :gcc,
"gcc-4.2" => :gcc_4_2,
"clang" => :clang,
"llvm_clang" => :llvm_clang,
}.freeze
@ -19,9 +18,11 @@ class CompilerFailure
def version(val = nil)
if val
@version = Version.parse(val.to_s)
else
@version
if name.to_s == "clang" && val.to_i < 600
odisabled "'fails_with :clang' with 'build' < 600"
end
end
@version
end
# Allows Apple compiler `fails_with` statements to keep using `build`
@ -66,14 +67,6 @@ class CompilerFailure
end
COLLECTIONS = {
cxx11: [
create(:gcc_4_2),
create(:clang) { build 425 },
],
cxx14: [
create(:clang) { build 600 },
create(:gcc_4_2),
],
openmp: [
create(:clang),
],
@ -86,9 +79,8 @@ class CompilerSelector
Compiler = Struct.new(:name, :version)
COMPILER_PRIORITY = {
clang: [:clang, :gcc_4_2, :gnu, :llvm_clang],
gcc_4_2: [:gcc_4_2, :gnu, :clang],
gcc: [:gnu, :gcc, :llvm_clang, :clang, :gcc_4_2],
clang: [:clang, :gnu, :llvm_clang],
gcc: [:gnu, :gcc, :llvm_clang, :clang],
}.freeze
def self.select_for(formula, compilers = self.compilers)

View File

@ -1,40 +1,3 @@
#: * `audit` [`--strict`] [`--fix`] [`--online`] [`--new-formula`] [`--display-cop-names`] [`--display-filename`] [`--only=`<method>|`--except=`<method>] [`--only-cops=`<cops>|`--except-cops=`<cops>] [<formulae>]:
#: Check <formulae> for Homebrew coding style violations. This should be run
#: before submitting a new formula. Will exit with a non-zero status if any errors
#: are found, which can be useful for implementing pre-commit hooks.
#:
#: If no <formulae> are provided, all of them are checked.
#:
#: If `--strict` is passed, additional checks are run, including RuboCop
#: style checks.
#:
#: If `--fix` is passed, style violations will be
#: automatically fixed using RuboCop's auto-correct feature.
#:
#: If `--online` is passed, additional slower checks that require a network
#: connection are run.
#:
#: If `--new-formula` is passed, various additional checks are run that check
#: if a new formula is eligible for Homebrew. This should be used when creating
#: new formulae and implies `--strict` and `--online`.
#:
#: If `--display-cop-names` is passed, the RuboCop cop name for each violation
#: is included in the output.
#:
#: If `--display-filename` is passed, every line of output is prefixed with the
#: name of the file or formula being audited, to make the output easy to grep.
#:
#: Specifying `--only=`<method> will run only the methods named `audit_`<method>,
#: while `--except=`<method> will skip the methods named `audit_`<method>.
#: For either option <method> should be a comma-separated list.
#:
#: Specifying `--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.
# Undocumented options:
# `-D` activates debugging and profiling of the audit methods (not the same as `--debug`)
require "formula"
require "formula_versions"
require "utils/curl"
@ -53,12 +16,12 @@ module Homebrew
def audit_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`audit` [<options>] <formulae>
`audit` [<options>] <formula>
Check <formulae> for Homebrew coding style violations. This should be run before
Check <formula> for Homebrew coding style violations. This should be run before
submitting a new formula. Will exit with a non-zero status if any errors are
found, which can be useful for implementing pre-commit hooks.
If no <formulae> are provided, all of them are checked.
If no <formula> are provided, all of them are checked.
EOS
switch "--strict",
description: "Run additional style checks, including RuboCop style checks."
@ -202,7 +165,7 @@ module Homebrew
end
def format_problem_lines(problems)
problems.map { |p| "* #{p.chomp.gsub("\n", "\n ")}" }
problems.uniq.map { |p| "* #{p.chomp.gsub("\n", "\n ")}" }
end
class FormulaText
@ -405,7 +368,6 @@ module Homebrew
@specs.each do |spec|
# Check for things we don't like to depend on.
# We allow non-Homebrew installs whenever possible.
options_message = "Formulae should not have optional or recommended dependencies"
spec.deps.each do |dep|
begin
dep_f = dep.to_formula
@ -434,7 +396,7 @@ module Homebrew
if @new_formula && dep_f.keg_only_reason &&
!["openssl", "apr", "apr-util"].include?(dep.name) &&
(!["openblas"].include?(dep.name) || @core_tap) &&
!["openblas"].include?(dep.name) &&
dep_f.keg_only_reason.reason == :provided_by_macos
new_formula_problem(
"Dependency '#{dep.name}' may be unnecessary as it is provided " \
@ -443,6 +405,7 @@ module Homebrew
end
dep.options.each do |opt|
next if @core_tap
next if dep_f.option_defined?(opt)
next if dep_f.requirements.find do |r|
if r.recommended?
@ -463,19 +426,17 @@ module Homebrew
problem "Dependency '#{dep.name}' is marked as :run. Remove :run; it is a no-op."
end
next unless @new_formula
next unless @core_tap
if dep.tags.include?(:recommended) || dep.tags.include?(:optional)
new_formula_problem options_message
problem "Formulae should not have optional or recommended dependencies"
end
end
next unless @new_formula
next unless @core_tap
if spec.requirements.map(&:recommended?).any? || spec.requirements.map(&:optional?).any?
new_formula_problem options_message
problem "Formulae should not have optional or recommended requirements"
end
end
end
@ -529,6 +490,8 @@ module Homebrew
def audit_postgresql
return unless formula.name == "postgresql"
return unless @core_tap
major_version = formula.version
.to_s
.split(".")
@ -602,20 +565,16 @@ module Homebrew
return unless formula.bottle_disabled?
return if formula.bottle_unneeded?
if !formula.bottle_disable_reason.valid?
unless formula.bottle_disable_reason.valid?
problem "Unrecognized bottle modifier"
else
bottle_disabled_whitelist = %w[
cryptopp
leafnode
]
return if bottle_disabled_whitelist.include?(formula.name)
problem "Formulae should not use `bottle :disabled`" if @core_tap
end
return unless @core_tap
problem "Formulae should not use `bottle :disabled`"
end
def audit_github_repository
return unless @core_tap
return unless @online
return unless @new_formula
@ -635,8 +594,7 @@ module Homebrew
return if metadata.nil?
new_formula_problem "GitHub fork (not canonical repository)" if metadata["fork"]
if @core_tap &&
(metadata["forks_count"] < 30) && (metadata["subscribers_count"] < 30) &&
if (metadata["forks_count"] < 30) && (metadata["subscribers_count"] < 30) &&
(metadata["stargazers_count"] < 75)
new_formula_problem "GitHub repository not notable enough (<30 forks, <30 watchers and <75 stars)"
end
@ -647,13 +605,8 @@ module Homebrew
end
def audit_specs
if head_only?(formula) && formula.tap.to_s.downcase !~ %r{[-/]head-only$}
problem "Head-only (no stable download)"
end
if devel_only?(formula) && formula.tap.to_s.downcase !~ %r{[-/]devel-only$}
problem "Devel-only (no stable download)"
end
problem "Head-only (no stable download)" if head_only?(formula)
problem "Devel-only (no stable download)" if devel_only?(formula)
%w[Stable Devel HEAD].each do |name|
spec_name = name.downcase.to_sym
@ -698,11 +651,11 @@ module Homebrew
end
end
if @core_tap && formula.devel
problem "Formulae should not have a `devel` spec"
end
return unless @core_tap
if @core_tap && formula.head
problem "Formulae should not have a `devel` spec" if formula.devel
if formula.head
head_spec_message = "Formulae should not have a `HEAD` spec"
if @new_formula
new_formula_problem head_spec_message
@ -922,10 +875,6 @@ module Homebrew
return unless @strict
if @core_tap && line.include?("env :std")
problem "`env :std` in `core` formulae is deprecated"
end
if line.include?("env :userpaths")
problem "`env :userpaths` in formulae is deprecated"
end
@ -944,13 +893,18 @@ module Homebrew
problem "Use \#{pkgshare} instead of \#{share}/#{formula.name}"
end
if line =~ /depends_on .+ if build\.with(out)?\?\(?["']\w+["']\)?/
if !@core_tap && 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}\")"
return unless @core_tap
return unless line.include?("env :std")
problem "`env :std` in `core` formulae is deprecated"
end
def audit_reverse_migration
@ -1131,20 +1085,9 @@ module Homebrew
end
def audit_urls
urls = [url] + mirrors
curl_openssl_or_deps = ResourceAuditor.curl_openssl_and_deps.include?(owner.name)
if spec_name == :stable && curl_openssl_or_deps
problem "should not use xz tarballs" if url.end_with?(".xz")
unless urls.find { |u| u.start_with?("http://") }
problem "should always include at least one HTTP mirror"
end
end
return unless @online
urls = [url] + mirrors
urls.each do |url|
next if !@strict && mirrors.include?(url)
@ -1154,7 +1097,7 @@ module Homebrew
# pull request.
next if url =~ %r{^https://dl.bintray.com/homebrew/mirror/}
if http_content_problem = curl_check_http_content(url, require_http: curl_openssl_or_deps)
if http_content_problem = curl_check_http_content(url)
problem http_content_problem
end
elsif strategy <= GitDownloadStrategy

View File

@ -1,35 +1,3 @@
#: * `bottle` [`--verbose`] [`--no-rebuild`|`--keep-old`] [`--skip-relocation`] [`--or-later`] [`--root-url=`<URL>] [`--force-core-tap`] [`--json`] <formulae>:
#: Generate a bottle (binary package) from a formula that was installed with
#: `--build-bottle`.
#:
#: If the formula specifies a rebuild version, it will be incremented in the
#: generated DSL. Passing `--keep-old` will attempt to keep it at its original
#: value, while `--no-rebuild` will remove it.
#:
#: If `--verbose` (or `-v`) is passed, print the bottling commands and any warnings
#: encountered.
#:
#: If `--skip-relocation` is passed, do not check if the bottle can be marked
#: as relocatable.
#:
#: If `--root-url` is passed, use the specified <URL> as the root of the
#: bottle's URL instead of Homebrew's default.
#:
#: If `--or-later` is passed, append `_or_later` to the bottle tag.
#:
#: If `--force-core-tap` is passed, build a bottle even if <formula> is not
#: in homebrew/core or any installed taps.
#:
#: If `--json` is passed, write bottle information to a JSON file, which can
#: be used as the argument for `--merge`.
#:
#: * `bottle` `--merge` [`--keep-old`] [`--write` [`--no-commit`]] <bottle_json_files>:
#: Generate a bottle from a `--json` output file and print the new DSL merged
#: into the existing formula.
#:
#: If `--write` is passed, write the changes to the formula file. A new
#: commit will then be generated unless `--no-commit` is passed.
require "formula"
require "utils/bottles"
require "tab"
@ -72,7 +40,7 @@ module Homebrew
def bottle_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`bottle` [<options>] <formulae>
`bottle` [<options>] <formula>
Generate a bottle (binary package) from a formula that was installed with
`--build-bottle`.
@ -365,6 +333,7 @@ module Homebrew
relocatable = false if keg_contain_absolute_symlink_starting_with?(prefix, keg)
relocatable = false if keg_contain?("#{prefix}/etc", keg, ignores)
relocatable = false if keg_contain?("#{prefix}/var", keg, ignores)
relocatable = false if keg_contain?("#{prefix}/share/vim", keg, ignores)
end
skip_relocation = relocatable && !keg.require_relocation?
end

View File

@ -1,46 +1,3 @@
#: * `bump-formula-pr` [`--devel`] [`--dry-run` [`--write`]] [`--no-audit`|`--strict`] [`--no-browse] [`--mirror=`<URL>] [`--version=`<version>] [`--message=`<message>] (`--url=`<URL> `--sha256=`<SHA-256>|`--tag=`<tag> `--revision=`<revision>) [<formula>]:
#: Create a pull request to update a formula with a new URL or a new tag.
#:
#: If a <URL> is specified, the <SHA-256> checksum of the new download should
#: also be specified. A best effort to determine the <SHA-256> and <formula>
#: name will be made if either or both values are not supplied by the user.
#:
#: If a <tag> is specified, the Git commit <revision> corresponding to that
#: tag must also be specified.
#:
#: If `--devel` is passed, bump the development rather than stable version.
#: The development spec must already exist.
#:
#: If `--dry-run` is passed, print what would be done rather than doing it.
#:
#: If `--write` is passed along with `--dry-run`, perform a not-so-dry run by
#: making the expected file modifications but not taking any Git actions.
#:
#: If `--no-audit` is passed, don't run `brew audit` before opening the PR.
#:
#: If `--strict` is passed, run `brew audit --strict` before opening the PR.
#:
#: If `--mirror=`<URL> is passed, use the value as a mirror URL.
#:
#: If `--version=`<version> is passed, use the value to override the value
#: parsed from the URL or tag. Note that `--version=0` can be used to delete
#: an existing version override from a formula if it has become redundant.
#:
#: If `--message=`<message> is passed, append <message> to the default PR
#: message.
#:
#: If `--no-browse` is passed, don't pass the `--browse` argument to `hub`
#: which opens the pull request URL in a browser. Instead, output it to the
#: command line.
#:
#: If `--quiet` is passed, don't output replacement messages or warn about
#: duplicate pull requests.
#:
#: *Note:* this command cannot be used to transition a formula from a
#: URL-and-SHA-256 style specification into a tag-and-revision style
#: specification, nor vice versa. It must use whichever style specification
#: the preexisting formula already uses.
require "formula"
require "cli_parser"
@ -104,6 +61,7 @@ module Homebrew
switch :quiet
switch :verbose
switch :debug
conflicts "--no-audit", "--strict"
conflicts "--url", "--tag"
end
end

View File

@ -1,24 +1,3 @@
#: * `create` [`--autotools`|`--cmake`|`--meson`] [`--no-fetch`] [`--set-name` <name>] [`--set-version` <version>] [`--tap` <user>`/`<repo>] <URL>:
#: 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`
#: formula serves as a simple example. For the complete API, see:
#: <https://www.rubydoc.info/github/Homebrew/brew/master/Formula>
#:
#: 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 SHA-256 to the formula for you, nor will it check
#: the GitHub API for GitHub projects (to fill out its description and homepage).
#:
#: The options `--set-name` and `--set-version` each take an argument and allow
#: you to explicitly set the name and version of the package you are creating.
#:
#: The option `--tap` takes a tap as its argument and generates the formula in
#: the specified tap.
require "formula"
require "formula_creator"
require "missing_formula"
@ -59,6 +38,7 @@ module Homebrew
switch :force
switch :verbose
switch :debug
conflicts "--autotools", "--cmake", "--meson"
end
end

View File

@ -1,9 +1,3 @@
#: * `edit`:
#: Open the Homebrew repository for editing.
#:
#: * `edit` <formula>:
#: Open <formula> in the editor set by `EDITOR` or `HOMEBREW_EDITOR`.
require "formula"
require "cli_parser"
@ -13,7 +7,7 @@ module Homebrew
def edit_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`edit` [<formulae>]
`edit` [<formula>]
Open a formula in the editor set by `EDITOR` or `HOMEBREW_EDITOR`, or open the
Homebrew repository for editing if no <formula> is provided.

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