Merge remote-tracking branch 'origin/master' into cache-optimization
This commit is contained in:
commit
555e2a2fc8
@ -38,7 +38,7 @@ module Hbc
|
||||
|
||||
class CaskAlreadyCreatedError < AbstractCaskErrorWithToken
|
||||
def to_s
|
||||
%Q(Cask '#{token}' already exists. Run #{Formatter.identifier("brew cask cat #{token}")} to edit it.)
|
||||
%Q(Cask '#{token}' already exists. Run #{Formatter.identifier("brew cask edit #{token}")} to edit it.)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
require "optparse"
|
||||
require "ostruct"
|
||||
require "set"
|
||||
|
||||
module Homebrew
|
||||
module CLI
|
||||
@ -13,6 +14,8 @@ module Homebrew
|
||||
@parsed_args = OpenStruct.new
|
||||
# undefine tap to allow --tap argument
|
||||
@parsed_args.instance_eval { undef tap }
|
||||
@constraints = []
|
||||
@conflicts = []
|
||||
instance_eval(&block)
|
||||
end
|
||||
|
||||
@ -34,7 +37,7 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def flag(name, description: nil)
|
||||
def flag(name, description: nil, required_for: nil, depends_on: nil)
|
||||
if name.end_with? "="
|
||||
required = OptionParser::REQUIRED_ARGUMENT
|
||||
name.chomp! "="
|
||||
@ -45,10 +48,16 @@ module Homebrew
|
||||
@parser.on(name, description, required) do |option_value|
|
||||
@parsed_args[option_to_name(name)] = option_value
|
||||
end
|
||||
|
||||
set_constraints(name, required_for: required_for, depends_on: depends_on)
|
||||
end
|
||||
|
||||
def conflicts(*options)
|
||||
@conflicts << options.map { |option| option_to_name(option) }
|
||||
end
|
||||
|
||||
def option_to_name(name)
|
||||
name.sub(/\A--?/, "").tr("-", "_")
|
||||
name.sub(/\A--?/, "").tr("-", "_").delete("=")
|
||||
end
|
||||
|
||||
def option_to_description(*names)
|
||||
@ -57,6 +66,7 @@ module Homebrew
|
||||
|
||||
def parse(cmdline_args = ARGV)
|
||||
@parser.parse(cmdline_args)
|
||||
check_constraint_violations
|
||||
@parsed_args
|
||||
end
|
||||
|
||||
@ -82,6 +92,91 @@ module Homebrew
|
||||
else name
|
||||
end
|
||||
end
|
||||
|
||||
def option_passed?(name)
|
||||
@parsed_args.respond_to?(name) || @parsed_args.respond_to?("#{name}?")
|
||||
end
|
||||
|
||||
def set_constraints(name, depends_on:, required_for:)
|
||||
secondary = option_to_name(name)
|
||||
unless required_for.nil?
|
||||
primary = option_to_name(required_for)
|
||||
@constraints << [primary, secondary, :mandatory]
|
||||
end
|
||||
|
||||
return if depends_on.nil?
|
||||
primary = option_to_name(depends_on)
|
||||
@constraints << [primary, secondary, :optional]
|
||||
end
|
||||
|
||||
def check_constraints
|
||||
@constraints.each do |primary, secondary, constraint_type|
|
||||
primary_passed = option_passed?(primary)
|
||||
secondary_passed = option_passed?(secondary)
|
||||
if :mandatory.equal?(constraint_type) && primary_passed && !secondary_passed
|
||||
raise OptionConstraintError.new(primary, secondary)
|
||||
end
|
||||
if secondary_passed && !primary_passed
|
||||
raise OptionConstraintError.new(primary, secondary, missing: true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def check_conflicts
|
||||
@conflicts.each do |mutually_exclusive_options_group|
|
||||
violations = mutually_exclusive_options_group.select do |option|
|
||||
option_passed? option
|
||||
end
|
||||
raise OptionConflictError, violations if violations.length > 1
|
||||
end
|
||||
end
|
||||
|
||||
def check_invalid_constraints
|
||||
@conflicts.each do |mutually_exclusive_options_group|
|
||||
@constraints.each do |p, s|
|
||||
next unless Set[p, s].subset?(Set[*mutually_exclusive_options_group])
|
||||
raise InvalidConstraintError.new(p, s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def check_constraint_violations
|
||||
check_invalid_constraints
|
||||
check_conflicts
|
||||
check_constraints
|
||||
end
|
||||
end
|
||||
|
||||
class OptionConstraintError < RuntimeError
|
||||
def initialize(arg1, arg2, missing: false)
|
||||
if !missing
|
||||
message = <<~EOS
|
||||
`#{arg1}` and `#{arg2}` should be passed together
|
||||
EOS
|
||||
else
|
||||
message = <<~EOS
|
||||
`#{arg2}` cannot be passed without `#{arg1}`
|
||||
EOS
|
||||
end
|
||||
super message
|
||||
end
|
||||
end
|
||||
|
||||
class OptionConflictError < RuntimeError
|
||||
def initialize(args)
|
||||
args_list = args.join("` and `")
|
||||
super <<~EOS
|
||||
`#{args_list}` are mutually exclusive
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
||||
class InvalidConstraintError < RuntimeError
|
||||
def initialize(arg1, arg2)
|
||||
super <<~EOS
|
||||
`#{arg1}` and `#{arg2}` cannot be mutually exclusive and mutually dependent simultaneously
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -13,22 +13,17 @@ if [[ -n "$HOMEBREW_MACOS" ]]
|
||||
then
|
||||
if [[ "$HOMEBREW_PROCESSOR" = "Intel" ]]
|
||||
then
|
||||
ruby_URL="https://homebrew.bintray.com/bottles-portable-ruby/portable-ruby-2.3.3.leopard_64.bottle.1.tar.gz"
|
||||
ruby_URL2="https://github.com/Homebrew/homebrew-portable-ruby/releases/download/2.3.3/portable-ruby-2.3.3.leopard_64.bottle.1.tar.gz"
|
||||
ruby_SHA="34ce9e4c9c1be28db564d744165aa29291426f8a3d2ef806ba4f0b9175aedb2b"
|
||||
ruby_URL="https://homebrew.bintray.com/bottles-portable-ruby/portable-ruby-2.3.3_1.leopard_64.bottle.tar.gz"
|
||||
ruby_URL2="https://github.com/Homebrew/homebrew-portable-ruby/releases/download/2.3.3_1/portable-ruby-2.3.3_1.leopard_64.bottle.tar.gz"
|
||||
ruby_SHA="a7f8ebcae0a3d88b3f1d9fd1ff77330b64a52a4fb5cbf25e3e02bec0211cbe23"
|
||||
fi
|
||||
elif [[ -n "$HOMEBREW_LINUX" ]]
|
||||
then
|
||||
case "$HOMEBREW_PROCESSOR" in
|
||||
armv7l)
|
||||
ruby_URL="https://homebrew.bintray.com/bottles-portable-ruby/portable-ruby-2.3.3.armv7l_linux.bottle.1.tar.gz"
|
||||
ruby_URL2="https://github.com/Homebrew/homebrew-portable-ruby/releases/download/2.3.3/portable-ruby-2.3.3.armv7l_linux.bottle.1.tar.gz"
|
||||
ruby_SHA="d26affe6f6ac299557a9044b311b4066b554874fc828ebc323d2705d3f4a8249"
|
||||
;;
|
||||
x86_64)
|
||||
ruby_URL="https://homebrew.bintray.com/bottles-portable-ruby/portable-ruby-2.3.3.x86_64_linux.bottle.1.tar.gz"
|
||||
ruby_URL2="https://github.com/Homebrew/homebrew-portable-ruby/releases/download/2.3.3/portable-ruby-2.3.3.x86_64_linux.bottle.1.tar.gz"
|
||||
ruby_SHA="33643b1ca6f860d6df01686636326785763e5e81cf0cef37d8a7ab96a6ca1fa1"
|
||||
ruby_URL="https://homebrew.bintray.com/bottles-portable-ruby/portable-ruby-2.3.3_1.x86_64_linux.bottle.tar.gz"
|
||||
ruby_URL2="https://github.com/Homebrew/homebrew-portable-ruby/releases/download/2.3.3_1/portable-ruby-2.3.3.x86_64_linux.bottle.tar.gz"
|
||||
ruby_SHA="1615136f44b2b8c0106f28ef1cae95f3abb7c083a7e42300fd2a3de021601f7b"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# @private
|
||||
module CompilerConstants
|
||||
GNU_GCC_VERSIONS = %w[4.3 4.4 4.5 4.6 4.7 4.8 4.9 5 6 7].freeze
|
||||
GNU_GCC_REGEXP = /^gcc-(4\.[3-9]|[5-7])$/
|
||||
GNU_GCC_VERSIONS = %w[4.3 4.4 4.5 4.6 4.7 4.8 4.9 5 6 7 8].freeze
|
||||
GNU_GCC_REGEXP = /^gcc-(4\.[3-9]|[5-8])$/
|
||||
COMPILER_SYMBOL_MAP = {
|
||||
"gcc-4.0" => :gcc_4_0,
|
||||
"gcc-4.2" => :gcc_4_2,
|
||||
|
||||
@ -42,16 +42,304 @@
|
||||
#: the preexisting formula already uses.
|
||||
|
||||
require "formula"
|
||||
require "cli_parser"
|
||||
|
||||
module Homebrew
|
||||
module_function
|
||||
|
||||
def bump_formula_pr
|
||||
@args = Homebrew::CLI::Parser.parse do
|
||||
switch "--devel"
|
||||
switch "-n", "--dry-run"
|
||||
switch "--write"
|
||||
switch "--audit"
|
||||
switch "--strict"
|
||||
switch "--no-browse"
|
||||
switch :quiet
|
||||
switch :force
|
||||
switch :verbose
|
||||
switch :debug
|
||||
|
||||
flag "--url="
|
||||
flag "--revision="
|
||||
flag "--tag=", required_for: "--revision="
|
||||
flag "--sha256=", depends_on: "--url="
|
||||
flag "--mirror="
|
||||
flag "--version="
|
||||
flag "--message="
|
||||
|
||||
conflicts "--url", "--tag"
|
||||
end
|
||||
|
||||
# As this command is simplifying user run commands then let's just use a
|
||||
# user path, too.
|
||||
ENV["PATH"] = ENV["HOMEBREW_PATH"]
|
||||
|
||||
# Use the user's browser, too.
|
||||
ENV["BROWSER"] = ENV["HOMEBREW_BROWSER"]
|
||||
|
||||
# Setup GitHub environment variables
|
||||
%w[GITHUB_USER GITHUB_PASSWORD GITHUB_TOKEN].each do |env|
|
||||
homebrew_env = ENV["HOMEBREW_#{env}"]
|
||||
next unless homebrew_env
|
||||
next if homebrew_env.empty?
|
||||
ENV[env] = homebrew_env
|
||||
end
|
||||
|
||||
gh_api_errors = [GitHub::AuthenticationFailedError, GitHub::HTTPNotFoundError,
|
||||
GitHub::RateLimitExceededError, GitHub::Error, JSON::ParserError].freeze
|
||||
|
||||
formula = ARGV.formulae.first
|
||||
|
||||
if formula
|
||||
check_for_duplicate_pull_requests(formula)
|
||||
checked_for_duplicates = true
|
||||
end
|
||||
|
||||
new_url = @args.url
|
||||
if new_url && !formula
|
||||
# Split the new URL on / and find any formulae that have the same URL
|
||||
# except for the last component, but don't try to match any more than the
|
||||
# first five components since sometimes the last component isn't the only
|
||||
# one to change.
|
||||
new_url_split = new_url.split("/")
|
||||
maximum_url_components_to_match = 5
|
||||
components_to_match = [new_url_split.count - 1, maximum_url_components_to_match].min
|
||||
base_url = new_url_split.first(components_to_match).join("/")
|
||||
base_url = /#{Regexp.escape(base_url)}/
|
||||
is_devel = @args.devel?
|
||||
guesses = []
|
||||
Formula.each do |f|
|
||||
if is_devel && f.devel && f.devel.url && f.devel.url.match(base_url)
|
||||
guesses << f
|
||||
elsif f.stable&.url && f.stable.url.match(base_url)
|
||||
guesses << f
|
||||
end
|
||||
end
|
||||
if guesses.count == 1
|
||||
formula = guesses.shift
|
||||
elsif guesses.count > 1
|
||||
odie "Couldn't guess formula for sure: could be one of these:\n#{guesses}"
|
||||
end
|
||||
end
|
||||
odie "No formula found!" unless formula
|
||||
|
||||
check_for_duplicate_pull_requests(formula) unless checked_for_duplicates
|
||||
|
||||
requested_spec, formula_spec = if @args.devel?
|
||||
devel_message = " (devel)"
|
||||
[:devel, formula.devel]
|
||||
else
|
||||
[:stable, formula.stable]
|
||||
end
|
||||
odie "#{formula}: no #{requested_spec} specification found!" unless formula_spec
|
||||
|
||||
hash_type, old_hash = if (checksum = formula_spec.checksum)
|
||||
[checksum.hash_type, checksum.hexdigest]
|
||||
end
|
||||
|
||||
new_hash = @args[hash_type]
|
||||
new_tag = @args.tag
|
||||
new_revision = @args.revision
|
||||
new_mirror = @args.mirror
|
||||
forced_version = @args.version
|
||||
new_url_hash = if new_url && new_hash
|
||||
true
|
||||
elsif new_tag && new_revision
|
||||
false
|
||||
elsif !hash_type
|
||||
odie "#{formula}: no --tag=/--revision= arguments specified!"
|
||||
elsif !new_url
|
||||
odie "#{formula}: no --url= argument specified!"
|
||||
else
|
||||
new_mirror = case new_url
|
||||
when requested_spec != :devel && %r{.*ftp.gnu.org/gnu.*}
|
||||
new_url.sub "ftp.gnu.org/gnu", "ftpmirror.gnu.org"
|
||||
when %r{.*mirrors.ocf.berkeley.edu/debian.*}
|
||||
new_url.sub "mirrors.ocf.berkeley.edu/debian", "mirrorservice.org/sites/ftp.debian.org/debian"
|
||||
end
|
||||
resource = Resource.new { @url = new_url }
|
||||
resource.download_strategy = DownloadStrategyDetector.detect_from_url(new_url)
|
||||
resource.owner = Resource.new(formula.name)
|
||||
resource.version = forced_version if forced_version
|
||||
odie "No --version= argument specified!" unless resource.version
|
||||
resource_path = resource.fetch
|
||||
tar_file_extensions = %w[.tar .tb2 .tbz .tbz2 .tgz .tlz .txz .tZ]
|
||||
if tar_file_extensions.any? { |extension| new_url.include? extension }
|
||||
gnu_tar_gtar_path = HOMEBREW_PREFIX/"opt/gnu-tar/bin/gtar"
|
||||
gnu_tar_gtar = gnu_tar_gtar_path if gnu_tar_gtar_path.executable?
|
||||
tar = which("gtar") || gnu_tar_gtar || which("tar")
|
||||
if Utils.popen_read(tar, "-tf", resource_path) =~ %r{/.*\.}
|
||||
new_hash = resource_path.sha256
|
||||
else
|
||||
odie "#{resource_path} is not a valid tar file!"
|
||||
end
|
||||
else
|
||||
new_hash = resource_path.sha256
|
||||
end
|
||||
end
|
||||
|
||||
if @args.dry_run?
|
||||
ohai "brew update"
|
||||
else
|
||||
safe_system "brew", "update"
|
||||
end
|
||||
|
||||
old_formula_version = formula_version(formula, requested_spec)
|
||||
|
||||
replacement_pairs = []
|
||||
if requested_spec == :stable && formula.revision.nonzero?
|
||||
replacement_pairs << [/^ revision \d+\n(\n( head "))?/m, "\\2"]
|
||||
end
|
||||
|
||||
replacement_pairs += formula_spec.mirrors.map do |mirror|
|
||||
[/ +mirror \"#{Regexp.escape(mirror)}\"\n/m, ""]
|
||||
end
|
||||
|
||||
replacement_pairs += if new_url_hash
|
||||
[
|
||||
[/#{Regexp.escape(formula_spec.url)}/, new_url],
|
||||
[old_hash, new_hash],
|
||||
]
|
||||
else
|
||||
[
|
||||
[formula_spec.specs[:tag], new_tag],
|
||||
[formula_spec.specs[:revision], new_revision],
|
||||
]
|
||||
end
|
||||
|
||||
backup_file = File.read(formula.path) unless @args.dry_run?
|
||||
|
||||
if new_mirror
|
||||
replacement_pairs << [/^( +)(url \"#{Regexp.escape(new_url)}\"\n)/m, "\\1\\2\\1mirror \"#{new_mirror}\"\n"]
|
||||
end
|
||||
|
||||
if forced_version && forced_version != "0"
|
||||
if requested_spec == :stable
|
||||
if File.read(formula.path).include?("version \"#{old_formula_version}\"")
|
||||
replacement_pairs << [old_formula_version.to_s, forced_version]
|
||||
elsif new_mirror
|
||||
replacement_pairs << [/^( +)(mirror \"#{new_mirror}\"\n)/m, "\\1\\2\\1version \"#{forced_version}\"\n"]
|
||||
else
|
||||
replacement_pairs << [/^( +)(url \"#{new_url}\"\n)/m, "\\1\\2\\1version \"#{forced_version}\"\n"]
|
||||
end
|
||||
elsif requested_spec == :devel
|
||||
replacement_pairs << [/( devel do.+?version \")#{old_formula_version}(\"\n.+?end\n)/m, "\\1#{forced_version}\\2"]
|
||||
end
|
||||
elsif forced_version && forced_version == "0"
|
||||
if requested_spec == :stable
|
||||
replacement_pairs << [/^ version \"[\w\.\-\+]+\"\n/m, ""]
|
||||
elsif requested_spec == :devel
|
||||
replacement_pairs << [/( devel do.+?)^ +version \"[^\n]+\"\n(.+?end\n)/m, "\\1\\2"]
|
||||
end
|
||||
end
|
||||
new_contents = inreplace_pairs(formula.path, replacement_pairs)
|
||||
|
||||
new_formula_version = formula_version(formula, requested_spec, new_contents)
|
||||
|
||||
if new_formula_version < old_formula_version
|
||||
formula.path.atomic_write(backup_file) unless @args.dry_run?
|
||||
odie <<~EOS
|
||||
You probably need to bump this formula manually since changing the
|
||||
version from #{old_formula_version} to #{new_formula_version} would be a downgrade.
|
||||
EOS
|
||||
elsif new_formula_version == old_formula_version
|
||||
formula.path.atomic_write(backup_file) unless @args.dry_run?
|
||||
odie <<~EOS
|
||||
You probably need to bump this formula manually since the new version
|
||||
and old version are both #{new_formula_version}.
|
||||
EOS
|
||||
end
|
||||
|
||||
if @args.dry_run?
|
||||
if @args.strict?
|
||||
ohai "brew audit --strict #{formula.path.basename}"
|
||||
elsif @args.audit?
|
||||
ohai "brew audit #{formula.path.basename}"
|
||||
end
|
||||
else
|
||||
failed_audit = false
|
||||
if @args.strict?
|
||||
system HOMEBREW_BREW_FILE, "audit", "--strict", formula.path
|
||||
failed_audit = !$CHILD_STATUS.success?
|
||||
elsif @args.audit?
|
||||
system HOMEBREW_BREW_FILE, "audit", formula.path
|
||||
failed_audit = !$CHILD_STATUS.success?
|
||||
end
|
||||
if failed_audit
|
||||
formula.path.atomic_write(backup_file)
|
||||
odie "brew audit failed!"
|
||||
end
|
||||
end
|
||||
|
||||
formula.path.parent.cd do
|
||||
branch = "#{formula.name}-#{new_formula_version}"
|
||||
git_dir = Utils.popen_read("git rev-parse --git-dir").chomp
|
||||
shallow = !git_dir.empty? && File.exist?("#{git_dir}/shallow")
|
||||
|
||||
if @args.dry_run?
|
||||
ohai "fork repository with GitHub API"
|
||||
ohai "git fetch --unshallow origin" if shallow
|
||||
ohai "git checkout --no-track -b #{branch} origin/master"
|
||||
ohai "git commit --no-edit --verbose --message='#{formula.name} #{new_formula_version}#{devel_message}' -- #{formula.path}"
|
||||
ohai "git push --set-upstream $HUB_REMOTE #{branch}:#{branch}"
|
||||
ohai "create pull request with GitHub API"
|
||||
ohai "git checkout -"
|
||||
else
|
||||
|
||||
begin
|
||||
response = GitHub.create_fork(formula.tap.full_name)
|
||||
# GitHub API responds immediately but fork takes a few seconds to be ready.
|
||||
sleep 3
|
||||
rescue *gh_api_errors => e
|
||||
formula.path.atomic_write(backup_file) unless @args.dry_run?
|
||||
odie "Unable to fork: #{e.message}!"
|
||||
end
|
||||
|
||||
remote_url = response.fetch("clone_url")
|
||||
username = response.fetch("owner").fetch("login")
|
||||
|
||||
safe_system "git", "fetch", "--unshallow", "origin" if shallow
|
||||
safe_system "git", "checkout", "--no-track", "-b", branch, "origin/master"
|
||||
safe_system "git", "commit", "--no-edit", "--verbose",
|
||||
"--message=#{formula.name} #{new_formula_version}#{devel_message}",
|
||||
"--", formula.path
|
||||
safe_system "git", "push", "--set-upstream", remote_url, "#{branch}:#{branch}"
|
||||
safe_system "git", "checkout", "--quiet", "-"
|
||||
pr_message = <<~EOS
|
||||
Created with `brew bump-formula-pr`.
|
||||
EOS
|
||||
user_message = @args.message
|
||||
if user_message
|
||||
pr_message += "\n" + <<~EOS
|
||||
---
|
||||
|
||||
#{user_message}
|
||||
EOS
|
||||
end
|
||||
pr_title = "#{formula.name} #{new_formula_version}#{devel_message}"
|
||||
|
||||
begin
|
||||
url = GitHub.create_pull_request(formula.tap.full_name, pr_title,
|
||||
"#{username}:#{branch}", "master", pr_message)["html_url"]
|
||||
if @args.no_browse?
|
||||
puts url
|
||||
else
|
||||
exec_browser url
|
||||
end
|
||||
rescue *gh_api_errors => e
|
||||
odie "Unable to open pull request: #{e.message}!"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def inreplace_pairs(path, replacement_pairs)
|
||||
if ARGV.dry_run?
|
||||
if @args.dry_run?
|
||||
contents = path.open("r") { |f| Formulary.ensure_utf8_encoding(f).read }
|
||||
contents.extend(StringInreplaceExtension)
|
||||
replacement_pairs.each do |old, new|
|
||||
unless ARGV.flag?("--quiet")
|
||||
unless Homebrew.args.quiet?
|
||||
ohai "replace #{old.inspect} with #{new.inspect}"
|
||||
end
|
||||
contents.gsub!(old, new)
|
||||
@ -59,12 +347,12 @@ module Homebrew
|
||||
unless contents.errors.empty?
|
||||
raise Utils::InreplaceError, path => contents.errors
|
||||
end
|
||||
path.atomic_write(contents) if ARGV.include?("--write")
|
||||
path.atomic_write(contents) if @args.write?
|
||||
contents
|
||||
else
|
||||
Utils::Inreplace.inreplace(path) do |s|
|
||||
replacement_pairs.each do |old, new|
|
||||
unless ARGV.flag?("--quiet")
|
||||
unless Homebrew.args.quiet?
|
||||
ohai "replace #{old.inspect} with #{new.inspect}"
|
||||
end
|
||||
s.gsub!(old, new)
|
||||
@ -103,279 +391,15 @@ module Homebrew
|
||||
#{pull_requests.map { |pr| "#{pr["title"]} #{pr["html_url"]}" }.join("\n")}
|
||||
EOS
|
||||
error_message = "Duplicate PRs should not be opened. Use --force to override this error."
|
||||
if ARGV.force? && !ARGV.flag?("--quiet")
|
||||
if Homebrew.args.force? && !Homebrew.args.quiet?
|
||||
opoo duplicates_message
|
||||
elsif !ARGV.force? && ARGV.flag?("--quiet")
|
||||
elsif !Homebrew.args.force? && Homebrew.args.quiet?
|
||||
odie error_message
|
||||
elsif !ARGV.force?
|
||||
elsif !Homebrew.args.force?
|
||||
odie <<~EOS
|
||||
#{duplicates_message.chomp}
|
||||
#{error_message}
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
||||
def bump_formula_pr
|
||||
# As this command is simplifying user run commands then let's just use a
|
||||
# user path, too.
|
||||
ENV["PATH"] = ENV["HOMEBREW_PATH"]
|
||||
|
||||
# Use the user's browser, too.
|
||||
ENV["BROWSER"] = ENV["HOMEBREW_BROWSER"]
|
||||
|
||||
# Setup GitHub environment variables
|
||||
%w[GITHUB_USER GITHUB_PASSWORD GITHUB_TOKEN].each do |env|
|
||||
homebrew_env = ENV["HOMEBREW_#{env}"]
|
||||
next unless homebrew_env
|
||||
next if homebrew_env.empty?
|
||||
ENV[env] = homebrew_env
|
||||
end
|
||||
|
||||
gh_api_errors = [GitHub::AuthenticationFailedError, GitHub::HTTPNotFoundError,
|
||||
GitHub::RateLimitExceededError, GitHub::Error, JSON::ParserError].freeze
|
||||
|
||||
formula = ARGV.formulae.first
|
||||
|
||||
if formula
|
||||
check_for_duplicate_pull_requests(formula)
|
||||
checked_for_duplicates = true
|
||||
end
|
||||
|
||||
new_url = ARGV.value("url")
|
||||
if new_url && !formula
|
||||
# Split the new URL on / and find any formulae that have the same URL
|
||||
# except for the last component, but don't try to match any more than the
|
||||
# first five components since sometimes the last component isn't the only
|
||||
# one to change.
|
||||
new_url_split = new_url.split("/")
|
||||
maximum_url_components_to_match = 5
|
||||
components_to_match = [new_url_split.count - 1, maximum_url_components_to_match].min
|
||||
base_url = new_url_split.first(components_to_match).join("/")
|
||||
base_url = /#{Regexp.escape(base_url)}/
|
||||
is_devel = ARGV.include?("--devel")
|
||||
guesses = []
|
||||
Formula.each do |f|
|
||||
if is_devel && f.devel && f.devel.url && f.devel.url.match(base_url)
|
||||
guesses << f
|
||||
elsif f.stable&.url && f.stable.url.match(base_url)
|
||||
guesses << f
|
||||
end
|
||||
end
|
||||
if guesses.count == 1
|
||||
formula = guesses.shift
|
||||
elsif guesses.count > 1
|
||||
odie "Couldn't guess formula for sure: could be one of these:\n#{guesses}"
|
||||
end
|
||||
end
|
||||
odie "No formula found!" unless formula
|
||||
|
||||
check_for_duplicate_pull_requests(formula) unless checked_for_duplicates
|
||||
|
||||
requested_spec, formula_spec = if ARGV.include?("--devel")
|
||||
devel_message = " (devel)"
|
||||
[:devel, formula.devel]
|
||||
else
|
||||
[:stable, formula.stable]
|
||||
end
|
||||
odie "#{formula}: no #{requested_spec} specification found!" unless formula_spec
|
||||
|
||||
hash_type, old_hash = if (checksum = formula_spec.checksum)
|
||||
[checksum.hash_type.to_s, checksum.hexdigest]
|
||||
end
|
||||
|
||||
new_hash = ARGV.value(hash_type)
|
||||
new_tag = ARGV.value("tag")
|
||||
new_revision = ARGV.value("revision")
|
||||
new_mirror = ARGV.value("mirror")
|
||||
forced_version = ARGV.value("version")
|
||||
new_url_hash = if new_url && new_hash
|
||||
true
|
||||
elsif new_tag && new_revision
|
||||
false
|
||||
elsif !hash_type
|
||||
odie "#{formula}: no --tag=/--revision= arguments specified!"
|
||||
elsif !new_url
|
||||
odie "#{formula}: no --url= argument specified!"
|
||||
else
|
||||
new_mirror = case new_url
|
||||
when requested_spec != :devel && %r{.*ftp.gnu.org/gnu.*}
|
||||
new_url.sub "ftp.gnu.org/gnu", "ftpmirror.gnu.org"
|
||||
when %r{.*mirrors.ocf.berkeley.edu/debian.*}
|
||||
new_url.sub "mirrors.ocf.berkeley.edu/debian", "mirrorservice.org/sites/ftp.debian.org/debian"
|
||||
end
|
||||
resource = Resource.new { @url = new_url }
|
||||
resource.download_strategy = DownloadStrategyDetector.detect_from_url(new_url)
|
||||
resource.owner = Resource.new(formula.name)
|
||||
resource.version = forced_version if forced_version
|
||||
odie "No --version= argument specified!" unless resource.version
|
||||
resource_path = resource.fetch
|
||||
tar_file_extensions = %w[.tar .tb2 .tbz .tbz2 .tgz .tlz .txz .tZ]
|
||||
if tar_file_extensions.any? { |extension| new_url.include? extension }
|
||||
gnu_tar_gtar_path = HOMEBREW_PREFIX/"opt/gnu-tar/bin/gtar"
|
||||
gnu_tar_gtar = gnu_tar_gtar_path if gnu_tar_gtar_path.executable?
|
||||
tar = which("gtar") || gnu_tar_gtar || which("tar")
|
||||
if Utils.popen_read(tar, "-tf", resource_path) =~ %r{/.*\.}
|
||||
new_hash = resource_path.sha256
|
||||
else
|
||||
odie "#{resource_path} is not a valid tar file!"
|
||||
end
|
||||
else
|
||||
new_hash = resource_path.sha256
|
||||
end
|
||||
end
|
||||
|
||||
if ARGV.dry_run?
|
||||
ohai "brew update"
|
||||
else
|
||||
safe_system "brew", "update"
|
||||
end
|
||||
|
||||
old_formula_version = formula_version(formula, requested_spec)
|
||||
|
||||
replacement_pairs = []
|
||||
if requested_spec == :stable && formula.revision.nonzero?
|
||||
replacement_pairs << [/^ revision \d+\n(\n( head "))?/m, "\\2"]
|
||||
end
|
||||
|
||||
replacement_pairs += formula_spec.mirrors.map do |mirror|
|
||||
[/ +mirror \"#{Regexp.escape(mirror)}\"\n/m, ""]
|
||||
end
|
||||
|
||||
replacement_pairs += if new_url_hash
|
||||
[
|
||||
[/#{Regexp.escape(formula_spec.url)}/, new_url],
|
||||
[old_hash, new_hash],
|
||||
]
|
||||
else
|
||||
[
|
||||
[formula_spec.specs[:tag], new_tag],
|
||||
[formula_spec.specs[:revision], new_revision],
|
||||
]
|
||||
end
|
||||
|
||||
backup_file = File.read(formula.path) unless ARGV.dry_run?
|
||||
|
||||
if new_mirror
|
||||
replacement_pairs << [/^( +)(url \"#{Regexp.escape(new_url)}\"\n)/m, "\\1\\2\\1mirror \"#{new_mirror}\"\n"]
|
||||
end
|
||||
|
||||
if forced_version && forced_version != "0"
|
||||
if requested_spec == :stable
|
||||
if File.read(formula.path).include?("version \"#{old_formula_version}\"")
|
||||
replacement_pairs << [old_formula_version.to_s, forced_version]
|
||||
elsif new_mirror
|
||||
replacement_pairs << [/^( +)(mirror \"#{new_mirror}\"\n)/m, "\\1\\2\\1version \"#{forced_version}\"\n"]
|
||||
else
|
||||
replacement_pairs << [/^( +)(url \"#{new_url}\"\n)/m, "\\1\\2\\1version \"#{forced_version}\"\n"]
|
||||
end
|
||||
elsif requested_spec == :devel
|
||||
replacement_pairs << [/( devel do.+?version \")#{old_formula_version}(\"\n.+?end\n)/m, "\\1#{forced_version}\\2"]
|
||||
end
|
||||
elsif forced_version && forced_version == "0"
|
||||
if requested_spec == :stable
|
||||
replacement_pairs << [/^ version \"[\w\.\-\+]+\"\n/m, ""]
|
||||
elsif requested_spec == :devel
|
||||
replacement_pairs << [/( devel do.+?)^ +version \"[^\n]+\"\n(.+?end\n)/m, "\\1\\2"]
|
||||
end
|
||||
end
|
||||
new_contents = inreplace_pairs(formula.path, replacement_pairs)
|
||||
|
||||
new_formula_version = formula_version(formula, requested_spec, new_contents)
|
||||
|
||||
if new_formula_version < old_formula_version
|
||||
formula.path.atomic_write(backup_file) unless ARGV.dry_run?
|
||||
odie <<~EOS
|
||||
You probably need to bump this formula manually since changing the
|
||||
version from #{old_formula_version} to #{new_formula_version} would be a downgrade.
|
||||
EOS
|
||||
elsif new_formula_version == old_formula_version
|
||||
formula.path.atomic_write(backup_file) unless ARGV.dry_run?
|
||||
odie <<~EOS
|
||||
You probably need to bump this formula manually since the new version
|
||||
and old version are both #{new_formula_version}.
|
||||
EOS
|
||||
end
|
||||
|
||||
if ARGV.dry_run?
|
||||
if ARGV.include? "--strict"
|
||||
ohai "brew audit --strict #{formula.path.basename}"
|
||||
elsif ARGV.include? "--audit"
|
||||
ohai "brew audit #{formula.path.basename}"
|
||||
end
|
||||
else
|
||||
failed_audit = false
|
||||
if ARGV.include? "--strict"
|
||||
system HOMEBREW_BREW_FILE, "audit", "--strict", formula.path
|
||||
failed_audit = !$CHILD_STATUS.success?
|
||||
elsif ARGV.include? "--audit"
|
||||
system HOMEBREW_BREW_FILE, "audit", formula.path
|
||||
failed_audit = !$CHILD_STATUS.success?
|
||||
end
|
||||
if failed_audit
|
||||
formula.path.atomic_write(backup_file)
|
||||
odie "brew audit failed!"
|
||||
end
|
||||
end
|
||||
|
||||
formula.path.parent.cd do
|
||||
branch = "#{formula.name}-#{new_formula_version}"
|
||||
git_dir = Utils.popen_read("git rev-parse --git-dir").chomp
|
||||
shallow = !git_dir.empty? && File.exist?("#{git_dir}/shallow")
|
||||
|
||||
if ARGV.dry_run?
|
||||
ohai "fork repository with GitHub API"
|
||||
ohai "git fetch --unshallow origin" if shallow
|
||||
ohai "git checkout --no-track -b #{branch} origin/master"
|
||||
ohai "git commit --no-edit --verbose --message='#{formula.name} #{new_formula_version}#{devel_message}' -- #{formula.path}"
|
||||
ohai "git push --set-upstream $HUB_REMOTE #{branch}:#{branch}"
|
||||
ohai "create pull request with GitHub API"
|
||||
ohai "git checkout -"
|
||||
else
|
||||
|
||||
begin
|
||||
response = GitHub.create_fork(formula.tap.full_name)
|
||||
# GitHub API responds immediately but fork takes a few seconds to be ready.
|
||||
sleep 3
|
||||
rescue *gh_api_errors => e
|
||||
formula.path.atomic_write(backup_file) unless ARGV.dry_run?
|
||||
odie "Unable to fork: #{e.message}!"
|
||||
end
|
||||
|
||||
remote_url = response.fetch("clone_url")
|
||||
username = response.fetch("owner").fetch("login")
|
||||
|
||||
safe_system "git", "fetch", "--unshallow", "origin" if shallow
|
||||
safe_system "git", "checkout", "--no-track", "-b", branch, "origin/master"
|
||||
safe_system "git", "commit", "--no-edit", "--verbose",
|
||||
"--message=#{formula.name} #{new_formula_version}#{devel_message}",
|
||||
"--", formula.path
|
||||
safe_system "git", "push", "--set-upstream", remote_url, "#{branch}:#{branch}"
|
||||
safe_system "git", "checkout", "--quiet", "-"
|
||||
pr_message = <<~EOS
|
||||
Created with `brew bump-formula-pr`.
|
||||
EOS
|
||||
user_message = ARGV.value("message")
|
||||
if user_message
|
||||
pr_message += "\n" + <<~EOS
|
||||
---
|
||||
|
||||
#{user_message}
|
||||
EOS
|
||||
end
|
||||
pr_title = "#{formula.name} #{new_formula_version}#{devel_message}"
|
||||
|
||||
begin
|
||||
url = GitHub.create_pull_request(formula.tap.full_name, pr_title,
|
||||
"#{username}:#{branch}", "master", pr_message)["html_url"]
|
||||
if ARGV.include?("--no-browse")
|
||||
puts url
|
||||
else
|
||||
exec_browser url
|
||||
end
|
||||
rescue *gh_api_errors => e
|
||||
odie "Unable to open pull request: #{e.message}!"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1503,7 +1503,6 @@ class Formula
|
||||
# @private
|
||||
def runtime_dependencies(read_from_tab: true)
|
||||
if read_from_tab &&
|
||||
installed_prefix.directory? &&
|
||||
(keg = opt_or_installed_prefix_keg) &&
|
||||
(tab_deps = keg.runtime_dependencies)
|
||||
return tab_deps.map { |d| Dependency.new d["full_name"] }.compact
|
||||
|
||||
@ -145,8 +145,12 @@ class LinkageChecker
|
||||
formula.build.without?(dep)
|
||||
end
|
||||
|
||||
declared_deps = formula.deps.reject { |dep| filter_out.call(dep) }.map(&:name)
|
||||
declared_dep_names = declared_deps.map { |dep| dep.split("/").last }
|
||||
declared_deps_full_names = formula.deps
|
||||
.reject { |dep| filter_out.call(dep) }
|
||||
.map(&:name)
|
||||
declared_deps_names = declared_deps_full_names.map do |dep|
|
||||
dep.split("/").last
|
||||
end
|
||||
recursive_deps = formula.declared_runtime_dependencies.map do |dep|
|
||||
begin
|
||||
dep.to_formula.name
|
||||
@ -161,7 +165,7 @@ class LinkageChecker
|
||||
name = full_name.split("/").last
|
||||
next if name == formula.name
|
||||
if recursive_deps.include?(name)
|
||||
indirect_deps << full_name unless declared_dep_names.include?(name)
|
||||
indirect_deps << full_name unless declared_deps_names.include?(name)
|
||||
else
|
||||
undeclared_deps << full_name
|
||||
end
|
||||
@ -170,9 +174,9 @@ class LinkageChecker
|
||||
sort_by_formula_full_name!(indirect_deps)
|
||||
sort_by_formula_full_name!(undeclared_deps)
|
||||
|
||||
unnecessary_deps = declared_dep_names.reject do |full_name|
|
||||
unnecessary_deps = declared_deps_full_names.reject do |full_name|
|
||||
next true if Formula[full_name].bin.directory?
|
||||
name = full_name.split("/").last
|
||||
next true if Formula[name].bin.directory?
|
||||
@brewed_dylibs.keys.map { |x| x.split("/").last }.include?(name)
|
||||
end
|
||||
|
||||
|
||||
@ -31,6 +31,7 @@ module RuboCop
|
||||
[{ name: :conflicts_with, type: :method_call }],
|
||||
[{ name: :go_resource, type: :block_call }, { name: :resource, type: :block_call }],
|
||||
[{ name: :install, type: :method_definition }],
|
||||
[{ name: :post_install, type: :method_definition }],
|
||||
[{ name: :caveats, type: :method_definition }],
|
||||
[{ name: :plist_options, type: :method_call }, { name: :plist, type: :method_definition }],
|
||||
[{ name: :test, type: :block_call }],
|
||||
|
||||
@ -70,4 +70,54 @@ describe Homebrew::CLI::Parser do
|
||||
expect(args.files).to eq %w[random1.txt random2.txt]
|
||||
end
|
||||
end
|
||||
|
||||
describe "test constraints" do
|
||||
subject(:parser) {
|
||||
described_class.new do
|
||||
flag "--flag1"
|
||||
flag "--flag3"
|
||||
flag "--flag2", required_for: "--flag1"
|
||||
flag "--flag4", depends_on: "--flag3"
|
||||
|
||||
conflicts "--flag1", "--flag3"
|
||||
end
|
||||
}
|
||||
|
||||
it "raises exception on depends mandatory constraint violation" do
|
||||
expect { parser.parse(["--flag1"]) }.to raise_error(Homebrew::CLI::OptionConstraintError)
|
||||
end
|
||||
|
||||
it "raises exception on depends constraint violation" do
|
||||
expect { parser.parse(["--flag2"]) }.to raise_error(Homebrew::CLI::OptionConstraintError)
|
||||
end
|
||||
|
||||
it "raises exception for conflict violation" do
|
||||
expect { parser.parse(["--flag1", "--flag3"]) }.to raise_error(Homebrew::CLI::OptionConflictError)
|
||||
end
|
||||
|
||||
it "raises no exception" do
|
||||
args = parser.parse(["--flag1", "--flag2"])
|
||||
expect(args.flag1).to be true
|
||||
expect(args.flag2).to be true
|
||||
end
|
||||
|
||||
it "raises no exception for optional dependency" do
|
||||
args = parser.parse(["--flag3"])
|
||||
expect(args.flag3).to be true
|
||||
end
|
||||
end
|
||||
|
||||
describe "test invalid constraints" do
|
||||
subject(:parser) {
|
||||
described_class.new do
|
||||
flag "--flag1"
|
||||
flag "--flag2", depends_on: "--flag1"
|
||||
conflicts "--flag1", "--flag2"
|
||||
end
|
||||
}
|
||||
|
||||
it "raises exception due to invalid constraints" do
|
||||
expect { parser.parse([]) }.to raise_error(Homebrew::CLI::InvalidConstraintError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1 +1 @@
|
||||
2.3.3
|
||||
2.3.3_1
|
||||
|
||||
@ -40,11 +40,11 @@ Homebrew's lead maintainer is [Mike McQuaid](https://github.com/mikemcquaid).
|
||||
|
||||
Homebrew/homebrew-core's lead maintainer is [ilovezfs](https://github.com/ilovezfs).
|
||||
|
||||
Homebrew/brew's other current maintainers are [ilovezfs](https://github.com/ilovezfs), [Alyssa Ross](https://github.com/alyssais), [JCount](https://github.com/jcount), [Misty De Meo](https://github.com/mistydemeo), [Gautham Goli](https://github.com/GauthamGoli), [Markus Reiter](https://github.com/reitermarkus) and [William Woodruff](https://github.com/woodruffw).
|
||||
Homebrew/brew's other current maintainers are [ilovezfs](https://github.com/ilovezfs), [JCount](https://github.com/jcount), [Misty De Meo](https://github.com/mistydemeo), [Gautham Goli](https://github.com/GauthamGoli), [Markus Reiter](https://github.com/reitermarkus) and [William Woodruff](https://github.com/woodruffw).
|
||||
|
||||
Homebrew/homebrew-core's other current maintainers are [FX Coudert](https://github.com/fxcoudert), [JCount](https://github.com/jcount), [Misty De Meo](https://github.com/mistydemeo) and [Tom Schoonjans](https://github.com/tschoonj).
|
||||
|
||||
Former maintainers with significant contributions include [Tim Smith](https://github.com/tdsmith), [Baptiste Fontaine](https://github.com/bfontaine), [Xu Cheng](https://github.com/xu-cheng), [Martin Afanasjew](https://github.com/UniqMartin), [Dominyk Tiller](https://github.com/DomT4), [Brett Koonce](https://github.com/asparagui), [Charlie Sharpsteen](https://github.com/Sharpie), [Jack Nagel](https://github.com/jacknagel), [Adam Vandenberg](https://github.com/adamv), [Andrew Janke](https://github.com/apjanke), [Alex Dunn](https://github.com/dunn), [neutric](https://github.com/neutric), [Tomasz Pajor](https://github.com/nijikon), [Uladzislau Shablinski](https://github.com/vladshablinsky) and Homebrew's creator: [Max Howell](https://github.com/mxcl).
|
||||
Former maintainers with significant contributions include [Tim Smith](https://github.com/tdsmith), [Baptiste Fontaine](https://github.com/bfontaine), [Xu Cheng](https://github.com/xu-cheng), [Martin Afanasjew](https://github.com/UniqMartin), [Dominyk Tiller](https://github.com/DomT4), [Brett Koonce](https://github.com/asparagui), [Charlie Sharpsteen](https://github.com/Sharpie), [Jack Nagel](https://github.com/jacknagel), [Adam Vandenberg](https://github.com/adamv), [Andrew Janke](https://github.com/apjanke), [Alex Dunn](https://github.com/dunn), [neutric](https://github.com/neutric), [Tomasz Pajor](https://github.com/nijikon), [Uladzislau Shablinski](https://github.com/vladshablinsky), [Alyssa Ross](https://github.com/alyssais), and Homebrew's creator: [Max Howell](https://github.com/mxcl).
|
||||
|
||||
## Community
|
||||
- [discourse.brew.sh (forum)](https://discourse.brew.sh)
|
||||
|
||||
@ -251,17 +251,6 @@ _brew_link() {
|
||||
__brew_complete_installed
|
||||
}
|
||||
|
||||
_brew_linkapps() {
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--*)
|
||||
__brewcomp "--local"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
__brew_complete_installed
|
||||
}
|
||||
|
||||
_brew_list() {
|
||||
local allopts="--unbrewed --verbose --pinned --versions --multiple"
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
@ -482,17 +471,6 @@ _brew_uninstall() {
|
||||
__brew_complete_installed
|
||||
}
|
||||
|
||||
_brew_unlinkapps() {
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--*)
|
||||
__brewcomp "--dry-run --local"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
__brew_complete_installed
|
||||
}
|
||||
|
||||
_brew_unpack() {
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
@ -827,7 +805,6 @@ _brew() {
|
||||
install|instal) _brew_install ;;
|
||||
irb) _brew_irb ;;
|
||||
link|ln) _brew_link ;;
|
||||
linkapps) _brew_linkapps ;;
|
||||
list|ls) _brew_list ;;
|
||||
log) _brew_log ;;
|
||||
man) _brew_man ;;
|
||||
@ -852,7 +829,6 @@ _brew() {
|
||||
tests) _brew_tests ;;
|
||||
uninstall|remove|rm) _brew_uninstall ;;
|
||||
unlink) __brew_complete_installed ;;
|
||||
unlinkapps) _brew_unlinkapps ;;
|
||||
unpack) _brew_unpack ;;
|
||||
unpin) __brew_complete_formulae ;;
|
||||
untap) __brew_complete_tapped ;;
|
||||
|
||||
@ -89,7 +89,6 @@ __brew_common_commands() {
|
||||
'reinstall:install a formula anew; re-using its current options'
|
||||
'leaves:show installed formulae that are not dependencies of another installed formula'
|
||||
'link:link a formula'
|
||||
'linkapps:symlink .app bundles provided by formulae into /Applications'
|
||||
'list:list files in a formula or not-installed formulae'
|
||||
'log:git commit log for a formula'
|
||||
'missing:check all installed formuale for missing dependencies.'
|
||||
@ -108,7 +107,6 @@ __brew_common_commands() {
|
||||
'test-bot:test a formula and build a bottle'
|
||||
'uninstall:uninstall a formula'
|
||||
'unlink:unlink a formula'
|
||||
'unlinkapps:remove symlinked .app bundles provided by formulae from /Applications'
|
||||
'unpin:unpin specified formulae'
|
||||
'untap:remove a tapped repository'
|
||||
'update:fetch latest version of Homebrew and all formulae'
|
||||
@ -448,13 +446,6 @@ _brew_linkage() {
|
||||
':formula:__brew_installed_formulae'
|
||||
}
|
||||
|
||||
# brew linkapps [--local] [formulae]:
|
||||
_brew_linkapps() {
|
||||
_arguments \
|
||||
'(--local)--local[symlink into ~/Application instead of the system directory]' \
|
||||
'::formula:__brew_installed_formulae'
|
||||
}
|
||||
|
||||
# brew list, ls [--full-name]:
|
||||
# brew list, ls --unbrewed:
|
||||
# brew list, ls [--versions [--multiple]] [--pinned] [formulae]:
|
||||
@ -704,14 +695,6 @@ _brew_unlink() {
|
||||
':formula:__brew_installed_formulae'
|
||||
}
|
||||
|
||||
# brew unlinkapps [--local] [--dry-run] [formulae]:
|
||||
_brew_unlinkapps() {
|
||||
_arguments \
|
||||
'(--local)--local[remove symlinks from ~/Applications instead of the system directory]' \
|
||||
'(--dry-run -n)'{--dry-run,-n}'[don''t unlink or delete any files]' \
|
||||
':formula:__brew_installed_formulae'
|
||||
}
|
||||
|
||||
# brew unpack [--git|--patch] [--destdir=path] formulae:
|
||||
_brew_unpack() {
|
||||
_arguments \
|
||||
|
||||
@ -13,20 +13,15 @@ We now accept versioned formulae as long as they [meet the requirements](Version
|
||||
|
||||
### We don’t like tools that upgrade themselves
|
||||
Software that can upgrade itself does not integrate well with Homebrew's own
|
||||
upgrade functionality.
|
||||
upgrade functionality. The self-update functionality should be disabled (if possible without complicating the formula).
|
||||
|
||||
### We don’t like install-scripts that download things
|
||||
Because that circumvents our hash-checks, makes finding/fixing bugs
|
||||
harder, often breaks patches and disables the caching. Almost always you
|
||||
can add a resource to the formula file to handle the
|
||||
separate download and then the installer script will not attempt to load
|
||||
that stuff on demand. Or there is a command-line switch where you can
|
||||
point it to the downloaded archive in order to avoid loading.
|
||||
### We don’t like install-scripts that download unversioned things
|
||||
We don't like install scripts that are pulling from the `master` branch of Git repositories or unversioned, unchecksummed tarballs. These should use `resource` blocks with specific revisions or checksummed tarballs instead. Note that we now allow tools like `cargo`, `gem` and `pip` to download things during installation.
|
||||
|
||||
### We don’t like binary formulae
|
||||
Our policy is that formulae in the core tap
|
||||
([homebrew/core](https://github.com/Homebrew/homebrew-core)) must be open-source
|
||||
and either built from source or produce cross-platform binaries (e.g. Java).
|
||||
and either built from source or produce cross-platform binaries (e.g. Java, Mono).
|
||||
Binary-only formulae should go to
|
||||
[Homebrew Cask](https://github.com/caskroom/homebrew-cask).
|
||||
|
||||
@ -41,7 +36,7 @@ due to upstream changes and we can’t provide [bottles](Bottles.md) for them.
|
||||
### Niche (or self-submitted) stuff
|
||||
The software in question must:
|
||||
|
||||
* be maintained (e.g. upstream is still making new releases)
|
||||
* be maintained (i.e. the last release wasn't ages ago, it works without patching on all supported macOS releases and has no outstanding, unpatched security vulnerabilites)
|
||||
* be known
|
||||
* be stable (e.g. not declared "unstable" or "beta" by upstream)
|
||||
* be used
|
||||
|
||||
@ -1283,11 +1283,11 @@ Homebrew's lead maintainer is Mike McQuaid.
|
||||
|
||||
Homebrew/homebrew-core's lead maintainer is ilovezfs.
|
||||
|
||||
Homebrew/brew's other current maintainers are ilovezfs, Alyssa Ross, JCount, Misty De Meo, Gautham Goli, Markus Reiter and William Woodruff.
|
||||
Homebrew/brew's other current maintainers are ilovezfs, JCount, Misty De Meo, Gautham Goli, Markus Reiter and William Woodruff.
|
||||
|
||||
Homebrew/homebrew-core's other current maintainers are FX Coudert, JCount, Misty De Meo and Tom Schoonjans.
|
||||
|
||||
Former maintainers with significant contributions include Tim Smith, Baptiste Fontaine, Xu Cheng, Martin Afanasjew, Dominyk Tiller, Brett Koonce, Charlie Sharpsteen, Jack Nagel, Adam Vandenberg, Andrew Janke, Alex Dunn, neutric, Tomasz Pajor, Uladzislau Shablinski and Homebrew's creator: Max Howell.
|
||||
Former maintainers with significant contributions include Tim Smith, Baptiste Fontaine, Xu Cheng, Martin Afanasjew, Dominyk Tiller, Brett Koonce, Charlie Sharpsteen, Jack Nagel, Adam Vandenberg, Andrew Janke, Alex Dunn, neutric, Tomasz Pajor, Uladzislau Shablinski, Alyssa Ross, and Homebrew's creator: Max Howell.
|
||||
|
||||
## BUGS
|
||||
|
||||
|
||||
@ -1325,13 +1325,13 @@ Homebrew\'s lead maintainer is Mike McQuaid\.
|
||||
Homebrew/homebrew\-core\'s lead maintainer is ilovezfs\.
|
||||
.
|
||||
.P
|
||||
Homebrew/brew\'s other current maintainers are ilovezfs, Alyssa Ross, JCount, Misty De Meo, Gautham Goli, Markus Reiter and William Woodruff\.
|
||||
Homebrew/brew\'s other current maintainers are ilovezfs, JCount, Misty De Meo, Gautham Goli, Markus Reiter and William Woodruff\.
|
||||
.
|
||||
.P
|
||||
Homebrew/homebrew\-core\'s other current maintainers are FX Coudert, JCount, Misty De Meo and Tom Schoonjans\.
|
||||
.
|
||||
.P
|
||||
Former maintainers with significant contributions include Tim Smith, Baptiste Fontaine, Xu Cheng, Martin Afanasjew, Dominyk Tiller, Brett Koonce, Charlie Sharpsteen, Jack Nagel, Adam Vandenberg, Andrew Janke, Alex Dunn, neutric, Tomasz Pajor, Uladzislau Shablinski and Homebrew\'s creator: Max Howell\.
|
||||
Former maintainers with significant contributions include Tim Smith, Baptiste Fontaine, Xu Cheng, Martin Afanasjew, Dominyk Tiller, Brett Koonce, Charlie Sharpsteen, Jack Nagel, Adam Vandenberg, Andrew Janke, Alex Dunn, neutric, Tomasz Pajor, Uladzislau Shablinski, Alyssa Ross, and Homebrew\'s creator: Max Howell\.
|
||||
.
|
||||
.SH "BUGS"
|
||||
See our issues on GitHub:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user