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

This commit is contained in:
AndrewMcBurney 2018-03-06 11:46:23 -05:00
commit 831fcfa5dd
87 changed files with 920 additions and 320 deletions

View File

@ -1,10 +1,10 @@
**Please note we will close your issue without comment if you delete, do not read or do not fill out the issue checklist below and provide ALL the requested information. If you repeatedly fail to use the issue template, we will block you from ever submitting issues to Homebrew again.** **Please note we will close your issue without comment if you delete, do not read or do not fill out the issue checklist below and provide ALL the requested information. If you repeatedly fail to use the issue template, we will block you from ever submitting issues to Homebrew again.**
# Please always follow these steps: - [ ] are reporting a bug others will be able to reproduce and not asking a question. If you're not sure or want to ask a question do so on our Discourse: https://discourse.brew.sh
- [ ] Confirmed this is a problem with running a `brew` command and not `brew install`ing or the post-install behaviour of one or more formulae? If it's a formulae-specific problem please file this issue at the relevant tap e.g. for Homebrew/homebrew-core https://github.com/Homebrew/homebrew-core/issues/new - [ ] ran a `brew` command and reproduced the problem with multiple formulae? If it's a problem with a single, official formula (not cask) please file this issue at Homebrew/homebrew-core: https://github.com/Homebrew/homebrew-core/issues/new. If it's a `brew cask` problem please file this issue at https://github.com/caskroom/homebrew-cask/issues/new. If it's a tap (e.g. Homebrew/homebrew-php) problem please file this issue at the tap.
- [ ] Ran `brew update` and retried your prior step? - [ ] ran `brew update` and can still reproduce the problem?
- [ ] Ran `brew doctor`, fixed all issues and retried your prior step? - [ ] ran `brew doctor`, fixed all issues and can still reproduce the problem?
- [ ] Ran `brew config` and `brew doctor` and included their output with your issue? - [ ] ran `brew config` and `brew doctor` and included their output with your issue?
To help us debug your issue please explain: To help us debug your issue please explain:
- What you were trying to do (and why) - What you were trying to do (and why)
@ -16,7 +16,7 @@ To help us debug your issue please explain:
Please replace this section with: Please replace this section with:
- a detailed description of your proposed feature - a detailed description of your proposed feature
- the motivation for the feature - the motivation for the feature
- how the feature would be relevant to at least 90% of Homebrew users - how the feature would be relevant to at least 90% of Homebrew users (if it's not: do not open a feature request)
- what alternatives to the feature you have considered - what alternatives to the feature you have considered
We will close this issue or ask you to create a pull-request if it's something we're not actively planning to work on. We will close this issue or ask you to create a pull-request if it's something the maintainers are not actively planning to work on.

View File

@ -3,7 +3,7 @@ cache:
directories: directories:
- $HOME/Library/Caches/Homebrew/style - $HOME/Library/Caches/Homebrew/style
- $HOME/Library/Caches/Homebrew/tests - $HOME/Library/Caches/Homebrew/tests
- $HOME/Library/Homebrew/vendor/bundle - Library/Homebrew/vendor/bundle
branches: branches:
only: only:
- master - master
@ -36,22 +36,8 @@ before_install:
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";
else
HOMEBREW_CORE_TAP_DIR="$(brew --repo "homebrew/core")";
mkdir -p "$HOMEBREW_CORE_TAP_DIR";
fi
- if [ "$MACOS" ]; then
travis_retry git -C Library/Taps/homebrew/homebrew-core fetch --depth=1 origin;
fi 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
- if [ "$LINUX" ]; then
HOMEBREW_TEST_BOT_TAP_DIR="$(brew --repo "homebrew/test-bot")";
ln -s "$HOMEBREW_TEST_BOT_TAP_DIR/.git" "$HOMEBREW_TEST_BOT_TAP_DIR/Formula" "$HOMEBREW_CORE_TAP_DIR";
fi
# can be removed after 1.5.3 is tagged
- if [ "$LINUX" ]; then
export HOMEBREW_FORCE_VENDOR_RUBY=1;
fi
script: script:
- brew test-bot - brew test-bot

View File

@ -5,7 +5,7 @@ First time contributing to Homebrew? Read our [Code of Conduct](https://github.c
* Run `brew update` (twice). * Run `brew update` (twice).
* Run and read `brew doctor`. * Run and read `brew doctor`.
* Read [the Troubleshooting Checklist](https://docs.brew.sh/Troubleshooting.html). * Read [the Troubleshooting Checklist](https://docs.brew.sh/Troubleshooting).
* Open an issue on the formula's repository or on Homebrew/brew if it's not a formula-specific issue. * Open an issue on the formula's repository or on Homebrew/brew if it's not a formula-specific issue.
### Propose a feature ### Propose a feature

View File

@ -3,6 +3,6 @@ This is the (partially) documented public API for Homebrew.
The main class you should look at is the {Formula} class (and classes linked from there). That's the class that's used to create Homebrew formulae (i.e. package descriptions). Assume anything else you stumble upon is private. The main class you should look at is the {Formula} class (and classes linked from there). That's the class that's used to create Homebrew formulae (i.e. package descriptions). Assume anything else you stumble upon is private.
You may also find the [Formula Cookbook](https://docs.brew.sh/Formula-Cookbook.html) and [Ruby Style Guide](https://github.com/styleguide/ruby) helpful in creating formulae. You may also find the [Formula Cookbook](https://docs.brew.sh/Formula-Cookbook) and [Ruby Style Guide](https://github.com/styleguide/ruby) helpful in creating formulae.
Good luck! Good luck!

View File

@ -75,7 +75,6 @@ case "$HOMEBREW_SYSTEM" in
Linux) HOMEBREW_LINUX="1" ;; Linux) HOMEBREW_LINUX="1" ;;
esac esac
HOMEBREW_CURL="curl"
if [[ -n "$HOMEBREW_MACOS" ]] if [[ -n "$HOMEBREW_MACOS" ]]
then then
HOMEBREW_PROCESSOR="$(uname -p)" HOMEBREW_PROCESSOR="$(uname -p)"
@ -97,11 +96,12 @@ then
HOMEBREW_FORCE_BREWED_CURL="1" HOMEBREW_FORCE_BREWED_CURL="1"
fi fi
if [[ -n "$HOMEBREW_FORCE_BREWED_CURL" && # The system Git is too old for some GitHub's SSL ciphers on older
-x "$HOMEBREW_PREFIX/opt/curl/bin/curl" ]] && # macOS versions.
"$HOMEBREW_PREFIX/opt/curl/bin/curl" --version >/dev/null # https://github.com/blog/2507-weak-cryptographic-standards-removed
if [[ "$HOMEBREW_MACOS_VERSION_NUMERIC" -lt "100900" ]]
then then
HOMEBREW_CURL="$HOMEBREW_PREFIX/opt/curl/bin/curl" HOMEBREW_SYSTEM_GIT_TOO_OLD="1"
fi fi
if [[ -z "$HOMEBREW_CACHE" ]] if [[ -z "$HOMEBREW_CACHE" ]]
@ -125,6 +125,16 @@ else
fi fi
fi fi
fi fi
if [[ -n "$HOMEBREW_FORCE_BREWED_CURL" &&
-x "$HOMEBREW_PREFIX/opt/curl/bin/curl" ]] &&
"$HOMEBREW_PREFIX/opt/curl/bin/curl" --version >/dev/null
then
HOMEBREW_CURL="$HOMEBREW_PREFIX/opt/curl/bin/curl"
else
HOMEBREW_CURL="curl"
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}')" HOMEBREW_CURL_VERSION="$("$HOMEBREW_CURL" --version 2>/dev/null | head -n1 | awk '{print $1"/"$2}')"
HOMEBREW_USER_AGENT_CURL="$HOMEBREW_USER_AGENT $HOMEBREW_CURL_VERSION" HOMEBREW_USER_AGENT_CURL="$HOMEBREW_USER_AGENT $HOMEBREW_CURL_VERSION"
@ -224,6 +234,15 @@ case "$HOMEBREW_COMMAND" in
--config) HOMEBREW_COMMAND="config" ;; --config) HOMEBREW_COMMAND="config" ;;
esac esac
if [[ "$HOMEBREW_COMMAND" = "cask" ]]
then
HOMEBREW_CASK_COMMAND="$1"
case "$HOMEBREW_CASK_COMMAND" in
instal) HOMEBREW_CASK_COMMAND="install" ;; # gem does the same
esac
fi
# Set HOMEBREW_DEV_CMD_RUN for users who have run a development command. # Set HOMEBREW_DEV_CMD_RUN for users who have run a development command.
# This makes them behave like HOMEBREW_DEVELOPERs for brew update. # This makes them behave like HOMEBREW_DEVELOPERs for brew update.
if [[ -z "$HOMEBREW_DEVELOPER" ]] if [[ -z "$HOMEBREW_DEVELOPER" ]]
@ -234,6 +253,14 @@ then
then then
export HOMEBREW_DEV_CMD_RUN="1" export HOMEBREW_DEV_CMD_RUN="1"
fi fi
# Don't allow non-developers to customise Ruby warnings.
unset HOMEBREW_RUBY_WARNINGS
fi
if [[ -z "$HOMEBREW_RUBY_WARNINGS" ]]
then
export HOMEBREW_RUBY_WARNINGS="-W0"
fi fi
if [[ -f "$HOMEBREW_LIBRARY/Homebrew/cmd/$HOMEBREW_COMMAND.sh" ]] if [[ -f "$HOMEBREW_LIBRARY/Homebrew/cmd/$HOMEBREW_COMMAND.sh" ]]
@ -297,7 +324,8 @@ update-preinstall() {
[[ -z "$HOMEBREW_AUTO_UPDATE_CHECKED" ]] || return [[ -z "$HOMEBREW_AUTO_UPDATE_CHECKED" ]] || return
[[ -z "$HOMEBREW_UPDATE_PREINSTALL" ]] || return [[ -z "$HOMEBREW_UPDATE_PREINSTALL" ]] || return
if [[ "$HOMEBREW_COMMAND" = "install" || "$HOMEBREW_COMMAND" = "upgrade" || "$HOMEBREW_COMMAND" = "tap" ]] if [[ "$HOMEBREW_COMMAND" = "install" || "$HOMEBREW_COMMAND" = "upgrade" || "$HOMEBREW_COMMAND" = "tap" ||
"$HOMEBREW_CASK_COMMAND" = "install" || "$HOMEBREW_CASK_COMMAND" = "upgrade" ]]
then then
if [[ -z "$HOMEBREW_VERBOSE" ]] if [[ -z "$HOMEBREW_VERBOSE" ]]
then then
@ -351,5 +379,5 @@ else
# Unshift command back into argument list (unless argument list was empty). # Unshift command back into argument list (unless argument list was empty).
[[ "$HOMEBREW_ARG_COUNT" -gt 0 ]] && set -- "$HOMEBREW_COMMAND" "$@" [[ "$HOMEBREW_ARG_COUNT" -gt 0 ]] && set -- "$HOMEBREW_COMMAND" "$@"
{ update-preinstall; exec "$HOMEBREW_RUBY_PATH" -W0 "$HOMEBREW_LIBRARY/Homebrew/brew.rb" "$@"; } { update-preinstall; exec "$HOMEBREW_RUBY_PATH" $HOMEBREW_RUBY_WARNINGS "$HOMEBREW_LIBRARY/Homebrew/brew.rb" "$@"; }
fi fi

View File

@ -23,7 +23,7 @@ module Hbc
def install_phase(command: nil, **_) def install_phase(command: nil, **_)
ohai "Running #{self.class.dsl_key} script '#{path.relative_path_from(cask.staged_path)}'" ohai "Running #{self.class.dsl_key} script '#{path.relative_path_from(cask.staged_path)}'"
FileUtils.chmod "+x", path unless path.executable? FileUtils.chmod "+x", path unless path.executable?
command.run(path, **args) command.run(path, **args, path: PATH.new(HOMEBREW_PREFIX/"bin", HOMEBREW_PREFIX/"sbin", ENV["PATH"]))
end end
end end

View File

@ -62,14 +62,16 @@ module Hbc
raise CaskError, "It seems the #{self.class.english_name} source '#{target}' is not there." raise CaskError, "It seems the #{self.class.english_name} source '#{target}' is not there."
end end
ohai "Moving #{self.class.english_name} '#{target.basename}' back to '#{source}'." ohai "Backing #{self.class.english_name} '#{target.basename}' up to '#{source}'."
source.dirname.mkpath source.dirname.mkpath
if target.parent.writable? if target.parent.writable?
FileUtils.move(target, source) FileUtils.cp_r(target, source)
else else
command.run("/bin/mv", args: [target, source], sudo: true) command.run("/bin/cp", args: ["-r", target, source], sudo: true)
end end
delete(target, force: force, command: command, **options)
end end
def delete(target, force: false, command: nil, **_) def delete(target, force: false, command: nil, **_)

View File

@ -16,11 +16,11 @@ module Hbc
end end
def initialize(content) def initialize(content)
@content = content @content = content.force_encoding("UTF-8")
end end
def load def load
instance_eval(content.force_encoding("UTF-8"), __FILE__, __LINE__) instance_eval(content, __FILE__, __LINE__)
end end
private private
@ -52,7 +52,7 @@ module Hbc
@content = IO.read(path) @content = IO.read(path)
super instance_eval(content, path)
end end
private private

View File

@ -24,6 +24,7 @@ module Hbc
check_software_versions check_software_versions
check_install_location check_install_location
check_staging_location check_staging_location
check_cached_downloads
check_taps check_taps
check_load_path check_load_path
check_environment_variables check_environment_variables

View File

@ -37,7 +37,7 @@ module Hbc
result result
end end
def initialize(executable, args: [], sudo: false, input: [], print_stdout: false, print_stderr: true, must_succeed: false, **options) def initialize(executable, args: [], sudo: false, input: [], print_stdout: false, print_stderr: true, must_succeed: false, path: ENV["PATH"], **options)
@executable = executable @executable = executable
@args = args @args = args
@sudo = sudo @sudo = sudo
@ -47,6 +47,7 @@ module Hbc
@must_succeed = must_succeed @must_succeed = must_succeed
options.extend(HashValidator).assert_valid_keys(:chdir) options.extend(HashValidator).assert_valid_keys(:chdir)
@options = options @options = options
@path = path
end end
def command def command
@ -55,7 +56,7 @@ module Hbc
private private
attr_reader :executable, :args, :input, :options, :processed_output, :processed_status attr_reader :executable, :args, :input, :options, :processed_output, :processed_status, :path
attr_predicate :sudo?, :print_stdout?, :print_stderr?, :must_succeed? attr_predicate :sudo?, :print_stdout?, :print_stderr?, :must_succeed?
@ -83,12 +84,8 @@ module Hbc
def each_output_line(&b) def each_output_line(&b)
executable, *args = expanded_command executable, *args = expanded_command
unless File.exist?(executable)
executable = which(executable, PATH.new(ENV["PATH"], HOMEBREW_PREFIX/"bin"))
end
raw_stdin, raw_stdout, raw_stderr, raw_wait_thr = raw_stdin, raw_stdout, raw_stderr, raw_wait_thr =
Open3.popen3([executable, executable], *args, **options) Open3.popen3({ "PATH" => path }, [executable, executable], *args, **options)
write_input_to(raw_stdin) write_input_to(raw_stdin)
raw_stdin.close_write raw_stdin.close_write

View File

@ -1,6 +1,6 @@
#: * `analytics` [`state`]: #: * `analytics` [`state`]:
#: Display anonymous user behaviour analytics state. #: Display anonymous user behaviour analytics state.
#: Read more at <https://docs.brew.sh/Analytics.html>. #: Read more at <https://docs.brew.sh/Analytics>.
#: #:
#: * `analytics` (`on`|`off`): #: * `analytics` (`on`|`off`):
#: Turn on/off Homebrew's analytics. #: Turn on/off Homebrew's analytics.

View File

@ -39,15 +39,6 @@ module Homebrew
files["00.tap.out"] = { content: tap } files["00.tap.out"] = { content: tap }
end end
# Description formatted to work well as page title when viewing gist
if f.core_formula?
descr = "#{f.name} on #{OS_VERSION} - Homebrew build logs"
else
descr = "#{f.name} (#{f.full_name}) on #{OS_VERSION} - Homebrew build logs"
end
url = create_gist(files, descr)
if ARGV.include?("--new-issue") || ARGV.switch?("n")
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:
@ -58,6 +49,15 @@ module Homebrew
login! login!
end end
# Description formatted to work well as page title when viewing gist
if f.core_formula?
descr = "#{f.name} on #{OS_VERSION} - Homebrew build logs"
else
descr = "#{f.name} (#{f.full_name}) on #{OS_VERSION} - Homebrew build logs"
end
url = create_gist(files, descr)
if ARGV.include?("--new-issue") || ARGV.switch?("n")
url = create_issue(f.tap, "#{f.name} failed to build on #{MacOS.full_version}", url) url = create_issue(f.tap, "#{f.name} failed to build on #{MacOS.full_version}", url)
end end

View File

@ -16,7 +16,7 @@ HOMEBREW_HELP = <<~EOS.freeze
Developers: Developers:
brew create [URL [--no-fetch]] brew create [URL [--no-fetch]]
brew edit [FORMULA...] brew edit [FORMULA...]
https://docs.brew.sh/Formula-Cookbook.html https://docs.brew.sh/Formula-Cookbook
Further help: Further help:
man brew man brew

View File

@ -17,7 +17,7 @@
#: information on all installed formulae. #: information on all installed formulae.
#: #:
#: See the docs for examples of using the JSON output: #: See the docs for examples of using the JSON output:
#: <https://docs.brew.sh/Querying-Brew.html> #: <https://docs.brew.sh/Querying-Brew>
require "missing_formula" require "missing_formula"
require "caveats" require "caveats"
@ -137,7 +137,12 @@ module Homebrew
EOS EOS
end end
kegs = f.installed_kegs.sort_by(&:version) kegs = f.installed_kegs
heads, versioned = kegs.partition { |k| k.version.head? }
kegs = [
*heads.sort_by { |k| -Tab.for_keg(k).time.to_i },
*versioned.sort_by(&:version),
]
if kegs.empty? if kegs.empty?
puts "Not installed" puts "Not installed"
else else

View File

@ -13,7 +13,7 @@
#: Pass `--installed` to get information on installed taps. #: Pass `--installed` to get information on installed taps.
#: #:
#: See the docs for examples of using the JSON output: #: See the docs for examples of using the JSON output:
#: <https://docs.brew.sh/Querying-Brew.html> #: <https://docs.brew.sh/Querying-Brew>
require "tap" require "tap"

View File

@ -35,7 +35,7 @@ module Homebrew
ohai "Homebrew has enabled anonymous aggregate user behaviour analytics." ohai "Homebrew has enabled anonymous aggregate user behaviour analytics."
puts <<~EOS puts <<~EOS
#{Tty.bold}Read the analytics documentation (and how to opt-out) here: #{Tty.bold}Read the analytics documentation (and how to opt-out) here:
#{Formatter.url("https://docs.brew.sh/Analytics.html")}#{Tty.reset} #{Formatter.url("https://docs.brew.sh/Analytics")}#{Tty.reset}
EOS EOS

View File

@ -390,12 +390,14 @@ EOS
brew install curl brew install curl
fi fi
if ! git --version >/dev/null 2>&1 if ! git --version &>/dev/null ||
[[ -n "$HOMEBREW_SYSTEM_GIT_TOO_OLD" &&
! -x "$HOMEBREW_PREFIX/opt/git/bin/git" ]]
then then
# we cannot install brewed git if homebrew/core is unavailable. # we cannot install brewed git if homebrew/core is unavailable.
[[ -d "$HOMEBREW_LIBRARY/Taps/homebrew/homebrew-core" ]] && brew install git [[ -d "$HOMEBREW_LIBRARY/Taps/homebrew/homebrew-core" ]] && brew install git
unset GIT_EXECUTABLE unset GIT_EXECUTABLE
if ! git --version >/dev/null 2>&1 if ! git --version &>/dev/null
then then
odie "Git must be installed and in your PATH!" odie "Git must be installed and in your PATH!"
fi fi

View File

@ -118,7 +118,7 @@ module Homebrew
fi = FormulaInstaller.new(f) fi = FormulaInstaller.new(f)
fi.options = options fi.options = options
fi.build_bottle = ARGV.build_bottle? || (!f.bottled? && f.build.build_bottle?) fi.build_bottle = ARGV.build_bottle? || (!f.bottled? && f.build.bottle?)
fi.installed_on_request = !ARGV.named.empty? fi.installed_on_request = !ARGV.named.empty?
fi.link_keg ||= keg_was_linked if keg_had_linked_opt fi.link_keg ||= keg_was_linked if keg_had_linked_opt
if tab if tab

View File

@ -52,14 +52,14 @@ class DependencyCollector
output_deprecation(spec, "open-mpi") output_deprecation(spec, "open-mpi")
Dependency.new("open-mpi", tags) Dependency.new("open-mpi", tags)
when :python, :python2 when :python, :python2
output_deprecation(spec, "python@2")
Dependency.new("python@2", tags)
when :python3
output_deprecation(spec, "python") output_deprecation(spec, "python")
Dependency.new("python", tags) Dependency.new("python", tags)
when :python3
output_deprecation(spec, "python3")
Dependency.new("python3", tags)
when :emacs, :mysql, :perl, :postgresql, :rbenv, :ruby when :emacs, :mysql, :perl, :postgresql, :rbenv, :ruby
output_deprecation(spec) output_deprecation(spec)
Dependency.new(spec, tags) Dependency.new(spec.to_s, tags)
else else
super super
end end

View File

@ -84,16 +84,16 @@ end
class PythonRequirement < Requirement class PythonRequirement < Requirement
fatal true fatal true
satisfy do satisfy do
odeprecated("PythonRequirement", "'depends_on \"python\"'") odeprecated("PythonRequirement", "'depends_on \"python@2\"'")
which "python" which "python2"
end end
end end
class Python3Requirement < Requirement class Python3Requirement < Requirement
fatal true fatal true
satisfy do satisfy do
odeprecated("Python3Requirement", "'depends_on \"python3\"'") odeprecated("Python3Requirement", "'depends_on \"python\"'")
which "python3" which "python"
end end
end end

View File

@ -38,9 +38,9 @@ class LanguageModuleRequirement < Requirement
when :perl when :perl
["/usr/bin/env", "perl", "-e", "use #{@import_name}"] ["/usr/bin/env", "perl", "-e", "use #{@import_name}"]
when :python when :python
["/usr/bin/env", "python", "-c", "import #{@import_name}"] ["/usr/bin/env", "python2", "-c", "import #{@import_name}"]
when :python3 when :python3
["/usr/bin/env", "python3", "-c", "import #{@import_name}"] ["/usr/bin/env", "python", "-c", "import #{@import_name}"]
when :ruby when :ruby
["/usr/bin/env", "ruby", "-rubygems", "-e", "require '#{@import_name}'"] ["/usr/bin/env", "ruby", "-rubygems", "-e", "require '#{@import_name}'"]
end end
@ -51,8 +51,8 @@ class LanguageModuleRequirement < Requirement
when :lua then "luarocks-5.2 install" when :lua then "luarocks-5.2 install"
when :lua51 then "luarocks-5.1 install" when :lua51 then "luarocks-5.1 install"
when :perl then "cpan -i" when :perl then "cpan -i"
when :python then "pip install" when :python then "pip3 install"
when :python3 then "pip3 install" when :python3 then "pip install"
when :ruby then "gem install" when :ruby then "gem install"
end end
end end

View File

@ -63,11 +63,19 @@ class DependencyCollector
end end
def cvs_dep_if_needed(tags) def cvs_dep_if_needed(tags)
Dependency.new("cvs", tags) Dependency.new("cvs", tags) unless which("cvs")
end end
def xz_dep_if_needed(tags) def xz_dep_if_needed(tags)
Dependency.new("xz", tags) Dependency.new("xz", tags) unless which("xz")
end
def unzip_dep_if_needed(tags)
Dependency.new("unzip", tags) unless which("unzip")
end
def bzip2_dep_if_needed(tags)
Dependency.new("bzip2", tags) unless which("bzip2")
end end
def ld64_dep_if_needed(*); end def ld64_dep_if_needed(*); end
@ -158,6 +166,8 @@ class DependencyCollector
def parse_url_spec(url, tags) def parse_url_spec(url, tags)
case File.extname(url) case File.extname(url)
when ".xz" then xz_dep_if_needed(tags) when ".xz" then xz_dep_if_needed(tags)
when ".zip" then unzip_dep_if_needed(tags)
when ".bz2" then bzip2_dep_if_needed(tags)
when ".lha", ".lzh" then Dependency.new("lha", tags) when ".lha", ".lzh" then Dependency.new("lha", tags)
when ".lz" then Dependency.new("lzip", tags) when ".lz" then Dependency.new("lzip", tags)
when ".rar" then Dependency.new("unrar", tags) when ".rar" then Dependency.new("unrar", tags)

View File

@ -167,7 +167,7 @@ class FormulaCreator
def template def template
<<~EOS <<~EOS
# Documentation: https://docs.brew.sh/Formula-Cookbook.html # Documentation: https://docs.brew.sh/Formula-Cookbook
# http://www.rubydoc.info/github/Homebrew/brew/master/Formula # http://www.rubydoc.info/github/Homebrew/brew/master/Formula
# PLEASE REMOVE ALL GENERATED COMMENTS BEFORE SUBMITTING YOUR PULL REQUEST! # PLEASE REMOVE ALL GENERATED COMMENTS BEFORE SUBMITTING YOUR PULL REQUEST!
class #{Formulary.class_s(name)} < Formula class #{Formulary.class_s(name)} < Formula

View File

@ -1,11 +1,9 @@
#: * `irb` [`--examples`]: #: * `irb` [`--examples`] [`--pry`]:
#: 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
require "formula" #: used instead of irb.
require "keg"
require "irb"
class Symbol class Symbol
def f(*args) def f(*args)
@ -23,17 +21,33 @@ module Homebrew
module_function module_function
def irb def irb
$LOAD_PATH.unshift("#{HOMEBREW_LIBRARY_PATH}/cask/lib")
require "hbc"
if ARGV.include? "--examples" if ARGV.include? "--examples"
puts "'v8'.f # => instance of the v8 formula" puts "'v8'.f # => instance of the v8 formula"
puts ":hub.f.installed?" puts ":hub.f.installed?"
puts ":lua.f.methods - 1.methods" puts ":lua.f.methods - 1.methods"
puts ":mpd.f.recursive_dependencies.reject(&:installed?)" puts ":mpd.f.recursive_dependencies.reject(&:installed?)"
return
end
if ARGV.pry?
Homebrew.install_gem_setup_path! "pry"
require "pry"
Pry.config.prompt_name = "brew"
else else
require "irb"
end
require "formula"
require "keg"
$LOAD_PATH.unshift("#{HOMEBREW_LIBRARY_PATH}/cask/lib")
require "hbc"
ohai "Interactive Homebrew Shell" ohai "Interactive Homebrew Shell"
puts "Example commands available with: brew irb --examples" puts "Example commands available with: brew irb --examples"
if ARGV.pry?
Pry.start
else
IRB.start IRB.start
end end
end end

View File

@ -14,7 +14,7 @@
#: 'keg.name' and forces a check on the dylibs. #: 'keg.name' and forces a check on the dylibs.
require "cache_store" require "cache_store"
require "os/mac/linkage_checker" require "linkage_checker"
module Homebrew module Homebrew
module_function module_function

View File

@ -0,0 +1,15 @@
#: * `prof` [<ruby options>]:
#: Run Homebrew with the Ruby profiler.
#: For example:
# brew prof readall
module Homebrew
module_function
def prof
Homebrew.install_gem_setup_path! "ruby-prof"
FileUtils.mkdir_p "prof"
brew_rb = (HOMEBREW_LIBRARY_PATH/"brew.rb").resolved_path
exec "ruby-prof", "--printer=multi", "--file=prof", brew_rb, "--", *ARGV
end
end

View File

@ -0,0 +1,13 @@
#: * `ruby` [<ruby options>]:
#: Run a Ruby instance with Homebrew's libraries loaded.
#: For example:
# brew ruby -e "puts :gcc.f.deps"
# brew ruby script.rb
module Homebrew
module_function
def ruby
exec ENV["HOMEBREW_RUBY_PATH"], "-I#{HOMEBREW_LIBRARY_PATH}", "-rglobal", "-rdev-cmd/irb", *ARGV
end
end

View File

@ -50,8 +50,7 @@ module Homebrew
osx_image: xcode9.2 osx_image: xcode9.2
cache: cache:
directories: directories:
- $HOME/.gem/ruby - /usr/local/Homebrew/Library/Homebrew/vendor/bundle
- Library/Homebrew/vendor/bundle
branches: branches:
only: only:
- master - master

View File

@ -788,7 +788,7 @@ module Homebrew
EOS EOS
end end
return if ENV["CI"] || ENV["JENKINS_HOME"] return if ENV["CI"]
branch = coretap_path.git_branch branch = coretap_path.git_branch
return if branch.nil? || branch =~ /master/ return if branch.nil? || branch =~ /master/
@ -822,7 +822,7 @@ module Homebrew
return if linked.empty? return if linked.empty?
inject_file_list linked.map(&:full_name), <<~EOS inject_file_list linked.map(&:full_name), <<~EOS
Some keg-only formula are linked into the Cellar. Some keg-only formulae are linked into the Cellar.
Linking a keg-only formula, such as gettext, into the cellar with Linking a keg-only formula, such as gettext, into the cellar with
`brew link <formula>` will cause other formulae to detect them during `brew link <formula>` will cause other formulae to detect them during
the `./configure` step. This may cause problems when compiling those the `./configure` step. This may cause problems when compiling those
@ -835,18 +835,6 @@ module Homebrew
EOS EOS
end end
def check_for_large_cache
return unless HOMEBREW_CACHE.exist?
# CI can be expected to have a large cache.
return if ENV["CI"] || ENV["JENKINS_HOME"]
cache_size = HOMEBREW_CACHE.disk_usage
return unless cache_size > 2_147_483_648
<<~EOS
Your HOMEBREW_CACHE is using #{disk_usage_readable(cache_size)} of disk space.
You may wish to consider running `brew cleanup`.
EOS
end
def check_for_other_frameworks def check_for_other_frameworks
# Other frameworks that are known to cause problems when present # Other frameworks that are known to cause problems when present
frameworks_to_check = %w[ frameworks_to_check = %w[
@ -884,7 +872,7 @@ module Homebrew
return if missing.empty? return if missing.empty?
<<~EOS <<~EOS
Some installed formula are missing dependencies. Some installed formulae are missing dependencies.
You should `brew install` the missing dependencies: You should `brew install` the missing dependencies:
brew install #{missing.sort_by(&:full_name) * " "} brew install #{missing.sort_by(&:full_name) * " "}
@ -946,7 +934,7 @@ module Homebrew
from your PATH variable. from your PATH variable.
Python scripts will now install into #{HOMEBREW_PREFIX}/bin. Python scripts will now install into #{HOMEBREW_PREFIX}/bin.
You can delete anything, except 'Extras', from the #{HOMEBREW_PREFIX}/share/python You can delete anything, except 'Extras', from the #{HOMEBREW_PREFIX}/share/python
(and #{HOMEBREW_PREFIX}/share/python3) dir and install affected Python packages (and #{HOMEBREW_PREFIX}/share/python@2) dir and install affected Python packages
anew with `pip install --upgrade`. anew with `pip install --upgrade`.
EOS EOS
end end

View File

@ -303,7 +303,11 @@ class AbstractFileDownloadStrategy < AbstractDownloadStrategy
# We can't use basename_without_params, because given a URL like # We can't use basename_without_params, because given a URL like
# https://example.com/download.php?file=foo-1.0.tar.gz # https://example.com/download.php?file=foo-1.0.tar.gz
# the extension we want is ".tar.gz", not ".php". # the extension we want is ".tar.gz", not ".php".
Pathname.new(@url).extname[/[^?]+/] Pathname.new(@url).ascend do |path|
ext = path.extname[/[^?]+/]
return ext if ext
end
nil
end end
end end

View File

@ -343,8 +343,8 @@ class FormulaAmbiguousPythonError < RuntimeError
def initialize(formula) def initialize(formula)
super <<~EOS super <<~EOS
The version of python to use with the virtualenv in the `#{formula.full_name}` formula The version of python to use with the virtualenv in the `#{formula.full_name}` formula
cannot be guessed automatically. If the simultaneous use of python and python3 cannot be guessed automatically. If the simultaneous use of python and python@2
is intentional, please add `:using => "python"` or `:using => "python3"` to is intentional, please add `:using => "python"` or `:using => "python@2"` to
`virtualenv_install_with_resources` to resolve the ambiguity manually. `virtualenv_install_with_resources` to resolve the ambiguity manually.
EOS EOS
end end

View File

@ -267,6 +267,10 @@ module HomebrewArgvExtension
include? "--fetch-HEAD" include? "--fetch-HEAD"
end end
def pry?
include?("--pry") || !ENV["HOMEBREW_PRY"].nil?
end
# eg. `foo -ns -i --bar` has three switches, n, s and i # eg. `foo -ns -i --bar` has three switches, n, s and i
def switch?(char) def switch?(char)
return false if char.length > 1 return false if char.length > 1

View File

@ -28,9 +28,9 @@ module EnvActivation
end end
def clear_sensitive_environment! def clear_sensitive_environment!
ENV.each_key do |key| each_key do |key|
next unless /(cookie|key|token|password)/i =~ key next unless /(cookie|key|token|password)/i =~ key
ENV.delete key delete key
end end
end end
end end

View File

@ -18,6 +18,10 @@ class DependencyCollector
Dependency.new("xz", tags) Dependency.new("xz", tags)
end end
def zip_dep_if_needed(tags); end
def bzip2_dep_if_needed(tags); end
def ld64_dep_if_needed(*) def ld64_dep_if_needed(*)
# Tiger's ld is too old to properly link some software # Tiger's ld is too old to properly link some software
return if MacOS.version > :tiger return if MacOS.version > :tiger

View File

@ -1,5 +1,5 @@
require "cache_store" require "cache_store"
require "os/mac/linkage_checker" require "linkage_checker"
module FormulaCellarChecks module FormulaCellarChecks
def check_shadowed_headers def check_shadowed_headers

View File

@ -23,6 +23,19 @@ class SystemConfig
@ponk.join(", ") unless @ponk.empty? @ponk.join(", ") unless @ponk.empty?
end end
def describe_java
# java_home doesn't exist on all macOSs; it might be missing on older versions.
return "N/A" unless File.executable? "/usr/libexec/java_home"
java_xml = Utils.popen_read("/usr/libexec/java_home", "--xml", "--failfast", err: :close)
return "N/A" unless $CHILD_STATUS.success?
javas = []
REXML::XPath.each(REXML::Document.new(java_xml), "//key[text()='JVMVersion']/following-sibling::string") do |item|
javas << item.text
end
javas.uniq.join(", ")
end
def describe_xquartz def describe_xquartz
return "N/A" unless MacOS::XQuartz.installed? return "N/A" unless MacOS::XQuartz.installed?
"#{MacOS::XQuartz.version} => #{describe_path(MacOS::XQuartz.prefix)}" "#{MacOS::XQuartz.version} => #{describe_path(MacOS::XQuartz.prefix)}"

View File

@ -28,7 +28,7 @@ require "language/python"
# @see SharedEnvExtension # @see SharedEnvExtension
# @see FileUtils # @see FileUtils
# @see Pathname # @see Pathname
# @see https://docs.brew.sh/Formula-Cookbook.html Formula Cookbook # @see https://docs.brew.sh/Formula-Cookbook Formula Cookbook
# @see https://github.com/styleguide/ruby Ruby Style Guide # @see https://github.com/styleguide/ruby Ruby Style Guide
# #
# <pre>class Wget < Formula # <pre>class Wget < Formula
@ -2057,7 +2057,7 @@ class Formula
# and you haven't passed or previously used any options on this formula. # and you haven't passed or previously used any options on this formula.
# #
# If you maintain your own repository, you can add your own bottle links. # If you maintain your own repository, you can add your own bottle links.
# https://docs.brew.sh/Bottles.html # https://docs.brew.sh/Bottles
# You can ignore this block entirely if submitting to Homebrew/homebrew-core. # You can ignore this block entirely if submitting to Homebrew/homebrew-core.
# It'll be handled for you by the Brew Test Bot. # It'll be handled for you by the Brew Test Bot.
# #
@ -2201,12 +2201,12 @@ class Formula
# # `build.with?` or `build.without? "another_formula"`: # # `build.with?` or `build.without? "another_formula"`:
# depends_on "postgresql" if build.without? "sqlite" # depends_on "postgresql" if build.without? "sqlite"
# #
# <pre># Python 2.7: # <pre># Python 3.x if the `--with-python` is given to `brew install example`
# depends_on "python"</pre>
# <pre># Python 2.7 but use system Python where possible
# depends_on "python" if MacOS.version <= :snow_leopard</pre>
# <pre># Python 3.x if the `--with-python3` is given to `brew install example`
# depends_on "python3" => :optional</pre> # depends_on "python3" => :optional</pre>
# <pre># Python 2.7:
# depends_on "python@2"</pre>
# <pre># Python 2.7 but use system Python where possible
# depends_on "python@2" if MacOS.version <= :snow_leopard</pre>
def depends_on(dep) def depends_on(dep)
specs.each { |spec| spec.depends_on(dep) } specs.each { |spec| spec.depends_on(dep) }
end end

View File

@ -566,7 +566,7 @@ class FormulaInstaller
def caveats def caveats
return if only_deps? return if only_deps?
audit_installed if ARGV.homebrew_developer? && !formula.keg_only? audit_installed if ARGV.homebrew_developer?
caveats = Caveats.new(formula) caveats = Caveats.new(formula)
@ -882,8 +882,10 @@ class FormulaInstaller
end end
def audit_installed def audit_installed
unless formula.keg_only?
problem_if_output(check_env_path(formula.bin)) problem_if_output(check_env_path(formula.bin))
problem_if_output(check_env_path(formula.sbin)) problem_if_output(check_env_path(formula.sbin))
end
super super
end end

View File

@ -9,16 +9,17 @@ module Language
Version.create(version.to_s) Version.create(version.to_s)
end end
def self.homebrew_site_packages(version = "2.7") def self.homebrew_site_packages(version = "3.6")
HOMEBREW_PREFIX/"lib/python#{version}/site-packages" HOMEBREW_PREFIX/"lib/python#{version}/site-packages"
end end
def self.each_python(build, &block) def self.each_python(build, &block)
original_pythonpath = ENV["PYTHONPATH"] original_pythonpath = ENV["PYTHONPATH"]
["python", "python3"].each do |python| { "python@3" => "python3", "python@2" => "python2.7" }.each do |python_formula, python|
next if build.without? python python_formula = Formulary.factory(python_formula)
next if build.without? python_formula.to_s
version = major_minor_version python version = major_minor_version python
ENV["PYTHONPATH"] = if Formulary.factory(python).installed? ENV["PYTHONPATH"] = if python_formula.installed?
nil nil
else else
homebrew_site_packages(version) homebrew_site_packages(version)
@ -88,7 +89,7 @@ module Language
# @param venv_root [Pathname, String] the path to the root of the virtualenv # @param venv_root [Pathname, String] the path to the root of the virtualenv
# (often `libexec/"venv"`) # (often `libexec/"venv"`)
# @param python [String] which interpreter to use (e.g. "python" # @param python [String] which interpreter to use (e.g. "python"
# or "python3") # or "python2")
# @param formula [Formula] the active Formula # @param formula [Formula] the active Formula
# @return [Virtualenv] a {Virtualenv} instance # @return [Virtualenv] a {Virtualenv} instance
def virtualenv_create(venv_root, python = "python", formula = self) def virtualenv_create(venv_root, python = "python", formula = self)
@ -114,8 +115,8 @@ module Language
# Returns true if a formula option for the specified python is currently # Returns true if a formula option for the specified python is currently
# active or if the specified python is required by the formula. Valid # active or if the specified python is required by the formula. Valid
# inputs are "python", "python3", :python, and :python3. Note that # inputs are "python", "python2", :python, and :python2. Note that
# "with-python", "without-python", "with-python3", and "without-python3" # "with-python", "without-python", "with-python@2", and "without-python@2"
# formula options are handled correctly even if not associated with any # formula options are handled correctly even if not associated with any
# corresponding depends_on statement. # corresponding depends_on statement.
# @api private # @api private
@ -127,16 +128,16 @@ module Language
# Helper method for the common case of installing a Python application. # Helper method for the common case of installing a Python application.
# Creates a virtualenv in `libexec`, installs all `resource`s defined # Creates a virtualenv in `libexec`, installs all `resource`s defined
# on the formula, and then installs the formula. An options hash may be # on the formula, and then installs the formula. An options hash may be
# passed (e.g., :using => "python3") to override the default, guessed # passed (e.g., :using => "python") to override the default, guessed
# formula preference for python or python3, or to resolve an ambiguous # formula preference for python or python2, or to resolve an ambiguous
# case where it's not clear whether python or python3 should be the # case where it's not clear whether python or python2 should be the
# default guess. # default guess.
def virtualenv_install_with_resources(options = {}) def virtualenv_install_with_resources(options = {})
python = options[:using] python = options[:using]
if python.nil? if python.nil?
wanted = %w[python python@2 python@3 python3].select { |py| needs_python?(py) } wanted = %w[python python@2 python2 python3].select { |py| needs_python?(py) }
raise FormulaAmbiguousPythonError, self if wanted.size > 1 raise FormulaAmbiguousPythonError, self if wanted.size > 1
python = wanted.first || "python2.7" python = wanted.first || "python"
end end
venv = virtualenv_create(libexec, python.delete("@")) venv = virtualenv_create(libexec, python.delete("@"))
venv.pip_install resources venv.pip_install resources
@ -153,7 +154,7 @@ module Language
# @param venv_root [Pathname, String] the path to the root of the # @param venv_root [Pathname, String] the path to the root of the
# virtualenv # virtualenv
# @param python [String] which interpreter to use; i.e. "python" or # @param python [String] which interpreter to use; i.e. "python" or
# "python3" # "python2"
def initialize(formula, venv_root, python) def initialize(formula, venv_root, python)
@formula = formula @formula = formula
@venv_root = Pathname.new(venv_root) @venv_root = Pathname.new(venv_root)
@ -179,11 +180,11 @@ module Language
end end
end end
# Robustify symlinks to survive python3 patch upgrades # Robustify symlinks to survive python patch upgrades
@venv_root.find do |f| @venv_root.find do |f|
next unless f.symlink? next unless f.symlink?
next unless (rp = f.realpath.to_s).start_with? HOMEBREW_CELLAR next unless (rp = f.realpath.to_s).start_with? HOMEBREW_CELLAR
python = rp.include?("python3") ? "python3" : "python" python = rp.include?("python2") ? "python2" : "python"
new_target = rp.sub %r{#{HOMEBREW_CELLAR}/#{python}/[^/]+}, Formula[python].opt_prefix new_target = rp.sub %r{#{HOMEBREW_CELLAR}/#{python}/[^/]+}, Formula[python].opt_prefix
f.unlink f.unlink
f.make_symlink new_target f.make_symlink new_target
@ -191,7 +192,7 @@ module Language
Pathname.glob(@venv_root/"lib/python*/orig-prefix.txt").each do |prefix_file| Pathname.glob(@venv_root/"lib/python*/orig-prefix.txt").each do |prefix_file|
prefix_path = prefix_file.read prefix_path = prefix_file.read
python = prefix_path.include?("python3") ? "python3" : "python" python = prefix_path.include?("python2") ? "python2" : "python"
prefix_path.sub! %r{^#{HOMEBREW_CELLAR}/#{python}/[^/]+}, Formula[python].opt_prefix prefix_path.sub! %r{^#{HOMEBREW_CELLAR}/#{python}/[^/]+}, Formula[python].opt_prefix
prefix_file.atomic_write prefix_path prefix_file.atomic_write prefix_path
end end

View File

@ -94,7 +94,7 @@ class LinkageChecker
formula.build.without?(dep) formula.build.without?(dep)
end end
declared_deps = formula.deps.reject { |dep| filter_out.call(dep) }.map(&:name) declared_deps = formula.deps.reject { |dep| filter_out.call(dep) }.map(&:name)
recursive_deps = keg.to_formula.runtime_dependencies.map { |dep| dep.to_formula.full_name } recursive_deps = keg.to_formula.runtime_dependencies.map { |dep| dep.to_formula.name }
declared_dep_names = declared_deps.map { |dep| dep.split("/").last } declared_dep_names = declared_deps.map { |dep| dep.split("/").last }
indirect_deps = [] indirect_deps = []
undeclared_deps = [] undeclared_deps = []

View File

@ -76,7 +76,7 @@ scripts that reside somewhere in the `PATH`, named `brew-`<cmdname> or
to create your own commands without modifying Homebrew's internals. to create your own commands without modifying Homebrew's internals.
Instructions for creating your own commands can be found in the docs: Instructions for creating your own commands can be found in the docs:
<https://docs.brew.sh/External-Commands.html> <https://docs.brew.sh/External-Commands>
## SPECIFYING FORMULAE ## SPECIFYING FORMULAE
@ -183,6 +183,10 @@ can take several different forms:
*Note:* Homebrew doesn't require permissions for any of the scopes. *Note:* Homebrew doesn't require permissions for any of the scopes.
* `HOMEBREW_INSTALL_BADGE`:
Text printed before the installation summary of each successful build.
Defaults to the beer emoji.
* `HOMEBREW_LOGS`: * `HOMEBREW_LOGS`:
If set, Homebrew will use the given directory to store log files. If set, Homebrew will use the given directory to store log files.
@ -193,12 +197,15 @@ can take several different forms:
*Default:* the number of available CPU cores. *Default:* the number of available CPU cores.
* `HOMEBREW_NO_ANALYTICS`: * `HOMEBREW_NO_ANALYTICS`:
If set, Homebrew will not send analytics. See: <https://docs.brew.sh/Analytics.html> If set, Homebrew will not send analytics. See: <https://docs.brew.sh/Analytics>
* `HOMEBREW_NO_AUTO_UPDATE`: * `HOMEBREW_NO_AUTO_UPDATE`:
If set, Homebrew will not auto-update before running `brew install`, If set, Homebrew will not auto-update before running `brew install`,
`brew upgrade` or `brew tap`. `brew upgrade` or `brew tap`.
* `HOMEBREW_NO_COLOR`:
If set, Homebrew will not print text with color added.
* `HOMEBREW_NO_EMOJI`: * `HOMEBREW_NO_EMOJI`:
If set, Homebrew will not print the `HOMEBREW_INSTALL_BADGE` on a If set, Homebrew will not print the `HOMEBREW_INSTALL_BADGE` on a
successful build. successful build.
@ -217,9 +224,8 @@ can take several different forms:
If set, Homebrew will not use the GitHub API for e.g searches or If set, Homebrew will not use the GitHub API for e.g searches or
fetching relevant issues on a failed install. fetching relevant issues on a failed install.
* `HOMEBREW_INSTALL_BADGE`: * `HOMEBREW_PRY`:
Text printed before the installation summary of each successful build. If set, Homebrew will use `pry` for the `brew irb` command.
Defaults to the beer emoji.
* `HOMEBREW_SVN`: * `HOMEBREW_SVN`:
When exporting from Subversion, Homebrew will use `HOMEBREW_SVN` if set, When exporting from Subversion, Homebrew will use `HOMEBREW_SVN` if set,

View File

@ -183,7 +183,7 @@ class Migrator
end end
def migrate def migrate
oh1 "Migrating #{Formatter.identifier(oldname)} to #{Formatter.identifier(newname)}" oh1 "Processing #{Formatter.identifier(oldname)} formula rename to #{Formatter.identifier(newname)}"
lock lock
unlink_oldname unlink_oldname
unlink_newname if new_cellar.exist? unlink_newname if new_cellar.exist?
@ -193,6 +193,14 @@ class Migrator
link_oldname_opt link_oldname_opt
link_newname unless old_linked_keg.nil? link_newname unless old_linked_keg.nil?
update_tabs update_tabs
return unless formula.outdated?
opoo <<~EOS
#{Formatter.identifier(newname)} is outdated!
To avoid broken installations, as soon as possible please run:
brew upgrade
Or, if you're OK with a less reliable fix:
brew upgrade #{newname}
EOS
rescue Interrupt rescue Interrupt
ignore_interrupts { backup_oldname } ignore_interrupts { backup_oldname }
rescue Exception => e # rubocop:disable Lint/RescueException rescue Exception => e # rubocop:disable Lint/RescueException
@ -226,7 +234,7 @@ class Migrator
end end
end end
oh1 "Moving #{Formatter.identifier(oldname)} children" oh1 "Moving #{Formatter.identifier(oldname)} versions to #{new_cellar}"
if new_cellar.exist? if new_cellar.exist?
FileUtils.mv(old_cellar.children, new_cellar) FileUtils.mv(old_cellar.children, new_cellar)
else else
@ -261,7 +269,7 @@ class Migrator
end end
def unlink_newname def unlink_newname
oh1 "Unlinking #{Formatter.identifier(newname)}" oh1 "Temporarily unlinking #{Formatter.identifier(newname)}"
new_cellar.subdirs.each do |d| new_cellar.subdirs.each do |d|
keg = Keg.new(d) keg = Keg.new(d)
keg.unlink keg.unlink
@ -269,7 +277,7 @@ class Migrator
end end
def link_newname def link_newname
oh1 "Linking #{Formatter.identifier(newname)}" oh1 "Relinking #{Formatter.identifier(newname)}"
new_keg = Keg.new(new_linked_keg_record) new_keg = Keg.new(new_linked_keg_record)
# If old_keg wasn't linked then we just optlink a keg. # If old_keg wasn't linked then we just optlink a keg.
@ -288,7 +296,8 @@ class Migrator
new_keg.remove_linked_keg_record if new_keg.linked? new_keg.remove_linked_keg_record if new_keg.linked?
begin begin
new_keg.link mode = OpenStruct.new(overwrite: true)
new_keg.link(mode)
rescue Keg::ConflictError => e rescue Keg::ConflictError => e
onoe "Error while executing `brew link` step on #{newname}" onoe "Error while executing `brew link` step on #{newname}"
puts e puts e

View File

@ -155,7 +155,7 @@ module Homebrew
git -C "$(brew --repo #{tap})" show #{short_hash}^:#{relative_path} git -C "$(brew --repo #{tap})" show #{short_hash}^:#{relative_path}
If you still use this formula consider creating your own tap: If you still use this formula consider creating your own tap:
https://docs.brew.sh/How-to-Create-and-Maintain-a-Tap.html https://docs.brew.sh/How-to-Create-and-Maintain-a-Tap
EOS EOS
end end
end end

View File

@ -17,10 +17,11 @@ module OS
require "os/mac" require "os/mac"
# Don't tell people to report issues on unsupported versions of macOS. # Don't tell people to report issues on unsupported versions of macOS.
if !OS::Mac.prerelease? && !OS::Mac.outdated_release? if !OS::Mac.prerelease? && !OS::Mac.outdated_release?
ISSUES_URL = "https://docs.brew.sh/Troubleshooting.html".freeze ISSUES_URL = "https://docs.brew.sh/Troubleshooting".freeze
end end
PATH_OPEN = "/usr/bin/open".freeze PATH_OPEN = "/usr/bin/open".freeze
elsif OS.linux? elsif OS.linux?
require "os/linux"
ISSUES_URL = "https://github.com/Linuxbrew/brew/wiki/troubleshooting".freeze ISSUES_URL = "https://github.com/Linuxbrew/brew/wiki/troubleshooting".freeze
PATH_OPEN = "xdg-open".freeze PATH_OPEN = "xdg-open".freeze
end end

View File

@ -0,0 +1,28 @@
module OS
# Define OS::Mac on Linux for formula API compatibility.
module Mac
module_function
::MacOS = self # rubocop:disable Naming/ConstantName
def prefer_64_bit?
Hardware::CPU.is_64_bit?
end
def version
Version::NULL
end
def full_version
Version::NULL
end
module Xcode
module_function
def version
Version::NULL
end
end
end
end

View File

@ -131,7 +131,7 @@ module OS
xcodebuild_output = Utils.popen_read(xcodebuild_path, "-version") xcodebuild_output = Utils.popen_read(xcodebuild_path, "-version")
next unless $CHILD_STATUS.success? next unless $CHILD_STATUS.success?
xcode_version = xcodebuild_output[/Xcode (\d(\.\d)*)/, 1] xcode_version = xcodebuild_output[/Xcode (\d+(\.\d+)*)/, 1]
return xcode_version if xcode_version return xcode_version if xcode_version
# Xcode 2.x's xcodebuild has a different version string # Xcode 2.x's xcodebuild has a different version string

View File

@ -2,6 +2,7 @@ require_relative "./rubocops/bottle_block_cop"
require_relative "./rubocops/formula_desc_cop" require_relative "./rubocops/formula_desc_cop"
require_relative "./rubocops/components_order_cop" require_relative "./rubocops/components_order_cop"
require_relative "./rubocops/components_redundancy_cop" require_relative "./rubocops/components_redundancy_cop"
require_relative "./rubocops/dependency_order_cop"
require_relative "./rubocops/homepage_cop" require_relative "./rubocops/homepage_cop"
require_relative "./rubocops/text_cop" require_relative "./rubocops/text_cop"
require_relative "./rubocops/caveats_cop" require_relative "./rubocops/caveats_cop"

View File

@ -0,0 +1,166 @@
require_relative "./extend/formula_cop"
module RuboCop
module Cop
module NewFormulaAudit
# This cop checks for correct order of `depends_on` in a Formula
#
# precedence order:
# build-time > run-time > normal > recommended > optional
class DependencyOrder < FormulaCop
def audit_formula(_node, _class_node, _parent_class_node, body_node)
check_dependency_nodes_order(body_node)
[:devel, :head, :stable].each do |block_name|
block = find_block(body_node, block_name)
next unless block
check_dependency_nodes_order(block.body)
end
end
def check_dependency_nodes_order(parent_node)
return if parent_node.nil?
dependency_nodes = fetch_depends_on_nodes(parent_node)
ordered = dependency_nodes.sort { |a, b| sort_by_dependency_name(a, b) }
ordered = sort_dependencies_by_type(ordered)
sort_conditional_dependencies!(ordered)
verify_order_in_source(ordered)
end
# Match all `depends_on` nodes among childnodes of given parent node
def fetch_depends_on_nodes(parent_node)
parent_node.each_child_node.select { |x| depends_on_node?(x) }
end
def sort_by_dependency_name(a, b)
a_name = dependency_name(a)
b_name = dependency_name(b)
if a_name < b_name
-1
elsif a_name > b_name
1
else
0
end
end
# Separate dependencies according to precedence order:
# build-time > run-time > normal > recommended > optional
def sort_dependencies_by_type(dependency_nodes)
ordered = []
ordered.concat(dependency_nodes.select { |dep| buildtime_dependency? dep }.to_a)
ordered.concat(dependency_nodes.select { |dep| runtime_dependency? dep }.to_a)
ordered.concat(dependency_nodes.reject { |dep| negate_normal_dependency? dep }.to_a)
ordered.concat(dependency_nodes.select { |dep| recommended_dependency? dep }.to_a)
ordered.concat(dependency_nodes.select { |dep| optional_dependency? dep }.to_a)
end
# `depends_on :apple if build.with? "foo"` should always be defined
# after `depends_on :foo`
# This method reorders dependencies array according to above rule
def sort_conditional_dependencies!(ordered)
length = ordered.size
idx = 0
while idx < length
idx1, idx2 = nil
ordered.each_with_index do |dep, pos|
idx = pos+1
match_nodes = build_with_dependency_name(dep)
idx1 = pos if match_nodes && !match_nodes.empty?
next unless idx1
idx2 = nil
ordered.drop(idx1+1).each_with_index do |dep2, pos2|
next unless match_nodes.index(dependency_name(dep2))
idx2 = pos2 if idx2.nil? || pos2 > idx2
end
break if idx2
end
insert_after!(ordered, idx1, idx2+idx1) if idx2
end
ordered
end
# Verify actual order of sorted `depends_on` nodes in source code
# Else raise RuboCop problem
def verify_order_in_source(ordered)
ordered.each_with_index do |dependency_node_1, idx|
l1 = line_number(dependency_node_1)
dependency_node_2 = nil
ordered.drop(idx+1).each do |node2|
l2 = line_number(node2)
dependency_node_2 = node2 if l2 < l1
end
next unless dependency_node_2
@offensive_nodes = [dependency_node_1, dependency_node_2]
component_problem dependency_node_1, dependency_node_2
end
end
# Node pattern method to match
# `depends_on` variants
def_node_matcher :depends_on_node?, <<~EOS
{(if _ (send nil? :depends_on ...) nil?)
(send nil? :depends_on ...)}
EOS
def_node_search :buildtime_dependency?, "(sym :build)"
def_node_search :recommended_dependency?, "(sym :recommended)"
def_node_search :runtime_dependency?, "(sym :run)"
def_node_search :optional_dependency?, "(sym :optional)"
def_node_search :negate_normal_dependency?, "(sym {:build :recommended :run :optional})"
# Node pattern method to extract `name` in `depends_on :name`
def_node_search :dependency_name_node, <<~EOS
{(send nil? :depends_on {(hash (pair $_ _)) $({str sym} _)})
(if _ (send nil? :depends_on {(hash (pair $_ _)) $({str sym} _)}) nil?)}
EOS
# Node pattern method to extract `name` in `build.with? :name`
def_node_search :build_with_dependency_node, <<~EOS
(send (send nil? :build) :with? $({str sym} _))
EOS
def insert_after!(arr, idx1, idx2)
arr.insert(idx2+1, arr.delete_at(idx1))
end
def build_with_dependency_name(node)
match_nodes = build_with_dependency_node(node)
match_nodes = match_nodes.to_a.delete_if(&:nil?)
match_nodes.map { |n| string_content(n) } unless match_nodes.empty?
end
def dependency_name(dependency_node)
match_node = dependency_name_node(dependency_node).to_a.first
string_content(match_node) if match_node
end
def autocorrect(_node)
succeeding_node = @offensive_nodes[0]
preceding_node = @offensive_nodes[1]
lambda do |corrector|
reorder_components(corrector, succeeding_node, preceding_node)
end
end
private
def component_problem(c1, c2)
offending_node(c1)
problem "dependency \"#{dependency_name(c1)}\" (line #{line_number(c1)}) should be put before dependency \"#{dependency_name(c2)}\" (line #{line_number(c2)})"
end
# Reorder two nodes in the source, using the corrector instance in autocorrect method
def reorder_components(corrector, node1, node2)
indentation = " " * (start_column(node2) - line_start_column(node2))
line_breaks = "\n"
corrector.insert_before(node2.source_range, node1.source + line_breaks + indentation)
corrector.remove(range_with_surrounding_space(range: node1.source_range, side: :left))
end
end
end
end
end

View File

@ -131,16 +131,10 @@ class SystemConfig
end end
def describe_java def describe_java
# java_home doesn't exist on all macOSs; it might be missing on older versions. return "N/A" unless which "java"
return "N/A" unless File.executable? "/usr/libexec/java_home" java_version = Utils.popen_read("java", "-version")
java_xml = Utils.popen_read("/usr/libexec/java_home", "--xml", "--failfast", err: :close)
return "N/A" unless $CHILD_STATUS.success? return "N/A" unless $CHILD_STATUS.success?
javas = [] java_version[/java version "([\d\._]+)"/, 1] || "N/A"
REXML::XPath.each(REXML::Document.new(java_xml), "//key[text()='JVMVersion']/following-sibling::string") do |item|
javas << item.text
end
javas.uniq.join(", ")
end end
def describe_git def describe_git

View File

@ -141,6 +141,20 @@ shared_examples EnvActivation do
expect(subject["MAKEFLAGS"]).to eq("-j4") expect(subject["MAKEFLAGS"]).to eq("-j4")
end end
describe "#clear_sensitive_environment!" do
it "removes sensitive environment variables" do
subject["SECRET_TOKEN"] = "password"
subject.clear_sensitive_environment!
expect(subject).not_to include("SECRET_TOKEN")
end
it "leaves non-sensitive environment variables alone" do
subject["FOO"] = "bar"
subject.clear_sensitive_environment!
expect(subject["FOO"]).to eq "bar"
end
end
end end
describe Stdenv do describe Stdenv do

View File

@ -5,6 +5,7 @@ require_relative "../constants"
gem "parallel_tests" gem "parallel_tests"
gem "rspec" gem "rspec"
gem "rspec-its", require: false gem "rspec-its", 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

View File

@ -1,7 +1,7 @@
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
ast (2.3.0) ast (2.4.0)
codecov (0.1.10) codecov (0.1.10)
json json
simplecov simplecov
@ -9,29 +9,31 @@ GEM
diff-lcs (1.3) diff-lcs (1.3)
docile (1.1.5) docile (1.1.5)
json (2.1.0) json (2.1.0)
parallel (1.12.0) parallel (1.12.1)
parallel_tests (2.17.0) parallel_tests (2.21.2)
parallel parallel
parser (2.4.0.2) parser (2.5.0.2)
ast (~> 2.3) ast (~> 2.4.0)
powerpack (0.1.1) powerpack (0.1.1)
rainbow (3.0.0) rainbow (3.0.0)
rspec (3.6.0) rspec (3.7.0)
rspec-core (~> 3.6.0) rspec-core (~> 3.7.0)
rspec-expectations (~> 3.6.0) rspec-expectations (~> 3.7.0)
rspec-mocks (~> 3.6.0) rspec-mocks (~> 3.7.0)
rspec-core (3.6.0) rspec-core (3.7.1)
rspec-support (~> 3.6.0) rspec-support (~> 3.7.0)
rspec-expectations (3.6.0) rspec-expectations (3.7.0)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.6.0) rspec-support (~> 3.7.0)
rspec-its (1.2.0) rspec-its (1.2.0)
rspec-core (>= 3.0.0) rspec-core (>= 3.0.0)
rspec-expectations (>= 3.0.0) rspec-expectations (>= 3.0.0)
rspec-mocks (3.6.0) rspec-mocks (3.7.0)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.6.0) rspec-support (~> 3.7.0)
rspec-support (3.6.0) rspec-retry (0.5.6)
rspec-core (> 3.3, < 3.8)
rspec-support (3.7.1)
rspec-wait (0.0.9) rspec-wait (0.0.9)
rspec (>= 3, < 4) rspec (>= 3, < 4)
rubocop (0.52.1) rubocop (0.52.1)
@ -58,9 +60,10 @@ DEPENDENCIES
parallel_tests parallel_tests
rspec rspec
rspec-its rspec-its
rspec-retry
rspec-wait rspec-wait
rubocop (= 0.52.1) rubocop (= 0.52.1)
simplecov simplecov
BUNDLED WITH BUNDLED WITH
1.16.0 1.16.1

View File

@ -13,7 +13,8 @@ describe Hbc::CLI::Reinstall, :cask do
Already downloaded: .*local-caffeine--1.2.3.zip Already downloaded: .*local-caffeine--1.2.3.zip
==> Verifying checksum for Cask local-caffeine ==> Verifying checksum for Cask local-caffeine
==> Uninstalling Cask local-caffeine ==> Uninstalling Cask local-caffeine
==> Moving App 'Caffeine.app' back to '.*Caffeine.app'. ==> Backing App 'Caffeine.app' up to '.*Caffeine.app'.
==> Removing App '.*Caffeine.app'.
==> Purging files for version 1.2.3 of Cask local-caffeine ==> Purging files for version 1.2.3 of Cask local-caffeine
==> Installing Cask local-caffeine ==> Installing Cask local-caffeine
==> Moving App 'Caffeine.app' to '.*Caffeine.app'. ==> Moving App 'Caffeine.app' to '.*Caffeine.app'.

View File

@ -12,7 +12,8 @@ describe Hbc::CLI::Uninstall, :cask do
output = Regexp.new <<~EOS output = Regexp.new <<~EOS
==> Uninstalling Cask local-caffeine ==> Uninstalling Cask local-caffeine
==> Moving App 'Caffeine.app' back to '.*Caffeine.app'. ==> Backing App 'Caffeine.app' up to '.*Caffeine.app'.
==> Removing App '.*Caffeine.app'.
==> Purging files for version 1.2.3 of Cask local-caffeine ==> Purging files for version 1.2.3 of Cask local-caffeine
EOS EOS

View File

@ -75,6 +75,7 @@ describe Hbc::DSL, :cask do
it "may use deprecated DSL version hash syntax" do it "may use deprecated DSL version hash syntax" do
allow(ENV).to receive(:[]).with("HOMEBREW_DEVELOPER").and_return(nil) allow(ENV).to receive(:[]).with("HOMEBREW_DEVELOPER").and_return(nil)
allow(ENV).to receive(:[]).with("HOMEBREW_NO_COLOR").and_return(nil)
expect(cask.token).to eq("with-dsl-version") expect(cask.token).to eq("with-dsl-version")
expect(cask.url.to_s).to eq("http://example.com/TestCask.dmg") expect(cask.url.to_s).to eq("http://example.com/TestCask.dmg")

View File

@ -29,7 +29,7 @@ describe "brew migrate", :integration_test do
install_and_rename_coretap_formula "testball1", "testball2" install_and_rename_coretap_formula "testball1", "testball2"
expect { brew "migrate", "testball1" } expect { brew "migrate", "testball1" }
.to output(/Migrating testball1 to testball2/).to_stdout .to output(/Processing testball1 formula rename to testball2/).to_stdout
.and not_to_output.to_stderr .and not_to_output.to_stderr
.and be_a_success .and be_a_success
end end

View File

@ -25,7 +25,7 @@ describe "brew search", :integration_test do
.and be_a_success .and be_a_success
end end
it "falls back to a GitHub tap search when no formula is found", :needs_network do it "falls back to a GitHub tap search when no formula is found", :needs_network, retry: 3 do
expect { brew "search", "caskroom/cask/firefox" } expect { brew "search", "caskroom/cask/firefox" }
.to output(/firefox/).to_stdout .to output(/firefox/).to_stdout
.and output(/Searching/).to_stderr .and output(/Searching/).to_stderr

View File

@ -1,4 +1,4 @@
describe "brew services", :integration_test, :needs_macos, :needs_network do describe "brew services", :integration_test, :needs_macos, :needs_network, retry: 3 do
it "allows controlling services" do it "allows controlling services" do
setup_remote_tap "homebrew/services" setup_remote_tap "homebrew/services"

View File

@ -6,7 +6,7 @@ describe "brew pull", :integration_test do
.and be_a_failure .and be_a_failure
end end
it "fetches a patch from a GitHub commit or pull request and applies it", :needs_network do it "fetches a patch from a GitHub commit or pull request and applies it", :needs_network, retry: 3 do
CoreTap.instance.path.cd do CoreTap.instance.path.cd do
system "git", "init" system "git", "init"
system "git", "checkout", "-b", "new-branch" system "git", "checkout", "-b", "new-branch"

View File

@ -0,0 +1,13 @@
describe "brew ruby", :integration_test do
it "executes ruby code with Homebrew's libraries loaded" do
expect { brew "ruby", "-e", "exit 0" }
.to be_a_success
.and not_to_output.to_stdout
.and not_to_output.to_stderr
expect { brew "ruby", "-e", "exit 1" }
.to be_a_failure
.and not_to_output.to_stdout
.and not_to_output.to_stderr
end
end

View File

@ -209,6 +209,19 @@ describe CurlDownloadStrategy do
it "parses the opts and sets the corresponding args" do it "parses the opts and sets the corresponding args" do
expect(subject.send(:_curl_opts)).to eq(["--user", "download:123456"]) expect(subject.send(:_curl_opts)).to eq(["--user", "download:123456"])
end end
describe "#tarball_path" do
subject { described_class.new(name, resource).tarball_path }
context "when URL ends with file" do
it { is_expected.to eq(HOMEBREW_CACHE/"foo-.tar.gz") }
end
context "when URL file is in middle" do
let(:url) { "http://example.com/foo.tar.gz/from/this/mirror" }
it { is_expected.to eq(HOMEBREW_CACHE/"foo-.tar.gz") }
end
end
end end
describe DownloadStrategyDetector do describe DownloadStrategyDetector do

View File

@ -31,10 +31,6 @@ describe LanguageModuleRequirement, :needs_compat do
it "does not satisfy invalid dependencies" do it "does not satisfy invalid dependencies" do
expect(described_class.new(:python, "notapackage")).not_to be_satisfied expect(described_class.new(:python, "notapackage")).not_to be_satisfied
end end
it "satisfies valid dependencies" do
expect(described_class.new(:python, "datetime")).to be_satisfied
end
end end
context "when the language is Ruby" do context "when the language is Ruby" do

View File

@ -0,0 +1,53 @@
require "dependency_collector"
describe DependencyCollector do
alias_matcher :be_a_build_requirement, :be_build
after(:each) do
described_class.clear_cache
end
describe "#add" do
resource = Resource.new
context "when xz, unzip, and bzip2 are not available" do
it "creates a resource dependency from a '.xz' URL" do
resource.url("http://example.com/foo.xz")
allow_any_instance_of(Object).to receive(:which).with("xz")
expect(subject.add(resource)).to eq(Dependency.new("xz", [:build]))
end
it "creates a resource dependency from a '.zip' URL" do
resource.url("http://example.com/foo.zip")
allow_any_instance_of(Object).to receive(:which).with("unzip")
expect(subject.add(resource)).to eq(Dependency.new("unzip", [:build]))
end
it "creates a resource dependency from a '.bz2' URL" do
resource.url("http://example.com/foo.tar.bz2")
allow_any_instance_of(Object).to receive(:which).with("bzip2")
expect(subject.add(resource)).to eq(Dependency.new("bzip2", [:build]))
end
end
context "when xz, zip, and bzip2 are available" do
it "does not create a resource dependency from a '.xz' URL" do
resource.url("http://example.com/foo.xz")
allow_any_instance_of(Object).to receive(:which).with("xz").and_return(Pathname.new("foo"))
expect(subject.add(resource)).to be nil
end
it "does not create a resource dependency from a '.zip' URL" do
resource.url("http://example.com/foo.zip")
allow_any_instance_of(Object).to receive(:which).with("unzip").and_return(Pathname.new("foo"))
expect(subject.add(resource)).to be nil
end
it "does not create a resource dependency from a '.bz2' URL" do
resource.url("http://example.com/foo.tar.bz2")
allow_any_instance_of(Object).to receive(:which).with("bzip2").and_return(Pathname.new("foo"))
expect(subject.add(resource)).to be nil
end
end
end
end

View File

@ -36,6 +36,18 @@ describe DependencyCollector do
expect(subject.add(resource)).to be nil expect(subject.add(resource)).to be nil
end end
specify "Resource dependency from a '.zip' URL" do
resource = Resource.new
resource.url("http://example.com/foo.zip")
expect(subject.add(resource)).to be nil
end
specify "Resource dependency from a '.bz2' URL" do
resource = Resource.new
resource.url("http://example.com/foo.tar.bz2")
expect(subject.add(resource)).to be nil
end
specify "Resource dependency from a '.git' URL" do specify "Resource dependency from a '.git' URL" do
resource = Resource.new resource = Resource.new
resource.url("git://example.com/foo/bar.git") resource.url("git://example.com/foo/bar.git")

View File

@ -0,0 +1,75 @@
require_relative "../../rubocops/dependency_order_cop"
describe RuboCop::Cop::NewFormulaAudit::DependencyOrder do
subject(:cop) { described_class.new }
context "depends_on" do
it "wrong conditional depends_on order" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "http://example.com"
url "http://example.com/foo-1.0.tgz"
depends_on "apple" if build.with? "foo"
depends_on "foo" => :optional
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dependency "foo" (line 5) should be put before dependency "apple" (line 4)
end
RUBY
end
it "wrong alphabetical depends_on order" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "http://example.com"
url "http://example.com/foo-1.0.tgz"
depends_on "foo"
depends_on "bar"
^^^^^^^^^^^^^^^^ dependency "bar" (line 5) should be put before dependency "foo" (line 4)
end
RUBY
end
it "wrong conditional depends_on order" do
expect_offense(<<~RUBY)
class Foo < Formula
homepage "http://example.com"
url "http://example.com/foo-1.0.tgz"
head do
depends_on "apple" if build.with? "foo"
depends_on "bar"
^^^^^^^^^^^^^^^^ dependency "bar" (line 6) should be put before dependency "apple" (line 5)
depends_on "foo" => :optional
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dependency "foo" (line 7) should be put before dependency "apple" (line 5)
end
depends_on "apple" if build.with? "foo"
depends_on "foo" => :optional
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dependency "foo" (line 10) should be put before dependency "apple" (line 9)
end
RUBY
end
end
context "autocorrect" do
it "wrong conditional depends_on order" do
source = <<~EOS
class Foo < Formula
homepage "http://example.com"
url "http://example.com/foo-1.0.tgz"
depends_on "apple" if build.with? "foo"
depends_on "foo" => :optional
end
EOS
correct_source = <<~EOS
class Foo < Formula
homepage "http://example.com"
url "http://example.com/foo-1.0.tgz"
depends_on "foo" => :optional
depends_on "apple" if build.with? "foo"
end
EOS
corrected_source = autocorrect_source(source)
expect(corrected_source).to eq(correct_source)
end
end
end

View File

@ -2,6 +2,7 @@ require "find"
require "pathname" require "pathname"
require "rspec/its" require "rspec/its"
require "rspec/wait" require "rspec/wait"
require "rspec/retry"
require "rubocop" require "rubocop"
require "rubocop/rspec/support" require "rubocop/rspec/support"
require "set" require "set"
@ -74,6 +75,10 @@ RSpec.configure do |config|
skip "Requires network connection." unless ENV["HOMEBREW_TEST_ONLINE"] skip "Requires network connection." unless ENV["HOMEBREW_TEST_ONLINE"]
end end
config.before(:each, :needs_svn) do
skip "Requires subversion." unless which "svn"
end
config.around(:each) do |example| config.around(:each) do |example|
def find_files def find_files
Find.find(TEST_TMPDIR) Find.find(TEST_TMPDIR)

View File

@ -30,7 +30,7 @@ describe Utils do
expect(described_class.svn_remote_exists(HOMEBREW_CACHE/"install")).to be_falsey expect(described_class.svn_remote_exists(HOMEBREW_CACHE/"install")).to be_falsey
end end
it "returns true when remote exists", :needs_network do it "returns true when remote exists", :needs_network, :needs_svn do
remote = "http://github.com/Homebrew/install" remote = "http://github.com/Homebrew/install"
svn = HOMEBREW_SHIMS_PATH/"scm/svn" svn = HOMEBREW_SHIMS_PATH/"scm/svn"

View File

@ -53,7 +53,7 @@ describe Tty do
allow($stdout).to receive(:tty?).and_return(true) allow($stdout).to receive(:tty?).and_return(true)
end end
it "returns an empty string for all colors" do it "returns ANSI escape codes for colors" do
expect(subject.to_s).to eq("") expect(subject.to_s).to eq("")
expect(subject.red.to_s).to eq("\033[31m") expect(subject.red.to_s).to eq("\033[31m")
expect(subject.green.to_s).to eq("\033[32m") expect(subject.green.to_s).to eq("\033[32m")
@ -63,5 +63,17 @@ describe Tty do
expect(subject.cyan.to_s).to eq("\033[36m") expect(subject.cyan.to_s).to eq("\033[36m")
expect(subject.default.to_s).to eq("\033[39m") expect(subject.default.to_s).to eq("\033[39m")
end end
it "returns an empty string for all colors when HOMEBREW_NO_COLOR is set" do
ENV["HOMEBREW_NO_COLOR"] = "1"
expect(subject.to_s).to eq("")
expect(subject.red.to_s).to eq("")
expect(subject.green.to_s).to eq("")
expect(subject.yellow.to_s).to eq("")
expect(subject.blue.to_s).to eq("")
expect(subject.magenta.to_s).to eq("")
expect(subject.cyan.to_s).to eq("")
expect(subject.default.to_s).to eq("")
end
end end
end end

View File

@ -40,7 +40,7 @@ module Utils
end end
# Send analytics. Don't send or store any personally identifiable information. # Send analytics. Don't send or store any personally identifiable information.
# https://docs.brew.sh/Analytics.html # https://docs.brew.sh/Analytics
# https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide # https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide
# https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters # https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters
if ENV["HOMEBREW_ANALYTICS_DEBUG"] if ENV["HOMEBREW_ANALYTICS_DEBUG"]

View File

@ -59,7 +59,9 @@ module Tty
end end
def to_s def to_s
return "" unless $stdout.tty? if ENV["HOMEBREW_NO_COLOR"] || !$stdout.tty?
return ""
end
current_escape_sequence current_escape_sequence
ensure ensure
reset_escape_sequence! reset_escape_sequence!

View File

@ -1,7 +1,7 @@
# Homebrew # Homebrew
[![GitHub release](https://img.shields.io/github/release/Homebrew/brew.svg)](https://github.com/Homebrew/brew/releases) [![GitHub release](https://img.shields.io/github/release/Homebrew/brew.svg)](https://github.com/Homebrew/brew/releases)
Features, usage and installation instructions are [summarised on the homepage](https://brew.sh). Terminology (e.g. the difference between a Cellar, Tap, Cask and so forth) is [explained here](docs/Formula-Cookbook.md#homebrew-terminology). Features, usage and installation instructions are [summarised on the homepage](https://brew.sh). Terminology (e.g. the difference between a Cellar, Tap, Cask and so forth) is [explained here](https://docs.brew.sh/Formula-Cookbook#homebrew-terminology).
## What Packages Are Available? ## What Packages Are Available?
1. Type `brew search` for a list. 1. Type `brew search` for a list.
@ -14,7 +14,7 @@ Features, usage and installation instructions are [summarised on the homepage](h
## Troubleshooting ## Troubleshooting
First, please run `brew update` and `brew doctor`. First, please run `brew update` and `brew doctor`.
Second, read the [Troubleshooting Checklist](https://docs.brew.sh/Troubleshooting.html). Second, read the [Troubleshooting Checklist](https://docs.brew.sh/Troubleshooting).
**If you don't read these it will take us far longer to help you with your problem.** **If you don't read these it will take us far longer to help you with your problem.**
@ -26,7 +26,7 @@ We'd love you to contribute to Homebrew. First, please read our [Contribution Gu
We explicitly welcome contributions from people who have never contributed to open-source before: we were all beginners once! We can help build on a partially working pull request with the aim of getting it merged. We are also actively seeking to diversify our contributors and especially welcome contributions from women from all backgrounds and people of colour. We explicitly welcome contributions from people who have never contributed to open-source before: we were all beginners once! We can help build on a partially working pull request with the aim of getting it merged. We are also actively seeking to diversify our contributors and especially welcome contributions from women from all backgrounds and people of colour.
A good starting point for contributing is running `brew audit --strict` with some of the packages you use (e.g. `brew audit --strict wget` if you use `wget`) and then read through the warnings, try to fix them until `brew audit --strict` shows no results and [submit a pull request](https://docs.brew.sh/How-To-Open-a-Homebrew-Pull-Request.html). If no formulae you use have warnings you can run `brew audit --strict` without arguments to have it run on all packages and pick one. A good starting point for contributing is running `brew audit --strict` with some of the packages you use (e.g. `brew audit --strict wget` if you use `wget`) and then read through the warnings, try to fix them until `brew audit --strict` shows no results and [submit a pull request](https://docs.brew.sh/How-To-Open-a-Homebrew-Pull-Request). If no formulae you use have warnings you can run `brew audit --strict` without arguments to have it run on all packages and pick one.
Alternatively, for something more substantial, check out one of the issues labeled `help wanted` in [Homebrew/brew](https://github.com/homebrew/brew/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) or [Homebrew/homebrew-core](https://github.com/homebrew/homebrew-core/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22). Alternatively, for something more substantial, check out one of the issues labeled `help wanted` in [Homebrew/brew](https://github.com/homebrew/brew/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) or [Homebrew/homebrew-core](https://github.com/homebrew/homebrew-core/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22).

View File

@ -47,7 +47,7 @@ HOMEBREW_LIBRARY="$HOMEBREW_REPOSITORY/Library"
# Whitelist and copy to HOMEBREW_* all variables previously mentioned in # Whitelist and copy to HOMEBREW_* all variables previously mentioned in
# manpage or used elsewhere by Homebrew. # manpage or used elsewhere by Homebrew.
for VAR in AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY BINTRAY_USER BINTRAY_KEY \ for VAR in AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY BINTRAY_USER BINTRAY_KEY \
BROWSER EDITOR GIT PATH VISUAL \ BROWSER EDITOR GIT NO_COLOR PATH VISUAL \
GITHUB_USER GITHUB_PASSWORD GITHUB_TOKEN GITHUB_USER GITHUB_PASSWORD GITHUB_TOKEN
do do
# Skip if variable value is empty. # Skip if variable value is empty.
@ -66,9 +66,9 @@ then
FILTERED_ENV=() FILTERED_ENV=()
# Filter all but the specific variables. # Filter all but the specific variables.
for VAR in HOME SHELL PATH TERM LOGNAME USER CI TRAVIS SSH_AUTH_SOCK SUDO_ASKPASS \ for VAR in HOME SHELL PATH TERM LOGNAME USER CI TRAVIS TRAVIS_SUDO SSH_AUTH_SOCK SUDO_ASKPASS \
http_proxy https_proxy ftp_proxy no_proxy all_proxy HTTPS_PROXY FTP_PROXY ALL_PROXY \ http_proxy https_proxy ftp_proxy no_proxy all_proxy HTTPS_PROXY FTP_PROXY ALL_PROXY \
"${!HOMEBREW_@}" "${!TRAVIS_@}" "${!JENKINS_@}" "${!HOMEBREW_@}"
do do
# Skip if variable value is empty. # Skip if variable value is empty.
[[ -z "${!VAR}" ]] && continue [[ -z "${!VAR}" ]] && continue

View File

@ -1 +0,0 @@
CgQNmjNTd6fUriinp4XpuRI5PBGp7zEXbEEsQceSD0k.unNjkXuFqjKx4BO8gem4nzeMm1tSZxPPeBjNqQhFCqQ

View File

@ -38,15 +38,6 @@ tarballs should include the version in the filename whenever possible.
We dont accept software without a tagged version because they regularly break We dont accept software without a tagged version because they regularly break
due to upstream changes and we cant provide [bottles](Bottles.md) for them. due to upstream changes and we cant provide [bottles](Bottles.md) for them.
### Bindings
First check that there is not already a binding available via
[`gem`](https://rubygems.org/) or [`pip`](http://www.pip-installer.org/)
etc.
If not, then put bindings in the formula they bind to. This is more
useful to people. Just install the stuff! Having to faff around with
foo-ruby, foo-perl etc. is a bad user experience.
### Niche (or self-submitted) stuff ### Niche (or self-submitted) stuff
The software in question must: The software in question must:

View File

@ -80,7 +80,7 @@ When running `brew upgrade`, you see something like this:
$ brew upgrade $ brew upgrade
Error: undefined method `include?' for nil:NilClass Error: undefined method `include?' for nil:NilClass
Please report this bug: Please report this bug:
https://docs.brew.sh/Troubleshooting.html https://docs.brew.sh/Troubleshooting
/usr/local/Library/Homebrew/formula.rb:393:in `canonical_name' /usr/local/Library/Homebrew/formula.rb:393:in `canonical_name'
/usr/local/Library/Homebrew/formula.rb:425:in `factory' /usr/local/Library/Homebrew/formula.rb:425:in `factory'
/usr/local/Library/Contributions/examples/brew-upgrade.rb:7 /usr/local/Library/Contributions/examples/brew-upgrade.rb:7

View File

@ -344,7 +344,7 @@ If you have already forked Homebrew on GitHub, then you can manually push (just
git push https://github.com/myname/homebrew-core/ <what-you-called-your-branch> git push https://github.com/myname/homebrew-core/ <what-you-called-your-branch>
``` ```
Now, [open a pull request](https://docs.brew.sh/How-To-Open-a-Homebrew-Pull-Request.html) for your changes. Now, [open a pull request](https://docs.brew.sh/How-To-Open-a-Homebrew-Pull-Request) for your changes.
* One formula per commit; one commit per formula * One formula per commit; one commit per formula
* Keep merge commits out of the pull request * Keep merge commits out of the pull request

View File

@ -11,8 +11,8 @@ Starting with OS X Lion (10.7), you need `sudo` to install to these like
so: `sudo gem install`, `sudo easy_install` or `sudo cpan -i`. so: `sudo gem install`, `sudo easy_install` or `sudo cpan -i`.
An option to avoid sudo is to use an access control list: An option to avoid sudo is to use an access control list:
`chmod +a 'user:YOUR_NAME_HERE allow add_subdirectory,add_file,delete_child,directory_inherit' /Library/Python/2.7/site-packages`, `chmod +a 'user:YOUR_NAME_HERE allow add_subdirectory,add_file,delete_child,directory_inherit' /Library/Python/3.6/site-packages`,
for example, will let you add packages to Python 2.7 as yourself. That for example, will let you add packages to Python 3.6 as yourself. That
is probably safer than changing the group ownership of the directory. is probably safer than changing the group ownership of the directory.
### So why was I using sudo? ### So why was I using sudo?
@ -29,14 +29,14 @@ Rather than changing the rights on `/Library/Python`, we recommend the
following options: following options:
### With a brewed Python ### With a brewed Python
Note, `easy_install` is deprecated. We install `pip` (or `pip3` for Note, `easy_install` is deprecated. We install `pip` (or `pip2` for
Python 3) along with python/python3. Python 2) along with python/python2.
We set up distutils such that `pip install` will always put modules in We set up distutils such that `pip install` will always put modules in
`$(brew --prefix)/lib/pythonX.Y/site-packages` and scripts in `$(brew --prefix)/lib/pythonX.Y/site-packages` and scripts in
`$(brew --prefix)/share/python`. Therefore, you wont need sudo! `$(brew --prefix)/share/python`. Therefore, you wont need sudo!
Do `brew info python` or `brew info python3` for precise information Do `brew info python` or `brew info python@2` for precise information
about the paths. Note, a brewed Python still searches for modules in about the paths. Note, a brewed Python still searches for modules in
`/Library/Python/X.Y/site-packages` and also in `/Library/Python/X.Y/site-packages` and also in
`~/Library/Python/X.Y/lib/python/site-packages`. `~/Library/Python/X.Y/lib/python/site-packages`.

View File

@ -4,33 +4,34 @@ This page describes how Python is handled in Homebrew for users. See [Python for
Homebrew should work with any [CPython](https://stackoverflow.com/questions/2324208/is-there-any-difference-between-cpython-and-python) and defaults to the macOS system Python. Homebrew should work with any [CPython](https://stackoverflow.com/questions/2324208/is-there-any-difference-between-cpython-and-python) and defaults to the macOS system Python.
Homebrew provides formulae to brew a more up-to-date Python 2.7.x and 3.x. Homebrew provides formulae to brew 3.x and a more up-to-date Python 2.7.x.
**Important:** If you choose to install a Python which isn't either of these two (system Python or brewed Python), the Homebrew team can only provide limited support. **Important:** If you choose to install a Python which isn't either of these two (system Python or brewed Python), the Homebrew team cannot support any breakage that may occur.
## Python 2.x or Python 3.x ## Python 3.x or Python 2.x
Homebrew provides one formula for Python 2.7.x and another for Python 3.x. The executables are organized as follows so that Python 2 and Python 3 can both be installed without conflict: Homebrew provides one formula for Python 3.x (`python`) and another for Python 2.7.x (`python@2`).
* `python` points to the macOS system Python (with no manual PATH modification)
The executables are organized as follows so that Python 2 and Python 3 can both be installed without conflict:
* `python` and `python3` point to Homebrew's Python 3.x (if installed) otherwise the macOS system Python
* `python2` points to Homebrew's Python 2.7.x (if installed) * `python2` points to Homebrew's Python 2.7.x (if installed)
* `python3` points to Homebrew's Python 3.x (if installed) * `pip` and `pip3` point to Homebrew's Python 3.x's pip (if installed)
* `pip2` points to Homebrew's Python 2.7.x's pip (if installed) * `pip2` points to Homebrew's Python 2.7.x's pip (if installed)
* `pip3` points to Homebrew's Python 3.x's pip (if installed)
([Wondering which one to choose?](https://wiki.python.org/moin/Python2orPython3)) ([Wondering which one to choose?](https://wiki.python.org/moin/Python2orPython3))
## Setuptools, Pip, etc. ## Setuptools, Pip, etc.
The Python formulae install [pip](http://www.pip-installer.org) (as `pip2` or `pip3`) and [Setuptools](https://pypi.python.org/pypi/setuptools). The Python formulae install [pip](http://www.pip-installer.org) (as `pip` or `pip2`) and [Setuptools](https://pypi.python.org/pypi/setuptools).
Setuptools can be updated via pip, without having to re-brew Python: Setuptools can be updated via pip, without having to re-brew Python:
```sh ```sh
python2 -m pip install --upgrade setuptools python -m pip install --upgrade setuptools
``` ```
Similarly, pip can be used to upgrade itself via: Similarly, pip can be used to upgrade itself via:
```sh ```sh
python2 -m pip install --upgrade pip python -m pip install --upgrade pip
``` ```
### Note on `pip install --user` ### Note on `pip install --user`
@ -39,7 +40,7 @@ The normal `pip install --user` is disabled for brewed Python. This is because o
A possible workaround (which puts executable scripts in `~/Library/Python/<X>.<Y>/bin`) is: A possible workaround (which puts executable scripts in `~/Library/Python/<X>.<Y>/bin`) is:
```sh ```sh
python2 -m pip install --user --install-option="--prefix=" <package-name> python -m pip install --user --install-option="--prefix=" <package-name>
``` ```
## `site-packages` and the `PYTHONPATH` ## `site-packages` and the `PYTHONPATH`
@ -49,12 +50,12 @@ The `site-packages` is a directory that contains Python modules (especially bind
$(brew --prefix)/lib/pythonX.Y/site-packages $(brew --prefix)/lib/pythonX.Y/site-packages
``` ```
So, for Python 2.7.x, you'll find it at `/usr/local/lib/python2.7/site-packages`. So, for Python 3.6.x, you'll find it at `/usr/local/lib/python3.6/site-packages`.
Python 2.7 also searches for modules in: Python 3.6 also searches for modules in:
- `/Library/Python/2.7/site-packages` - `/Library/Python/3.6/site-packages`
- `~/Library/Python/2.7/lib/python/site-packages` - `~/Library/Python/3.6/lib/python/site-packages`
Homebrew's `site-packages` directory is first created if (1) any Homebrew formula with Python bindings are installed, or (2) upon `brew install python`. Homebrew's `site-packages` directory is first created if (1) any Homebrew formula with Python bindings are installed, or (2) upon `brew install python`.
@ -62,9 +63,7 @@ Homebrew's `site-packages` directory is first created if (1) any Homebrew formul
The reasoning for this location is to preserve your modules between (minor) upgrades or re-installations of Python. Additionally, Homebrew has a strict policy never to write stuff outside of the `brew --prefix`, so we don't spam your system. The reasoning for this location is to preserve your modules between (minor) upgrades or re-installations of Python. Additionally, Homebrew has a strict policy never to write stuff outside of the `brew --prefix`, so we don't spam your system.
## Homebrew-provided Python bindings ## Homebrew-provided Python bindings
Some formulae provide Python bindings. Sometimes a `--with-python` or `--with-python3` option has to be passed to `brew install` in order to build the Python bindings. (Check with `brew options <formula>`.) Some formulae provide Python bindings. Sometimes a `--with-python` or `--with-python@2` option has to be passed to `brew install` in order to build the Python bindings. (Check with `brew options <formula>`.)
Homebrew builds bindings against the first `python` (and `python-config`) in your `PATH`. (Check with `which python`).
**Warning!** Python may crash (see [Common Issues](Common-Issues.md)) if you `import <module>` from a brewed Python if you ran `brew install <formula_with_python_bindings>` against the system Python. If you decide to switch to the brewed Python, then reinstall all formulae with Python bindings (e.g. `pyside`, `wxwidgets`, `pygtk`, `pygobject`, `opencv`, `vtk` and `boost-python`). **Warning!** Python may crash (see [Common Issues](Common-Issues.md)) if you `import <module>` from a brewed Python if you ran `brew install <formula_with_python_bindings>` against the system Python. If you decide to switch to the brewed Python, then reinstall all formulae with Python bindings (e.g. `pyside`, `wxwidgets`, `pygtk`, `pygobject`, `opencv`, `vtk` and `boost-python`).
@ -89,4 +88,4 @@ Homebrew will still install Python modules into Homebrew's `site-packages` and *
Virtualenv has a `--system-site-packages` switch to allow "global" (i.e. Homebrew's) `site-packages` to be accessible from within the virtualenv. Virtualenv has a `--system-site-packages` switch to allow "global" (i.e. Homebrew's) `site-packages` to be accessible from within the virtualenv.
## Why is Homebrew's Python being installed as a dependency? ## Why is Homebrew's Python being installed as a dependency?
Formulae that declare an unconditional dependency on the `"python"` or `"python3"` formulae are bottled against Homebrew's Python 2.7.x or 3.x and require it to be installed. Formulae that declare an unconditional dependency on the `"python"` or `"python@2"` formulae are bottled against Homebrew's Python 3.x or 2.7.x and require it to be installed.

View File

@ -39,7 +39,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note
* `analytics` [`state`]: * `analytics` [`state`]:
Display anonymous user behaviour analytics state. Display anonymous user behaviour analytics state.
Read more at <https://docs.brew.sh/Analytics.html>. Read more at <https://docs.brew.sh/Analytics>.
* `analytics` (`on`|`off`): * `analytics` (`on`|`off`):
Turn on/off Homebrew's analytics. Turn on/off Homebrew's analytics.
@ -212,7 +212,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note
information on all installed formulae. information on all installed formulae.
See the docs for examples of using the JSON output: See the docs for examples of using the JSON output:
<https://docs.brew.sh/Querying-Brew.html> <https://docs.brew.sh/Querying-Brew>
* `install` [`--debug`] [`--env=`(`std`|`super`)] [`--ignore-dependencies`|`--only-dependencies`] [`--cc=``compiler`] [`--build-from-source`|`--force-bottle`] [`--devel`|`--HEAD`] [`--keep-tmp`] [`--build-bottle`] [`--force`] [`--verbose`] `formula` [`options` ...]: * `install` [`--debug`] [`--env=`(`std`|`super`)] [`--ignore-dependencies`|`--only-dependencies`] [`--cc=``compiler`] [`--build-from-source`|`--force-bottle`] [`--devel`|`--HEAD`] [`--keep-tmp`] [`--build-bottle`] [`--force`] [`--verbose`] `formula` [`options` ...]:
Install `formula`. Install `formula`.
@ -280,11 +280,6 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note
If `--git` (or `-g`) is passed, Homebrew will create a Git repository, useful for If `--git` (or `-g`) is passed, Homebrew will create a Git repository, useful for
creating patches to the software. creating patches to the software.
* `irb` [`--examples`]:
Enter the interactive Homebrew Ruby shell.
If `--examples` is passed, several examples will be shown.
* `leaves`: * `leaves`:
Show installed formulae that are not dependencies of another installed formula. Show installed formulae that are not dependencies of another installed formula.
@ -493,7 +488,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note
Pass `--installed` to get information on installed taps. Pass `--installed` to get information on installed taps.
See the docs for examples of using the JSON output: See the docs for examples of using the JSON output:
<https://docs.brew.sh/Querying-Brew.html> <https://docs.brew.sh/Querying-Brew>
* `tap-pin` `tap`: * `tap-pin` `tap`:
Pin `tap`, prioritizing its formulae over core when formula names are supplied Pin `tap`, prioritizing its formulae over core when formula names are supplied
@ -761,6 +756,13 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note
* `formula` `formula`: * `formula` `formula`:
Display the path where `formula` is located. Display the path where `formula` is located.
* `irb` [`--examples`] [`--pry`]:
Enter the interactive Homebrew Ruby shell.
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.
* `linkage` [`--test`] [`--reverse`] `formula`: * `linkage` [`--test`] [`--reverse`] `formula`:
Checks the library links of an installed formula. Checks the library links of an installed formula.
@ -782,6 +784,10 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note
Additionally, the date used in new manpages will match those in the existing Additionally, the date used in new manpages will match those in the existing
manpages (to allow comparison without factoring in the date). manpages (to allow comparison without factoring in the date).
* `prof` [`ruby options`]:
Run Homebrew with the Ruby profiler.
For example:
* `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. Gets a patch from a GitHub commit or pull request and applies it to Homebrew.
@ -839,6 +845,10 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note
If `--markdown` is passed, output as a Markdown list. If `--markdown` is passed, output as a Markdown list.
* `ruby` [`ruby options`]:
Run a Ruby instance with Homebrew's libraries loaded.
For example:
* `tap-new` `user``/``repo`: * `tap-new` `user``/``repo`:
Generate the template files for a new tap. Generate the template files for a new tap.
@ -914,7 +924,7 @@ scripts that reside somewhere in the `PATH`, named `brew-``cmdname` or
to create your own commands without modifying Homebrew's internals. to create your own commands without modifying Homebrew's internals.
Instructions for creating your own commands can be found in the docs: Instructions for creating your own commands can be found in the docs:
<https://docs.brew.sh/External-Commands.html> <https://docs.brew.sh/External-Commands>
## SPECIFYING FORMULAE ## SPECIFYING FORMULAE
@ -1021,6 +1031,10 @@ can take several different forms:
*Note:* Homebrew doesn't require permissions for any of the scopes. *Note:* Homebrew doesn't require permissions for any of the scopes.
* `HOMEBREW_INSTALL_BADGE`:
Text printed before the installation summary of each successful build.
Defaults to the beer emoji.
* `HOMEBREW_LOGS`: * `HOMEBREW_LOGS`:
If set, Homebrew will use the given directory to store log files. If set, Homebrew will use the given directory to store log files.
@ -1031,12 +1045,15 @@ can take several different forms:
*Default:* the number of available CPU cores. *Default:* the number of available CPU cores.
* `HOMEBREW_NO_ANALYTICS`: * `HOMEBREW_NO_ANALYTICS`:
If set, Homebrew will not send analytics. See: <https://docs.brew.sh/Analytics.html> If set, Homebrew will not send analytics. See: <https://docs.brew.sh/Analytics>
* `HOMEBREW_NO_AUTO_UPDATE`: * `HOMEBREW_NO_AUTO_UPDATE`:
If set, Homebrew will not auto-update before running `brew install`, If set, Homebrew will not auto-update before running `brew install`,
`brew upgrade` or `brew tap`. `brew upgrade` or `brew tap`.
* `HOMEBREW_NO_COLOR`:
If set, Homebrew will not print text with color added.
* `HOMEBREW_NO_EMOJI`: * `HOMEBREW_NO_EMOJI`:
If set, Homebrew will not print the `HOMEBREW_INSTALL_BADGE` on a If set, Homebrew will not print the `HOMEBREW_INSTALL_BADGE` on a
successful build. successful build.
@ -1055,9 +1072,8 @@ can take several different forms:
If set, Homebrew will not use the GitHub API for e.g searches or If set, Homebrew will not use the GitHub API for e.g searches or
fetching relevant issues on a failed install. fetching relevant issues on a failed install.
* `HOMEBREW_INSTALL_BADGE`: * `HOMEBREW_PRY`:
Text printed before the installation summary of each successful build. If set, Homebrew will use `pry` for the `brew irb` command.
Defaults to the beer emoji.
* `HOMEBREW_SVN`: * `HOMEBREW_SVN`:
When exporting from Subversion, Homebrew will use `HOMEBREW_SVN` if set, When exporting from Subversion, Homebrew will use `HOMEBREW_SVN` if set,

View File

@ -39,8 +39,8 @@ A few requests:
own fork. own fork.
- if still in doubt please ask for help and we'll help you out - if still in doubt please ask for help and we'll help you out
- please read: - please read:
- https://docs.brew.sh/Brew-Test-Bot-For-Core-Contributors.html - https://docs.brew.sh/Brew-Test-Bot-For-Core-Contributors
- https://docs.brew.sh/Maintainer-Guidelines.html - https://docs.brew.sh/Maintainer-Guidelines
- anything else you haven't read on https://docs.brew.sh - anything else you haven't read on https://docs.brew.sh
How does that sound? How does that sound?

View File

@ -16,16 +16,16 @@ Applications should unconditionally bundle all of their Python-language dependen
### Python declarations ### Python declarations
Formulae for apps that require Python 3 **should** declare an unconditional dependency on `"python"`. These apps **must** work with the current Homebrew Python 3.x formula.
Applications that are compatible with Python 2 **should** use the Apple-provided system Python in `/usr/bin` on systems that provide Python 2.7. To do this, declare: Applications that are compatible with Python 2 **should** use the Apple-provided system Python in `/usr/bin` on systems that provide Python 2.7. To do this, declare:
```ruby ```ruby
depends_on "python" if MacOS.version <= :snow_leopard depends_on "python@2" if MacOS.version <= :snow_leopard
``` ```
No explicit Python dependency is needed on recent OS versions since `/usr/bin` is always in `PATH` for Homebrew formulae; on Leopard and older, the `python` in `PATH` is used if it's at least version 2.7, or else Homebrew's Python 2.7.x is installed. No explicit Python dependency is needed on recent OS versions since `/usr/bin` is always in `PATH` for Homebrew formulae; on Leopard and older, the `python` in `PATH` is used if it's at least version 2.7, or else Homebrew's Python 2.7.x is installed.
Formulae for apps that require Python 3 **should** declare an unconditional dependency on `"python3"`. These apps **must** work with the current Homebrew Python 3.x formula.
### Installing ### Installing
Applications should be installed into a Python [virtualenv](https://virtualenv.pypa.io/en/stable/) environment rooted in `libexec`. This prevents the app's Python modules from contaminating the system site-packages and vice versa. Applications should be installed into a Python [virtualenv](https://virtualenv.pypa.io/en/stable/) environment rooted in `libexec`. This prevents the app's Python modules from contaminating the system site-packages and vice versa.
@ -66,7 +66,7 @@ This is exactly the same as writing:
```ruby ```ruby
def install def install
# Create a virtualenv in `libexec`. If your app needs Python 3, make sure that # Create a virtualenv in `libexec`. If your app needs Python 3, make sure that
# `depends_on "python3"` is declared, and use `virtualenv_create(libexec, "python3")`. # `depends_on "python"` is declared, and use `virtualenv_create(libexec, "python")`.
venv = virtualenv_create(libexec) venv = virtualenv_create(libexec)
# Install all of the resources declared on the formula into the virtualenv. # Install all of the resources declared on the formula into the virtualenv.
venv.pip_install resources venv.pip_install resources
@ -121,9 +121,9 @@ in case you need to do different things for different resources.
## Bindings ## Bindings
Build bindings with the system Python by default (don't add an option) and they should be usable with any binary-compatible Python. If that isn't the case, it's an upstream bug; [here's some advice for resolving it](http://blog.tim-smith.us/2015/09/python-extension-modules-os-x/). To add bindings for Python 3, please add `depends_on "python"`.
To add bindings for Python 3, please add `depends_on "python3" => :optional` and make the bindings conditional on `build.with?("python3")`. Build Python 2 bindings with the system Python by default (don't add an option) and they should be usable with any binary-compatible Python. If that isn't the case, it's an upstream bug; [here's some advice for resolving it](http://blog.tim-smith.us/2015/09/python-extension-modules-os-x/).
### Dependencies ### Dependencies
@ -153,7 +153,9 @@ Sometimes we have to `inreplace` a `Makefile` to use our prefix for the Python b
### Python declarations ### Python declarations
Python 2 libraries do not need a `depends_on "python"` declaration; they will be built with the system Python, but should still be usable with any other Python 2.7. If this is not the case, it is an upstream bug; [here is some advice for resolving it](http://blog.tim-smith.us/2015/09/python-extension-modules-os-x/). Libraries built for Python 3 should include `depends_on "python3"`, which will bottle against Homebrew's Python 3.x. If a library supports both Python 2.x and Python 3.x, the `"python3"` dependency should be `:optional`. Python 2.x libraries must function when they are installed against either the system Python or brewed Python. Libraries built for Python 3 should include `depends_on "python"`, which will bottle against Homebrew's Python 3.x. Python 2.x libraries must function when they are installed against either the system Python or brewed Python.
Python 2 libraries do not need a `depends_on "python@2"` declaration; they will be built with the system Python, but should still be usable with any other Python 2.7. If this is not the case, it is an upstream bug; [here is some advice for resolving it](http://blog.tim-smith.us/2015/09/python-extension-modules-os-x/).
### Installing ### Installing

View File

@ -11,8 +11,11 @@ Versioned formulae we include in [homebrew/core](https://github.com/homebrew/hom
* Versioned formulae should differ in major/minor (not patch) versions from the current stable release. This is because patch versions indicate bug or security updates and we want to ensure you apply security updates. * Versioned formulae should differ in major/minor (not patch) versions from the current stable release. This is because patch versions indicate bug or security updates and we want to ensure you apply security updates.
* Upstream should have a release branch for the versioned formulae version and still make security updates for that version, when necessary. For example, [PHP 5.5 was not a supported version but PHP 7.2 was](http://php.net/supported-versions.php) in January 2018 * Upstream should have a release branch for the versioned formulae version and still make security updates for that version, when necessary. For example, [PHP 5.5 was not a supported version but PHP 7.2 was](http://php.net/supported-versions.php) in January 2018
* Formulae that depend on versioned formulae must not depend on the same formulae at two different versions twice in their recursive dependencies. For example, if you depend on `openssl@1.0` and `foo`, and `foo` depends on `openssl` then you must instead use `openssl`. * Formulae that depend on versioned formulae must not depend on the same formulae at two different versions twice in their recursive dependencies. For example, if you depend on `openssl@1.0` and `foo`, and `foo` depends on `openssl` then you must instead use `openssl`.
* Versioned formulae should only be linkable at the same time as their non-versioned counterpart if the upstream project provides support for it, e.g. using suffixed binaries. If this is not possible, use `keg_only :versioned_formula` to allow users to have multiple versions installed at once. Note `keg_only :versioned_formula` should not `post_install` anything in the `HOMEBREW_PREFIX` that conflicts with or duplicates the non-versioned counterpart (or other versioned formulae). For example, a `node@6` formula should not install its `npm` into `HOMEBREW_PREFIX` like the `node` formula does. * Versioned formulae should only be linkable at the same time as their non-versioned counterpart if the upstream project provides support for it, e.g. using suffixed binaries. If this is not possible, use `keg_only :versioned_formula` to allow users to have multiple versions installed at once.
* A `keg_only :versioned_formula` should not `post_install` anything in the `HOMEBREW_PREFIX` that conflicts with or duplicates the non-versioned counterpart (or other versioned formulae). For example, a `node@6` formula should not install its `npm` into `HOMEBREW_PREFIX` like the `node` formula does.
* Versioned formulae submitted should be expected to be used by a large number of people. If this ceases to be the case: they will be removed. We will aim not to remove those in the [top 1000 `install_on_request` formulae](https://brew.sh/analytics/install-on-request/). * Versioned formulae submitted should be expected to be used by a large number of people. If this ceases to be the case: they will be removed. We will aim not to remove those in the [top 1000 `install_on_request` formulae](https://brew.sh/analytics/install-on-request/).
* Versioned formulae should not have `resource`s that require security updates. For example, a `node@6` formula should not have an `npm` resource but instead rely on the `npm` provided by the upstream tarball.
* Versioned formulae should be as similar as possible and sensible to the unversioned formulae. Creating or updating a versioned formula should be a chance to ask questions of the unversioned formula e.g. can some unused or useless options be removed or made default?
* No more than five versions of a formula (including the non-versioned one) will be supported at any given time, regardless of usage. When removing formulae that violate this we will aim to do so based on usage and support status rather than age. * No more than five versions of a formula (including the non-versioned one) will be supported at any given time, regardless of usage. When removing formulae that violate this we will aim to do so based on usage and support status rather than age.
Homebrew's versions are not intended to be used for any old versions you personally require for your project. You should create your own [tap](How-to-Create-and-Maintain-a-Tap.md) for formulae you or your organisation wish to control the versioning of or those that do not meet the above standards. Software that has regular API or ABI breaking releases still needs to meet all the above requirements; that a `brew upgrade` has broken something for you is not an argument for us to add and maintain a formula for you. Homebrew's versions are not intended to be used for any old versions you personally require for your project. You should create your own [tap](How-to-Create-and-Maintain-a-Tap.md) for formulae you or your organisation wish to control the versioning of or those that do not meet the above standards. Software that has regular API or ABI breaking releases still needs to meet all the above requirements; that a `brew upgrade` has broken something for you is not an argument for us to add and maintain a formula for you.

View File

@ -1,17 +1,32 @@
include: [.well-known] title: Homebrew Documentation
exclude: [bin, vendor, CNAME, Gemfile, Gemfile.lock] description: Documentation for the missing package manager for macOS.
# Same as GitHub Pages exclude:
# https://help.github.com/articles/using-jekyll-with-pages#troubleshooting - bin
# Disable despite enabled on GitHub Pages for supported plugins to work. - CNAME
# safe: true - Gemfile*
kramdown: - vendor
input: GFM
hard_wrap: false
lsi: false
highlighter: rouge
gems: plugins:
- jekyll-feed - jekyll-feed
- jekyll-sitemap - jekyll-sitemap
- jekyll-seo-tag - jekyll-seo-tag
permalink: :title
defaults:
- scope:
path: ""
values:
image: /img/homebrew-256x256.png
logo: /img/homebrew-256x256.png
github:
repository_nwo: Homebrew/brew
twitter:
username: MacHomebrew
facebook:
publisher: https://www.facebook.com/machomebrew/

View File

@ -0,0 +1,22 @@
---
layout: base
---
{% assign json = site.data.analytics[page.category] %}
<h2>{{ page.category_pretty }} Events</h2>
<h3>{{ json.start_date }} - {{ json.end_date }}</h3>
<table class="full-width">
<tr>
<th></th>
<th>{% if page.category == "os-version" %}Version{% else %}Formula{% endif %}</th>
<th>Events</th>
<th>%</th>
</tr>
{% for item in json.items %}
<tr>
<td class="number-data">#{{ item.number }}</td>
<td><code>{% if page.category == "os-version" %}{{ item.os_version }}{% else %}{{ item.formula }}{% endif %}</code></td>
<td class="number-data">{{ item.count }}</td>
<td class="number-data">{{ item.percent }}%</td>
</tr>
{% endfor %}
</table>

View File

@ -1,13 +1,18 @@
{% assign t = site.data.locales[page.lang][page.lang] %}
<!DOCTYPE html> <!DOCTYPE html>
<html {% if page.direction == "rtl" %}dir="rtl" {% endif %}lang="{{ page.lang }}"> <html {% if page.direction == "rtl" %}dir="rtl" {% endif %}lang="{{ page.lang }}">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
{% if page.title %} {% if page.title %}
<title>{{ page.title }} — Homebrew</title> <title>{{ page.title }} — {{ site.title }}</title>
{% elsif page.direction == "rtl" %} {% elsif t.subtitle %}
<title>{{ page.subtitle }} — Homebrew</title> {% if page.direction == "rtl" %}
<title>{{ site.title }} — {{ t.subtitle }}</title>
{% else %} {% else %}
<title>Homebrew — {{ page.subtitle }}</title> <title>{{ t.subtitle }} — {{ t.subtitle }}</title>
{% endif %}
{% else %}
<title>{{ site.title }}</title>
{% endif %} {% endif %}
{% seo title=false %} {% seo title=false %}
{% feed_meta %} {% feed_meta %}
@ -16,6 +21,9 @@
<link rel="apple-touch-icon" href="/img/apple-touch-icon.png"> <link rel="apple-touch-icon" href="/img/apple-touch-icon.png">
<link rel="stylesheet" href="/css/screen.css" type="text/css" media="screen"> <link rel="stylesheet" href="/css/screen.css" type="text/css" media="screen">
<link rel="stylesheet" href="/css/pygments.css" type="text/css" media="screen"> <link rel="stylesheet" href="/css/pygments.css" type="text/css" media="screen">
{% if site.url == "http://localhost:4000" %}
<script src="https://github.com/Khan/tota11y/releases/download/0.1.3/tota11y.min.js"></script>
{% endif %}
<script> <script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
@ -27,31 +35,37 @@
ga('send', 'pageview'); ga('send', 'pageview');
</script> </script>
{% for lang in site.langs %} {% if site.data.locales %}
{% if lang.langcode == "en" %} {% assign locales = site.data.locales | sort %}
{% for locale in locales %}
{% assign lang = locale[0] %}
{% if lang == "en" %}
<link rel="alternate" hreflang="en" href="{{ site.url }}" /> <link rel="alternate" hreflang="en" href="{{ site.url }}" />
<link rel="alternate" hreflang="x-default" href="{{ site.url }}" /> <link rel="alternate" hreflang="x-default" href="{{ site.url }}" />
{% else %} {% else %}
<link rel="alternate" hreflang="{{ lang.langcode }}" href="{{ lang.langcode | downcase | append: '.html' | prepend: '/index_' | prepend: site.url }}" /> <link rel="alternate" hreflang="{{ lang }}" href="{{ lang | prepend: '/index_' | prepend: site.url }}" />
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% endif %}
</head> </head>
<body> <body>
<div id="wrap"> <div id="wrap">
<div id="header" class="{{ page.header-class }}"> <div id="header" class="{{ page.header-class }}">
<img alt="Homebrew logo" src="/img/homebrew-256x256.png" width="128" height="128"> <img alt="Homebrew logo" src="/img/homebrew-256x256.png" width="128" height="128">
<h1><a href="/">Homebrew</a></h1> <h1><a href="/">Homebrew</a></h1>
{% if page.subtitle %} {% if t.subtitle %}
<p id="subtitle"><strong>{{ page.subtitle }}</strong></p> <p id="subtitle"><strong>{{ t.subtitle }}</strong></p>
{% endif %} {% endif %}
{% if page.lang %} {% if page.lang %}
<select id="language" onchange="loadLanguage(this.options[this.selectedIndex].value)"> <select id="language" onchange="loadLanguage(this.options[this.selectedIndex].value)">
{% for lang in site.langs %} {% for locale in locales %}
{% if page.lang == lang.langcode %} {% assign lang = locale[0] %}
<option value="{{ lang.langcode | downcase }}" selected="selected">{{ lang.lang_string }}</option> {% assign locale_name = locale[1][lang].locale_name %}
{% if page.lang == lang %}
<option value="{{ lang }}" selected="selected">{{ locale_name }}</option>
{% else %} {% else %}
<option value="{{ lang.langcode | downcase }}">{{ lang.lang_string }}</option> <option value="{{ lang }}">{{ locale_name }}</option>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</select> </select>
@ -80,9 +94,9 @@
if (lang === {{ page.lang | jsonify }}) { if (lang === {{ page.lang | jsonify }}) {
return; return;
} else if (lang === "en") { } else if (lang === "en") {
window.location.replace("/"); window.location.assign("/");
} else { } else {
window.location.replace("/index_" + lang + ".html"); window.location.assign("/index_" + lang);
} }
} }
</script> </script>

View File

@ -1,28 +1,29 @@
--- ---
layout: base layout: base
--- ---
{% assign t = site.data.locales[page.lang][page.lang] %}
<div id="information"> <div id="information">
<ul> <ul>
<li> <li>
<div class="group row"> <div class="group row">
<h2 id="install">{{ page.pagecontent.install.install }}</h2> <h2 id="install">{{ t.pagecontent.install.install }}</h2>
<br> <br>
<pre style='clear:both;text-align:center;margin-bottom:0.9em'><code id='selectable' onclick="selectText(this)">/usr/bin/ruby -e &quot;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)&quot;</code></pre> <pre style='clear:both;text-align:center;margin-bottom:0.9em'><code id='selectable' onclick="selectText(this)">/usr/bin/ruby -e &quot;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)&quot;</code></pre>
<div class="col-1"> <div class="col-1">
<p>{{ page.pagecontent.install.paste }}</p> <p>{{ t.pagecontent.install.paste }}</p>
</div> </div>
<div class="col-2"> <div class="col-2">
<p>{{ page.pagecontent.install.what }}</p> <p>{{ t.pagecontent.install.what }}</p>
</div> </div>
</div> </div>
</li> </li>
<li> <li>
<div class="group row"> <div class="group row">
<h2 id="question">{{ page.pagecontent.question }}</h2> <h2 id="question">{{ t.pagecontent.question }}</h2>
<br> <br>
<div class="col-1"> <div class="col-1">
<p>{{ page.pagecontent.what }}</p> <p>{{ t.pagecontent.what }}</p>
</div> </div>
<div class="col-2"> <div class="col-2">
{% highlight bash %} {% highlight bash %}
@ -34,7 +35,7 @@ $ brew install wget
<li> <li>
<div class="group row"> <div class="group row">
<div class="col-1"> <div class="col-1">
<p>{{ page.pagecontent.how }}</p> <p>{{ t.pagecontent.how }}</p>
</div> </div>
<div class="col-2"> <div class="col-2">
{% highlight bash %} {% highlight bash %}
@ -53,14 +54,14 @@ bin/wget -> ../Cellar/wget/1.16.1/bin/wget
<li> <li>
<div class="group row"> <div class="group row">
<div class="col-1"> <div class="col-1">
<p>{{ page.pagecontent.prefix }}</p> <p>{{ t.pagecontent.prefix }}</p>
</div> </div>
</div> </div>
</li> </li>
<li> <li>
<div class="group row"> <div class="group row">
<div class="col-1"> <div class="col-1">
<p>{{ page.pagecontent.createpackages }}</p> <p>{{ t.pagecontent.createpackages }}</p>
</div> </div>
<div class="col-2"> <div class="col-2">
{% highlight bash %} {% highlight bash %}
@ -73,11 +74,11 @@ Created /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/bar.rb
<li> <li>
<div class="group row"> <div class="group row">
<div class="col-1"> <div class="col-1">
<p>{{ page.pagecontent.hack }}</p> <p>{{ t.pagecontent.hack }}</p>
</div> </div>
<div class="col-2"> <div class="col-2">
{% highlight bash %} {% highlight bash %}
$ brew edit wget # {{ page.pagecontent.editor }} $ brew edit wget # {{ t.pagecontent.editor }}
{% endhighlight %} {% endhighlight %}
</div> </div>
</div> </div>
@ -85,7 +86,7 @@ $ brew edit wget # {{ page.pagecontent.editor }}
<li> <li>
<div class="group row"> <div class="group row">
<div class="col-1"> <div class="col-1">
<p>{{ page.pagecontent.formula }}</p> <p>{{ t.pagecontent.formula }}</p>
</div> </div>
<div class="col-2"> <div class="col-2">
{% highlight ruby %} {% highlight ruby %}
@ -106,41 +107,68 @@ end
<li> <li>
<div class="group row"> <div class="group row">
<div class="col-1"> <div class="col-1">
<p>{{ page.pagecontent.complement }}</p> <p>{{ t.pagecontent.complement }}</p>
</div> </div>
</div> </div>
</li> </li>
<li> <li>
<div class="group row"> <div class="group row">
<h2 id="further-doc">{{ page.pagecontent.doc.further }}</h2> <h2 id="further-doc">{{ t.pagecontent.doc.further }}</h2>
<div class="button"> <div class="button">
<p><a href="https://docs.brew.sh/">docs.brew.sh</a></p> <p><a href="https://docs.brew.sh">docs.brew.sh</a></p>
</div> </div>
</div> </div>
</li> </li>
<li> <li>
<div class="group row"> <div class="group row">
<h2 id="homebrew-community">{{ page.pagecontent.doc.community }}</h2> <h2 id="homebrew-patreon">{{ t.pagecontent.doc.patreon }}</h2>
<div class="button"> <div class="button">
<p><a href="https://discourse.brew.sh/">discourse.brew.sh</a></p> <p><a href="https://www.patreon.com/homebrew">patreon.com/homebrew</a></p>
</div> </div>
</div> </div>
</li> </li>
<li> <li>
<div class="group row"> <div class="group row">
<h2 id="homebrew-blog">{{ page.pagecontent.doc.blog }}</h2> <h2 id="homebrew-community">{{ t.pagecontent.doc.community }}</h2>
<div class="button"> <div class="button">
<p><a href="/blog">brew.sh/blog</a></p> <p><a href="https://discourse.brew.sh">discourse.brew.sh</a></p>
</div>
</div>
</li>
<li>
<div class="group row">
<h2 id="homebrew-blog">{{ t.pagecontent.doc.blog }}</h2>
<div class="button">
<p><a href="/blog/">brew.sh/blog</a></p>
</div>
</div>
</li>
<li>
<div class="group row">
<h2 id="homebrew-formulae">{{ t.pagecontent.doc.formulae }}</h2>
<div class="button">
<p><a href="http://formulae.brew.sh">formulae.brew.sh</a></p>
</div>
</div>
</li>
<li>
<div class="group row">
<h2 id="analytics-data">{{ t.pagecontent.doc.analytics }}</h2>
<div class="button">
<p><a href="/analytics/">brew.sh/analytics</a></p>
</div> </div>
</div> </div>
</li> </li>
<li> <li>
<div class="group row credits"> <div class="group row credits">
<p>{{ page.pagecontent.foot.code }} {{ page.pagecontent.foot.page }} {{ page.pagecontent.foot.translation }}</p> <p>{{ t.pagecontent.foot.code }} {{ t.pagecontent.foot.page }} {{ t.pagecontent.foot.translation }}</p>
</div> </div>
</li> </li>
</ul> </ul>

View File

@ -45,7 +45,7 @@ Perform a substring search of formula names for \fItext\fR\. If \fItext\fR is su
. .
.TP .TP
\fBanalytics\fR [\fBstate\fR] \fBanalytics\fR [\fBstate\fR]
Display anonymous user behaviour analytics state\. Read more at \fIhttps://docs\.brew\.sh/Analytics\.html\fR\. Display anonymous user behaviour analytics state\. Read more at \fIhttps://docs\.brew\.sh/Analytics\fR\.
. .
.TP .TP
\fBanalytics\fR (\fBon\fR|\fBoff\fR) \fBanalytics\fR (\fBon\fR|\fBoff\fR)
@ -226,7 +226,7 @@ Print a JSON representation of \fIformulae\fR\. Currently the only accepted valu
Pass \fB\-\-all\fR to get information on all formulae, or \fB\-\-installed\fR to get information on all installed formulae\. Pass \fB\-\-all\fR to get information on all formulae, or \fB\-\-installed\fR to get information on all installed formulae\.
. .
.IP .IP
See the docs for examples of using the JSON output: \fIhttps://docs\.brew\.sh/Querying\-Brew\.html\fR See the docs for examples of using the JSON output: \fIhttps://docs\.brew\.sh/Querying\-Brew\fR
. .
.TP .TP
\fBinstall\fR [\fB\-\-debug\fR] [\fB\-\-env=\fR(\fBstd\fR|\fBsuper\fR)] [\fB\-\-ignore\-dependencies\fR|\fB\-\-only\-dependencies\fR] [\fB\-\-cc=\fR\fIcompiler\fR] [\fB\-\-build\-from\-source\fR|\fB\-\-force\-bottle\fR] [\fB\-\-devel\fR|\fB\-\-HEAD\fR] [\fB\-\-keep\-tmp\fR] [\fB\-\-build\-bottle\fR] [\fB\-\-force\fR] [\fB\-\-verbose\fR] \fIformula\fR [\fIoptions\fR \.\.\.] \fBinstall\fR [\fB\-\-debug\fR] [\fB\-\-env=\fR(\fBstd\fR|\fBsuper\fR)] [\fB\-\-ignore\-dependencies\fR|\fB\-\-only\-dependencies\fR] [\fB\-\-cc=\fR\fIcompiler\fR] [\fB\-\-build\-from\-source\fR|\fB\-\-force\-bottle\fR] [\fB\-\-devel\fR|\fB\-\-HEAD\fR] [\fB\-\-keep\-tmp\fR] [\fB\-\-build\-bottle\fR] [\fB\-\-force\fR] [\fB\-\-verbose\fR] \fIformula\fR [\fIoptions\fR \.\.\.]
@ -291,13 +291,6 @@ If \fB\-\-interactive\fR (or \fB\-i\fR) is passed, download and patch \fIformula
If \fB\-\-git\fR (or \fB\-g\fR) is passed, Homebrew will create a Git repository, useful for creating patches to the software\. If \fB\-\-git\fR (or \fB\-g\fR) is passed, Homebrew will create a Git repository, useful for creating patches to the software\.
. .
.TP .TP
\fBirb\fR [\fB\-\-examples\fR]
Enter the interactive Homebrew Ruby shell\.
.
.IP
If \fB\-\-examples\fR is passed, several examples will be shown\.
.
.TP
\fBleaves\fR \fBleaves\fR
Show installed formulae that are not dependencies of another installed formula\. Show installed formulae that are not dependencies of another installed formula\.
. .
@ -510,7 +503,7 @@ Print a JSON representation of \fItaps\fR\. Currently the only accepted value fo
Pass \fB\-\-installed\fR to get information on installed taps\. Pass \fB\-\-installed\fR to get information on installed taps\.
. .
.IP .IP
See the docs for examples of using the JSON output: \fIhttps://docs\.brew\.sh/Querying\-Brew\.html\fR See the docs for examples of using the JSON output: \fIhttps://docs\.brew\.sh/Querying\-Brew\fR
. .
.TP .TP
\fBtap\-pin\fR \fItap\fR \fBtap\-pin\fR \fItap\fR
@ -781,6 +774,13 @@ Open \fIformula\fR in the editor\.
Display the path where \fIformula\fR is located\. Display the path where \fIformula\fR is located\.
. .
.TP .TP
\fBirb\fR [\fB\-\-examples\fR] [\fB\-\-pry\fR]
Enter the interactive Homebrew Ruby shell\.
.
.IP
If \fB\-\-examples\fR is passed, several examples will be shown\. If \fB\-\-pry\fR is passed or HOMEBREW_PRY is set, pry will be used instead of irb\.
.
.TP
\fBlinkage\fR [\fB\-\-test\fR] [\fB\-\-reverse\fR] \fIformula\fR \fBlinkage\fR [\fB\-\-test\fR] [\fB\-\-reverse\fR] \fIformula\fR
Checks the library links of an installed formula\. Checks the library links of an installed formula\.
. .
@ -801,6 +801,10 @@ Generate Homebrew\'s manpages\.
If \fB\-\-fail\-if\-changed\fR is passed, the command will return a failing status code if changes are detected in the manpage outputs\. This can be used for CI to be notified when the manpages are out of date\. Additionally, the date used in new manpages will match those in the existing manpages (to allow comparison without factoring in the date)\. If \fB\-\-fail\-if\-changed\fR is passed, the command will return a failing status code if changes are detected in the manpage outputs\. This can be used for CI to be notified when the manpages are out of date\. Additionally, the date used in new manpages will match those in the existing manpages (to allow comparison without factoring in the date)\.
. .
.TP .TP
\fBprof\fR [\fIruby options\fR]
Run Homebrew with the Ruby profiler\. For example:
.
.TP
\fBpull\fR [\fB\-\-bottle\fR] [\fB\-\-bump\fR] [\fB\-\-clean\fR] [\fB\-\-ignore\-whitespace\fR] [\fB\-\-resolve\fR] [\fB\-\-branch\-okay\fR] [\fB\-\-no\-pbcopy\fR] [\fB\-\-no\-publish\fR] [\fB\-\-warn\-on\-publish\-failure\fR] [\fB\-\-bintray\-org=\fR\fIbintray\-org\fR] [\fB\-\-test\-bot\-user=\fR\fItest\-bot\-user\fR] \fIpatch\-source\fR [\fIpatch\-source\fR]: \fBpull\fR [\fB\-\-bottle\fR] [\fB\-\-bump\fR] [\fB\-\-clean\fR] [\fB\-\-ignore\-whitespace\fR] [\fB\-\-resolve\fR] [\fB\-\-branch\-okay\fR] [\fB\-\-no\-pbcopy\fR] [\fB\-\-no\-publish\fR] [\fB\-\-warn\-on\-publish\-failure\fR] [\fB\-\-bintray\-org=\fR\fIbintray\-org\fR] [\fB\-\-test\-bot\-user=\fR\fItest\-bot\-user\fR] \fIpatch\-source\fR [\fIpatch\-source\fR]:
. .
.IP .IP
@ -862,6 +866,10 @@ Output the merged pull requests on Homebrew/brew between two Git refs\. If no \f
If \fB\-\-markdown\fR is passed, output as a Markdown list\. If \fB\-\-markdown\fR is passed, output as a Markdown list\.
. .
.TP .TP
\fBruby\fR [\fIruby options\fR]
Run a Ruby instance with Homebrew\'s libraries loaded\. For example:
.
.TP
\fBtap\-new\fR \fIuser\fR\fB/\fR\fIrepo\fR \fBtap\-new\fR \fIuser\fR\fB/\fR\fIrepo\fR
Generate the template files for a new tap\. Generate the template files for a new tap\.
. .
@ -937,7 +945,7 @@ Integrates Homebrew formulae with macOS\'s \fBlaunchctl\fR(1) manager: \fIhttps:
Homebrew, like \fBgit\fR(1), supports external commands\. These are executable scripts that reside somewhere in the \fBPATH\fR, named \fBbrew\-\fR\fIcmdname\fR or \fBbrew\-\fR\fIcmdname\fR\fB\.rb\fR, which can be invoked like \fBbrew\fR \fIcmdname\fR\. This allows you to create your own commands without modifying Homebrew\'s internals\. Homebrew, like \fBgit\fR(1), supports external commands\. These are executable scripts that reside somewhere in the \fBPATH\fR, named \fBbrew\-\fR\fIcmdname\fR or \fBbrew\-\fR\fIcmdname\fR\fB\.rb\fR, which can be invoked like \fBbrew\fR \fIcmdname\fR\. This allows you to create your own commands without modifying Homebrew\'s internals\.
. .
.P .P
Instructions for creating your own commands can be found in the docs: \fIhttps://docs\.brew\.sh/External\-Commands\.html\fR Instructions for creating your own commands can be found in the docs: \fIhttps://docs\.brew\.sh/External\-Commands\fR
. .
.SH "SPECIFYING FORMULAE" .SH "SPECIFYING FORMULAE"
Many Homebrew commands accept one or more \fIformula\fR arguments\. These arguments can take several different forms: Many Homebrew commands accept one or more \fIformula\fR arguments\. These arguments can take several different forms:
@ -1040,6 +1048,10 @@ A personal access token for the GitHub API, which you can create at \fIhttps://g
\fINote:\fR Homebrew doesn\'t require permissions for any of the scopes\. \fINote:\fR Homebrew doesn\'t require permissions for any of the scopes\.
. .
.TP .TP
\fBHOMEBREW_INSTALL_BADGE\fR
Text printed before the installation summary of each successful build\. Defaults to the beer emoji\.
.
.TP
\fBHOMEBREW_LOGS\fR \fBHOMEBREW_LOGS\fR
If set, Homebrew will use the given directory to store log files\. If set, Homebrew will use the given directory to store log files\.
. .
@ -1052,13 +1064,17 @@ If set, instructs Homebrew to use the value of \fBHOMEBREW_MAKE_JOBS\fR as the n
. .
.TP .TP
\fBHOMEBREW_NO_ANALYTICS\fR \fBHOMEBREW_NO_ANALYTICS\fR
If set, Homebrew will not send analytics\. See: \fIhttps://docs\.brew\.sh/Analytics\.html\fR If set, Homebrew will not send analytics\. See: \fIhttps://docs\.brew\.sh/Analytics\fR
. .
.TP .TP
\fBHOMEBREW_NO_AUTO_UPDATE\fR \fBHOMEBREW_NO_AUTO_UPDATE\fR
If set, Homebrew will not auto\-update before running \fBbrew install\fR, \fBbrew upgrade\fR or \fBbrew tap\fR\. If set, Homebrew will not auto\-update before running \fBbrew install\fR, \fBbrew upgrade\fR or \fBbrew tap\fR\.
. .
.TP .TP
\fBHOMEBREW_NO_COLOR\fR
If set, Homebrew will not print text with color added\.
.
.TP
\fBHOMEBREW_NO_EMOJI\fR \fBHOMEBREW_NO_EMOJI\fR
If set, Homebrew will not print the \fBHOMEBREW_INSTALL_BADGE\fR on a successful build\. If set, Homebrew will not print the \fBHOMEBREW_INSTALL_BADGE\fR on a successful build\.
. .
@ -1077,8 +1093,8 @@ While ensuring your downloads are fully secure, this is likely to cause from\-so
If set, Homebrew will not use the GitHub API for e\.g searches or fetching relevant issues on a failed install\. If set, Homebrew will not use the GitHub API for e\.g searches or fetching relevant issues on a failed install\.
. .
.TP .TP
\fBHOMEBREW_INSTALL_BADGE\fR \fBHOMEBREW_PRY\fR
Text printed before the installation summary of each successful build\. Defaults to the beer emoji\. If set, Homebrew will use \fBpry\fR for the \fBbrew irb\fR command\.
. .
.TP .TP
\fBHOMEBREW_SVN\fR \fBHOMEBREW_SVN\fR