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

This commit is contained in:
Mike McQuaid 2018-05-02 09:46:58 +01:00
commit 555e2a2fc8
16 changed files with 473 additions and 351 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1 +1 @@
2.3.3
2.3.3_1

View File

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

View File

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

View File

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

View File

@ -13,20 +13,15 @@ We now accept versioned formulae as long as they [meet the requirements](Version
### We dont 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 dont 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 dont 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 dont 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 cant 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

View File

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

View File

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