Merge branch 'master' into feature/homebrew_install_cleanup

This commit is contained in:
Jarek Wojciechowski 2018-10-29 11:24:56 -04:00
commit 452d1db109
207 changed files with 8424 additions and 1100 deletions

15
.gitignore vendored
View File

@ -23,7 +23,9 @@
**/.bundle/cache **/.bundle/cache
**/vendor/bundle **/vendor/bundle
**/vendor/ruby **/vendor/ruby
**/vendor/bundle-standalone/ruby/*/bin
**/vendor/bundle-standalone/ruby/*/cache **/vendor/bundle-standalone/ruby/*/cache
**/vendor/bundle-standalone/ruby/*/extensions
**/vendor/bundle-standalone/ruby/*/gems/*/* **/vendor/bundle-standalone/ruby/*/gems/*/*
**/vendor/bundle-standalone/ruby/*/specifications **/vendor/bundle-standalone/ruby/*/specifications
@ -39,6 +41,17 @@
**/vendor/bundle-standalone/ruby/*/gems/thread_safe-*/lib **/vendor/bundle-standalone/ruby/*/gems/thread_safe-*/lib
**/vendor/bundle-standalone/ruby/*/gems/tzinfo-*/lib **/vendor/bundle-standalone/ruby/*/gems/tzinfo-*/lib
# Ignore rubocop dependencies we don't wish to vendor
**/vendor/bundle-standalone/ruby/*/gems/ast-*/
**/vendor/bundle-standalone/ruby/*/gems/jaro_winkler-*/
**/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-*/
**/vendor/bundle-standalone/ruby/*/gems/ruby-progressbar-*/
**/vendor/bundle-standalone/ruby/*/gems/unicode-display_width-*/
# Ignore `bin` contents (again). # Ignore `bin` contents (again).
/bin /bin
@ -64,6 +77,8 @@
!/CHANGELOG.md !/CHANGELOG.md
!/CODE_OF_CONDUCT.md !/CODE_OF_CONDUCT.md
!/CONTRIBUTING.md !/CONTRIBUTING.md
!/Dockerfile
!/Dockerfile.test.yml
!/LICENSE.txt !/LICENSE.txt
!/README.md !/README.md

View File

@ -1,5 +1,7 @@
language: ruby language: ruby
rvm: system rvm: system
os: osx
osx_image: xcode10
cache: cache:
directories: directories:
@ -11,38 +13,21 @@ branches:
only: only:
- master - master
matrix: env:
fast_finish: true - HOMEBREW_FORCE_HOMEBREW_ON_LINUX=1
include:
- os: osx
osx_image: xcode10
- os: linux
sudo: false
before_install: before_install:
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then - HOMEBREW_REPOSITORY="$(brew --repo)"
MACOS="1"; - sudo chown -R "$USER" "$HOMEBREW_REPOSITORY"
HOMEBREW_REPOSITORY="$(brew --repo)";
sudo chown -R "$USER" "$HOMEBREW_REPOSITORY";
else
LINUX="1";
export PATH="$PWD/bin:/usr/bin:/bin:/usr/local/bin";
fi
# umask 022 fixes Linux `brew tests` failures;
- if [ "$LINUX" ]; then
umask 022;
fi
# trigger vendored ruby installation # trigger vendored ruby installation
- brew help - brew help
- if [ "$MACOS" ]; then - mv "$HOMEBREW_REPOSITORY/Library/Taps" "$PWD/Library"
mv "$HOMEBREW_REPOSITORY/Library/Taps" "$PWD/Library"; - sudo rm -rf "$HOMEBREW_REPOSITORY"
sudo rm -rf "$HOMEBREW_REPOSITORY"; - sudo ln -s "$PWD" "$HOMEBREW_REPOSITORY"
sudo ln -s "$PWD" "$HOMEBREW_REPOSITORY";
fi
- travis_retry git clone --depth=1 https://github.com/Homebrew/homebrew-test-bot Library/Taps/homebrew/homebrew-test-bot - travis_retry git clone --depth=1 https://github.com/Homebrew/homebrew-test-bot Library/Taps/homebrew/homebrew-test-bot
script: script:
- brew test-bot - travis_wait 60 brew test-bot
notifications: notifications:
slack: machomebrew:1XNF7p1JRCdBUuKaeSwsWEc1 slack: machomebrew:1XNF7p1JRCdBUuKaeSwsWEc1

43
Dockerfile Normal file
View File

@ -0,0 +1,43 @@
FROM ubuntu:xenial
LABEL maintainer="Shaun Jackman <sjackman@gmail.com>"
RUN apt-get update \
&& apt-get install -y --no-install-recommends software-properties-common \
&& add-apt-repository -y ppa:git-core/ppa \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
bzip2 \
ca-certificates \
curl \
file \
fonts-dejavu-core \
g++ \
git \
locales \
make \
openssh-client \
patch \
sudo \
uuid-runtime \
&& rm -rf /var/lib/apt/lists/*
RUN localedef -i en_US -f UTF-8 en_US.UTF-8 \
&& useradd -m -s /bin/bash linuxbrew \
&& echo 'linuxbrew ALL=(ALL) NOPASSWD:ALL' >>/etc/sudoers
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
# Install portable-ruby and tap homebrew/core.
RUN HOMEBREW_NO_ANALYTICS=1 HOMEBREW_NO_AUTO_UPDATE=1 brew tap homebrew/core \
&& rm -rf ~/.cache

3
Dockerfile.test.yml Normal file
View File

@ -0,0 +1,3 @@
sut:
build: .
command: brew test-bot

View File

@ -5,9 +5,7 @@ AllCops:
- '**/vendor/**/*' - '**/vendor/**/*'
DisplayCopNames: false DisplayCopNames: false
require: require: ./Homebrew/rubocops.rb
- ./Homebrew/rubocops.rb
- rubocop-rspec
# enable all formulae audits # enable all formulae audits
FormulaAudit: FormulaAudit:

View File

@ -37,8 +37,8 @@ begin
homebrew_path = PATH.new(ENV["HOMEBREW_PATH"]) homebrew_path = PATH.new(ENV["HOMEBREW_PATH"])
# Add SCM wrappers. # Add SCM wrappers.
path.append(HOMEBREW_SHIMS_PATH/"scm") path.prepend(HOMEBREW_SHIMS_PATH/"scm")
homebrew_path.append(HOMEBREW_SHIMS_PATH/"scm") homebrew_path.prepend(HOMEBREW_SHIMS_PATH/"scm")
ENV["PATH"] = path ENV["PATH"] = path

View File

@ -55,6 +55,12 @@ git() {
"$HOMEBREW_LIBRARY/Homebrew/shims/scm/git" "$@" "$HOMEBREW_LIBRARY/Homebrew/shims/scm/git" "$@"
} }
numeric() {
# Condense the exploded argument into a single return value.
# shellcheck disable=SC2086,SC2183
printf "%01d%02d%02d%02d" ${1//./ }
}
HOMEBREW_VERSION="$(git -C "$HOMEBREW_REPOSITORY" describe --tags --dirty --abbrev=7 2>/dev/null)" HOMEBREW_VERSION="$(git -C "$HOMEBREW_REPOSITORY" describe --tags --dirty --abbrev=7 2>/dev/null)"
HOMEBREW_USER_AGENT_VERSION="$HOMEBREW_VERSION" HOMEBREW_USER_AGENT_VERSION="$HOMEBREW_VERSION"
if [[ -z "$HOMEBREW_VERSION" ]] if [[ -z "$HOMEBREW_VERSION" ]]
@ -86,7 +92,6 @@ then
HOMEBREW_OS_VERSION="macOS $HOMEBREW_MACOS_VERSION" HOMEBREW_OS_VERSION="macOS $HOMEBREW_MACOS_VERSION"
# Don't change this from Mac OS X to match what macOS itself does in Safari on 10.12 # 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" HOMEBREW_OS_USER_AGENT_VERSION="Mac OS X $HOMEBREW_MACOS_VERSION"
HOMEBREW_BOTTLE_DEFAULT_DOMAIN="https://homebrew.bintray.com"
# The system Curl is too old for some modern HTTPS certificates on # The system Curl is too old for some modern HTTPS certificates on
# older macOS versions. # older macOS versions.
@ -100,7 +105,8 @@ then
HOMEBREW_FORCE_BREWED_CURL="1" HOMEBREW_FORCE_BREWED_CURL="1"
fi fi
# The system Git is too old for some Homebrew functionality we rely on. # 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" ]] if [[ "$HOMEBREW_MACOS_VERSION_NUMERIC" -lt "101200" ]]
then then
HOMEBREW_FORCE_BREWED_GIT="1" HOMEBREW_FORCE_BREWED_GIT="1"
@ -114,13 +120,38 @@ else
[[ -n "$HOMEBREW_LINUX" ]] && HOMEBREW_OS_VERSION="$(lsb_release -sd 2>/dev/null)" [[ -n "$HOMEBREW_LINUX" ]] && HOMEBREW_OS_VERSION="$(lsb_release -sd 2>/dev/null)"
: "${HOMEBREW_OS_VERSION:=$(uname -r)}" : "${HOMEBREW_OS_VERSION:=$(uname -r)}"
HOMEBREW_OS_USER_AGENT_VERSION="$HOMEBREW_OS_VERSION" HOMEBREW_OS_USER_AGENT_VERSION="$HOMEBREW_OS_VERSION"
HOMEBREW_BOTTLE_DEFAULT_DOMAIN="https://linuxbrew.bintray.com"
# Ensure the system Curl is a version that supports modern HTTPS certificates.
HOMEBREW_MINIMUM_CURL_VERSION="7.41.0"
system_curl_version_output="$($(command -v curl) --version 2>/dev/null)"
system_curl_name_and_version="${system_curl_version_output%% (*}"
if [[ $(numeric "${system_curl_name_and_version##* }") -lt $(numeric "$HOMEBREW_MINIMUM_CURL_VERSION") ]]
then
HOMEBREW_SYSTEM_CURL_TOO_OLD="1"
HOMEBREW_FORCE_BREWED_CURL="1"
fi
# Ensure the system Git is at or newer than the minimum required version.
# Git 2.7.4 is the version of git on Ubuntu 16.04 LTS (Xenial Xerus).
HOMEBREW_MINIMUM_GIT_VERSION="2.7.0"
system_git_version_output="$($(command -v git) --version 2>/dev/null)"
if [[ $(numeric "${system_git_version_output##* }") -lt $(numeric "$HOMEBREW_MINIMUM_GIT_VERSION") ]]
then
HOMEBREW_FORCE_BREWED_GIT="1"
fi
CACHE_HOME="${XDG_CACHE_HOME:-${HOME}/.cache}" CACHE_HOME="${XDG_CACHE_HOME:-${HOME}/.cache}"
HOMEBREW_CACHE="${HOMEBREW_CACHE:-${CACHE_HOME}/Homebrew}" HOMEBREW_CACHE="${HOMEBREW_CACHE:-${CACHE_HOME}/Homebrew}"
HOMEBREW_SYSTEM_TEMP="/tmp" HOMEBREW_SYSTEM_TEMP="/tmp"
fi fi
if [[ -n "$HOMEBREW_MACOS" || -n "$HOMEBREW_FORCE_HOMEBREW_ON_LINUX" ]]
then
HOMEBREW_BOTTLE_DEFAULT_DOMAIN="https://homebrew.bintray.com"
else
HOMEBREW_BOTTLE_DEFAULT_DOMAIN="https://linuxbrew.bintray.com"
fi
HOMEBREW_TEMP="${HOMEBREW_TEMP:-${HOMEBREW_SYSTEM_TEMP}}" HOMEBREW_TEMP="${HOMEBREW_TEMP:-${HOMEBREW_SYSTEM_TEMP}}"
if [[ -n "$HOMEBREW_FORCE_BREWED_CURL" && if [[ -n "$HOMEBREW_FORCE_BREWED_CURL" &&
@ -148,8 +179,9 @@ else
fi fi
HOMEBREW_USER_AGENT="$HOMEBREW_PRODUCT/$HOMEBREW_USER_AGENT_VERSION ($HOMEBREW_SYSTEM; $HOMEBREW_PROCESSOR $HOMEBREW_OS_USER_AGENT_VERSION)" HOMEBREW_USER_AGENT="$HOMEBREW_PRODUCT/$HOMEBREW_USER_AGENT_VERSION ($HOMEBREW_SYSTEM; $HOMEBREW_PROCESSOR $HOMEBREW_OS_USER_AGENT_VERSION)"
HOMEBREW_CURL_VERSION="$("$HOMEBREW_CURL" --version 2>/dev/null | head -n1 | awk '{print $1"/"$2}')" curl_version_output="$("$HOMEBREW_CURL" --version 2>/dev/null)"
HOMEBREW_USER_AGENT_CURL="$HOMEBREW_USER_AGENT $HOMEBREW_CURL_VERSION" curl_name_and_version="${curl_version_output%% (*}"
HOMEBREW_USER_AGENT_CURL="$HOMEBREW_USER_AGENT ${curl_name_and_version// //}"
# Declared in bin/brew # Declared in bin/brew
export HOMEBREW_BREW_FILE export HOMEBREW_BREW_FILE
@ -167,6 +199,7 @@ export HOMEBREW_SYSTEM
export HOMEBREW_CURL export HOMEBREW_CURL
export HOMEBREW_SYSTEM_CURL_TOO_OLD export HOMEBREW_SYSTEM_CURL_TOO_OLD
export HOMEBREW_GIT export HOMEBREW_GIT
export HOMEBREW_MINIMUM_GIT_VERSION
export HOMEBREW_PROCESSOR export HOMEBREW_PROCESSOR
export HOMEBREW_PRODUCT export HOMEBREW_PRODUCT
export HOMEBREW_OS_VERSION export HOMEBREW_OS_VERSION

View File

@ -169,7 +169,9 @@ module Cask
end end
end end
def uninstall_login_item(*login_items, command: nil, **_) def uninstall_login_item(*login_items, command: nil, upgrade: false, **_)
return if upgrade
login_items.each do |name| login_items.each do |name|
ohai "Removing login item #{name}" ohai "Removing login item #{name}"
command.run!( command.run!(

View File

@ -424,7 +424,7 @@ module Cask
next unless artifact.respond_to?(:uninstall_phase) next unless artifact.respond_to?(:uninstall_phase)
odebug "Un-installing artifact of class #{artifact.class}" odebug "Un-installing artifact of class #{artifact.class}"
artifact.uninstall_phase(command: @command, verbose: verbose?, skip: clear, force: force?) artifact.uninstall_phase(command: @command, verbose: verbose?, skip: clear, force: force?, upgrade: upgrade?)
end end
end end

View File

@ -42,8 +42,12 @@ module Homebrew
def switch(*names, description: nil, env: nil, required_for: nil, depends_on: nil) def switch(*names, description: nil, env: nil, required_for: nil, depends_on: nil)
global_switch = names.first.is_a?(Symbol) global_switch = names.first.is_a?(Symbol)
names, env, description = common_switch(*names) if global_switch names, env, default_description = common_switch(*names) if global_switch
description = option_to_description(*names) if description.nil? if description.nil? && global_switch
description = default_description
elsif description.nil?
description = option_to_description(*names)
end
process_option(*names, description) process_option(*names, description)
@parser.on(*names, *wrap_option_desc(description)) do @parser.on(*names, *wrap_option_desc(description)) do
enable_switch(*names) enable_switch(*names)
@ -72,20 +76,24 @@ module Homebrew
end end
end end
def flag(name, description: nil, required_for: nil, depends_on: nil) def flag(*names, description: nil, required_for: nil, depends_on: nil)
if name.end_with? "=" if names.any? { |name| name.end_with? "=" }
required = OptionParser::REQUIRED_ARGUMENT required = OptionParser::REQUIRED_ARGUMENT
name.chomp! "="
else else
required = OptionParser::OPTIONAL_ARGUMENT required = OptionParser::OPTIONAL_ARGUMENT
end end
description = option_to_description(name) if description.nil? names.map! { |name| name.chomp "=" }
process_option(name, description) description = option_to_description(*names) if description.nil?
@parser.on(name, *wrap_option_desc(description), required) do |option_value| process_option(*names, description)
Homebrew.args[option_to_name(name)] = option_value @parser.on(*names, *wrap_option_desc(description), required) do |option_value|
names.each do |name|
Homebrew.args[option_to_name(name)] = option_value
end
end end
set_constraints(name, required_for: required_for, depends_on: depends_on) names.each do |name|
set_constraints(name, required_for: required_for, depends_on: depends_on)
end
end end
def conflicts(*options) def conflicts(*options)
@ -118,6 +126,7 @@ module Homebrew
remaining_args = @parser.parse(cmdline_args) remaining_args = @parser.parse(cmdline_args)
check_constraint_violations check_constraint_violations
Homebrew.args[:remaining] = remaining_args Homebrew.args[:remaining] = remaining_args
Homebrew.args.freeze
@parser @parser
end end

View File

@ -25,8 +25,10 @@ module Homebrew
puts "-DCMAKE_INSTALL_PREFIX=#{prefix}" puts "-DCMAKE_INSTALL_PREFIX=#{prefix}"
elsif File.file? "configure" elsif File.file? "configure"
puts "--prefix=#{prefix}" puts "--prefix=#{prefix}"
elsif File.file? "meson.build"
puts "-Dprefix=#{prefix}"
else else
raise "Couldn't determine build system" raise "Couldn't determine build system. You can manually put files into #{prefix}"
end end
end end

View File

@ -10,16 +10,39 @@
# `--list-checks` lists all audit methods # `--list-checks` lists all audit methods
require "diagnostic" require "diagnostic"
require "cli_parser"
module Homebrew module Homebrew
module_function module_function
def doctor_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`doctor` [<options>]
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.
EOS
switch "--list-checks",
description: "List all audit methods."
switch "-D", "--audit-debug",
description: "Enable debugging and profiling of audit methods."
switch :verbose
switch :debug
end
end
def doctor def doctor
inject_dump_stats!(Diagnostic::Checks, /^check_*/) if ARGV.switch? "D" doctor_args.parse
inject_dump_stats!(Diagnostic::Checks, /^check_*/) if args.audit_debug?
checks = Diagnostic::Checks.new checks = Diagnostic::Checks.new
if ARGV.include? "--list-checks" if args.list_checks?
puts checks.all.sort puts checks.all.sort
exit exit
end end
@ -36,7 +59,7 @@ module Homebrew
first_warning = true first_warning = true
methods.each do |method| methods.each do |method|
$stderr.puts "Checking #{method}" if ARGV.debug? $stderr.puts "Checking #{method}" if args.debug?
unless checks.respond_to?(method) unless checks.respond_to?(method)
Homebrew.failed = true Homebrew.failed = true
puts "No check available by the name: #{method}" puts "No check available by the name: #{method}"

View File

@ -1,4 +1,4 @@
#: * `gist-logs` [`--new-issue`|`-n`] <formula>: #: * `gist-logs` [`--new-issue`|`-n`] [`--private`|`-p`] <formula>:
#: Upload logs for a failed build of <formula> to a new Gist. #: 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 #: <formula> is usually the name of the formula to install, but it can be specified
@ -9,6 +9,9 @@
#: If `--new-issue` is passed, automatically create a new issue in the appropriate #: If `--new-issue` is passed, automatically create a new issue in the appropriate
#: GitHub repository as well as creating the Gist. #: 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. #: If no logs are found, an error message is presented.
require "formula" require "formula"
@ -42,8 +45,8 @@ module Homebrew
if GitHub.api_credentials_type == :none if GitHub.api_credentials_type == :none
puts <<~EOS puts <<~EOS
You can create a new personal access token: You can create a new personal access token:
#{GitHub::ALL_SCOPES_URL} #{GitHub::ALL_SCOPES_URL}
and then set the new HOMEBREW_GITHUB_API_TOKEN as the authentication method. #{Utils::Shell.set_variable_in_profile("HOMEBREW_GITHUB_API_TOKEN", "your_token_here")}
EOS EOS
login! login!
@ -77,7 +80,7 @@ module Homebrew
s s
end end
# Hack for ruby < 1.9.3 # Causes some terminals to display secure password entry indicators
def noecho_gets def noecho_gets
system "stty -echo" system "stty -echo"
result = $stdin.gets result = $stdin.gets
@ -110,9 +113,13 @@ module Homebrew
logs logs
end end
def create_private?
ARGV.include?("--private") || ARGV.switch?("p")
end
def create_gist(files, description) def create_gist(files, description)
url = "https://api.github.com/gists" url = "https://api.github.com/gists"
data = { "public" => true, "files" => files, "description" => description } data = { "public" => !create_private?, "files" => files, "description" => description }
scopes = GitHub::CREATE_GIST_SCOPES scopes = GitHub::CREATE_GIST_SCOPES
GitHub.open_api(url, data: data, scopes: scopes)["html_url"] GitHub.open_api(url, data: data, scopes: scopes)["html_url"]
end end

View File

@ -1,11 +1,23 @@
#: * `info`: #: * `info`:
#: Display brief statistics for your Homebrew installation. #: Display brief statistics for your Homebrew installation.
#: #:
#: * `info` <formula> [`--verbose`]: #: * `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 #: Display information about <formula> and analytics data (provided neither
#: `HOMEBREW_NO_ANALYTICS` or `HOMEBREW_NO_GITHUB_API` are set) #: `HOMEBREW_NO_ANALYTICS` or `HOMEBREW_NO_GITHUB_API` are set)
#: #:
#: Pass `--verbose` to see more detailed analytics data. #: Pass `--verbose` to see more verbose analytics data.
#:
#: Pass `--analytics` to see only more verbose analytics data instead of
#: formula information.
#: #:
#: * `info` `--github` <formula>: #: * `info` `--github` <formula>:
#: Open a browser to the GitHub History page for <formula>. #: Open a browser to the GitHub History page for <formula>.
@ -47,7 +59,9 @@ module Homebrew
def print_info def print_info
if ARGV.named.empty? if ARGV.named.empty?
if HOMEBREW_CELLAR.exist? if ARGV.include?("--analytics")
output_analytics
elsif HOMEBREW_CELLAR.exist?
count = Formula.racks.length count = Formula.racks.length
puts "#{count} #{"keg".pluralize(count)}, #{HOMEBREW_CELLAR.abv}" puts "#{count} #{"keg".pluralize(count)}, #{HOMEBREW_CELLAR.abv}"
end end
@ -55,12 +69,21 @@ module Homebrew
ARGV.named.each_with_index do |f, i| ARGV.named.each_with_index do |f, i|
puts unless i.zero? puts unless i.zero?
begin begin
if f.include?("/") || File.exist?(f) formula = if f.include?("/") || File.exist?(f)
info_formula Formulary.factory(f) Formulary.factory(f)
else else
info_formula Formulary.find_with_priority(f) Formulary.find_with_priority(f)
end
if ARGV.include?("--analytics")
output_formula_analytics(formula)
else
info_formula(formula)
end end
rescue FormulaUnavailableError => e rescue FormulaUnavailableError => e
if ARGV.include?("--analytics")
output_analytics(filter: f)
next
end
ofail e.message ofail e.message
# No formula with this name, try a missing formula lookup # No formula with this name, try a missing formula lookup
if (reason = MissingFormula.reason(f)) if (reason = MissingFormula.reason(f))
@ -184,42 +207,165 @@ module Homebrew
caveats = Caveats.new(f) caveats = Caveats.new(f)
ohai "Caveats", caveats.to_s unless caveats.empty? ohai "Caveats", caveats.to_s unless caveats.empty?
output_analytics(f) output_formula_analytics(f)
end end
def output_analytics(f) def formulae_api_json(endpoint)
return if ENV["HOMEBREW_NO_ANALYTICS"] return if ENV["HOMEBREW_NO_ANALYTICS"] || ENV["HOMEBREW_NO_GITHUB_API"]
return if ENV["HOMEBREW_NO_GITHUB_API"]
formulae_json_url = "https://formulae.brew.sh/api/formula/#{f}.json" output, = curl_output("--max-time", "3",
output, = curl_output("--max-time", "3", formulae_json_url) "https://formulae.brew.sh/api/#{endpoint}")
return if output.empty? return if output.blank?
json = begin JSON.parse(output)
JSON.parse(output) rescue JSON::ParserError
rescue JSON::ParserError nil
nil end
def analytics_table(category, days, results, os_version: false)
oh1 "#{category} (#{days} days)"
total_count = results.values.inject("+")
formatted_total_count = format_count(total_count)
formatted_total_percent = format_percent(100)
index_header = "Index"
count_header = "Count"
percent_header = "Percent"
name_with_options_header = if os_version
"macOS Version"
else
"Name (with options)"
end end
return if json.nil? || json.empty? || json["analytics"].empty?
ohai "Analytics" total_index_footer = "Total"
if ARGV.verbose? max_index_width = results.length.to_s.length
json["analytics"].each do |category, value| index_width = [
value.each do |range, results| index_header.length,
oh1 "#{category} (#{range})" total_index_footer.length,
results.each do |name_with_options, count| max_index_width,
puts "#{name_with_options}: #{number_readable(count)}" ].max
end count_width = [
end count_header.length,
formatted_total_count.length,
].max
percent_width = [
percent_header.length,
formatted_total_percent.length,
].max
name_with_options_width = Tty.width -
index_width -
count_width -
percent_width -
10 # spacing and lines
formatted_index_header =
format "%#{index_width}s", index_header
formatted_name_with_options_header =
format "%-#{name_with_options_width}s",
name_with_options_header[0..name_with_options_width-1]
formatted_count_header =
format "%#{count_width}s", count_header
formatted_percent_header =
format "%#{percent_width}s", percent_header
puts "#{formatted_index_header} | #{formatted_name_with_options_header} | "\
"#{formatted_count_header} | #{formatted_percent_header}"
columns_line = "#{"-"*index_width}:|-#{"-"*name_with_options_width}-|-"\
"#{"-"*count_width}:|-#{"-"*percent_width}:"
puts columns_line
index = 0
results.each do |name_with_options, count|
index += 1
formatted_index = format "%0#{max_index_width}d", index
formatted_index = format "%-#{index_width}s", formatted_index
formatted_name_with_options =
format "%-#{name_with_options_width}s",
name_with_options[0..name_with_options_width-1]
formatted_count = format "%#{count_width}s", format_count(count)
formatted_percent = if total_count.zero?
format "%#{percent_width}s", format_percent(0)
else
format "%#{percent_width}s",
format_percent((count.to_i * 100) / total_count.to_f)
end end
puts "#{formatted_index} | #{formatted_name_with_options} | " \
"#{formatted_count} | #{formatted_percent}%"
next if index > 10
end
return unless results.length > 1
formatted_total_footer =
format "%-#{index_width}s", total_index_footer
formatted_blank_footer =
format "%-#{name_with_options_width}s", ""
formatted_total_count_footer =
format "%#{count_width}s", formatted_total_count
formatted_total_percent_footer =
format "%#{percent_width}s", formatted_total_percent
puts "#{formatted_total_footer} | #{formatted_blank_footer} | "\
"#{formatted_total_count_footer} | #{formatted_total_percent_footer}%"
end
def output_analytics(filter: nil)
days = ARGV.value("days") || "30"
valid_days = %w[30 90 365]
unless valid_days.include?(days)
raise ArgumentError("Days must be one of #{valid_days.join(", ")}!")
end
category = ARGV.value("category") || "install"
valid_categories = %w[install install-on-request build-error os-version]
unless valid_categories.include?(category)
raise ArgumentError("Categories must be one of #{valid_categories.join(", ")}")
end
json = formulae_api_json("analytics/#{category}/#{days}d.json")
return if json.blank? || json["items"].blank?
os_version = category == "os-version"
results = {}
json["items"].each do |item|
key = if os_version
item["os_version"]
else
item["formula"]
end
if filter.present?
next if key != filter && !key.start_with?("#{filter} ")
end
results[key] = item["count"].tr(",", "").to_i
end
if filter.present? && results.blank?
onoe "No results matching `#{filter}` found!"
return return
end end
analytics_table(category, days, results, os_version: os_version)
end
def output_formula_analytics(f)
json = formulae_api_json("formula/#{f}.json")
return if json.blank? || json["analytics"].blank?
full_analytics = ARGV.include?("--analytics") || ARGV.verbose?
ohai "Analytics"
json["analytics"].each do |category, value| json["analytics"].each do |category, value|
analytics = value.map do |range, results| analytics = []
"#{number_readable(results.values.inject("+"))} (#{range})"
value.each do |days, results|
days = days.to_i
if full_analytics
analytics_table(category, days, results)
else
total_count = results.values.inject("+")
analytics << "#{number_readable(total_count)} (#{days} days)"
end
end end
puts "#{category}: #{analytics.join(", ")}"
puts "#{category}: #{analytics.join(", ")}" unless full_analytics
end end
end end
@ -247,4 +393,12 @@ module Homebrew
"#{dep.name} #{dep.option_tags.map { |o| "--#{o}" }.join(" ")}" "#{dep.name} #{dep.option_tags.map { |o| "--#{o}" }.join(" ")}"
end end
def format_count(count)
count.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
end
def format_percent(percent)
format "%.2f", percent
end
end end

View File

@ -38,8 +38,6 @@ module Homebrew
def tap def tap
if ARGV.include? "--repair" if ARGV.include? "--repair"
Tap.each(&:link_completions_and_manpages) Tap.each(&:link_completions_and_manpages)
elsif ARGV.include? "--list-official"
odisabled("brew tap --list-official")
elsif ARGV.include? "--list-pinned" elsif ARGV.include? "--list-pinned"
puts Tap.select(&:pinned?).map(&:name) puts Tap.select(&:pinned?).map(&:name)
elsif ARGV.named.empty? elsif ARGV.named.empty?

View File

@ -24,7 +24,7 @@ git() {
git_init_if_necessary() { git_init_if_necessary() {
BREW_OFFICIAL_REMOTE="https://github.com/Homebrew/brew" BREW_OFFICIAL_REMOTE="https://github.com/Homebrew/brew"
if [[ -n "$HOMEBREW_MACOS" ]] || [[ -n "$HOMEBREW_FORCE_HOMEBREW_ORG" ]] if [[ -n "$HOMEBREW_MACOS" ]] || [[ -n "$HOMEBREW_FORCE_HOMEBREW_ON_LINUX" ]]
then then
CORE_OFFICIAL_REMOTE="https://github.com/Homebrew/homebrew-core" CORE_OFFICIAL_REMOTE="https://github.com/Homebrew/homebrew-core"
else else

View File

@ -1,8 +1,7 @@
require "compat/os/mac" require "compat/extend/os/mac/utils/bottles"
require "compat/dependable" require "compat/requirements/x11_requirement"
require "compat/dependency_collector" require "compat/requirements/xcode_requirement"
require "compat/cask"
require "compat/download_strategy" require "compat/download_strategy"
require "compat/fileutils" require "compat/fileutils"
require "compat/formula_support"
require "compat/cask"
require "compat/tap" require "compat/tap"

View File

@ -6,6 +6,8 @@ module Cask
module Compat module Compat
private 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) def cask(header_token, **options, &block)
if header_token.is_a?(Hash) && header_token.key?(:v1) if header_token.is_a?(Hash) && header_token.key?(:v1)
odisabled %q("cask :v1 => 'token'"), %q("cask 'token'") odisabled %q("cask :v1 => 'token'"), %q("cask 'token'")

View File

@ -16,9 +16,7 @@ module Cask
end end
def run def run
odeprecated "`brew cask --version`", "`brew --version`", disable_on: Time.new(2018, 10, 31) odisabled "`brew cask --version`", "`brew --version`"
ARGV.clear
Homebrew.__version
end end
def self.help def self.help

View File

@ -22,18 +22,7 @@ module Cask
end end
def run def run
odeprecated "`brew cask cleanup`", "`brew cleanup`", disable_on: Time.new(2018, 9, 30) odisabled "`brew cask cleanup`", "`brew cleanup`"
cleanup = Homebrew::Cleanup.new
casks(alternative: -> { Cask.to_a }).each do |cask|
cleanup.cleanup_cask(cask)
end
return if cleanup.disk_cleanup_size.zero?
disk_space = disk_usage_readable(cleanup.disk_cleanup_size)
ohai "This operation has freed approximately #{disk_space} of disk space."
end end
end end
end end

View File

@ -6,8 +6,7 @@ module Cask
module Compat module Compat
class Search < AbstractCommand class Search < AbstractCommand
def run def run
odeprecated "`brew cask search`", "`brew search`", disable_on: Time.new(2018, 9, 30) odisabled "`brew cask search`", "`brew search`"
Homebrew.search(args.empty? ? "--casks" : args)
end end
def self.visible def self.visible

View File

@ -1,8 +1,11 @@
module Cask module Cask
class DSL class DSL
module Compat module Compat
# TODO: can't delete this code until the merge of
# https://github.com/Homebrew/brew/pull/4730 or an equivalent.
def gpg(*) def gpg(*)
odeprecated "the `gpg` stanza", disable_on: Time.new(2018, 12, 31) odisabled "the `gpg` stanza"
end end
def license(*) def license(*)
@ -10,7 +13,7 @@ module Cask
end end
def accessibility_access(*) def accessibility_access(*)
odeprecated "the `accessibility_access` stanza" odisabled "the `accessibility_access` stanza"
end end
end end

View File

@ -1,10 +0,0 @@
module Dependable
module Compat
def run?
odisabled "Dependable#run?"
tags.include? :run
end
end
prepend Compat
end

View File

@ -1,12 +0,0 @@
require "dependency_collector"
class DependencyCollector
module Compat
def parse_string_spec(spec, tags)
odisabled "'depends_on ... => :run'" if tags.include?(:run)
super
end
end
prepend Compat
end

View File

@ -10,7 +10,7 @@ require "download_strategy"
class S3DownloadStrategy < CurlDownloadStrategy class S3DownloadStrategy < CurlDownloadStrategy
def initialize(url, name, version, **meta) def initialize(url, name, version, **meta)
odeprecated("S3DownloadStrategy", odeprecated("S3DownloadStrategy",
"maintaining S3DownloadStrategy in your own formula or tap") "a vendored S3DownloadStrategy in your own formula or tap (using require_relative)")
super super
end end
@ -26,6 +26,13 @@ class S3DownloadStrategy < CurlDownloadStrategy
ENV["AWS_ACCESS_KEY_ID"] = ENV["HOMEBREW_AWS_ACCESS_KEY_ID"] ENV["AWS_ACCESS_KEY_ID"] = ENV["HOMEBREW_AWS_ACCESS_KEY_ID"]
ENV["AWS_SECRET_ACCESS_KEY"] = ENV["HOMEBREW_AWS_SECRET_ACCESS_KEY"] 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 begin
signer = Aws::S3::Presigner.new signer = Aws::S3::Presigner.new
s3url = signer.presigned_url :get_object, bucket: bucket, key: key s3url = signer.presigned_url :get_object, bucket: bucket, key: key
@ -52,7 +59,7 @@ class GitHubPrivateRepositoryDownloadStrategy < CurlDownloadStrategy
def initialize(url, name, version, **meta) def initialize(url, name, version, **meta)
odeprecated("GitHubPrivateRepositoryDownloadStrategy", odeprecated("GitHubPrivateRepositoryDownloadStrategy",
"maintaining GitHubPrivateRepositoryDownloadStrategy in your own formula or tap") "a vendored GitHubPrivateRepositoryDownloadStrategy in your own formula or tap (using require_relative)")
super super
parse_url_pattern parse_url_pattern
set_github_token set_github_token
@ -106,7 +113,7 @@ end
class GitHubPrivateRepositoryReleaseDownloadStrategy < GitHubPrivateRepositoryDownloadStrategy class GitHubPrivateRepositoryReleaseDownloadStrategy < GitHubPrivateRepositoryDownloadStrategy
def initialize(url, name, version, **meta) def initialize(url, name, version, **meta)
odeprecated("GitHubPrivateRepositoryReleaseDownloadStrategy", odeprecated("GitHubPrivateRepositoryReleaseDownloadStrategy",
"maintaining GitHubPrivateRepositoryReleaseDownloadStrategy in your own formula or tap") "a vendored GitHubPrivateRepositoryReleaseDownloadStrategy in your own formula or tap (using require_relative)")
super super
end end
@ -162,7 +169,7 @@ end
class ScpDownloadStrategy < AbstractFileDownloadStrategy class ScpDownloadStrategy < AbstractFileDownloadStrategy
def initialize(url, name, version, **meta) def initialize(url, name, version, **meta)
odeprecated("ScpDownloadStrategy", odeprecated("ScpDownloadStrategy",
"maintaining ScpDownloadStrategy in your own formula or tap") "a vendored ScpDownloadStrategy in your own formula or tap (using require_relative)")
super super
parse_url_pattern parse_url_pattern
end end
@ -204,21 +211,15 @@ end
class DownloadStrategyDetector class DownloadStrategyDetector
class << self class << self
module Compat module Compat
def detect(url, using = nil)
strategy = super
require_aws_sdk if strategy == S3DownloadStrategy
strategy
end
def detect_from_url(url) def detect_from_url(url)
case url case url
when %r{^s3://} when %r{^s3://}
odeprecated("s3://", odeprecated("s3://",
"maintaining S3DownloadStrategy in your own formula or tap") "a vendored S3DownloadStrategy in your own formula or tap (using require_relative)")
S3DownloadStrategy S3DownloadStrategy
when %r{^scp://} when %r{^scp://}
odeprecated("scp://", odeprecated("scp://",
"maintaining ScpDownloadStrategy in your own formula or tap") "a vendored ScpDownloadStrategy in your own formula or tap (using require_relative)")
ScpDownloadStrategy ScpDownloadStrategy
else else
super(url) super(url)
@ -229,19 +230,20 @@ class DownloadStrategyDetector
case symbol case symbol
when :github_private_repo when :github_private_repo
odeprecated(":github_private_repo", odeprecated(":github_private_repo",
"maintaining GitHubPrivateRepositoryDownloadStrategy in your own formula or tap") "a vendored GitHubPrivateRepositoryDownloadStrategy in your own formula or tap (using require_relative)")
GitHubPrivateRepositoryDownloadStrategy GitHubPrivateRepositoryDownloadStrategy
when :github_private_release when :github_private_release
odeprecated(":github_private_repo", odeprecated(":github_private_repo",
"maintaining GitHubPrivateRepositoryReleaseDownloadStrategy in your own formula or tap") "a vendored GitHubPrivateRepositoryReleaseDownloadStrategy in your own formula or tap "\
"(using require_relative)")
GitHubPrivateRepositoryReleaseDownloadStrategy GitHubPrivateRepositoryReleaseDownloadStrategy
when :s3 when :s3
odeprecated(":s3", odeprecated(":s3",
"maintaining S3DownloadStrategy in your own formula or tap") "a vendored S3DownloadStrategy in your own formula or tap (using require_relative)")
S3DownloadStrategy S3DownloadStrategy
when :scp when :scp
odeprecated(":scp", odeprecated(":scp",
"maintaining ScpDownloadStrategy in your own formula or tap") "a vendored ScpDownloadStrategy in your own formula or tap (using require_relative)")
ScpDownloadStrategy ScpDownloadStrategy
else else
super(symbol) super(symbol)

View File

@ -0,0 +1,19 @@
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")
odeprecated "`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,16 +2,12 @@ require "fileutils"
module FileUtils module FileUtils
module Compat module Compat
def ruby(*args) def ruby(*)
odeprecated "ruby", 'system "ruby"' odisabled "ruby", 'system "ruby"'
system RUBY_PATH, *args
end end
def mktemp(prefix = name, opts = {}) def mktemp(*)
odeprecated("FileUtils.mktemp", "mktemp") odisabled("FileUtils.mktemp", "mktemp")
Mktemp.new(prefix, opts).run do |staging|
yield staging
end
end end
module_function :mktemp module_function :mktemp
end end

View File

@ -1,75 +0,0 @@
require "formula_support"
class KegOnlyReason
module Compat
def valid?
case @reason
when :provided_pre_mountain_lion
odisabled "keg_only :provided_pre_mountain_lion"
MacOS.version < :mountain_lion
when :provided_pre_mavericks
odisabled "keg_only :provided_pre_mavericks"
MacOS.version < :mavericks
when :provided_pre_el_capitan
odisabled "keg_only :provided_pre_el_capitan"
MacOS.version < :el_capitan
when :provided_pre_high_sierra
odisabled "keg_only :provided_pre_high_sierra"
MacOS.version < :high_sierra
when :provided_until_xcode43
odisabled "keg_only :provided_until_xcode43"
MacOS::Xcode.version < "4.3"
when :provided_until_xcode5
odisabled "keg_only :provided_until_xcode5"
MacOS::Xcode.version < "5.0"
else
super
end
end
def to_s
case @reason
when :provided_pre_mountain_lion
odisabled "keg_only :provided_pre_mountain_lion"
<<~EOS
macOS already provides this software in versions before Mountain Lion
EOS
when :provided_pre_mavericks
odisabled "keg_only :provided_pre_mavericks"
<<~EOS
macOS already provides this software in versions before Mavericks
EOS
when :provided_pre_el_capitan
odisabled "keg_only :provided_pre_el_capitan"
<<~EOS
macOS already provides this software in versions before El Capitan
EOS
when :provided_pre_high_sierra
odisabled "keg_only :provided_pre_high_sierra"
<<~EOS
macOS already provides this software in versions before High Sierra
EOS
when :provided_until_xcode43
odisabled "keg_only :provided_until_xcode43"
<<~EOS
Xcode provides this software prior to version 4.3
EOS
when :provided_until_xcode5
odisabled "keg_only :provided_until_xcode5"
<<~EOS
Xcode provides this software prior to version 5
EOS
else
super
end.to_s.strip
end
end
prepend Compat
end

View File

@ -1,14 +0,0 @@
module OS
module Mac
class << self
module Compat
def release
odisabled "MacOS.release", "MacOS.version"
version
end
end
prepend Compat
end
end
end

View File

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

View File

@ -0,0 +1,21 @@
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/)
odeprecated('depends_on :xcode => [..., "X.Y.Z"]')
tags.delete(tag)
end
end
super(tags)
end
end
prepend Compat
end

View File

@ -116,15 +116,17 @@ class DependencyCollector
def parse_symbol_spec(spec, tags) def parse_symbol_spec(spec, tags)
case spec case spec
when :x11 then X11Requirement.new(spec.to_s, tags) when :arch then ArchRequirement.new(tags)
when :xcode then XcodeRequirement.new(tags) when :codesign then CodesignRequirement.new(tags)
when :linux then LinuxRequirement.new(tags) when :java then JavaRequirement.new(tags)
when :macos then MacOSRequirement.new(tags) when :linux then LinuxRequirement.new(tags)
when :arch then ArchRequirement.new(tags) when :macos then MacOSRequirement.new(tags)
when :java then JavaRequirement.new(tags) when :maximum_macos then MaximumMacOSRequirement.new(tags)
when :osxfuse then OsxfuseRequirement.new(tags) when :osxfuse then OsxfuseRequirement.new(tags)
when :tuntap then TuntapRequirement.new(tags) when :tuntap then TuntapRequirement.new(tags)
when :ld64 then ld64_dep_if_needed(tags) when :x11 then X11Requirement.new(tags)
when :xcode then XcodeRequirement.new(tags)
when :ld64 then ld64_dep_if_needed(tags)
else else
raise ArgumentError, "Unsupported special dependency #{spec.inspect}" raise ArgumentError, "Unsupported special dependency #{spec.inspect}"
end end

View File

@ -1,6 +1,7 @@
#: * `audit` [`--strict`] [`--fix`] [`--online`] [`--new-formula`] [`--display-cop-names`] [`--display-filename`] [`--only=`<method>|`--except=`<method>] [`--only-cops=`<cops>|`--except-cops=`<cops>] [<formulae>]: #: * `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 #: Check <formulae> for Homebrew coding style violations. This should be run
#: run before submitting a new formula. #: 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 <formulae> are provided, all of them are checked.
#: #:
@ -23,16 +24,13 @@
#: If `--display-filename` is passed, every line of output is prefixed with the #: 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. #: name of the file or formula being audited, to make the output easy to grep.
#: #:
#: Passing `--only=`<method> will run only the methods named `audit_<method>`, #: Specifying `--only=`<method> will run only the methods named `audit_`<method>,
#: while `--except=`<method> will skip 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. #: For either option <method> should be a comma-separated list.
#: #:
#: Passing `--only-cops=`<cops> will check for violations of only the listed #: Specifying `--only-cops=`<cops> will check for violations of only the listed
#: RuboCop <cops>, while `--except-cops=`<cops> will skip checking 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. #: <cops>. For either option <cops> should be a comma-separated list of cop names.
#:
#: `audit` exits with a non-zero status if any errors are found. This is useful,
#: for instance, for implementing pre-commit hooks.
# Undocumented options: # Undocumented options:
# `-D` activates debugging and profiling of the audit methods (not the same as `--debug`) # `-D` activates debugging and profiling of the audit methods (not the same as `--debug`)
@ -55,14 +53,15 @@ module Homebrew
def audit_args def audit_args
Homebrew::CLI::Parser.new do Homebrew::CLI::Parser.new do
usage_banner <<~EOS usage_banner <<~EOS
`audit` [<options>] <formulae>: `audit` [<options>] <formulae>
Check <formulae> for Homebrew coding style violations. This should be Check <formulae> for Homebrew coding style violations. This should be run before
run before submitting a new formula. 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 <formulae> are provided, all of them are checked.
EOS EOS
switch "--strict", switch "--strict",
description: "Run additional style checks, including Rubocop style checks." description: "Run additional style checks, including RuboCop style checks."
switch "--online", switch "--online",
description: "Run additional slower style checks that require a network connection." description: "Run additional slower style checks that require a network connection."
switch "--new-formula", switch "--new-formula",
@ -74,24 +73,26 @@ module Homebrew
switch "--display-cop-names", switch "--display-cop-names",
description: "Include the RuboCop cop name for each violation in the output." description: "Include the RuboCop cop name for each violation in the output."
switch "--display-filename", switch "--display-filename",
description: "Prefix everyline of output with name of the file or formula being audited, to "\ description: "Prefix every line of output with name of the file or formula being audited, to "\
"make output easy to grep." "make output easy to grep."
switch "-D", "--audit-debug", switch "-D", "--audit-debug",
description: "Activates debugging and profiling" description: "Enable debugging and profiling of audit methods."
comma_array "--only", comma_array "--only",
description: "Passing `--only=`<method> will run only the methods named audit_<method>. "\ description: "Specify a comma-separated <method> list to only run the methods named "\
"<method> should be a comma-separated list." "`audit_`<method>."
comma_array "--except", comma_array "--except",
description: "Passing `--except=`<method> will run only the methods named audit_<method>, "\ description: "Specify a comma-separated <method> list to skip running the methods named "\
"<method> should be a comma-separated list." "`audit_`<method>."
comma_array "--only-cops", comma_array "--only-cops",
description: "Passing `--only-cops=`<cops> will check for violations of only the listed "\ description: "Specify a comma-separated <cops> list to check for violations of only the listed "\
"RuboCop cops. <cops> should be a comma-separated list of cop names." "RuboCop cops."
comma_array "--except-cops", comma_array "--except-cops",
description: "Passing `--except-cops=`<cops> will skip checking the listed RuboCop cops "\ description: "Specify a comma-separated <cops> list to skip checking for violations of the listed "\
"violations. <cops> should be a comma-separated list of cop names." "RuboCop cops."
switch :verbose switch :verbose
switch :debug switch :debug
conflicts "--only", "--except"
conflicts "--only-cops", "--except-cops"
end end
end end
@ -126,7 +127,7 @@ module Homebrew
if only_cops && except_cops if only_cops && except_cops
odie "--only-cops and --except-cops cannot be used simultaneously!" odie "--only-cops and --except-cops cannot be used simultaneously!"
elsif (only_cops || except_cops) && (strict || args.only) elsif (only_cops || except_cops) && (strict || args.only)
odie "--only-cops/--except-cops and --strict/--only cannot be used simultaneously" odie "--only-cops/--except-cops and --strict/--only cannot be used simultaneously!"
end end
options = { fix: args.fix?, realpath: true } options = { fix: args.fix?, realpath: true }
@ -252,7 +253,9 @@ module Homebrew
def initialize(formula, options = {}) def initialize(formula, options = {})
@formula = formula @formula = formula
@new_formula = options[:new_formula] && !formula.versioned_formula? @versioned_formula = formula.versioned_formula?
@new_formula_inclusive = options[:new_formula]
@new_formula = options[:new_formula] && !@versioned_formula
@strict = options[:strict] @strict = options[:strict]
@online = options[:online] @online = options[:online]
@display_cop_names = options[:display_cop_names] @display_cop_names = options[:display_cop_names]
@ -273,7 +276,7 @@ module Homebrew
@style_offenses.each do |offense| @style_offenses.each do |offense|
if offense.cop_name.start_with?("NewFormulaAudit") if offense.cop_name.start_with?("NewFormulaAudit")
next if formula.versioned_formula? next if @versioned_formula
new_formula_problem offense.to_s(display_cop_name: @display_cop_names) new_formula_problem offense.to_s(display_cop_name: @display_cop_names)
next next
@ -307,7 +310,7 @@ module Homebrew
problem "File should end with a newline" unless text.trailing_newline? problem "File should end with a newline" unless text.trailing_newline?
if formula.versioned_formula? if @versioned_formula
unversioned_formula = begin unversioned_formula = begin
# build this ourselves as we want e.g. homebrew/core to be present # build this ourselves as we want e.g. homebrew/core to be present
full_name = if formula.tap full_name = if formula.tap
@ -493,7 +496,6 @@ module Homebrew
end end
def audit_keg_only_style def audit_keg_only_style
return unless @strict
return unless formula.keg_only? return unless formula.keg_only?
whitelist = %w[ whitelist = %w[
@ -526,7 +528,7 @@ module Homebrew
end end
def audit_versioned_keg_only def audit_versioned_keg_only
return unless formula.versioned_formula? return unless @versioned_formula
return unless @core_tap return unless @core_tap
return if formula.keg_only? && formula.keg_only_reason.reason == :versioned_formula return if formula.keg_only? && formula.keg_only_reason.reason == :versioned_formula
@ -561,6 +563,18 @@ module Homebrew
end end
end end
def audit_bottle_spec
# special case: new versioned formulae should be audited
return unless @new_formula_inclusive
return unless @core_tap
return if formula.bottle_disabled?
return unless formula.bottle_defined?
new_formula_problem "New formulae should not have a `bottle do` block"
end
def audit_bottle_disabled def audit_bottle_disabled
return unless formula.bottle_disabled? return unless formula.bottle_disabled?
return if formula.bottle_unneeded? return if formula.bottle_unneeded?
@ -661,24 +675,27 @@ module Homebrew
end end
end end
if @core_tap && (formula.head || formula.devel) if @core_tap && formula.devel
unstable_spec_message = "Formulae should not have a `HEAD` or `devel` spec" problem "Formulae should not have a `devel` spec"
end
if @core_tap && formula.head
head_spec_message = "Formulae should not have a `HEAD` spec"
if @new_formula if @new_formula
new_formula_problem unstable_spec_message new_formula_problem head_spec_message
elsif formula.versioned_formula? elsif @versioned_formula
versioned_unstable_spec = %w[ versioned_head_spec = %w[
bash-completion@2 bash-completion@2
imagemagick@6 imagemagick@6
python@2 python@2
] ]
problem unstable_spec_message unless versioned_unstable_spec.include?(formula.name) problem head_spec_message unless versioned_head_spec.include?(formula.name)
end end
end end
throttled = %w[ throttled = %w[
aws-sdk-cpp 10 aws-sdk-cpp 10
awscli 10 awscli 10
heroku 10
quicktype 10 quicktype 10
vim 50 vim 50
] ]
@ -687,14 +704,13 @@ module Homebrew
next if formula.stable.nil? next if formula.stable.nil?
version = formula.stable.version.to_s.split(".").last.to_i version = formula.stable.version.to_s.split(".").last.to_i
if @strict && a == formula.name && version.modulo(b.to_i).nonzero? if a == formula.name && version.modulo(b.to_i).nonzero?
problem "should only be updated every #{b} releases on multiples of #{b}" problem "should only be updated every #{b} releases on multiples of #{b}"
end end
end end
unstable_whitelist = %w[ unstable_whitelist = %w[
aalib 1.4rc5 aalib 1.4rc5
angolmois 2.0.0alpha2
automysqlbackup 3.0-rc6 automysqlbackup 3.0-rc6
aview 1.3.0rc1 aview 1.3.0rc1
distcc 3.2rc1 distcc 3.2rc1
@ -703,10 +719,8 @@ module Homebrew
hidapi 0.8.0-rc1 hidapi 0.8.0-rc1
libcaca 0.99b19 libcaca 0.99b19
nethack4 4.3.0-beta2 nethack4 4.3.0-beta2
opensyobon 1.0rc2
premake 4.4-beta5 premake 4.4-beta5
pwnat 0.3-beta pwnat 0.3-beta
pxz 4.999.9
recode 3.7-beta2 recode 3.7-beta2
speexdsp 1.2rc3 speexdsp 1.2rc3
sqoop 1.4.6 sqoop 1.4.6

View File

@ -1,10 +1,10 @@
#: * `bottle` [`--verbose`] [`--no-rebuild`|`--keep-old`] [`--skip-relocation`] [`--or-later`] [`--root-url=`<URL>] [`--force-core-tap`] [`--json`] <formulae>: #: * `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 installed with #: Generate a bottle (binary package) from a formula that was installed with
#: `--build-bottle`. #: `--build-bottle`.
#: #:
#: If the formula specifies a rebuild version, it will be incremented in the #: 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 #: generated DSL. Passing `--keep-old` will attempt to keep it at its original
#: original value, while `--no-rebuild` will remove it. #: value, while `--no-rebuild` will remove it.
#: #:
#: If `--verbose` (or `-v`) is passed, print the bottling commands and any warnings #: If `--verbose` (or `-v`) is passed, print the bottling commands and any warnings
#: encountered. #: encountered.
@ -15,7 +15,7 @@
#: If `--root-url` is passed, use the specified <URL> as the root of the #: If `--root-url` is passed, use the specified <URL> as the root of the
#: bottle's URL instead of Homebrew's default. #: bottle's URL instead of Homebrew's default.
#: #:
#: If `--or-later` is passed, append _or_later to the bottle tag. #: 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 #: If `--force-core-tap` is passed, build a bottle even if <formula> is not
#: in homebrew/core or any installed taps. #: in homebrew/core or any installed taps.
@ -72,13 +72,13 @@ module Homebrew
def bottle_args def bottle_args
Homebrew::CLI::Parser.new do Homebrew::CLI::Parser.new do
usage_banner <<~EOS usage_banner <<~EOS
`bottle` [<options>] <formulae>: `bottle` [<options>] <formulae>
Generate a bottle (binary package) from a formula installed with Generate a bottle (binary package) from a formula that was installed with
`--build-bottle`. `--build-bottle`.
If the formula specifies a rebuild version, it will be incremented in the 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 generated DSL. Passing `--keep-old` will attempt to keep it at its original
original value, while `--no-rebuild` will remove it. value, while `--no-rebuild` will remove it.
EOS EOS
switch "--skip-relocation", switch "--skip-relocation",
description: "Do not check if the bottle can be marked as relocatable." description: "Do not check if the bottle can be marked as relocatable."
@ -87,28 +87,30 @@ module Homebrew
switch "--force-core-tap", switch "--force-core-tap",
description: "Build a bottle even if <formula> is not in homebrew/core or any installed taps." description: "Build a bottle even if <formula> is not in homebrew/core or any installed taps."
switch "--no-rebuild", switch "--no-rebuild",
description: "If the formula specifies a rebuild version, it will be removed in the generated DSL." description: "If the formula specifies a rebuild version, remove it from the generated DSL."
switch "--keep-old", switch "--keep-old",
description: "If the formula specifies a rebuild version, it will attempted to be kept in the "\ description: "If the formula specifies a rebuild version, attempt to preserve its value in the "\
" generated DSL." "generated DSL."
switch "--merge",
description: "Generate a bottle from a formula and print the new DSL merged into the "\
"existing formula."
switch "--write",
description: "Changes will be written to the formula file. A new commit will be generated unless "\
"`--no-commit` is passed."
switch "--no-commit",
description: "When passed with `--write`, a new commit will not generated while writing changes "\
"to the formula file.",
depends_on: "--write"
switch "--json", switch "--json",
description: "Write bottle information to a JSON file, which can be used as the argument for "\ description: "Write bottle information to a JSON file, which can be used as the argument for "\
"`--merge`." "`--merge`."
switch "--merge",
description: "Generate an updated bottle block for a formula and optionally merge it into the "\
"formula file. Instead of a formula name, requires a JSON file generated with "\
"`brew bottle --json` <formula>."
switch "--write",
depends_on: "--merge",
description: "Write the changes to the formula file. A new commit will be generated unless "\
"`--no-commit` is passed."
switch "--no-commit",
depends_on: "--write",
description: "When passed with `--write`, a new commit will not generated after writing changes "\
"to the formula file."
flag "--root-url", flag "--root-url",
description: "Use the specified <URL> as the root of the bottle's URL instead of Homebrew's "\ description: "Use the specified <URL> as the root of the bottle's URL instead of Homebrew's default."
"default."
switch :verbose switch :verbose
switch :debug switch :debug
conflicts "--no-rebuild", "--keep-old"
end end
end end
@ -228,7 +230,7 @@ module Homebrew
unless tap = f.tap unless tap = f.tap
unless args.force_core_tap? unless args.force_core_tap?
return ofail "Formula not from core or any taps: #{f.full_name}" return ofail "Formula not from core or any installed taps: #{f.full_name}"
end end
tap = CoreTap.instance tap = CoreTap.instance

View File

@ -1,11 +1,11 @@
#: * `bump-formula-pr` [`--devel`] [`--dry-run` [`--write`]] [`--audit`|`--strict`] [`--mirror=`<URL>] [`--version=`<version>] [`--message=`<message>] (`--url=`<URL> `--sha256=`<sha-256>|`--tag=`<tag> `--revision=`<revision>) <formula>: #: * `bump-formula-pr` [`--devel`] [`--dry-run` [`--write`]] [`--audit`|`--strict`] [`--no-browse] [`--mirror=`<URL>] [`--version=`<version>] [`--message=`<message>] (`--url=`<URL> `--sha256=`<SHA-256>|`--tag=`<tag> `--revision=`<revision>) [<formula>]:
#: Creates a pull request to update the formula with a new URL or a new tag. #: 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 must #: 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> #: 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. #: 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 #: If a <tag> is specified, the Git commit <revision> corresponding to that
#: tag must also be specified. #: tag must also be specified.
#: #:
#: If `--devel` is passed, bump the development rather than stable version. #: If `--devel` is passed, bump the development rather than stable version.
@ -13,8 +13,8 @@
#: #:
#: If `--dry-run` is passed, print what would be done rather than doing it. #: 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 #: 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. #: making the expected file modifications but not taking any Git actions.
#: #:
#: If `--audit` is passed, run `brew audit` before opening the PR. #: If `--audit` is passed, run `brew audit` before opening the PR.
#: #:
@ -24,7 +24,7 @@
#: #:
#: If `--version=`<version> is passed, use the value to override the value #: 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 #: 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. #: an existing version override from a formula if it has become redundant.
#: #:
#: If `--message=`<message> is passed, append <message> to the default PR #: If `--message=`<message> is passed, append <message> to the default PR
#: message. #: message.
@ -36,8 +36,8 @@
#: If `--quiet` is passed, don't output replacement messages or warn about #: If `--quiet` is passed, don't output replacement messages or warn about
#: duplicate pull requests. #: duplicate pull requests.
#: #:
#: Note that this command cannot be used to transition a formula from a #: *Note:* this command cannot be used to transition a formula from a
#: URL-and-sha256 style specification into a tag-and-revision style #: URL-and-SHA-256 style specification into a tag-and-revision style
#: specification, nor vice versa. It must use whichever style specification #: specification, nor vice versa. It must use whichever style specification
#: the preexisting formula already uses. #: the preexisting formula already uses.
@ -50,57 +50,58 @@ module Homebrew
def bump_formula_pr_args def bump_formula_pr_args
Homebrew::CLI::Parser.new do Homebrew::CLI::Parser.new do
usage_banner <<~EOS usage_banner <<~EOS
`bump-formula-pr` [<options>] <formula>: `bump-formula-pr` [<options>] [<formula>]
Creates a pull request to update the formula with a new URL or a new tag. 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 must If a <URL> is specified, the <SHA-256> checksum of the new download should also
also be specified. A best effort to determine the <sha-256> and <formula> be specified. A best effort to determine the <SHA-256> and <formula> name will
name will be made if either or both values are not supplied by the user. 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 If a <tag> is specified, the Git commit <revision> corresponding to that tag
tag must also be specified. must also be specified.
Note that this command cannot be used to transition a formula from a *Note:* this command cannot be used to transition a formula from a
URL-and-sha256 style specification into a tag-and-revision style URL-and-SHA-256 style specification into a tag-and-revision style specification,
specification, nor vice versa. It must use whichever style specification nor vice versa. It must use whichever style specification the preexisting
the preexisting formula already uses. formula already uses.
EOS EOS
switch "--devel", switch "--devel",
description: "Bump the development rather than stable version. The development spec must already exist." description: "Bump the development rather than stable version. The development spec must already exist."
switch "-n", "--dry-run", switch "-n", "--dry-run",
description: "Print what would be done rather than doing it." description: "Print what would be done rather than doing it."
switch "--write", switch "--write",
description: "When passed along with `--dry-run`, perform a not-so-dry run making the expected "\ depends_on: "--dry-run",
"file modifications but not taking any git actions." description: "When passed along with `--dry-run`, perform a not-so-dry run by making the expected "\
"file modifications but not taking any Git actions."
switch "--audit", switch "--audit",
description: "Run `brew audit` before opening the PR." description: "Run `brew audit` before opening the PR."
switch "--strict", switch "--strict",
description: "Run `brew audit --strict` before opening the PR." description: "Run `brew audit --strict` before opening the PR."
switch "--no-browse", switch "--no-browse",
description: "Output the pull request URL instead of opening in a browser" description: "Print the pull request URL instead of opening in a browser."
flag "--url=", flag "--mirror=",
description: "Provide new <URL> for the formula. If a <URL> is specified, the <sha-256> "\
"checksum of the new download must also be specified."
flag "--revision=",
description: "Specify the new git commit <revision> corresponding to a specified <tag>."
flag "--tag=",
required_for: "--revision=",
description: "Specify the new git commit <tag> for the formula."
flag "--sha256=",
depends_on: "--url=",
description: "Specify the <sha-256> checksum of new download."
flag "--mirror=",
description: "Use the provided <URL> as a mirror URL." description: "Use the provided <URL> as a mirror URL."
flag "--version=", flag "--version=",
description: "Use the provided <version> to override the value parsed from the URL or tag. Note "\ description: "Use the provided <version> 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 "\ "that `--version=0` can be used to delete an existing version override from a "\
"formula if it has become redundant." "formula if it has become redundant."
flag "--message=", flag "--message=",
description: "Append provided <message> to the default PR message." description: "Append the provided <message> to the default PR message."
flag "--url=",
description: "Specify the <URL> for the new download. If a <URL> is specified, the <SHA-256> "\
"checksum of the new download should also be specified."
flag "--sha256=",
depends_on: "--url=",
description: "Specify the <SHA-256> checksum of the new download."
flag "--tag=",
description: "Specify the new git commit <tag> for the formula."
flag "--revision=",
required_for: "--tag=",
description: "Specify the new git commit <revision> corresponding to a specified <tag>."
switch :quiet
switch :force switch :force
switch :quiet
switch :verbose switch :verbose
switch :debug switch :debug
conflicts "--url", "--tag" conflicts "--url", "--tag"
@ -352,7 +353,7 @@ module Homebrew
"#{new_formula_version}#{devel_message}' -- #{formula.path}" "#{new_formula_version}#{devel_message}' -- #{formula.path}"
ohai "git push --set-upstream $HUB_REMOTE #{branch}:#{branch}" ohai "git push --set-upstream $HUB_REMOTE #{branch}:#{branch}"
ohai "create pull request with GitHub API" ohai "create pull request with GitHub API"
ohai "git checkout -" ohai "git checkout --quiet -"
else else
begin begin

View File

@ -1,17 +1,17 @@
#: * `create` <URL> [`--autotools`|`--cmake`|`--meson`] [`--no-fetch`] [`--set-name` <name>] [`--set-version` <version>] [`--tap` <user>`/`<repo>]: #: * `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. #: Generate a formula for the downloadable file at <URL> and open it in the editor.
#: Homebrew will attempt to automatically derive the formula name #: 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` #: 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 have a look at #: formula serves as a simple example. For the complete API, see:
#: <https://www.rubydoc.info/github/Homebrew/brew/master/Formula>. #: <https://www.rubydoc.info/github/Homebrew/brew/master/Formula>
#: #:
#: If `--autotools` is passed, create a basic template for an Autotools-style build. #: 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 `--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 `--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 #: If `--no-fetch` is passed, Homebrew will not download <URL> to the cache and
#: will thus not add the SHA256 to the formula for you. It will also not check #: 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 the description and homepage). #: 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 #: 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. #: you to explicitly set the name and version of the package you are creating.
@ -30,13 +30,13 @@ module Homebrew
def create_args def create_args
Homebrew::CLI::Parser.new do Homebrew::CLI::Parser.new do
usage_banner <<~EOS usage_banner <<~EOS
`create` <URL> [<options>]: `create` [<options>] <URL>
Generate a formula for the downloadable file at <URL> and open it in the editor. Generate a formula for the downloadable file at <URL> and open it in the editor.
Homebrew will attempt to automatically derive the formula name Homebrew will attempt to automatically derive the formula name and version, but
and version, but if it fails, you'll have to make your own template. The `wget` if it fails, you'll have to make your own template. The `wget` formula serves as
formula serves as a simple example. For the complete API have a look at a simple example. For the complete API, see:
<http://www.rubydoc.info/github/Homebrew/brew/master/Formula>. <http://www.rubydoc.info/github/Homebrew/brew/master/Formula>
EOS EOS
switch "--autotools", switch "--autotools",
description: "Create a basic template for an Autotools-style build." description: "Create a basic template for an Autotools-style build."
@ -45,17 +45,17 @@ module Homebrew
switch "--meson", switch "--meson",
description: "Create a basic template for a Meson-style build." description: "Create a basic template for a Meson-style build."
switch "--no-fetch", switch "--no-fetch",
description: "Homebrew will not download <URL> to the cache and will thus not add the SHA256 to "\ description: "Homebrew will not download <URL> to the cache and will thus not add the SHA-256 "\
"the formula for you. It will also not check the GitHub API for GitHub projects "\ "to the formula for you, nor will it check the GitHub API for GitHub projects "\
"(to fill out the description and homepage)." "(to fill out its description and homepage)."
switch "--HEAD" switch "--HEAD",
description: "Indicate that <URL> points to the package's repository rather than a file."
flag "--set-name=", flag "--set-name=",
description: "Set the provided name of the package you are creating." description: "Set the name of the new formula to the provided <name>."
flag "--set-version=", flag "--set-version=",
description: "Set the provided version of the package you are creating." description: "Set the version of the new formula to the provided <version>."
flag "--tap=", flag "--tap=",
description: "Takes a tap [<user>`/`<repo>] as argument and generates the formula in the "\ description: "Generate the new formula in the provided tap, specified as <user>`/`<repo>."
"specified tap."
switch :force switch :force
switch :verbose switch :verbose
switch :debug switch :debug

View File

@ -1,8 +1,8 @@
#: * `edit`: #: * `edit`:
#: Open all of Homebrew for editing. #: Open the Homebrew repository for editing.
#: #:
#: * `edit` <formula>: #: * `edit` <formula>:
#: Open <formula> in the editor. #: Open <formula> in the editor set by `EDITOR` or `HOMEBREW_EDITOR`.
require "formula" require "formula"
require "cli_parser" require "cli_parser"
@ -13,9 +13,10 @@ module Homebrew
def edit_args def edit_args
Homebrew::CLI::Parser.new do Homebrew::CLI::Parser.new do
usage_banner <<~EOS usage_banner <<~EOS
`edit` <formula>: `edit` [<formulae>]
Open <formula> in the editor. Open all of Homebrew for editing if
no <formula> is provided. Open a formula in the editor set by `EDITOR` or `HOMEBREW_EDITOR`, or open the
Homebrew repository for editing if no <formula> is provided.
EOS EOS
switch :force switch :force
switch :verbose switch :verbose
@ -29,7 +30,7 @@ module Homebrew
unless (HOMEBREW_REPOSITORY/".git").directory? unless (HOMEBREW_REPOSITORY/".git").directory?
raise <<~EOS raise <<~EOS
Changes will be lost! Changes will be lost!
The first time you `brew update', all local changes will be lost, you should The first time you `brew update', all local changes will be lost; you should
thus `brew update' before you `brew edit'! thus `brew update' before you `brew edit'!
EOS EOS
end end

View File

@ -1,7 +1,7 @@
#: * `extract` [`--force`] <formula> <tap> [`--version=`<version>]: #: * `extract` [`--force`] <formula> <tap> [`--version=`<version>]:
#: Looks through repository history to find the <version> of <formula> and #: Look through repository history to find the most recent version of <formula> and
#: creates a copy in <tap>/Formula/<formula>@<version>.rb. If the tap is #: create a copy in <tap>`/Formula/`<formula>`@`<version>`.rb`. If the tap is
#: not installed yet, attempts to install/clone the tap before continuing. #: not installed yet, attempt to install/clone the tap before continuing.
#: #:
#: If `--force` is passed, the file at the destination will be overwritten #: If `--force` is passed, the file at the destination will be overwritten
#: if it already exists. Otherwise, existing files will be preserved. #: if it already exists. Otherwise, existing files will be preserved.
@ -99,18 +99,17 @@ module Homebrew
def extract_args def extract_args
Homebrew::CLI::Parser.new do Homebrew::CLI::Parser.new do
usage_banner <<~EOS usage_banner <<~EOS
`extract` [<options>] <formula> <tap>: `extract` [<options>] <formula> <tap>
Looks through repository history to find the <version> of <formula> and Look through repository history to find the most recent version of <formula> and
creates a copy in <tap>/Formula/<formula>@<version>.rb. If the tap is create a copy in <tap>`/Formula/`<formula>`@`<version>`.rb`. If the tap is not
not installed yet, attempts to install/clone the tap before continuing. installed yet, attempt to install/clone the tap before continuing.
EOS EOS
flag "--version=", flag "--version=",
description: "Provided <version> of <formula> will be extracted and placed in the destination "\ description: "Extract the provided <version> of <formula> instead of the most recent."
"tap. Otherwise, the most recent version that can be found will be used."
switch :debug
switch :force switch :force
switch :debug
end end
end end
@ -128,7 +127,7 @@ module Homebrew
repo = CoreTap.instance.path repo = CoreTap.instance.path
# Formulae can technically live in "<repo>/<formula>.rb" or # Formulae can technically live in "<repo>/<formula>.rb" or
# "<repo>/Formula/<formula>.rb", but explicitly use the latter for now # "<repo>/Formula/<formula>.rb", but explicitly use the latter for now
# since that is now core tap is structured. # since that is how the core tap is structured.
file = repo/"Formula/#{name}.rb" file = repo/"Formula/#{name}.rb"
if args.version if args.version
@ -175,7 +174,7 @@ module Homebrew
odie <<~EOS odie <<~EOS
Destination formula already exists: #{path} Destination formula already exists: #{path}
To overwrite it and continue anyways, run: To overwrite it and continue anyways, run:
`brew extract #{name} --version=#{version} --tap=#{destination_tap.name} --force` brew extract --force --version=#{version} #{name} #{destination_tap.name}
EOS EOS
end end
ohai "Overwriting existing formula at #{path}" if ARGV.debug? ohai "Overwriting existing formula at #{path}" if ARGV.debug?

View File

@ -1,5 +1,5 @@
#: * `formula` <formula>: #: * `formula` <formulae>:
#: Display the path where <formula> is located. #: Display the path where a formula is located.
require "formula" require "formula"
require "cli_parser" require "cli_parser"
@ -10,12 +10,12 @@ module Homebrew
def formula_args def formula_args
Homebrew::CLI::Parser.new do Homebrew::CLI::Parser.new do
usage_banner <<~EOS usage_banner <<~EOS
`formula` <formula>: `formula` <formulae>
Display the path where <formula> is located. Display the path where a formula is located.
EOS EOS
switch :debug
switch :verbose switch :verbose
switch :debug
end end
end end

View File

@ -2,8 +2,9 @@
#: Enter the interactive Homebrew Ruby shell. #: Enter the interactive Homebrew Ruby shell.
#: #:
#: If `--examples` is passed, several examples will be shown. #: If `--examples` is passed, several examples will be shown.
#: If `--pry` is passed or HOMEBREW_PRY is set, pry will be #:
#: used instead of irb. #: If `--pry` is passed or `HOMEBREW_PRY` is set, Pry will be
#: used instead of IRB.
require "cli_parser" require "cli_parser"
@ -25,7 +26,7 @@ module Homebrew
def irb_args def irb_args
Homebrew::CLI::Parser.new do Homebrew::CLI::Parser.new do
usage_banner <<~EOS usage_banner <<~EOS
`irb` [<options>]: `irb` [<options>]
Enter the interactive Homebrew Ruby shell. Enter the interactive Homebrew Ruby shell.
EOS EOS
@ -33,7 +34,7 @@ module Homebrew
description: "Show several examples." description: "Show several examples."
switch "--pry", switch "--pry",
env: :pry, env: :pry,
description: "Pry will be used instead of irb if `--pry` is passed or HOMEBREW_PRY is set." description: "Use Pry instead of IRB. Implied if `HOMEBREW_PRY` is set."
end end
end end

View File

@ -1,14 +1,12 @@
#: * `linkage` [`--test`] [`--reverse`] [<formulae>]: #: * `linkage` [`--test`] [`--reverse`] [<formulae>]:
#: Checks the library links of installed formulae. #: Check the library links for kegs of installed formulae.
#: #: Raises an error if run on uninstalled formulae.
#: Only works on installed formulae. An error is raised if it is run on
#: uninstalled formulae.
#: #:
#: If `--test` is passed, only display missing libraries and exit with a #: If `--test` is passed, only display missing libraries and exit with a
#: non-zero exit code if any missing libraries were found. #: non-zero status if any missing libraries are found.
#: #:
#: If `--reverse` is passed, print the dylib followed by the binaries #: If `--reverse` is passed, for every library that a keg references,
#: which link to it for each library the keg references. #: print its dylib path followed by the binaries that link to it.
#: #:
#: If <formulae> are given, check linkage for only the specified brews. #: If <formulae> are given, check linkage for only the specified brews.
@ -22,21 +20,19 @@ module Homebrew
def linkage_args def linkage_args
Homebrew::CLI::Parser.new do Homebrew::CLI::Parser.new do
usage_banner <<~EOS usage_banner <<~EOS
`linkage` [<options>] <formula>: `linkage` [<options>] [<formulae>]
Checks the library links of an installed formula. Check the library links for kegs of installed formulae.
Raises an error if run on uninstalled formulae.
Only works on installed formulae. An error is raised if it is run on
uninstalled formulae.
EOS EOS
switch "--test", switch "--test",
description: "Display only missing libraries and exit with a non-zero exit code if any missing "\ description: "Display only missing libraries and exit with a non-zero status if any missing "\
"libraries were found." "libraries are found."
switch "--reverse", switch "--reverse",
description: "Print the dylib followed by the binaries which link to it for each library the keg "\ description: "For every library that a keg references, print its dylib path followed by the "\
"references." "binaries that link to it."
switch "--cached", switch "--cached",
description: "Print the cached linkage values stored in HOMEBREW_CACHE, set from a previous "\ description: "Print the cached linkage values stored in `HOMEBREW_CACHE`, set by a previous "\
"`brew linkage` run." "`brew linkage` run."
switch :verbose switch :verbose
switch :debug switch :debug

View File

@ -16,14 +16,17 @@ require "dev-cmd/bottle"
require "dev-cmd/bump-formula-pr" require "dev-cmd/bump-formula-pr"
require "dev-cmd/create" require "dev-cmd/create"
require "dev-cmd/edit" require "dev-cmd/edit"
require "dev-cmd/extract"
require "dev-cmd/formula" require "dev-cmd/formula"
require "dev-cmd/irb" require "dev-cmd/irb"
require "dev-cmd/linkage" require "dev-cmd/linkage"
require "dev-cmd/mirror" require "dev-cmd/mirror"
require "dev-cmd/prof"
require "dev-cmd/pull" require "dev-cmd/pull"
require "dev-cmd/extract"
require "dev-cmd/release-notes" require "dev-cmd/release-notes"
require "dev-cmd/ruby"
require "dev-cmd/tap-new" require "dev-cmd/tap-new"
require "dev-cmd/test"
require "dev-cmd/tests" require "dev-cmd/tests"
require "dev-cmd/update-test" require "dev-cmd/update-test"
@ -37,7 +40,7 @@ module Homebrew
def man_args def man_args
Homebrew::CLI::Parser.new do Homebrew::CLI::Parser.new do
usage_banner <<~EOS usage_banner <<~EOS
`man` [<options>]: `man` [<options>]
Generate Homebrew's manpages. Generate Homebrew's manpages.
EOS EOS
@ -47,7 +50,7 @@ module Homebrew
"the date used in new manpages will match those in the existing manpages (to allow "\ "the date used in new manpages will match those in the existing manpages (to allow "\
"comparison without factoring in the date)." "comparison without factoring in the date)."
switch "--link", switch "--link",
description: "It is now done automatically by `brew update`." description: "This is now done automatically by `brew update`."
end end
end end
@ -186,6 +189,7 @@ module Homebrew
def generate_cmd_manpages(glob) def generate_cmd_manpages(glob)
cmd_paths = Pathname.glob(glob).sort cmd_paths = Pathname.glob(glob).sort
man_page_lines = [] man_page_lines = []
man_args = Homebrew.args
cmd_paths.each do |cmd_path| cmd_paths.each do |cmd_path|
begin begin
cmd_parser = Homebrew.send(cmd_arg_parser(cmd_path)) cmd_parser = Homebrew.send(cmd_arg_parser(cmd_path))
@ -194,6 +198,7 @@ module Homebrew
man_page_lines << path_glob_commands(cmd_path.to_s).first man_page_lines << path_glob_commands(cmd_path.to_s).first
end end
end end
Homebrew.args = man_args
man_page_lines man_page_lines
end end
@ -220,15 +225,16 @@ module Homebrew
end end
def generate_option_doc(short, long, desc) def generate_option_doc(short, long, desc)
"* #{format_short_opt(short)} #{format_long_opt(long)}:" + "\n" + desc + "\n" comma = (short && long) ? ", " : ""
"* #{format_short_opt(short)}" + comma + "#{format_long_opt(long)}:" + "\n " + desc + "\n"
end end
def format_short_opt(opt) def format_short_opt(opt)
"`#{opt}`, " unless opt.nil? "`#{opt}`" unless opt.nil?
end end
def format_long_opt(opt) def format_long_opt(opt)
"`#{opt}`" "`#{opt}`" unless opt.nil?
end end
def format_usage_banner(usage_banner) def format_usage_banner(usage_banner)

View File

@ -10,19 +10,19 @@ module Homebrew
def mirror_args def mirror_args
Homebrew::CLI::Parser.new do Homebrew::CLI::Parser.new do
usage_banner <<~EOS usage_banner <<~EOS
`mirror` <formulae>: `mirror` <formulae>
Reuploads the stable URL for a formula to Bintray to use it as a mirror. Reuploads the stable URL for a formula to Bintray to use it as a mirror.
EOS EOS
switch :debug
switch :verbose switch :verbose
switch :debug
end end
end end
def mirror def mirror
mirror_args.parse mirror_args.parse
odie "This command requires at least formula argument!" if ARGV.named.empty? odie "This command requires at least one formula argument!" if ARGV.named.empty?
bintray_user = ENV["HOMEBREW_BINTRAY_USER"] bintray_user = ENV["HOMEBREW_BINTRAY_USER"]
bintray_key = ENV["HOMEBREW_BINTRAY_KEY"] bintray_key = ENV["HOMEBREW_BINTRAY_KEY"]

View File

@ -1,11 +1,23 @@
#: * `prof` [<ruby options>]: #: * `prof` [<ruby options>]:
#: Run Homebrew with the Ruby profiler. #: Run Homebrew with the Ruby profiler.
#: For example: #:
#: brew prof readall #: *Example:* `brew prof readall`
module Homebrew module Homebrew
module_function module_function
def prof_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`prof` [<ruby options>]
Run Homebrew with the Ruby profiler.
*Example:* `brew prof readall`
EOS
end
end
def prof def prof
Homebrew.install_gem_setup_path! "ruby-prof" Homebrew.install_gem_setup_path! "ruby-prof"
FileUtils.mkdir_p "prof" FileUtils.mkdir_p "prof"

View File

@ -1,6 +1,6 @@
#: * `pull` [`--bottle`] [`--bump`] [`--clean`] [`--ignore-whitespace`] [`--resolve`] [`--branch-okay`] [`--no-pbcopy`] [`--no-publish`] [`--warn-on-publish-failure`] [`--bintray-org=`<bintray-org>] [`--test-bot-user=`<test-bot-user>] <patch-source> [<patch-source>]: #: * `pull` [`--bottle`] [`--bump`] [`--clean`] [`--ignore-whitespace`] [`--resolve`] [`--branch-okay`] [`--no-pbcopy`] [`--no-publish`] [`--warn-on-publish-failure`] [`--bintray-org=`<bintray-org>] [`--test-bot-user=`<test-bot-user>] <patch-source> [<patch-source>]:
#: Gets a patch from a GitHub commit or pull request and applies it to Homebrew. #: Get a patch from a GitHub commit or pull request and apply it to Homebrew.
#: Optionally, installs the formulae changed by the patch. #: Optionally, publish updated bottles for the formulae changed by the patch.
#: #:
#: Each <patch-source> may be one of: #: Each <patch-source> may be one of:
#: #:
@ -41,11 +41,11 @@
#: If `--warn-on-publish-failure` was passed, do not exit if there's a #: If `--warn-on-publish-failure` was passed, do not exit if there's a
#: failure publishing bottles on Bintray. #: failure publishing bottles on Bintray.
#: #:
#: If `--bintray-org=`<bintray-org> is passed, publish at the given Bintray #: If `--bintray-org=`<bintray-org> is passed, publish at the provided Bintray
#: organisation. #: organisation.
#: #:
#: If `--test-bot-user=`<test-bot-user> is passed, pull the bottle block #: If `--test-bot-user=`<test-bot-user> is passed, pull the bottle block
#: commit from the specified user on GitHub. #: commit from the provided user on GitHub.
require "net/http" require "net/http"
require "net/https" require "net/https"
@ -74,12 +74,12 @@ module Homebrew
def pull_args def pull_args
Homebrew::CLI::Parser.new do Homebrew::CLI::Parser.new do
usage_banner <<~EOS usage_banner <<~EOS
`pull` [<options>] <formula>: `pull` [<options>] <patch sources>
Gets a patch from a GitHub commit or pull request and applies it to Homebrew. Get a patch from a GitHub commit or pull request and apply it to Homebrew.
Optionally, installs the formulae changed by the patch. Optionally, publish updated bottles for the formulae changed by the patch.
Each <patch-source> may be one of: Each <patch source> may be one of:
~ The ID number of a PR (pull request) in the homebrew/core GitHub ~ The ID number of a PR (pull request) in the homebrew/core GitHub
repository repository
@ -112,9 +112,9 @@ module Homebrew
switch "--warn-on-publish-failure", switch "--warn-on-publish-failure",
description: "Do not exit if there's a failure publishing bottles on Bintray." description: "Do not exit if there's a failure publishing bottles on Bintray."
flag "--bintray-org=", flag "--bintray-org=",
description: "Publish at the given Bintray organisation." description: "Publish bottles at the provided Bintray <organisation>."
flag "--test-bot-user=", flag "--test-bot-user=",
description: "Pull the bottle block commit from the specified user on GitHub." description: "Pull the bottle block commit from the provided <user> on GitHub."
switch :verbose switch :verbose
switch :debug switch :debug
end end

View File

@ -1,9 +1,9 @@
#: * `release-notes` [`--markdown`] [<previous_tag>] [<end_ref>]: #: * `release-notes` [`--markdown`] [<previous_tag>] [<end_ref>]:
#: Output the merged pull requests on Homebrew/brew between two Git refs. #: Print the merged pull requests on Homebrew/brew between two Git refs.
#: If no <previous_tag> is provided it defaults to the latest tag. #: If no <previous_tag> is provided it defaults to the latest tag.
#: If no <end_ref> is provided it defaults to `origin/master`. #: If no <end_ref> is provided it defaults to `origin/master`.
#: #:
#: If `--markdown` is passed, output as a Markdown list. #: If `--markdown` is passed, print as a Markdown list.
require "cli_parser" require "cli_parser"
@ -13,14 +13,14 @@ module Homebrew
def release_notes_args def release_notes_args
Homebrew::CLI::Parser.new do Homebrew::CLI::Parser.new do
usage_banner <<~EOS usage_banner <<~EOS
`release-notes` [<options>] [<previous_tag>] [<end_ref>]: `release-notes` [<options>] [<previous_tag>] [<end_ref>]
Output the merged pull requests on Homebrew/brew between two Git refs. Print the merged pull requests on Homebrew/brew between two Git refs.
If no <previous_tag> is provided it defaults to the latest tag. If no <previous_tag> is provided it defaults to the latest tag.
If no <end_ref> is provided it defaults to `origin/master`. If no <end_ref> is provided it defaults to `origin/master`.
EOS EOS
switch "--markdown", switch "--markdown",
description: "Output as a Markdown list." description: "Print as a Markdown list."
end end
end end

View File

@ -1,13 +1,32 @@
#: * `ruby` [<ruby options>]: #: * `ruby` [<ruby options>]:
#: Run a Ruby instance with Homebrew's libraries loaded. #: Run a Ruby instance with Homebrew's libraries loaded.
#: For example: #:
# brew ruby -e "puts :gcc.f.deps" #: *Example:* `brew ruby -e "puts :gcc.f.deps"` or `brew ruby script.rb`
# brew ruby script.rb
require "cli_parser"
module Homebrew module Homebrew
module_function module_function
def ruby_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`ruby` [<ruby options>]
Run a Ruby instance with Homebrew's libraries loaded.
*Example:* `brew ruby -e "puts :gcc.f.deps"` or `brew ruby script.rb`
EOS
switch "-e",
description: "Execute the provided string argument as a script."
switch :verbose
switch :debug
end
end
def ruby def ruby
ruby_args.parse
exec ENV["HOMEBREW_RUBY_PATH"], "-I", $LOAD_PATH.join(File::PATH_SEPARATOR), "-rglobal", "-rdev-cmd/irb", *ARGV exec ENV["HOMEBREW_RUBY_PATH"], "-I", $LOAD_PATH.join(File::PATH_SEPARATOR), "-rglobal", "-rdev-cmd/irb", *ARGV
end end
end end

View File

@ -7,23 +7,15 @@ require "cli_parser"
module Homebrew module Homebrew
module_function module_function
def write_path(tap, filename, content)
path = tap.path/filename
tap.path.mkpath
raise "#{path} already exists" if path.exist?
path.write content
end
def tap_new_args def tap_new_args
Homebrew::CLI::Parser.new do Homebrew::CLI::Parser.new do
usage_banner <<~EOS usage_banner <<~EOS
`tap-new` <user>/<repo>: `tap-new` <user>`/`<repo>
Generate the template files for a new tap. Generate the template files for a new tap.
EOS EOS
switch :debug
switch :verbose switch :verbose
switch :debug
end end
end end
@ -84,4 +76,12 @@ module Homebrew
YAML YAML
write_path(tap, ".travis.yml", travis) write_path(tap, ".travis.yml", travis)
end end
def write_path(tap, filename, content)
path = tap.path/filename
tap.path.mkpath
raise "#{path} already exists" if path.exist?
path.write content
end
end end

View File

@ -1,8 +1,7 @@
#: * `test` [`--devel`|`--HEAD`] [`--debug`] [`--keep-tmp`] <formula>: #: * `test` [`--devel`|`--HEAD`] [`--debug`] [`--keep-tmp`] <formulae>:
#: Most formulae provide a test method. `brew test` <formula> runs this #: Run the test method provided by a formula.
#: test method. There is no standard output or return code, but it should #: There is no standard output or return code, but generally it should notify the
#: generally indicate to the user if something is wrong with the installed #: user if something is wrong with the installed formula.
#: formula.
#: #:
#: To test the development or head version of a formula, use `--devel` or #: To test the development or head version of a formula, use `--devel` or
#: `--HEAD`. #: `--HEAD`.
@ -13,7 +12,7 @@
#: If `--keep-tmp` is passed, the temporary files created for the test are #: If `--keep-tmp` is passed, the temporary files created for the test are
#: not deleted. #: not deleted.
#: #:
#: Example: `brew install jruby && brew test jruby` #: *Example:* `brew install jruby && brew test jruby`
require "extend/ENV" require "extend/ENV"
require "formula_assertions" require "formula_assertions"
@ -23,6 +22,28 @@ require "timeout"
module Homebrew module Homebrew
module_function module_function
def test_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`test` [<options>] <formulae>
Run the test method provided by an installed formula.
There is no standard output or return code, but generally it should notify the
user if something is wrong with the installed formula.
*Example:* `brew install jruby && brew test jruby`
EOS
switch "--devel",
description: "Test the development version of a formula."
switch "--HEAD",
description: "Test the head version of a formula."
switch "--keep-tmp",
description: "Keep the temporary files created for the test."
switch :verbose
switch :debug
end
end
def test def test
raise FormulaUnspecifiedError if ARGV.named.empty? raise FormulaUnspecifiedError if ARGV.named.empty?

View File

@ -1,6 +1,6 @@
#: * `tests` [`--verbose`] [`--coverage`] [`--generic`] [`--no-compat`] [`--only=`<test_script>[`:`<line_number>]] [`--seed=`<seed>] [`--online`] [`--official-cmd-taps`]: #: * `tests` [`--verbose`] [`--coverage`] [`--generic`] [`--no-compat`] [`--only=`<test_script>[`:`<line_number>]] [`--seed=`<seed>] [`--online`]:
#: Run Homebrew's unit and integration tests. If provided, #: Run Homebrew's unit and integration tests. If provided,
#: `--only=`<test_script> runs only <test_script>_spec.rb, and `--seed` #: `--only=`<test_script> runs only <test_script>`_spec.rb`, and `--seed`
#: randomizes tests with the provided value instead of a random seed. #: randomizes tests with the provided value instead of a random seed.
#: #:
#: If `--verbose` (or `-v`) is passed, print the command that runs the tests. #: If `--verbose` (or `-v`) is passed, print the command that runs the tests.
@ -24,25 +24,24 @@ module Homebrew
def tests_args def tests_args
Homebrew::CLI::Parser.new do Homebrew::CLI::Parser.new do
usage_banner <<~EOS usage_banner <<~EOS
`tests` [<options>]: `tests` [<options>]
Run Homebrew's unit and integration tests. If provided, Run Homebrew's unit and integration tests.
`--only=`<test_script> runs only <test_script>_spec.rb, and `--seed`
randomizes tests with the provided value instead of a random seed.
EOS EOS
switch "--coverage", switch "--coverage",
description: "Generate code coverage reports." description: "Generate code coverage reports."
switch "--generic", switch "--generic",
description: "Run only OS-agnostic tests." description: "Run only OS-agnostic tests."
switch "--no-compat", switch "--no-compat",
description: "Do not load the compatibility layer when running tests." description: "Do not load the compatibility layer when running tests."
switch "--online", switch "--online",
description: "Include tests that use the GitHub API and tests that use any of the taps for "\ description: "Include tests that use the GitHub API and tests that use any of the taps for "\
"official external commands." "official external commands."
flag "--only=", flag "--only=",
description: "Run only <test_script>_spec.rb" description: "Run only <test_script>`_spec.rb`. Appending `:`<line_number> will start at a "\
"specific line."
flag "--seed=", flag "--seed=",
description: "Randomizes tests with the provided value instead of a random seed." description: "Randomize tests with the provided <value> instead of a random seed."
switch :verbose switch :verbose
switch :debug switch :debug
end end

View File

@ -1,5 +1,5 @@
#: * `update-test` [`--commit=`<commit>] [`--before=`<date>] [`--to-tag`] [`--keep-tmp`]: #: * `update-test` [`--commit=`<commit>] [`--before=`<date>] [`--to-tag`] [`--keep-tmp`]:
#: Runs a test of `brew update` with a new repository clone. #: Run a test of `brew update` with a new repository clone.
#: #:
#: If no arguments are passed, use `origin/master` as the start commit. #: If no arguments are passed, use `origin/master` as the start commit.
#: #:
@ -22,10 +22,9 @@ module Homebrew
def update_test_args def update_test_args
Homebrew::CLI::Parser.new do Homebrew::CLI::Parser.new do
usage_banner <<~EOS usage_banner <<~EOS
`update-test` [<options>]: `update-test` [<options>]
Runs a test of `brew update` with a new repository clone.
Run a test of `brew update` with a new repository clone.
If no arguments are passed, use `origin/master` as the start commit. If no arguments are passed, use `origin/master` as the start commit.
EOS EOS
switch "--to-tag", switch "--to-tag",

View File

@ -489,8 +489,7 @@ module Homebrew
end end
def check_git_version def check_git_version
# System Git version on macOS Sierra. minimum_version = ENV["HOMEBREW_MINIMUM_GIT_VERSION"].freeze
minimum_version = "2.14.3".freeze
return unless Utils.git_available? return unless Utils.git_available?
return if Version.create(Utils.git_version) >= Version.create(minimum_version) return if Version.create(Utils.git_version) >= Version.create(minimum_version)

View File

@ -352,8 +352,9 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy
end end
end end
filenames = lines.map { |line| line[/^Content\-Disposition:\s*attachment;\s*filename=(["']?)([^;]+)\1/i, 2] } filenames =
.compact lines.map { |line| line[/^Content\-Disposition:\s*(?:inline|attachment);\s*filename=(["']?)([^;]+)\1/i, 2] }
.compact
basename = filenames.last || parse_basename(redirect_url) basename = filenames.last || parse_basename(redirect_url)

View File

@ -0,0 +1 @@
require "extend/os/mac/keg" if OS.mac?

View File

@ -1,5 +1,8 @@
class Keg class Keg
def relocate_dynamic_linkage(relocation) def relocate_dynamic_linkage(relocation)
# Patching the dynamic linker of glibc breaks it.
return if name == "glibc"
# Patching patchelf using itself fails with "Text file busy" or SIGBUS. # Patching patchelf using itself fails with "Text file busy" or SIGBUS.
return if name == "patchelf" return if name == "patchelf"
@ -83,4 +86,17 @@ class Keg
def self.relocation_formulae def self.relocation_formulae
["patchelf"] ["patchelf"]
end end
def self.bottle_dependencies
@bottle_dependencies ||= begin
formulae = relocation_formulae
gcc = Formula["gcc"]
if !ENV["HOMEBREW_FORCE_HOMEBREW_ON_LINUX"] &&
DevelopmentTools.non_apple_gcc_version("gcc") < gcc.version.to_i
formulae += gcc.recursive_dependencies.map(&:name)
formulae << gcc.name
end
formulae
end
end
end end

View File

@ -1,6 +1,6 @@
class CoreTap < Tap class CoreTap < Tap
def default_remote def default_remote
if ENV["HOMEBREW_FORCE_HOMEBREW_ORG"] if ENV["HOMEBREW_FORCE_HOMEBREW_ON_LINUX"]
"https://github.com/Homebrew/homebrew-core".freeze "https://github.com/Homebrew/homebrew-core".freeze
else else
"https://github.com/Linuxbrew/homebrew-core".freeze "https://github.com/Linuxbrew/homebrew-core".freeze

View File

@ -0,0 +1,4 @@
class Keg
GENERIC_KEG_LINK_DIRECTORIES = remove_const :KEG_LINK_DIRECTORIES
KEG_LINK_DIRECTORIES = (GENERIC_KEG_LINK_DIRECTORIES + ["Frameworks"]).freeze
end

View File

@ -1,15 +0,0 @@
require "requirement"
class NonBinaryOsxfuseRequirement < Requirement
fatal true
satisfy(build_env: false) do
HOMEBREW_PREFIX.to_s != "/usr/local" || !OsxfuseRequirement.binary_osxfuse_installed?
end
def message
<<~EOS
osxfuse is already installed from the binary distribution and
conflicts with this formula.
EOS
end
end

View File

@ -42,6 +42,10 @@ module Utils
altivec_tag if key?(altivec_tag) altivec_tag if key?(altivec_tag)
end end
def tag_without_or_later(tag)
tag
end
# Find a bottle built for a previous version of macOS. # Find a bottle built for a previous version of macOS.
def find_older_compatible_tag(tag) def find_older_compatible_tag(tag)
begin begin
@ -51,13 +55,12 @@ module Utils
end end
keys.find do |key| keys.find do |key|
# TODO: move to compat? key_tag_version = tag_without_or_later(key)
key_tag_version = if key.to_s.end_with?("_or_later") begin
key.to_s[/(\w+)_or_later$/, 1].to_sym MacOS::Version.from_symbol(key_tag_version) <= tag_version
else rescue ArgumentError
key false
end end
MacOS::Version.from_symbol(key_tag_version) <= tag_version
end end
end end
end end

View File

@ -1,3 +0,0 @@
if OS.mac?
require "extend/os/mac/requirements/non_binary_osxfuse_requirement"
end

View File

@ -165,13 +165,14 @@ class Pathname
# The enclosing `mktmpdir` and the `chmod` are a workaround # The enclosing `mktmpdir` and the `chmod` are a workaround
# for https://github.com/rails/rails/pull/34037. # for https://github.com/rails/rails/pull/34037.
Dir.mktmpdir(".d", dirname) do |tmpdir| Dir.mktmpdir(".d", dirname) do |tmpdir|
should_fix_sticky_bit = dirname.world_writable? && !dirname.sticky?
FileUtils.chmod "+t", dirname if should_fix_sticky_bit
begin begin
FileUtils.chmod "+t", dirname File.atomic_write(self, tmpdir) do |file|
rescue Errno::EPERM file.write(content)
:ignore end
end ensure
File.atomic_write(self, tmpdir) do |file| FileUtils.chmod "-t", dirname if should_fix_sticky_bit
file.write(content)
end end
end end
end end

View File

@ -2532,7 +2532,6 @@ class Formula
# version '4.8.1' # version '4.8.1'
# end</pre> # end</pre>
def fails_with(compiler, &block) def fails_with(compiler, &block)
odisabled "fails_with :llvm" if compiler == :llvm
specs.each { |spec| spec.fails_with(compiler, &block) } specs.each { |spec| spec.fails_with(compiler, &block) }
end end

View File

@ -489,14 +489,20 @@ class FormulaInstaller
end end
end end
if pour_bottle && !Keg.relocation_formulae.include?(formula.name) if pour_bottle && !Keg.bottle_dependencies.empty?
bottle_deps = Keg.relocation_formulae bottle_deps = if !Keg.bottle_dependencies.include?(formula.name)
.map { |formula| Dependency.new(formula) } Keg.bottle_dependencies
.reject do |dep| elsif !Keg.relocation_formulae.include?(formula.name)
Keg.relocation_formulae
else
[]
end
bottle_deps = bottle_deps.map { |formula| Dependency.new(formula) }
.reject do |dep|
inherited_options[dep.name] |= inherited_options_for(dep) inherited_options[dep.name] |= inherited_options_for(dep)
dep.satisfied? inherited_options[dep.name] dep.satisfied? inherited_options[dep.name]
end end
expanded_deps = Dependency.merge_repeats(bottle_deps + expanded_deps) unless bottle_deps.empty? expanded_deps = Dependency.merge_repeats(bottle_deps + expanded_deps)
end end
expanded_deps.map { |dep| [dep, inherited_options[dep.name]] } expanded_deps.map { |dep| [dep, inherited_options[dep.name]] }

View File

@ -54,7 +54,7 @@ HOMEBREW_USER_AGENT_FAKE_SAFARI =
# `HOMEBREW_BOTTLE_DEFAULT_DOMAIN` isn't set. # `HOMEBREW_BOTTLE_DEFAULT_DOMAIN` isn't set.
HOMEBREW_BOTTLE_DEFAULT_DOMAIN = if ENV["HOMEBREW_BOTTLE_DEFAULT_DOMAIN"] HOMEBREW_BOTTLE_DEFAULT_DOMAIN = if ENV["HOMEBREW_BOTTLE_DEFAULT_DOMAIN"]
ENV["HOMEBREW_BOTTLE_DEFAULT_DOMAIN"] ENV["HOMEBREW_BOTTLE_DEFAULT_DOMAIN"]
elsif OS.mac? elsif OS.mac? || ENV["HOMEBREW_FORCE_HOMEBREW_ON_LINUX"]
"https://homebrew.bintray.com".freeze "https://homebrew.bintray.com".freeze
else else
"https://linuxbrew.bintray.com".freeze "https://linuxbrew.bintray.com".freeze

View File

@ -66,7 +66,7 @@ class Keg
LOCALEDIR_RX = %r{(locale|man)/([a-z]{2}|C|POSIX)(_[A-Z]{2})?(\.[a-zA-Z\-0-9]+(@.+)?)?} LOCALEDIR_RX = %r{(locale|man)/([a-z]{2}|C|POSIX)(_[A-Z]{2})?(\.[a-zA-Z\-0-9]+(@.+)?)?}
INFOFILE_RX = %r{info/([^.].*?\.info|dir)$} INFOFILE_RX = %r{info/([^.].*?\.info|dir)$}
KEG_LINK_DIRECTORIES = %w[ KEG_LINK_DIRECTORIES = %w[
bin etc include lib sbin share var Frameworks bin etc include lib sbin share var
].freeze ].freeze
MUST_EXIST_SUBDIRECTORIES = ( MUST_EXIST_SUBDIRECTORIES = (
KEG_LINK_DIRECTORIES - %w[var] + %w[ KEG_LINK_DIRECTORIES - %w[var] + %w[
@ -672,3 +672,5 @@ class Keg
end end
end end
end end
require "extend/os/keg"

View File

@ -187,6 +187,10 @@ class Keg
def self.relocation_formulae def self.relocation_formulae
[] []
end end
def self.bottle_dependencies
relocation_formulae
end
end end
require "extend/os/keg_relocate" require "extend/os/keg_relocate"

View File

@ -10,7 +10,7 @@
# When done, regenerate the man page and its HTML version by running `brew man`. # When done, regenerate the man page and its HTML version by running `brew man`.
%> %>
brew(1) -- The missing package manager for macOS brew(1) -- The missing package manager for macOS
=============================================== ================================================
## SYNOPSIS ## SYNOPSIS
@ -105,6 +105,7 @@ can take several different forms:
The formula file will be cached for later use. The formula file will be cached for later use.
## ENVIRONMENT ## ENVIRONMENT
Note that environment variables must have a value set to be detected. For example, `export HOMEBREW_NO_INSECURE_REDIRECT=1` rather than just `export HOMEBREW_NO_INSECURE_REDIRECT`. Note that environment variables must have a value set to be detected. For example, `export HOMEBREW_NO_INSECURE_REDIRECT=1` rather than just `export HOMEBREW_NO_INSECURE_REDIRECT`.
* `HOMEBREW_ARTIFACT_DOMAIN`: * `HOMEBREW_ARTIFACT_DOMAIN`:
@ -180,22 +181,16 @@ Note that environment variables must have a value set to be detected. For exampl
editors will do strange things in this case. editors will do strange things in this case.
* `HOMEBREW_FORCE_BREWED_CURL`: * `HOMEBREW_FORCE_BREWED_CURL`:
If set, Homebrew will use a Homebrew-installed `curl` rather than the If set, Homebrew will always use a Homebrew-installed `curl` rather than the
system version. system version. Automatically set if the system version of `curl` is too old.
* `HOMEBREW_FORCE_VENDOR_RUBY`: * `HOMEBREW_FORCE_VENDOR_RUBY`:
If set, Homebrew will always use its vendored, relocatable Ruby version If set, Homebrew will always use its vendored, relocatable Ruby version
even if the system version of Ruby is new enough. even if the system version of Ruby is new enough.
* `HOMEBREW_GIT`:
When using Git, Homebrew will use `GIT` if set,
a Homebrew-built Git if installed, or the system-provided binary.
Set this to force Homebrew to use a particular git binary.
* `HOMEBREW_FORCE_BREWED_GIT`: * `HOMEBREW_FORCE_BREWED_GIT`:
If set, Homebrew will use a Homebrew-installed `git` rather than the If set, Homebrew will always use a Homebrew-installed `git` rather than the
system version. system version. Automatically set if the system version of `git` is too old.
* `HOMEBREW_GITHUB_API_TOKEN`: * `HOMEBREW_GITHUB_API_TOKEN`:
A personal access token for the GitHub API, which you can create at A personal access token for the GitHub API, which you can create at

View File

@ -1,3 +1,7 @@
module Homebrew module Homebrew
DEFAULT_PREFIX = "/home/linuxbrew/.linuxbrew".freeze DEFAULT_PREFIX = if ENV["HOMEBREW_FORCE_HOMEBREW_ON_LINUX"]
"/usr/local".freeze
else
"/home/linuxbrew/.linuxbrew".freeze
end
end end

View File

@ -150,10 +150,6 @@ class Requirement
attr_reader :env_proc, :build attr_reader :env_proc, :build
attr_rw :fatal, :cask, :download attr_rw :fatal, :cask, :download
def default_formula(_val = nil)
odisabled "Requirement.default_formula"
end
def satisfy(options = nil, &block) def satisfy(options = nil, &block)
return @satisfied if options.nil? && !block_given? return @satisfied if options.nil? && !block_given?

View File

@ -1,11 +1,11 @@
require "requirement" require "requirement"
require "requirements/arch_requirement"
require "requirements/codesign_requirement"
require "requirements/java_requirement"
require "requirements/linux_requirement" require "requirements/linux_requirement"
require "requirements/macos_requirement" require "requirements/macos_requirement"
require "requirements/maximum_macos_requirement" require "requirements/maximum_macos_requirement"
require "requirements/osxfuse_requirement" require "requirements/osxfuse_requirement"
require "requirements/java_requirement"
require "requirements/tuntap_requirement" require "requirements/tuntap_requirement"
require "requirements/unsigned_kext_requirement"
require "requirements/x11_requirement" require "requirements/x11_requirement"
require "requirements/arch_requirement"
require "requirements/xcode_requirement" require "requirements/xcode_requirement"

View File

@ -3,9 +3,9 @@ require "requirement"
class ArchRequirement < Requirement class ArchRequirement < Requirement
fatal true fatal true
def initialize(arch) def initialize(tags)
@arch = arch.pop @arch = tags.shift
super super(tags)
end end
satisfy(build_env: false) do satisfy(build_env: false) do

View File

@ -0,0 +1,32 @@
class CodesignRequirement < Requirement
fatal true
def initialize(tags)
options = tags.shift
unless options.is_a?(Hash)
raise ArgumentError("CodesignRequirement requires an options Hash!")
end
unless options.key?(:identity)
raise ArgumentError("CodesignRequirement requires an identity key!")
end
@identity = options.fetch(:identity)
@with = options.fetch(:with, "code signing")
@url = options.fetch(:url, nil)
super(tags)
end
satisfy(build_env: false) do
mktemp do
FileUtils.cp "/usr/bin/false", "codesign_check"
quiet_system "/usr/bin/codesign", "-f", "-s", @identity,
"--dryrun", "codesign_check"
end
end
def message
message = "#{@identity} identity must be available to build with #{@with}"
message += ":\n#{@url}" if @url.present?
message
end
end

View File

@ -27,7 +27,7 @@ class JavaRequirement < Requirement
def initialize(tags = []) def initialize(tags = [])
@version = tags.shift if /(\d+\.)+\d/ =~ tags.first @version = tags.shift if /(\d+\.)+\d/ =~ tags.first
super super(tags)
end end
def message def message
@ -39,7 +39,7 @@ class JavaRequirement < Requirement
end end
def inspect def inspect
"#<#{self.class.name}: #{name.inspect} #{tags.inspect} version=#{@version.inspect}>" "#<#{self.class.name}: #{tags.inspect} version=#{@version.inspect}>"
end end
def display_s def display_s

View File

@ -4,8 +4,8 @@ class MacOSRequirement < Requirement
fatal true fatal true
def initialize(tags = []) def initialize(tags = [])
@version = MacOS::Version.from_symbol(tags.first) unless tags.empty? @version = MacOS::Version.from_symbol(tags.shift) unless tags.empty?
super super(tags)
end end
def minimum_version_specified? def minimum_version_specified?

View File

@ -4,8 +4,8 @@ class MaximumMacOSRequirement < Requirement
fatal true fatal true
def initialize(tags) def initialize(tags)
@version = MacOS::Version.from_symbol(tags.first) @version = MacOS::Version.from_symbol(tags.shift)
super super(tags)
end end
satisfy(build_env: false) { MacOS.version <= @version } satisfy(build_env: false) { MacOS.version <= @version }

View File

@ -1,7 +0,0 @@
require "requirement"
class NonBinaryOsxfuseRequirement < Requirement
fatal false
end
require "extend/os/requirements/non_binary_osxfuse_requirement"

View File

@ -1,16 +0,0 @@
require "requirement"
class UnsignedKextRequirement < Requirement
fatal true
satisfy(build_env: false) { MacOS.version < :yosemite }
def message
s = <<~EOS
Building this formula from source isn't possible due to OS X
Yosemite (10.10) and above's strict unsigned kext ban.
EOS
s += super
s
end
end

View File

@ -10,13 +10,6 @@ class X11Requirement < Requirement
env { ENV.x11 } env { ENV.x11 }
def initialize(name = "x11", tags = [])
@name = name
# no-op on version specified as a tag argument
tags.shift if /(\d\.)+\d/ =~ tags.first
super(tags)
end
def min_version def min_version
"1.12.2" "1.12.2"
end end
@ -51,7 +44,7 @@ class X11Requirement < Requirement
end end
def inspect def inspect
"#<#{self.class.name}: #{name.inspect} #{tags.inspect}>" "#<#{self.class.name}: #{tags.inspect}>"
end end
end end

View File

@ -6,8 +6,8 @@ class XcodeRequirement < Requirement
satisfy(build_env: false) { xcode_installed_version } satisfy(build_env: false) { xcode_installed_version }
def initialize(tags = []) def initialize(tags = [])
@version = tags.find { |tag| tags.delete(tag) if tag =~ /(\d\.)+\d/ } @version = tags.shift if tags.first.to_s.match?(/(\d\.)+\d/)
super super(tags)
end end
def xcode_installed_version def xcode_installed_version
@ -40,6 +40,6 @@ class XcodeRequirement < Requirement
end end
def inspect def inspect
"#<#{self.class.name}: #{name.inspect} #{tags.inspect} version=#{@version.inspect}>" "#<#{self.class.name}: #{tags.inspect} version=#{@version.inspect}>"
end end
end end

View File

@ -1,5 +1,6 @@
require_relative "load_path" require_relative "load_path"
require "rubocop-rspec"
require "rubocops/formula_desc_cop" require "rubocops/formula_desc_cop"
require "rubocops/components_order_cop" require "rubocops/components_order_cop"
require "rubocops/components_redundancy_cop" require "rubocops/components_redundancy_cop"

View File

@ -6,6 +6,7 @@ module RuboCop
# This cop audits `options` in Formulae. # This cop audits `options` in Formulae.
class Options < FormulaCop class Options < FormulaCop
DEPRECATION_MSG = "macOS has been 64-bit only since 10.6 so 32-bit options are deprecated.".freeze DEPRECATION_MSG = "macOS has been 64-bit only since 10.6 so 32-bit options are deprecated.".freeze
UNI_DEPRECATION_MSG = "macOS has been 64-bit only since 10.6 so universal options are deprecated.".freeze
def audit_formula(_node, _class_node, _parent_class_node, body_node) def audit_formula(_node, _class_node, _parent_class_node, body_node)
option_call_nodes = find_every_method_call_by_name(body_node, :option) option_call_nodes = find_every_method_call_by_name(body_node, :option)
@ -13,20 +14,11 @@ module RuboCop
option = parameters(option_call).first option = parameters(option_call).first
problem DEPRECATION_MSG if regex_match_group(option, /32-bit/) problem DEPRECATION_MSG if regex_match_group(option, /32-bit/)
end end
end
end
end
module FormulaAuditStrict
class Options < FormulaCop
DEPRECATION_MSG = "macOS has been 64-bit only since 10.6 so universal options are deprecated.".freeze
def audit_formula(_node, _class_node, _parent_class_node, body_node)
option_call_nodes = find_every_method_call_by_name(body_node, :option)
option_call_nodes.each do |option_call| option_call_nodes.each do |option_call|
offending_node(option_call) offending_node(option_call)
option = string_content(parameters(option_call).first) option = string_content(parameters(option_call).first)
problem DEPRECATION_MSG if option == "universal" problem UNI_DEPRECATION_MSG if option == "universal"
if option !~ /with(out)?-/ && if option !~ /with(out)?-/ &&
option != "cxx11" && option != "cxx11" &&

View File

@ -43,6 +43,7 @@ module RuboCop
%r{^http://code\.google\.com/}, %r{^http://code\.google\.com/},
%r{^http://fossies\.org/}, %r{^http://fossies\.org/},
%r{^http://mirrors\.kernel\.org/}, %r{^http://mirrors\.kernel\.org/},
%r{^http://mirrors\.ocf\.berkeley\.edu/},
%r{^http://(?:[^/]*\.)?bintray\.com/}, %r{^http://(?:[^/]*\.)?bintray\.com/},
%r{^http://tools\.ietf\.org/}, %r{^http://tools\.ietf\.org/},
%r{^http://launchpad\.net/}, %r{^http://launchpad\.net/},
@ -125,10 +126,19 @@ module RuboCop
problem <<~EOS problem <<~EOS
Please use a secure mirror for Debian URLs. Please use a secure mirror for Debian URLs.
We recommend: We recommend:
https://mirrors.ocf.berkeley.edu/debian/#{match[1]} https://deb.debian.org/debian/#{match[1]}
EOS EOS
end end
# Check to use canonical urls for Debian packages
noncanon_deb_pattern =
Regexp.union([%r{^https://mirrors\.kernel\.org/debian/},
%r{^https://mirrors\.ocf\.berkeley\.edu/debian/},
%r{^https://(?:[^/]*\.)?mirrorservice\.org/sites/ftp\.debian\.org/debian/}])
audit_urls(urls, noncanon_deb_pattern) do |_, url|
problem "Please use https://deb.debian.org/debian/ for #{url}"
end
# Check for new-url Google Code download urls, https:// is preferred # Check for new-url Google Code download urls, https:// is preferred
google_code_pattern = Regexp.union([%r{^http://.*\.googlecode\.com/files.*}, google_code_pattern = Regexp.union([%r{^http://.*\.googlecode\.com/files.*},
%r{^http://code\.google\.com/}]) %r{^http://code\.google\.com/}])

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# This script because we support $GIT, $HOMEBREW_SVN, etc., Xcode-only and # This script because we support $HOMEBREW_GIT, $HOMEBREW_SVN, etc., Xcode-only and
# no Xcode/CLT configurations. Order is careful to be what the user would want. # no Xcode/CLT configurations. Order is careful to be what the user would want.
set +o posix set +o posix

View File

@ -212,7 +212,6 @@ class SoftwareSpec
end end
def fails_with(compiler, &block) def fails_with(compiler, &block)
odisabled "fails_with :llvm" if compiler == :llvm
compiler_failures << CompilerFailure.create(compiler, &block) compiler_failures << CompilerFailure.create(compiler, &block)
end end

View File

@ -123,7 +123,6 @@ class SystemConfig
HOMEBREW_CACHE: "#{ENV["HOME"]}/Library/Caches/Homebrew", HOMEBREW_CACHE: "#{ENV["HOME"]}/Library/Caches/Homebrew",
HOMEBREW_TEMP: ENV["HOMEBREW_SYSTEM_TEMP"], HOMEBREW_TEMP: ENV["HOMEBREW_SYSTEM_TEMP"],
HOMEBREW_RUBY_WARNINGS: "-W0", HOMEBREW_RUBY_WARNINGS: "-W0",
HOMEBREW_GIT: "git",
}.freeze }.freeze
boring_keys = %w[ boring_keys = %w[
HOMEBREW_BROWSER HOMEBREW_BROWSER
@ -137,10 +136,12 @@ class SystemConfig
HOMEBREW_BREW_FILE HOMEBREW_BREW_FILE
HOMEBREW_COMMAND_DEPTH HOMEBREW_COMMAND_DEPTH
HOMEBREW_CURL HOMEBREW_CURL
HOMEBREW_GIT
HOMEBREW_GIT_CONFIG_FILE HOMEBREW_GIT_CONFIG_FILE
HOMEBREW_LIBRARY HOMEBREW_LIBRARY
HOMEBREW_MACOS_VERSION HOMEBREW_MACOS_VERSION
HOMEBREW_MACOS_VERSION_NUMERIC HOMEBREW_MACOS_VERSION_NUMERIC
HOMEBREW_MINIMUM_GIT_VERSION
HOMEBREW_RUBY_PATH HOMEBREW_RUBY_PATH
HOMEBREW_SYSTEM HOMEBREW_SYSTEM
HOMEBREW_SYSTEM_TEMP HOMEBREW_SYSTEM_TEMP
@ -168,9 +169,6 @@ class SystemConfig
if defaults_hash[:HOMEBREW_RUBY_WARNINGS] != ENV["HOMEBREW_RUBY_WARNINGS"].to_s if defaults_hash[:HOMEBREW_RUBY_WARNINGS] != ENV["HOMEBREW_RUBY_WARNINGS"].to_s
f.puts "HOMEBREW_RUBY_WARNINGS: #{ENV["HOMEBREW_RUBY_WARNINGS"]}" f.puts "HOMEBREW_RUBY_WARNINGS: #{ENV["HOMEBREW_RUBY_WARNINGS"]}"
end end
if defaults_hash[:HOMEBREW_GIT] != ENV["HOMEBREW_GIT"].to_s
f.puts "HOMEBREW_GIT: #{ENV["HOMEBREW_GIT"]}"
end
unless ENV["HOMEBREW_ENV"] unless ENV["HOMEBREW_ENV"]
ENV.sort.each do |key, value| ENV.sort.each do |key, value|
next unless key.start_with?("HOMEBREW_") next unless key.start_with?("HOMEBREW_")

View File

@ -121,17 +121,6 @@ RSpec/RepeatedDescription:
- 'rubocops/lines_cop_spec.rb' - 'rubocops/lines_cop_spec.rb'
- 'tab_spec.rb' - 'tab_spec.rb'
# Offense count: 10
RSpec/RepeatedExample:
Exclude:
- 'compiler_selector_spec.rb'
- 'utils/shell_spec.rb'
# Offense count: 2
RSpec/ScatteredLet:
Exclude:
- 'cask/artifact/uninstall_zap_shared_examples.rb'
# Offense count: 31 # Offense count: 31
RSpec/SubjectStub: RSpec/SubjectStub:
Exclude: Exclude:

View File

@ -8,7 +8,6 @@ gem "rspec-its", require: false
gem "rspec-retry", require: false gem "rspec-retry", require: false
gem "rspec-wait", require: false gem "rspec-wait", require: false
gem "rubocop", HOMEBREW_RUBOCOP_VERSION gem "rubocop", HOMEBREW_RUBOCOP_VERSION
gem "rubocop-rspec", require: false
group :development do group :development do
gem "ronn", require: false gem "ronn", require: false

View File

@ -13,9 +13,9 @@ GEM
json (2.1.0) json (2.1.0)
mustache (1.1.0) mustache (1.1.0)
parallel (1.12.1) parallel (1.12.1)
parallel_tests (2.23.0) parallel_tests (2.26.0)
parallel parallel
parser (2.5.1.2) parser (2.5.3.0)
ast (~> 2.4.0) ast (~> 2.4.0)
powerpack (0.1.2) powerpack (0.1.2)
rainbow (3.0.0) rainbow (3.0.0)
@ -52,8 +52,6 @@ GEM
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1) unicode-display_width (~> 1.0, >= 1.0.1)
rubocop-rspec (1.30.0)
rubocop (>= 0.58.0)
ruby-progressbar (1.10.0) ruby-progressbar (1.10.0)
simplecov (0.16.1) simplecov (0.16.1)
docile (~> 1.1) docile (~> 1.1)
@ -77,7 +75,6 @@ DEPENDENCIES
rspec-retry rspec-retry
rspec-wait rspec-wait
rubocop (= 0.59.1) rubocop (= 0.59.1)
rubocop-rspec
simplecov simplecov
simplecov-cobertura simplecov-cobertura

View File

@ -158,6 +158,8 @@ shared_examples "#uninstall_phase or #zap_phase" do
let(:glob_path1) { Pathname.new("#{dir}/glob_path1") } let(:glob_path1) { Pathname.new("#{dir}/glob_path1") }
let(:glob_path2) { Pathname.new("#{dir}/glob_path2") } let(:glob_path2) { Pathname.new("#{dir}/glob_path2") }
let(:paths) { [absolute_path, path_with_tilde, glob_path1, glob_path2] } let(:paths) { [absolute_path, path_with_tilde, glob_path1, glob_path2] }
let(:fake_system_command) { NeverSudoSystemCommand }
let(:cask) { Cask::CaskLoader.load(cask_path("with-#{artifact_dsl_key}-#{directive}")) }
around(:each) do |example| around(:each) do |example|
begin begin
@ -171,9 +173,6 @@ shared_examples "#uninstall_phase or #zap_phase" do
end end
end end
let(:fake_system_command) { NeverSudoSystemCommand }
let(:cask) { Cask::CaskLoader.load(cask_path("with-#{artifact_dsl_key}-#{directive}")) }
before(:each) do before(:each) do
allow_any_instance_of(Cask::Artifact::AbstractUninstall).to receive(:trash_paths) allow_any_instance_of(Cask::Artifact::AbstractUninstall).to receive(:trash_paths)
.and_wrap_original do |method, *args| .and_wrap_original do |method, *args|

View File

@ -46,6 +46,11 @@ describe Homebrew::CLI::Parser do
parser.parse([]) parser.parse([])
expect(Homebrew.args.pry?).to be true expect(Homebrew.args.pry?).to be true
end end
it ":verbose with custom description" do
_, _, _, desc = parser.processed_options.find { |short, _| short == "-v" }
expect(desc).to eq "Flag for verbosity"
end
end end
describe "test long flag options" do describe "test long flag options" do
@ -71,6 +76,20 @@ describe Homebrew::CLI::Parser do
end end
end end
describe "test short flag options" do
subject(:parser) {
described_class.new do
flag "-f", "--filename=", description: "Name of the file"
end
}
it "parses a short flag option with its argument" do
parser.parse(["--filename=random.txt"])
expect(Homebrew.args.filename).to eq "random.txt"
expect(Homebrew.args.f).to eq "random.txt"
end
end
describe "test constraints for flag options" do describe "test constraints for flag options" do
subject(:parser) { subject(:parser) {
described_class.new do described_class.new do
@ -158,4 +177,18 @@ describe Homebrew::CLI::Parser do
expect(Homebrew.args.switch_b?).to be true expect(Homebrew.args.switch_b?).to be true
end end
end end
describe "test immutability of args" do
subject(:parser) {
described_class.new do
switch "-a", "--switch-a"
switch "-b", "--switch-b"
end
}
it "raises exception upon Homebrew.args mutation" do
parser.parse(["--switch-a"])
expect { parser.parse(["--switch-b"]) }.to raise_error(RuntimeError, /can't modify frozen OpenStruct/)
end
end
end end

View File

@ -23,6 +23,13 @@ end
describe Homebrew do describe Homebrew do
let(:remote) { "https://github.com/Homebrew/homebrew-core" } let(:remote) { "https://github.com/Homebrew/homebrew-core" }
specify "::analytics_table" do
results = { ack: 10, wget: 100 }
expect { subject.analytics_table("install", "30", results) }
.to output(/110 | 100.00%/).to_stdout
.and not_to_output.to_stderr
end
specify "::github_remote_path" do specify "::github_remote_path" do
expect(subject.github_remote_path(remote, "Formula/git.rb")) expect(subject.github_remote_path(remote, "Formula/git.rb"))
.to eq("https://github.com/Homebrew/homebrew-core/blob/master/Formula/git.rb") .to eq("https://github.com/Homebrew/homebrew-core/blob/master/Formula/git.rb")

View File

@ -27,29 +27,10 @@ describe CompilerSelector do
end end
describe "#compiler" do describe "#compiler" do
it "raises an error if no matching compiler can be found" do
software_spec.fails_with(:clang)
software_spec.fails_with(:gcc_4_2)
software_spec.fails_with(gcc: "4.8")
software_spec.fails_with(gcc: "4.7")
expect { subject.compiler }.to raise_error(CompilerSelectionError)
end
it "defaults to cc" do it "defaults to cc" do
expect(subject.compiler).to eq(cc) expect(subject.compiler).to eq(cc)
end end
it "returns gcc if it fails with clang" do
software_spec.fails_with(:clang)
expect(subject.compiler).to eq(:gcc_4_2)
end
it "returns clang if it fails with gcc" do
software_spec.fails_with(:gcc_4_2)
expect(subject.compiler).to eq(:clang)
end
it "returns clang if it fails with non-Apple gcc" do it "returns clang if it fails with non-Apple gcc" do
software_spec.fails_with(gcc: "4.8") software_spec.fails_with(gcc: "4.8")
expect(subject.compiler).to eq(:clang) expect(subject.compiler).to eq(:clang)
@ -84,23 +65,7 @@ describe CompilerSelector do
expect(subject.compiler).to eq("gcc-4.7") expect(subject.compiler).to eq("gcc-4.7")
end end
it "prefers gcc" do it "raises an error when gcc or llvm is missing" do
software_spec.fails_with(:clang)
software_spec.fails_with(:gcc_4_2)
expect(subject.compiler).to eq("gcc-4.8")
end
it "raises an error when gcc is missing" do
allow(versions).to receive(:gcc_4_2_build_version).and_return(Version::NULL)
software_spec.fails_with(:clang)
software_spec.fails_with(gcc: "4.8")
software_spec.fails_with(gcc: "4.7")
expect { subject.compiler }.to raise_error(CompilerSelectionError)
end
it "raises an error when llvm and gcc are missing" do
allow(versions).to receive(:gcc_4_2_build_version).and_return(Version::NULL) allow(versions).to receive(:gcc_4_2_build_version).and_return(Version::NULL)
software_spec.fails_with(:clang) software_spec.fails_with(:clang)

View File

@ -38,7 +38,7 @@ describe DependencyCollector do
end end
specify "requirement tags" do specify "requirement tags" do
subject.add x11: "2.5.1" subject.add :x11
subject.add xcode: :build subject.add xcode: :build
expect(find_requirement(X11Requirement).tags).to be_empty expect(find_requirement(X11Requirement).tags).to be_empty
expect(find_requirement(XcodeRequirement)).to be_a_build_requirement expect(find_requirement(XcodeRequirement)).to be_a_build_requirement

View File

@ -8,7 +8,7 @@ describe "brew bottle", :integration_test do
(HOMEBREW_CELLAR/"patchelf/1.0/bin").mkpath (HOMEBREW_CELLAR/"patchelf/1.0/bin").mkpath
expect { brew "bottle", "--no-rebuild", testball } expect { brew "bottle", "--no-rebuild", testball }
.to output(/Formula not from core or any taps/).to_stderr .to output(/Formula not from core or any installed taps/).to_stderr
.and not_to_output.to_stdout .and not_to_output.to_stdout
.and be_a_failure .and be_a_failure

View File

@ -18,6 +18,7 @@ describe FormulaInstaller do
expect(formula).to pour_bottle expect(formula).to pour_bottle
stub_formula_loader formula stub_formula_loader formula
stub_formula_loader formula("gcc") { url "gcc-1.0" }
stub_formula_loader formula("patchelf") { url "patchelf-1.0" } stub_formula_loader formula("patchelf") { url "patchelf-1.0" }
allow(Formula["patchelf"]).to receive(:installed?).and_return(true) allow(Formula["patchelf"]).to receive(:installed?).and_return(true)
described_class.new(formula).install described_class.new(formula).install

View File

@ -798,7 +798,7 @@ describe Formula do
stub_formula_loader(f1) stub_formula_loader(f1)
java = JavaRequirement.new java = JavaRequirement.new
x11 = X11Requirement.new("x11", [:recommended]) x11 = X11Requirement.new([:recommended])
xcode = XcodeRequirement.new(["1.0", :optional]) xcode = XcodeRequirement.new(["1.0", :optional])
expect(Set.new(f1.recursive_requirements)).to eq(Set[java, x11]) expect(Set.new(f1.recursive_requirements)).to eq(Set[java, x11])

View File

@ -138,6 +138,7 @@ describe Formulary do
context "with installed Formula" do context "with installed Formula" do
before do before do
allow(described_class).to receive(:loader_for).and_call_original allow(described_class).to receive(:loader_for).and_call_original
stub_formula_loader formula("gcc") { url "gcc-1.0" }
stub_formula_loader formula("patchelf") { url "patchelf-1.0" } stub_formula_loader formula("patchelf") { url "patchelf-1.0" }
allow(Formula["patchelf"]).to receive(:installed?).and_return(true) allow(Formula["patchelf"]).to receive(:installed?).and_return(true)
end end

View File

@ -14,7 +14,7 @@ describe JavaRequirement do
describe "#inspect" do describe "#inspect" do
subject { described_class.new(%w[1.7+]) } subject { described_class.new(%w[1.7+]) }
its(:inspect) { is_expected.to eq('#<JavaRequirement: "java" [] version="1.7+">') } its(:inspect) { is_expected.to eq('#<JavaRequirement: [] version="1.7+">') }
end end
describe "#display_s" do describe "#display_s" do

View File

@ -0,0 +1,21 @@
require "requirements/codesign_requirement"
describe CodesignRequirement do
subject(:requirement) {
described_class.new([{ identity: identity, with: with, url: url }])
}
let(:identity) { "lldb_codesign" }
let(:with) { "LLDB" }
let(:url) {
"https://llvm.org/svn/llvm-project/lldb/trunk/docs/code-signing.txt"
}
describe "#message" do
it "includes all parameters" do
expect(requirement.message).to include(identity)
expect(requirement.message).to include(with)
expect(requirement.message).to include(url)
end
end
end

View File

@ -1,9 +0,0 @@
require "requirements/non_binary_osxfuse_requirement"
describe NonBinaryOsxfuseRequirement, :needs_macos do
subject { described_class.new([]) }
describe "#message" do
its(:message) { is_expected.to match("osxfuse is already installed from the binary distribution") }
end
end

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