diff options
240 files changed, 2856 insertions, 2584 deletions
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3061f42b6..f7730b6e2 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,6 +2,7 @@ - [ ] Have you checked to ensure there aren't other open [Pull Requests](https://github.com/Homebrew/brew/pulls) for the same change? - [ ] Have you added an explanation of what your changes do and why you'd like us to include them? - [ ] Have you written new tests for your changes? [Here's an example](https://github.com/Homebrew/homebrew/pull/49031). +- [ ] Have you successfully run `brew style` with your changes locally? - [ ] Have you successfully run `brew tests` with your changes locally? ----- diff --git a/.gitignore b/.gitignore index b70874d2f..4d78ef02d 100644 --- a/.gitignore +++ b/.gitignore @@ -45,7 +45,6 @@ /docs/.bundle /docs/bin /docs/vendor -/docs/Gemfile.lock /docs/.jekyll-metadata # Unignore our shell completion diff --git a/.travis.yml b/.travis.yml index 37944df57..fd43e3942 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,9 @@ -language: ruby -rvm: system +language: c cache: directories: - - $HOME/.gem/ruby - $HOME/Library/Caches/Homebrew/style - $HOME/Library/Caches/Homebrew/tests + - $HOME/Library/Homebrew/vendor/bundle branches: only: - master @@ -12,31 +11,47 @@ matrix: fast_finish: true include: - os: osx - osx_image: xcode9 + compiler: clang + osx_image: xcode9.2 - os: linux + compiler: gcc sudo: false before_install: - - export HOMEBREW_NO_AUTO_UPDATE=1 - - export HOMEBREW_DEVELOPER=1 - - export HOMEBREW_FORCE_VENDOR_RUBY=1 - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then + MACOS="1"; HOMEBREW_REPOSITORY="$(brew --repo)"; - sudo chown -R "$USER" "$HOMEBREW_REPOSITORY/Library/Taps"; + sudo chown -R "$USER" "$HOMEBREW_REPOSITORY"; + else + LINUX="1"; + export PATH="$PWD/bin:$PATH"; + fi + # umask 022 fixes Linux `brew tests` failures; + - if [ "$LINUX" ]; then + umask 022; + fi + # trigger vendored ruby installation + - brew help + - if [ "$MACOS" ]; then mv "$HOMEBREW_REPOSITORY/Library/Taps" "$PWD/Library"; sudo rm -rf "$HOMEBREW_REPOSITORY"; sudo ln -s "$PWD" "$HOMEBREW_REPOSITORY"; - git clone --depth=1 https://github.com/Homebrew/homebrew-test-bot Library/Taps/homebrew/homebrew-test-bot; else - umask 022; - git fetch --unshallow; - export PATH="$PWD/bin:$PATH"; HOMEBREW_CORE_TAP_DIR="$(brew --repo "homebrew/core")"; mkdir -p "$HOMEBREW_CORE_TAP_DIR"; - git clone --depth=1 https://github.com/Homebrew/homebrew-test-bot Library/Taps/homebrew/homebrew-test-bot; + fi + - if [ "$MACOS" ]; then + travis_retry git -C Library/Taps/homebrew/homebrew-core fetch --depth=1 origin; + fi + - 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: - brew test-bot diff --git a/Library/.rubocop.yml b/Library/.rubocop.yml index 051a57f93..f43fbe54c 100644 --- a/Library/.rubocop.yml +++ b/Library/.rubocop.yml @@ -3,6 +3,7 @@ AllCops: Exclude: - '**/Casks/**/*' - '**/vendor/**/*' + DisplayCopNames: false require: ./Homebrew/rubocops.rb @@ -123,6 +124,14 @@ Style/Documentation: Style/Encoding: Enabled: true +# disabled until we get the Metrics/LineLength down to 80. +Style/IfUnlessModifier: + Enabled: false + +# messes with existing plist/caveats style +Style/TrailingBodyOnMethodDefinition: + Enabled: false + # use spaces for indentation; detect tabs Layout/Tab: Enabled: true @@ -214,7 +223,7 @@ Style/FrozenStringLiteralComment: Enabled: false # generally rescuing StandardError is fine -Lint/RescueWithoutErrorClass: +Style/RescueStandardError: Enabled: false # implicitly allow EOS as we use it everywhere diff --git a/Library/Homebrew/.rubocop.yml b/Library/Homebrew/.rubocop.yml index 354867738..e0089e050 100644 --- a/Library/Homebrew/.rubocop.yml +++ b/Library/Homebrew/.rubocop.yml @@ -5,6 +5,7 @@ AllCops: Include: - '**/.simplecov' Exclude: + - 'bin/*' - '**/Casks/**/*' - '**/vendor/**/*' @@ -79,3 +80,7 @@ Style/GuardClause: # hash-rockets preferred for formulae, a: 1 preferred elsewhere Style/HashSyntax: EnforcedStyle: ruby19_no_mixed_keys + +# so many of these in formulae but none in here +Style/TrailingBodyOnMethodDefinition: + Enabled: true diff --git a/Library/Homebrew/.simplecov b/Library/Homebrew/.simplecov index e0d6d7601..2fa803466 100755 --- a/Library/Homebrew/.simplecov +++ b/Library/Homebrew/.simplecov @@ -38,11 +38,22 @@ SimpleCov.start do track_files "#{SimpleCov.root}/{#{subdirs},*.rb}" end + add_filter %r{^/build.rb$} + add_filter %r{^/config.rb$} + add_filter %r{^/constants.rb$} + add_filter %r{^/postinstall.rb$} + add_filter %r{^/test.rb$} add_filter %r{^/compat/} add_filter %r{^/dev-cmd/tests.rb$} add_filter %r{^/test/} add_filter %r{^/vendor/} + require "rbconfig" + add_filter %r{^/os/mac/} unless RbConfig::CONFIG["host_os"].include?("darwin") + unless RbConfig::CONFIG["host_os"].include?("linux") + add_filter %r{^/os/linux/} + end + # Add groups and the proper project name to the output. project_name "Homebrew" add_group "Cask", %r{^/cask/} diff --git a/Library/Homebrew/brew.sh b/Library/Homebrew/brew.sh index c8f66bd45..60952c7fe 100644 --- a/Library/Homebrew/brew.sh +++ b/Library/Homebrew/brew.sh @@ -19,14 +19,6 @@ case "$*" in --repository|--repo) echo "$HOMEBREW_REPOSITORY"; exit 0 ;; esac -HOMEBREW_VERSION="$(git -C "$HOMEBREW_REPOSITORY" describe --tags --dirty --abbrev=7 2>/dev/null)" -HOMEBREW_USER_AGENT_VERSION="$HOMEBREW_VERSION" -if [[ -z "$HOMEBREW_VERSION" ]] -then - HOMEBREW_VERSION=">1.2.0 (shallow or no git repository)" - HOMEBREW_USER_AGENT_VERSION="1.X.Y" -fi - # A depth of 1 means this command was directly invoked by a user. # Higher depths mean this command was invoked by another Homebrew command. export HOMEBREW_COMMAND_DEPTH=$((HOMEBREW_COMMAND_DEPTH + 1)) @@ -63,41 +55,27 @@ git() { "$HOMEBREW_LIBRARY/Homebrew/shims/scm/git" "$@" } -if [[ "$HOMEBREW_PREFIX" = "/" || "$HOMEBREW_PREFIX" = "/usr" ]] +HOMEBREW_VERSION="$(git -C "$HOMEBREW_REPOSITORY" describe --tags --dirty --abbrev=7 2>/dev/null)" +HOMEBREW_USER_AGENT_VERSION="$HOMEBREW_VERSION" +if [[ -z "$HOMEBREW_VERSION" ]] then - # it may work, but I only see pain this route and don't want to support it - odie "Cowardly refusing to continue at this prefix: $HOMEBREW_PREFIX" + HOMEBREW_VERSION=">=1.4.0 (shallow or no git repository)" + HOMEBREW_USER_AGENT_VERSION="1.X.Y" fi -# Save values to use for installing gems -if [[ -n "$GEM_HOME" ]] -then - export HOMEBREW_GEM_HOME="$GEM_HOME" -fi -if [[ -n "$GEM_PATH" ]] +if [[ "$HOMEBREW_PREFIX" = "/" || "$HOMEBREW_PREFIX" = "/usr" ]] then - export HOMEBREW_GEM_PATH="$GEM_PATH" + # it may work, but I only see pain this route and don't want to support it + odie "Cowardly refusing to continue at this prefix: $HOMEBREW_PREFIX" fi -# Users may have these set, pointing the system Ruby -# at non-system gem paths -unset GEM_HOME -unset GEM_PATH - -# Users may have this set, injecting arbitrary environment changes into -# bash processes inside builds -unset BASH_ENV - -# Users may have this set, breaking grep's output. -unset GREP_OPTIONS - HOMEBREW_SYSTEM="$(uname -s)" case "$HOMEBREW_SYSTEM" in Darwin) HOMEBREW_MACOS="1" ;; Linux) HOMEBREW_LINUX="1" ;; esac -HOMEBREW_CURL="/usr/bin/curl" +HOMEBREW_CURL="curl" if [[ -n "$HOMEBREW_MACOS" ]] then HOMEBREW_PROCESSOR="$(uname -p)" @@ -148,7 +126,7 @@ else fi fi 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 | /usr/bin/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" # Declared in bin/brew @@ -246,6 +224,18 @@ case "$HOMEBREW_COMMAND" in --config) HOMEBREW_COMMAND="config" ;; esac +# Set HOMEBREW_DEV_CMD_RUN for users who have run a development command. +# This makes them behave like HOMEBREW_DEVELOPERs for brew update. +if [[ -z "$HOMEBREW_DEVELOPER" ]] +then + export HOMEBREW_GIT_CONFIG_FILE="$HOMEBREW_REPOSITORY/.git/config" + HOMEBREW_GIT_CONFIG_DEVELOPERMODE="$(git config --file="$HOMEBREW_GIT_CONFIG_FILE" --get homebrew.devcmdrun 2>/dev/null)" + if [[ "$HOMEBREW_GIT_CONFIG_DEVELOPERMODE" = "true" ]] + then + export HOMEBREW_DEV_CMD_RUN="1" + fi +fi + if [[ -f "$HOMEBREW_LIBRARY/Homebrew/cmd/$HOMEBREW_COMMAND.sh" ]] then HOMEBREW_BASH_COMMAND="$HOMEBREW_LIBRARY/Homebrew/cmd/$HOMEBREW_COMMAND.sh" diff --git a/Library/Homebrew/build.rb b/Library/Homebrew/build.rb index 836b360da..d61c3672a 100644 --- a/Library/Homebrew/build.rb +++ b/Library/Homebrew/build.rb @@ -48,9 +48,6 @@ class Build Requirement.prune elsif req.build? && dependent != formula Requirement.prune - elsif req.satisfied? && (dep = req.to_dependency) && dep.installed? - deps << dep - Requirement.prune end end end diff --git a/Library/Homebrew/cask/lib/hbc.rb b/Library/Homebrew/cask/lib/hbc.rb index db036d279..d865b31f2 100644 --- a/Library/Homebrew/cask/lib/hbc.rb +++ b/Library/Homebrew/cask/lib/hbc.rb @@ -17,6 +17,7 @@ require "hbc/download_strategy" require "hbc/exceptions" require "hbc/installer" require "hbc/locations" +require "hbc/config" require "hbc/macos" require "hbc/pkg" require "hbc/qualified_token" diff --git a/Library/Homebrew/cask/lib/hbc/artifact/abstract_artifact.rb b/Library/Homebrew/cask/lib/hbc/artifact/abstract_artifact.rb index f9f736662..077105468 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/abstract_artifact.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/abstract_artifact.rb @@ -95,10 +95,11 @@ module Hbc [executable, arguments] end - attr_reader :cask + attr_reader :cask, :config def initialize(cask) @cask = cask + @config = cask.config end def to_s diff --git a/Library/Homebrew/cask/lib/hbc/artifact/abstract_uninstall.rb b/Library/Homebrew/cask/lib/hbc/artifact/abstract_uninstall.rb index 94e906a73..d299733d8 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/abstract_uninstall.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/abstract_uninstall.rb @@ -222,7 +222,7 @@ module Hbc paths.each do |path| resolved_path = Pathname.new(path) - resolved_path = resolved_path.expand_path if path.start_with?("~") + resolved_path = resolved_path.expand_path if path.to_s.start_with?("~") if resolved_path.relative? || resolved_path.split.any? { |part| part.to_s == ".." } opoo "Skipping #{Formatter.identifier(action)} for relative path '#{path}'." diff --git a/Library/Homebrew/cask/lib/hbc/artifact/artifact.rb b/Library/Homebrew/cask/lib/hbc/artifact/artifact.rb index 0f37afade..b7df4b0bd 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/artifact.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/artifact.rb @@ -25,7 +25,7 @@ module Hbc new(cask, source_string, **target_hash) end - def self.resolve_target(target) + def resolve_target(target) Pathname(target) end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/moved.rb b/Library/Homebrew/cask/lib/hbc/artifact/moved.rb index f5ef790eb..856ab2766 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/moved.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/moved.rb @@ -65,7 +65,7 @@ module Hbc ohai "Moving #{self.class.english_name} '#{target.basename}' back to '#{source}'." source.dirname.mkpath - if source.parent.writable? + if target.parent.writable? FileUtils.move(target, source) else command.run("/bin/mv", args: [target, source], sudo: true) diff --git a/Library/Homebrew/cask/lib/hbc/artifact/relocated.rb b/Library/Homebrew/cask/lib/hbc/artifact/relocated.rb index 540699630..9195d889a 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/relocated.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/relocated.rb @@ -18,8 +18,8 @@ module Hbc new(cask, source_string, **target_hash) end - def self.resolve_target(target) - Hbc.public_send(dirmethod).join(target) + def resolve_target(target) + config.public_send(self.class.dirmethod).join(target) end attr_reader :source, :target @@ -32,7 +32,7 @@ module Hbc source = cask.staged_path.join(source) @source = source target ||= source.basename - @target = self.class.resolve_target(target) + @target = resolve_target(target) end def to_a diff --git a/Library/Homebrew/cask/lib/hbc/cask.rb b/Library/Homebrew/cask/lib/hbc/cask.rb index df885371a..681130c1b 100644 --- a/Library/Homebrew/cask/lib/hbc/cask.rb +++ b/Library/Homebrew/cask/lib/hbc/cask.rb @@ -6,17 +6,18 @@ module Hbc extend Forwardable include Metadata - attr_reader :token, :sourcefile_path + attr_reader :token, :sourcefile_path, :config def tap return super if block_given? # Object#tap @tap end - def initialize(token, sourcefile_path: nil, tap: nil, &block) + def initialize(token, sourcefile_path: nil, tap: nil, config: Config.global, &block) @token = token @sourcefile_path = sourcefile_path @tap = tap + @config = config @dsl = DSL.new(self) return unless block_given? @dsl.instance_eval(&block) diff --git a/Library/Homebrew/cask/lib/hbc/cli.rb b/Library/Homebrew/cask/lib/hbc/cli.rb index e2deb6f67..6410af5ae 100644 --- a/Library/Homebrew/cask/lib/hbc/cli.rb +++ b/Library/Homebrew/cask/lib/hbc/cli.rb @@ -49,19 +49,19 @@ module Hbc include Options - option "--appdir=PATH", ->(value) { Hbc.appdir = value } - option "--colorpickerdir=PATH", ->(value) { Hbc.colorpickerdir = value } - option "--prefpanedir=PATH", ->(value) { Hbc.prefpanedir = value } - option "--qlplugindir=PATH", ->(value) { Hbc.qlplugindir = value } - option "--dictionarydir=PATH", ->(value) { Hbc.dictionarydir = value } - option "--fontdir=PATH", ->(value) { Hbc.fontdir = value } - option "--servicedir=PATH", ->(value) { Hbc.servicedir = value } - option "--input_methoddir=PATH", ->(value) { Hbc.input_methoddir = value } - option "--internet_plugindir=PATH", ->(value) { Hbc.internet_plugindir = value } - option "--audio_unit_plugindir=PATH", ->(value) { Hbc.audio_unit_plugindir = value } - option "--vst_plugindir=PATH", ->(value) { Hbc.vst_plugindir = value } - option "--vst3_plugindir=PATH", ->(value) { Hbc.vst3_plugindir = value } - option "--screen_saverdir=PATH", ->(value) { Hbc.screen_saverdir = value } + option "--appdir=PATH", ->(value) { Config.global.appdir = value } + option "--colorpickerdir=PATH", ->(value) { Config.global.colorpickerdir = value } + option "--prefpanedir=PATH", ->(value) { Config.global.prefpanedir = value } + option "--qlplugindir=PATH", ->(value) { Config.global.qlplugindir = value } + option "--dictionarydir=PATH", ->(value) { Config.global.dictionarydir = value } + option "--fontdir=PATH", ->(value) { Config.global.fontdir = value } + option "--servicedir=PATH", ->(value) { Config.global.servicedir = value } + option "--input_methoddir=PATH", ->(value) { Config.global.input_methoddir = value } + option "--internet_plugindir=PATH", ->(value) { Config.global.internet_plugindir = value } + option "--audio_unit_plugindir=PATH", ->(value) { Config.global.audio_unit_plugindir = value } + option "--vst_plugindir=PATH", ->(value) { Config.global.vst_plugindir = value } + option "--vst3_plugindir=PATH", ->(value) { Config.global.vst3_plugindir = value } + option "--screen_saverdir=PATH", ->(value) { Config.global.screen_saverdir = value } option "--help", :help, false @@ -96,7 +96,7 @@ module Hbc if command.respond_to?(:run) # usual case: built-in command verb command.run(*args) - elsif require?(which("brewcask-#{command}.rb")) + elsif require?(which("brewcask-#{command}.rb", ENV["HOMEBREW_PATH"])) # external command as Ruby library on PATH, Homebrew-style elsif command.to_s.include?("/") && require?(command.to_s) # external command as Ruby library with literal path, useful @@ -229,6 +229,7 @@ module Hbc purpose usage + return if @command.nil? return if @command == "help" && @args.empty? raise ArgumentError, "help does not take arguments." diff --git a/Library/Homebrew/cask/lib/hbc/cli/doctor.rb b/Library/Homebrew/cask/lib/hbc/cli/doctor.rb index 1ad5eaff5..a586a00ab 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/doctor.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/doctor.rb @@ -35,6 +35,7 @@ module Hbc def check_software_versions ohai "Homebrew-Cask Version", Hbc.full_version ohai "macOS", MacOS.full_version + ohai "SIP", self.class.check_sip ohai "Java", SystemConfig.describe_java end @@ -145,6 +146,15 @@ module Hbc self.class.render_env_var(var) end + def self.check_sip + csrutil = "/usr/bin/csrutil" + return "N/A" unless File.executable?(csrutil) + Open3.capture2(csrutil, "status")[0] + .gsub("This is an unsupported configuration, likely to break in the future and leave your machine in an unknown state.", "") + .gsub("System Integrity Protection status: ", "") + .delete("\t\.").capitalize.strip + end + def self.locale_variables ENV.keys.grep(/^(?:LC_\S+|LANG|LANGUAGE)\Z/).sort end diff --git a/Library/Homebrew/cask/lib/hbc/cli/style.rb b/Library/Homebrew/cask/lib/hbc/cli/style.rb index 86fc98eaa..261bed50b 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/style.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/style.rb @@ -10,9 +10,9 @@ module Hbc def run install_rubocop cache_env = { "XDG_CACHE_HOME" => "#{HOMEBREW_CACHE}/style" } - system(cache_env, "rubocop", *rubocop_args, "--", *cask_paths) + hide_warnings = debug? ? [] : [ENV["HOMEBREW_RUBY_PATH"], "-W0", "-S"] + system(cache_env, *hide_warnings, "rubocop", *rubocop_args, "--", *cask_paths) raise CaskError, "style check failed" unless $CHILD_STATUS.success? - true end def install_rubocop @@ -36,18 +36,21 @@ module Hbc end def rubocop_args - fix? ? autocorrect_args : default_args + fix? ? autocorrect_args : normal_args end def default_args [ "--require", "rubocop-cask", "--force-default-config", - "--force-exclusion", "--format", "simple" ] end + def normal_args + default_args + ["--parallel"] + end + def autocorrect_args default_args + ["--auto-correct"] end diff --git a/Library/Homebrew/cask/lib/hbc/config.rb b/Library/Homebrew/cask/lib/hbc/config.rb new file mode 100644 index 000000000..43408d53d --- /dev/null +++ b/Library/Homebrew/cask/lib/hbc/config.rb @@ -0,0 +1,65 @@ +module Hbc + class Config + def self.global + @global ||= new + end + + attr_reader :binarydir + + def initialize( + appdir: "/Applications", + prefpanedir: "~/Library/PreferencePanes", + qlplugindir: "~/Library/QuickLook", + dictionarydir: "~/Library/Dictionaries", + fontdir: "~/Library/Fonts", + colorpickerdir: "~/Library/ColorPickers", + servicedir: "~/Library/Services", + input_methoddir: "~/Library/Input Methods", + internet_plugindir: "~/Library/Internet Plug-Ins", + audio_unit_plugindir: "~/Library/Audio/Plug-Ins/Components", + vst_plugindir: "~/Library/Audio/Plug-Ins/VST", + vst3_plugindir: "~/Library/Audio/Plug-Ins/VST3", + screen_saverdir: "~/Library/Screen Savers" + ) + + self.appdir = appdir + self.prefpanedir = prefpanedir + self.qlplugindir = qlplugindir + self.dictionarydir = dictionarydir + self.fontdir = fontdir + self.colorpickerdir = colorpickerdir + self.servicedir = servicedir + self.input_methoddir = input_methoddir + self.internet_plugindir = internet_plugindir + self.audio_unit_plugindir = audio_unit_plugindir + self.vst_plugindir = vst_plugindir + self.vst3_plugindir = vst3_plugindir + self.screen_saverdir = screen_saverdir + + # `binarydir` is not customisable. + @binarydir = HOMEBREW_PREFIX/"bin" + end + + [ + :appdir, + :prefpanedir, + :qlplugindir, + :dictionarydir, + :fontdir, + :colorpickerdir, + :servicedir, + :input_methoddir, + :internet_plugindir, + :audio_unit_plugindir, + :vst_plugindir, + :vst3_plugindir, + :screen_saverdir, + ].each do |dir| + attr_reader dir + + define_method(:"#{dir}=") do |path| + instance_variable_set(:"@#{dir}", Pathname(path).expand_path) + end + end + end +end diff --git a/Library/Homebrew/cask/lib/hbc/container/cab.rb b/Library/Homebrew/cask/lib/hbc/container/cab.rb index 010fccbc4..327aece6e 100644 --- a/Library/Homebrew/cask/lib/hbc/container/cab.rb +++ b/Library/Homebrew/cask/lib/hbc/container/cab.rb @@ -10,7 +10,7 @@ module Hbc end def extract - if (cabextract = which("cabextract")).nil? + unless cabextract = which("cabextract", PATH.new(ENV["PATH"], HOMEBREW_PREFIX/"bin")) raise CaskError, "Expected to find cabextract executable. Cask '#{@cask}' must add: depends_on formula: 'cabextract'" end diff --git a/Library/Homebrew/cask/lib/hbc/container/generic_unar.rb b/Library/Homebrew/cask/lib/hbc/container/generic_unar.rb index 7a465e12e..63ab917ea 100644 --- a/Library/Homebrew/cask/lib/hbc/container/generic_unar.rb +++ b/Library/Homebrew/cask/lib/hbc/container/generic_unar.rb @@ -6,14 +6,14 @@ module Hbc class Container class GenericUnar < Base def self.me?(criteria) - !(lsar = which("lsar")).nil? && - criteria.command.run(lsar, - args: ["-l", "-t", "--", criteria.path], - print_stderr: false).stdout.chomp.end_with?("passed, 0 failed.") + return false unless lsar = which("lsar", PATH.new(ENV["PATH"], HOMEBREW_PREFIX/"bin")) + criteria.command.run(lsar, + args: ["-l", "-t", "--", criteria.path], + print_stderr: false).stdout.chomp.end_with?("passed, 0 failed.") end def extract - if (unar = which("unar")).nil? + unless unar = which("unar", PATH.new(ENV["PATH"], HOMEBREW_PREFIX/"bin")) raise CaskError, "Expected to find unar executable. Cask #{@cask} must add: depends_on formula: 'unar'" end diff --git a/Library/Homebrew/cask/lib/hbc/container/gpg.rb b/Library/Homebrew/cask/lib/hbc/container/gpg.rb index 3f37b5aa6..09c75468a 100644 --- a/Library/Homebrew/cask/lib/hbc/container/gpg.rb +++ b/Library/Homebrew/cask/lib/hbc/container/gpg.rb @@ -24,7 +24,7 @@ module Hbc end def extract - if (gpg = which("gpg")).nil? + unless gpg = which("gpg", PATH.new(ENV["PATH"], HOMEBREW_PREFIX/"bin")) raise CaskError, "Expected to find gpg executable. Cask '#{@cask}' must add: depends_on formula: 'gpg'" end diff --git a/Library/Homebrew/cask/lib/hbc/container/lzma.rb b/Library/Homebrew/cask/lib/hbc/container/lzma.rb index 1221acfbc..1e165ba2a 100644 --- a/Library/Homebrew/cask/lib/hbc/container/lzma.rb +++ b/Library/Homebrew/cask/lib/hbc/container/lzma.rb @@ -10,7 +10,7 @@ module Hbc end def extract - if (unlzma = which("unlzma")).nil? + unless unlzma = which("unlzma", PATH.new(ENV["PATH"], HOMEBREW_PREFIX/"bin")) raise CaskError, "Expected to find unlzma executable. Cask '#{@cask}' must add: depends_on formula: 'lzma'" end diff --git a/Library/Homebrew/cask/lib/hbc/container/xz.rb b/Library/Homebrew/cask/lib/hbc/container/xz.rb index cd9f9aee2..4086ae188 100644 --- a/Library/Homebrew/cask/lib/hbc/container/xz.rb +++ b/Library/Homebrew/cask/lib/hbc/container/xz.rb @@ -10,7 +10,7 @@ module Hbc end def extract - if (unxz = which("unxz")).nil? + unless unxz = which("unxz", PATH.new(ENV["PATH"], HOMEBREW_PREFIX/"bin")) raise CaskError, "Expected to find unxz executable. Cask '#{@cask}' must add: depends_on formula: 'xz'" end diff --git a/Library/Homebrew/cask/lib/hbc/dsl.rb b/Library/Homebrew/cask/lib/hbc/dsl.rb index 22f0d2f66..9a88f1b62 100644 --- a/Library/Homebrew/cask/lib/hbc/dsl.rb +++ b/Library/Homebrew/cask/lib/hbc/dsl.rb @@ -292,11 +292,7 @@ module Hbc end def appdir - self.class.appdir - end - - def self.appdir - Hbc.appdir.sub(%r{\/$}, "") + cask.config.appdir end end end diff --git a/Library/Homebrew/cask/lib/hbc/installer.rb b/Library/Homebrew/cask/lib/hbc/installer.rb index 8520f154d..a2833e8f9 100644 --- a/Library/Homebrew/cask/lib/hbc/installer.rb +++ b/Library/Homebrew/cask/lib/hbc/installer.rb @@ -75,7 +75,7 @@ module Hbc fetch uninstall_existing_cask if @reinstall - oh1 "Installing Cask #{@cask}" + oh1 "Installing Cask #{Formatter.identifier(@cask)}" stage install_artifacts enable_accessibility_access @@ -348,7 +348,7 @@ module Hbc end def uninstall - oh1 "Uninstalling Cask #{@cask}" + oh1 "Uninstalling Cask #{Formatter.identifier(@cask)}" disable_accessibility_access uninstall_artifacts(clear: true) purge_versioned_files @@ -356,7 +356,7 @@ module Hbc end def start_upgrade - oh1 "Starting upgrade for Cask #{@cask}" + oh1 "Starting upgrade for Cask #{Formatter.identifier(@cask)}" disable_accessibility_access uninstall_artifacts diff --git a/Library/Homebrew/cask/lib/hbc/locations.rb b/Library/Homebrew/cask/lib/hbc/locations.rb index e55bdf15d..40ba2989f 100644 --- a/Library/Homebrew/cask/lib/hbc/locations.rb +++ b/Library/Homebrew/cask/lib/hbc/locations.rb @@ -7,102 +7,14 @@ module Hbc end module ClassMethods - attr_writer :caskroom - def caskroom @caskroom ||= HOMEBREW_PREFIX.join("Caskroom") end - attr_writer :cache - def cache @cache ||= HOMEBREW_CACHE.join("Cask") end - attr_writer :appdir - - def appdir - @appdir ||= Pathname.new("/Applications").expand_path - end - - attr_writer :prefpanedir - - def prefpanedir - @prefpanedir ||= Pathname.new("~/Library/PreferencePanes").expand_path - end - - attr_writer :qlplugindir - - def qlplugindir - @qlplugindir ||= Pathname.new("~/Library/QuickLook").expand_path - end - - attr_writer :dictionarydir - - def dictionarydir - @dictionarydir ||= Pathname.new("~/Library/Dictionaries").expand_path - end - - attr_writer :fontdir - - def fontdir - @fontdir ||= Pathname.new("~/Library/Fonts").expand_path - end - - attr_writer :colorpickerdir - - def colorpickerdir - @colorpickerdir ||= Pathname.new("~/Library/ColorPickers").expand_path - end - - attr_writer :servicedir - - def servicedir - @servicedir ||= Pathname.new("~/Library/Services").expand_path - end - - attr_writer :binarydir - - def binarydir - @binarydir ||= HOMEBREW_PREFIX.join("bin") - end - - attr_writer :input_methoddir - - def input_methoddir - @input_methoddir ||= Pathname.new("~/Library/Input Methods").expand_path - end - - attr_writer :internet_plugindir - - def internet_plugindir - @internet_plugindir ||= Pathname.new("~/Library/Internet Plug-Ins").expand_path - end - - attr_writer :audio_unit_plugindir - - def audio_unit_plugindir - @audio_unit_plugindir ||= Pathname.new("~/Library/Audio/Plug-Ins/Components").expand_path - end - - attr_writer :vst_plugindir - - def vst_plugindir - @vst_plugindir ||= Pathname.new("~/Library/Audio/Plug-Ins/VST").expand_path - end - - attr_writer :vst3_plugindir - - def vst3_plugindir - @vst3_plugindir ||= Pathname.new("~/Library/Audio/Plug-Ins/VST3").expand_path - end - - attr_writer :screen_saverdir - - def screen_saverdir - @screen_saverdir ||= Pathname.new("~/Library/Screen Savers").expand_path - end - attr_writer :default_tap def default_tap diff --git a/Library/Homebrew/cask/lib/hbc/system_command.rb b/Library/Homebrew/cask/lib/hbc/system_command.rb index f64d85c07..a890c42e4 100644 --- a/Library/Homebrew/cask/lib/hbc/system_command.rb +++ b/Library/Homebrew/cask/lib/hbc/system_command.rb @@ -50,11 +50,7 @@ module Hbc end def command - @command ||= if sudo? - [*sudo_prefix, executable, *args] - else - [Shellwords.shellescape(executable), *args] - end + [*sudo_prefix, executable, *args] end private @@ -85,8 +81,14 @@ module Hbc end def each_output_line(&b) + 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 = - Open3.popen3(*expanded_command, **options) + Open3.popen3([executable, executable], *args, **options) write_input_to(raw_stdin) raw_stdin.close_write diff --git a/Library/Homebrew/caveats.rb b/Library/Homebrew/caveats.rb index 49a517bd4..8cd1053fb 100644 --- a/Library/Homebrew/caveats.rb +++ b/Library/Homebrew/caveats.rb @@ -1,4 +1,5 @@ require "forwardable" +require "language/python" class Caveats extend Forwardable @@ -64,7 +65,7 @@ class Caveats s << "\nFor compilers to find this software you may need to set:\n" s << " LDFLAGS: -L#{f.opt_lib}\n" if f.lib.directory? s << " CPPFLAGS: -I#{f.opt_include}\n" if f.include.directory? - if which("pkg-config") && + if which("pkg-config", ENV["HOMEBREW_PATH"]) && ((f.lib/"pkgconfig").directory? || (f.share/"pkgconfig").directory?) s << "For pkg-config to find this software you may need to set:\n" s << " PKG_CONFIG_PATH: #{f.opt_lib}/pkgconfig\n" if (f.lib/"pkgconfig").directory? @@ -76,7 +77,7 @@ class Caveats def function_completion_caveats(shell) return unless keg - return unless which(shell.to_s) + return unless which(shell.to_s, ENV["HOMEBREW_PATH"]) completion_installed = keg.completion_installed?(shell) functions_installed = keg.functions_installed?(shell) @@ -86,21 +87,23 @@ class Caveats installed << "completions" if completion_installed installed << "functions" if functions_installed + root_dir = f.keg_only? ? f.opt_prefix : HOMEBREW_PREFIX + case shell when :bash <<~EOS Bash completion has been installed to: - #{HOMEBREW_PREFIX}/etc/bash_completion.d + #{root_dir}/etc/bash_completion.d EOS when :zsh <<~EOS zsh #{installed.join(" and ")} have been installed to: - #{HOMEBREW_PREFIX}/share/zsh/site-functions + #{root_dir}/share/zsh/site-functions EOS when :fish fish_caveats = "fish #{installed.join(" and ")} have been installed to:" - fish_caveats << "\n #{HOMEBREW_PREFIX}/share/fish/vendor_completions.d" if completion_installed - fish_caveats << "\n #{HOMEBREW_PREFIX}/share/fish/vendor_functions.d" if functions_installed + fish_caveats << "\n #{root_dir}/share/fish/vendor_completions.d" if completion_installed + fish_caveats << "\n #{root_dir}/share/fish/vendor_functions.d" if functions_installed fish_caveats end end diff --git a/Library/Homebrew/cmd/--env.rb b/Library/Homebrew/cmd/--env.rb index 90beee89c..e0a2b9f19 100644 --- a/Library/Homebrew/cmd/--env.rb +++ b/Library/Homebrew/cmd/--env.rb @@ -1,5 +1,11 @@ -#: * `--env`: -#: Show a summary of the Homebrew build environment. +#: * `--env` [`--shell=`(<shell>|`auto`)|`--plain`]: +#: Show a summary of the Homebrew build environment as a plain list. +#: +#: Pass `--shell=`<shell> to generate a list of environment variables for the +#: specified shell, or `--shell=auto` to detect the current shell. +#: +#: If the command's output is sent through a pipe and no shell is specified, +#: the list is formatted for export to `bash`(1) unless `--plain` is passed. require "extend/ENV" require "build_environment" diff --git a/Library/Homebrew/cmd/deps.rb b/Library/Homebrew/cmd/deps.rb index ae758e143..0627e84bd 100644 --- a/Library/Homebrew/cmd/deps.rb +++ b/Library/Homebrew/cmd/deps.rb @@ -94,26 +94,14 @@ module Homebrew if ARGV.include?("--include-requirements") deps else - deps.map do |dep| - if dep.is_a? Dependency - dep - elsif dep.default_formula? - dep.to_dependency - end - end.compact + deps.select { |dep| dep.is_a? Dependency } end end def dep_display_name(dep) str = if dep.is_a? Requirement if ARGV.include?("--include-requirements") - if dep.default_formula? - ":#{dep.display_s} (#{dep_display_name(dep.to_dependency)})" - else - ":#{dep.display_s}" - end - elsif dep.default_formula? - dep_display_name(dep.to_dependency) + ":#{dep.display_s}" else # This shouldn't happen, but we'll put something here to help debugging "::#{dep.name}" @@ -207,7 +195,7 @@ module Homebrew max = dependables.length - 1 @dep_stack.push f.name dependables.each_with_index do |dep, i| - next if !ARGV.include?("--include-requirements") && dep.is_a?(Requirement) && !dep.default_formula? + next if !ARGV.include?("--include-requirements") && dep.is_a?(Requirement) tree_lines = if i == max "└──" else @@ -223,9 +211,6 @@ module Homebrew else "│ " end - if dep.is_a?(Requirement) && dep.default_formula? - recursive_deps_tree(Formulary.factory(dep.to_dependency.name), prefix + prefix_addition, true) - end if dep.is_a? Dependency recursive_deps_tree(Formulary.factory(dep.name), prefix + prefix_addition, true) end diff --git a/Library/Homebrew/cmd/desc.rb b/Library/Homebrew/cmd/desc.rb index 53291602e..ccb7e9925 100644 --- a/Library/Homebrew/cmd/desc.rb +++ b/Library/Homebrew/cmd/desc.rb @@ -1,11 +1,12 @@ #: * `desc` <formula>: #: Display <formula>'s name and one-line description. #: -#: * `desc` [`-s`|`-n`|`-d`] (<text>|`/`<text>`/`): -#: Search both name and description (`-s`), just the names (`-n`), or just the -#: descriptions (`-d`) for <text>. If <text> is flanked by slashes, it is interpreted -#: as a regular expression. Formula descriptions are cached; the cache is created on -#: the first search, making that search slower than subsequent ones. +#: * `desc` [`--search`|`--name`|`--description`] (<text>|`/`<text>`/`): +#: Search both name and description (`--search` or `-s`), just the names +#: (`--name` or `-n`), or just the descriptions (`--description` or `-d`) for +#: <text>. If <text> is flanked by slashes, it is interpreted as a regular +#: expression. Formula descriptions are cached; the cache is created on the +#: first search, making that search slower than subsequent ones. require "descriptions" require "cmd/search" diff --git a/Library/Homebrew/cmd/doctor.rb b/Library/Homebrew/cmd/doctor.rb index 7b1778e63..4e439fa0a 100644 --- a/Library/Homebrew/cmd/doctor.rb +++ b/Library/Homebrew/cmd/doctor.rb @@ -1,9 +1,13 @@ #: * `doctor`: #: Check your system for potential problems. Doctor exits with a non-zero status -#: if any problems are found. +#: if any potential problems are found. Please note that these warnings are just +#: used to help the Homebrew maintainers with debugging if you file an issue. If +#: everything you use Homebrew for is working fine: please don't worry or file +#: an issue; just ignore this. # Undocumented options: -# -D activates debugging and profiling of the audit methods (not the same as --debug) +# `-D` activates debugging and profiling of the audit methods (not the same as `--debug`) +# `--list-checks` lists all audit methods require "diagnostic" @@ -46,7 +50,7 @@ module Homebrew $stderr.puts <<~EOS #{Tty.bold}Please note that these warnings are just used to help the Homebrew maintainers with debugging if you file an issue. If everything you use Homebrew for is - working fine: please don't worry and just ignore them. Thanks!#{Tty.reset} + working fine: please don't worry or file an issue; just ignore this. Thanks!#{Tty.reset} EOS end diff --git a/Library/Homebrew/cmd/fetch.rb b/Library/Homebrew/cmd/fetch.rb index 411753992..f150d8f16 100644 --- a/Library/Homebrew/cmd/fetch.rb +++ b/Library/Homebrew/cmd/fetch.rb @@ -63,7 +63,12 @@ module Homebrew next if fetched_bottle fetch_formula(f) - f.resources.each { |r| fetch_resource(r) } + + f.resources.each do |r| + fetch_resource(r) + r.patches.each { |p| fetch_patch(p) if p.external? } + end + f.patchlist.each { |p| fetch_patch(p) if p.external? } end end diff --git a/Library/Homebrew/cmd/gist-logs.rb b/Library/Homebrew/cmd/gist-logs.rb index 45537602b..630361ca2 100644 --- a/Library/Homebrew/cmd/gist-logs.rb +++ b/Library/Homebrew/cmd/gist-logs.rb @@ -4,6 +4,8 @@ #: <formula> is usually the name of the formula to install, but it can be specified #: in several different ways. See [SPECIFYING FORMULAE](#specifying-formulae). #: +#: If `--with-hostname` is passed, include the hostname in the Gist. +#: #: If `--new-issue` is passed, automatically create a new issue in the appropriate #: GitHub repository as well as creating the Gist. #: @@ -27,7 +29,7 @@ module Homebrew # Dummy summary file, asciibetically first, to control display title of gist files["# #{f.name} - #{timestamp}.txt"] = { content: brief_build_info(f) } files["00.config.out"] = { content: s.string } - files["00.doctor.out"] = { content: `brew doctor 2>&1` } + files["00.doctor.out"] = { content: Utils.popen_read("#{HOMEBREW_PREFIX}/bin/brew", "doctor", err: :out) } unless f.core_formula? tap = <<~EOS Formula: #{f.name} diff --git a/Library/Homebrew/cmd/info.rb b/Library/Homebrew/cmd/info.rb index 83bb712ab..1eb9fe9fe 100644 --- a/Library/Homebrew/cmd/info.rb +++ b/Library/Homebrew/cmd/info.rb @@ -1,8 +1,11 @@ +#: * `info`: +#: Display brief statistics for your Homebrew installation. +#: #: * `info` <formula>: #: Display information about <formula>. #: #: * `info` `--github` <formula>: -#: Open a browser to the GitHub History page for formula <formula>. +#: Open a browser to the GitHub History page for <formula>. #: #: To view formula history locally: `brew log -p <formula>` #: @@ -164,7 +167,7 @@ module Homebrew end end - unless f.options.empty? + if !f.options.empty? || f.head || f.devel ohai "Options" Homebrew.dump_options_for_formula f end diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb index 575dbc4b3..e1e4712ea 100644 --- a/Library/Homebrew/cmd/install.rb +++ b/Library/Homebrew/cmd/install.rb @@ -1,4 +1,4 @@ -#: * `install` [`--debug`] [`--env=`(`std`|`super`)] [`--ignore-dependencies`|`--only-dependencies`] [`--cc=`<compiler>] [`--build-from-source`|`--force-bottle`] [`--devel`|`--HEAD`] [`--keep-tmp`] [`--build-bottle`] <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>. #: #: <formula> is usually the name of the formula to install, but it can be specified @@ -47,6 +47,11 @@ #: If `--build-bottle` is passed, prepare the formula for eventual bottling #: during installation. #: +#: If `--force` (or `-f`) is passed, install without checking for previously +#: installed keg-only or non-migrated versions +#: +#: If `--verbose` (or `-v`) is passed, print the verification and postinstall steps. +#: #: Installation options specific to <formula> may be appended to the command, #: and can be listed with `brew options` <formula>. #: diff --git a/Library/Homebrew/cmd/linkapps.rb b/Library/Homebrew/cmd/linkapps.rb index e8d482529..1bec67a04 100644 --- a/Library/Homebrew/cmd/linkapps.rb +++ b/Library/Homebrew/cmd/linkapps.rb @@ -1,3 +1,4 @@ +#: @hide_from_man_page #: * `linkapps` [`--local`] [<formulae>]: #: Find installed formulae that provide `.app`-style macOS apps and symlink them #: into `/Applications`, allowing for easier access (deprecated). @@ -6,11 +7,6 @@ #: either aliases or symlinks and Homebrew formulae do not build "proper" `.app` #: bundles that can be relocated. Instead, please consider using `brew cask` and #: migrate formulae using `.app`s to casks. -#: -#: If no <formulae> are provided, all of them will have their apps symlinked. -#: -#: If provided, `--local` will symlink them into the user's `~/Applications` -#: directory instead of the system directory. require "keg" require "formula" @@ -19,14 +15,7 @@ module Homebrew module_function def linkapps - opoo <<~EOS - `brew linkapps` has been deprecated and will eventually be removed! - - Unfortunately `brew linkapps` cannot behave nicely with e.g. Spotlight using - either aliases or symlinks and Homebrew formulae do not build "proper" `.app` - bundles that can be relocated. Instead, please consider using `brew cask` and - migrate formulae using `.app`s to casks. - EOS + odeprecated "'brew linkapps'" target_dir = linkapps_target(local: ARGV.include?("--local")) diff --git a/Library/Homebrew/cmd/list.rb b/Library/Homebrew/cmd/list.rb index 1f90a3ac3..482100ba2 100644 --- a/Library/Homebrew/cmd/list.rb +++ b/Library/Homebrew/cmd/list.rb @@ -6,7 +6,7 @@ #: * `list`, `ls` `--unbrewed`: #: List all files in the Homebrew prefix not installed by Homebrew. #: -#: * `list`, `ls` [`--versions` [`--multiple`]] [`--pinned`] [<formulae>]: +#: * `list`, `ls` [`--verbose`] [`--versions` [`--multiple`]] [`--pinned`] [<formulae>]: #: List the installed files for <formulae>. Combined with `--verbose`, recursively #: list the contents of all subdirectories in each <formula>'s keg. #: diff --git a/Library/Homebrew/cmd/outdated.rb b/Library/Homebrew/cmd/outdated.rb index f163212e1..97367ca1e 100644 --- a/Library/Homebrew/cmd/outdated.rb +++ b/Library/Homebrew/cmd/outdated.rb @@ -9,8 +9,8 @@ #: #: If `--verbose` (or `-v`) is passed, display detailed version information. #: -#: If `--json=`<version> is passed, the output will be in JSON format. The only -#: valid version is `v1`. +#: If `--json=`<version> is passed, the output will be in JSON format. +#: Currently the only accepted value for <version> is `v1`. #: #: If `--fetch-HEAD` is passed, fetch the upstream repository to detect if #: the HEAD installation of the formula is outdated. Otherwise, the diff --git a/Library/Homebrew/cmd/pin.rb b/Library/Homebrew/cmd/pin.rb index 5a14f853c..9935d1636 100644 --- a/Library/Homebrew/cmd/pin.rb +++ b/Library/Homebrew/cmd/pin.rb @@ -1,7 +1,6 @@ #: * `pin` <formulae>: #: Pin the specified <formulae>, preventing them from being upgraded when -#: issuing the `brew upgrade <formulae>` command (but can still be upgraded -#: as dependencies for other formulae). See also `unpin`. +#: issuing the `brew upgrade <formulae>` command. See also `unpin`. require "formula" diff --git a/Library/Homebrew/cmd/readall.rb b/Library/Homebrew/cmd/readall.rb index 3bde16e7e..0a581c383 100644 --- a/Library/Homebrew/cmd/readall.rb +++ b/Library/Homebrew/cmd/readall.rb @@ -1,9 +1,13 @@ -#: * `readall` [tap]: -#: Import all formulae from specified taps (defaults to all installed taps). +#: * `readall` [`--aliases`] [`--syntax`] [<taps>]: +#: Import all formulae from specified <taps> (defaults to all installed taps). #: #: This can be useful for debugging issues across all formulae when making #: significant changes to `formula.rb`, testing the performance of loading #: all formulae or to determine if any current formulae have Ruby issues. +#: +#: If `--aliases` is passed, also verify any alias symlinks in each tap. +#: +#: If `--syntax` is passed, also syntax-check all of Homebrew's Ruby files. require "readall" diff --git a/Library/Homebrew/cmd/reinstall.rb b/Library/Homebrew/cmd/reinstall.rb index 6727c0b6b..7c62d8092 100644 --- a/Library/Homebrew/cmd/reinstall.rb +++ b/Library/Homebrew/cmd/reinstall.rb @@ -1,5 +1,5 @@ #: * `reinstall` <formula>: -#: Uninstall and then install <formula>. +#: Uninstall and then install <formula> (with existing install options). require "formula_installer" require "development_tools" @@ -39,10 +39,10 @@ module Homebrew fi.build_bottle = ARGV.build_bottle? || (!f.bottled? && f.build.bottle?) fi.interactive = ARGV.interactive? fi.git = ARGV.git? - fi.link_keg = keg_was_linked if keg_had_linked_opt + fi.link_keg ||= keg_was_linked if keg_had_linked_opt fi.prelude - oh1 "Reinstalling #{f.full_name} #{options.to_a.join " "}" + oh1 "Reinstalling #{Formatter.identifier(f.full_name)} #{options.to_a.join " "}" fi.install fi.finish diff --git a/Library/Homebrew/cmd/style.rb b/Library/Homebrew/cmd/style.rb index 89484d67d..1f0d385de 100644 --- a/Library/Homebrew/cmd/style.rb +++ b/Library/Homebrew/cmd/style.rb @@ -1,19 +1,19 @@ -#: * `style` [`--fix`] [`--display-cop-names`] [`--only-cops=`[COP1,COP2..]|`--except-cops=`[COP1,COP2..]] [<files>|<taps>|<formulae>]: +#: * `style` [`--fix`] [`--display-cop-names`] [`--only-cops=`<cops>|`--except-cops=`<cops>] [<files>|<taps>|<formulae>]: #: Check formulae or files for conformance to Homebrew style guidelines. #: -#: <formulae> and <files> may not be combined. If both are omitted, style will run -#: style checks on the whole Homebrew `Library`, including core code and all -#: formulae. +#: Lists of <files>, <taps> and <formulae> may not be combined. If none are +#: provided, `style` will run style checks on the whole Homebrew library, +#: including core code and all formulae. #: -#: If `--fix` is passed, style violations will be automatically fixed using -#: RuboCop's `--auto-correct` feature. +#: If `--fix` is passed, automatically fix style violations using RuboCop's +#: auto-correct feature. #: -#: If `--display-cop-names` is passed, the RuboCop cop name for each violation -#: is included in the output. +#: If `--display-cop-names` is passed, include the RuboCop cop name for each +#: violation in the output. #: -#: If `--only-cops` is passed, only the given Rubocop cop(s)' violations would be checked. -#: -#: If `--except-cops` is passed, the given Rubocop cop(s)' checks would be skipped. +#: Passing `--only-cops=`<cops> will check for violations of only the listed +#: RuboCop <cops>, while `--except-cops=`<cops> will skip checking the listed +#: <cops>. For either option <cops> should be a comma-separated list of cop names. #: #: Exits with a non-zero status if any style violations are found. diff --git a/Library/Homebrew/cmd/uninstall.rb b/Library/Homebrew/cmd/uninstall.rb index f95b6c7bb..af0efaf62 100644 --- a/Library/Homebrew/cmd/uninstall.rb +++ b/Library/Homebrew/cmd/uninstall.rb @@ -46,6 +46,16 @@ module Homebrew rm_pin rack else kegs.each do |keg| + begin + f = Formulary.from_rack(rack) + if f.pinned? + onoe "#{f.full_name} is pinned. You must unpin it to uninstall." + next + end + rescue + nil + end + keg.lock do puts "Uninstalling #{keg}... (#{keg.abv})" keg.unlink diff --git a/Library/Homebrew/cmd/unlinkapps.rb b/Library/Homebrew/cmd/unlinkapps.rb index 7f401aaeb..721e4d639 100644 --- a/Library/Homebrew/cmd/unlinkapps.rb +++ b/Library/Homebrew/cmd/unlinkapps.rb @@ -1,3 +1,4 @@ +#: @hide_from_man_page #: * `unlinkapps` [`--local`] [`--dry-run`] [<formulae>]: #: Remove symlinks created by `brew linkapps` from `/Applications` (deprecated). #: @@ -5,14 +6,6 @@ #: either aliases or symlinks and Homebrew formulae do not build "proper" `.app` #: bundles that can be relocated. Instead, please consider using `brew cask` and #: migrate formulae using `.app`s to casks. -#: -#: If no <formulae> are provided, all linked apps will be removed. -#: -#: If provided, `--local` will remove symlinks from the user's `~/Applications` -#: directory instead of the system directory. -#: -#: If `--dry-run` or `-n` is passed, Homebrew will list all symlinks which -#: would be removed, but will not actually delete any files. require "cmd/linkapps" @@ -20,11 +13,7 @@ module Homebrew module_function def unlinkapps - opoo <<~EOS - `brew unlinkapps` has been deprecated and will eventually be removed! - - Unfortunately `brew linkapps` cannot behave nicely with e.g. Spotlight using either aliases or symlinks and Homebrew formulae do not build "proper" `.app` bundles that can be relocated. Instead, please consider using `brew cask` and migrate formulae using `.app`s to casks. - EOS + odeprecated "'brew unlinkapps'" target_dir = linkapps_target(local: ARGV.include?("--local")) diff --git a/Library/Homebrew/cmd/unpack.rb b/Library/Homebrew/cmd/unpack.rb index 51c2b59f0..aee4ea2eb 100644 --- a/Library/Homebrew/cmd/unpack.rb +++ b/Library/Homebrew/cmd/unpack.rb @@ -36,7 +36,7 @@ module Homebrew rm_rf stage_dir end - oh1 "Unpacking #{f.full_name} to: #{stage_dir}" + oh1 "Unpacking #{Formatter.identifier(f.full_name)} to: #{stage_dir}" ENV["VERBOSE"] = "1" # show messages about tar f.brew do diff --git a/Library/Homebrew/cmd/update-report.rb b/Library/Homebrew/cmd/update-report.rb index 98823a152..055c55a84 100644 --- a/Library/Homebrew/cmd/update-report.rb +++ b/Library/Homebrew/cmd/update-report.rb @@ -1,5 +1,5 @@ #: @hide_from_man_page -#: * `update_report`: +#: * `update_report` [`--preinstall`]: #: The Ruby implementation of `brew update`. Never called manually. require "formula_versions" diff --git a/Library/Homebrew/cmd/update.sh b/Library/Homebrew/cmd/update.sh index 609e4094a..747784527 100644 --- a/Library/Homebrew/cmd/update.sh +++ b/Library/Homebrew/cmd/update.sh @@ -410,9 +410,6 @@ EOS QUIET_ARGS=() fi - # ensure GIT_CONFIG is unset as we need to operate on .git/config - unset GIT_CONFIG - # only allow one instance of brew update lock update diff --git a/Library/Homebrew/cmd/upgrade.rb b/Library/Homebrew/cmd/upgrade.rb index de886ff3d..debd5eea2 100644 --- a/Library/Homebrew/cmd/upgrade.rb +++ b/Library/Homebrew/cmd/upgrade.rb @@ -1,5 +1,5 @@ #: * `upgrade` [<install-options>] [`--cleanup`] [`--fetch-HEAD`] [<formulae>]: -#: Upgrade outdated, unpinned brews. +#: Upgrade outdated, unpinned brews (with existing install options). #: #: Options for the `install` command are also valid here. #: @@ -25,13 +25,7 @@ module Homebrew Homebrew.perform_preinstall_checks - if ARGV.include?("--all") - opoo <<~EOS - We decided to not change the behaviour of `brew upgrade` so - `brew upgrade --all` is equivalent to `brew upgrade` without any other - arguments (so the `--all` is a no-op and can be removed). - EOS - end + odeprecated "'brew upgrade --all'", "'brew upgrade'" if ARGV.include?("--all") if ARGV.named.empty? outdated = Formula.installed.select do |f| @@ -56,11 +50,8 @@ module Homebrew exit 1 if outdated.empty? end - unless upgrade_pinned? - pinned = outdated.select(&:pinned?) - outdated -= pinned - end - + pinned = outdated.select(&:pinned?) + outdated -= pinned formulae_to_install = outdated.map(&:latest_formula) if formulae_to_install.empty? @@ -70,8 +61,8 @@ module Homebrew puts formulae_to_install.map { |f| "#{f.full_specified_name} #{f.pkg_version}" } * ", " end - unless upgrade_pinned? || pinned.empty? - oh1 "Not upgrading #{Formatter.pluralize(pinned.length, "pinned package")}:" + unless pinned.empty? + onoe "Not upgrading #{Formatter.pluralize(pinned.length, "pinned package")}:" puts pinned.map { |f| "#{f.full_specified_name} #{f.pkg_version}" } * ", " end @@ -89,17 +80,18 @@ module Homebrew formulae_to_install.each do |f| Migrator.migrate_if_needed(f) - upgrade_formula(f) - next unless ARGV.include?("--cleanup") - next unless f.installed? - Homebrew::Cleanup.cleanup_formula f + begin + upgrade_formula(f) + next unless ARGV.include?("--cleanup") + next unless f.installed? + Homebrew::Cleanup.cleanup_formula f + rescue UnsatisfiedRequirements => e + Homebrew.failed = true + onoe "#{f}: #{e}" + end end end - def upgrade_pinned? - !ARGV.named.empty? - end - def upgrade_formula(f) if f.opt_prefix.directory? keg = Keg.new(f.opt_prefix.resolved_path) @@ -119,19 +111,23 @@ module Homebrew tab = Tab.for_keg(keg) end + build_options = BuildOptions.new(Options.create(ARGV.flags_only), f.options) + options = build_options.used_options + options |= f.build.used_options + options &= f.options + fi = FormulaInstaller.new(f) - fi.options = f.build.used_options - fi.options &= f.options + fi.options = options fi.build_bottle = ARGV.build_bottle? || (!f.bottled? && f.build.build_bottle?) 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 fi.installed_as_dependency = tab.installed_as_dependency fi.installed_on_request ||= tab.installed_on_request end fi.prelude - oh1 "Upgrading #{f.full_specified_name} #{fi.options.to_a.join " "}" + oh1 "Upgrading #{Formatter.identifier(f.full_specified_name)} #{fi.options.to_a.join " "}" # first we unlink the currently active keg for this formula otherwise it is # possible for the existing build to interfere with the build we are about to @@ -140,13 +136,6 @@ module Homebrew fi.install fi.finish - - # If the formula was pinned, and we were force-upgrading it, unpin and - # pin it again to get a symlink pointing to the correct keg. - if f.pinned? - f.unpin - f.pin - end rescue FormulaInstallationAlreadyAttemptedError # We already attempted to upgrade f as part of the dependency tree of # another formula. In that case, don't generate an error, just move on. diff --git a/Library/Homebrew/cmd/uses.rb b/Library/Homebrew/cmd/uses.rb index 1688899f9..d5c9210f6 100644 --- a/Library/Homebrew/cmd/uses.rb +++ b/Library/Homebrew/cmd/uses.rb @@ -113,9 +113,7 @@ module Homebrew end end - reqs.any? do |req| - req.name == ff.name || [ff.name, ff.full_name].include?(req.default_formula) - end + reqs.any? { |req| req.name == ff.name } rescue FormulaUnavailableError # Silently ignore this case as we don't care about things used in # taps that aren't currently tapped. diff --git a/Library/Homebrew/cmd/vendor-install.sh b/Library/Homebrew/cmd/vendor-install.sh index bf6fe0c59..3b91dae5c 100644 --- a/Library/Homebrew/cmd/vendor-install.sh +++ b/Library/Homebrew/cmd/vendor-install.sh @@ -8,26 +8,26 @@ source "$HOMEBREW_LIBRARY/Homebrew/utils/lock.sh" VENDOR_DIR="$HOMEBREW_LIBRARY/Homebrew/vendor" -# Built from https://github.com/Homebrew/homebrew-portable. +# Built from https://github.com/Homebrew/homebrew-portable-ruby. if [[ -n "$HOMEBREW_MACOS" ]] then if [[ "$HOMEBREW_PROCESSOR" = "Intel" ]] then - ruby_URL="https://homebrew.bintray.com/bottles-portable/portable-ruby-2.3.3.leopard_64.bottle.1.tar.gz" + ruby_URL="https://homebrew.bintray.com/bottles-portable-ruby/portable-ruby-2.3.3.leopard_64.bottle.1.tar.gz" + ruby_URL2="https://github.com/Homebrew/homebrew-portable-ruby/releases/download/2.3.3/portable-ruby-2.3.3.leopard_64.bottle.1.tar.gz" ruby_SHA="34ce9e4c9c1be28db564d744165aa29291426f8a3d2ef806ba4f0b9175aedb2b" - else - ruby_URL="" - ruby_SHA="" fi elif [[ -n "$HOMEBREW_LINUX" ]] then case "$HOMEBREW_PROCESSOR" in armv7l) - ruby_URL="https://homebrew.bintray.com/bottles-portable/portable-ruby-2.3.3.armv7l_linux.bottle.1.tar.gz" + ruby_URL="https://homebrew.bintray.com/bottles-portable-ruby/portable-ruby-2.3.3.armv7l_linux.bottle.1.tar.gz" + ruby_URL2="https://github.com/Homebrew/homebrew-portable-ruby/releases/download/2.3.3/portable-ruby-2.3.3.armv7l_linux.bottle.1.tar.gz" ruby_SHA="d26affe6f6ac299557a9044b311b4066b554874fc828ebc323d2705d3f4a8249" ;; x86_64) - ruby_URL="https://homebrew.bintray.com/bottles-portable/portable-ruby-2.3.3.x86_64_linux.bottle.1.tar.gz" + ruby_URL="https://homebrew.bintray.com/bottles-portable-ruby/portable-ruby-2.3.3.x86_64_linux.bottle.1.tar.gz" + ruby_URL2="https://github.com/Homebrew/homebrew-portable-ruby/releases/download/2.3.3/portable-ruby-2.3.3.x86_64_linux.bottle.1.tar.gz" ruby_SHA="33643b1ca6f860d6df01686636326785763e5e81cf0cef37d8a7ab96a6ca1fa1" ;; esac @@ -90,7 +90,20 @@ fetch() { if [[ ! -f "$temporary_path" ]] then - odie "Download failed: $VENDOR_URL" + [[ -n "$HOMEBREW_QUIET" ]] || echo "==> Downloading $VENDOR_URL2" >&2 + "$HOMEBREW_CURL" "${curl_args[@]}" "$VENDOR_URL2" -o "$temporary_path" + fi + + if [[ ! -f "$temporary_path" ]] + then + odie <<EOS +Failed to download $VENDOR_URL and $VENDOR_URL2! + +Do not file an issue on GitHub about this: you will need to figure out for +yourself what issue with your internet connection restricts your access to +both Bintray (used for Homebrew bottles/binary packages) and GitHub +(used for Homebrew updates). +EOS fi trap '' SIGINT @@ -211,8 +224,10 @@ homebrew-vendor-install() { [[ -n "$HOMEBREW_DEBUG" ]] && set -x url_var="${VENDOR_NAME}_URL" + url2_var="${VENDOR_NAME}_URL2" sha_var="${VENDOR_NAME}_SHA" VENDOR_URL="${!url_var}" + VENDOR_URL2="${!url2_var}" VENDOR_SHA="${!sha_var}" if [[ -z "$VENDOR_URL" || -z "$VENDOR_SHA" ]] diff --git a/Library/Homebrew/compat.rb b/Library/Homebrew/compat.rb index 8b3d72ec7..6c3fa2dbb 100644 --- a/Library/Homebrew/compat.rb +++ b/Library/Homebrew/compat.rb @@ -3,6 +3,7 @@ require "compat/tap" require "compat/hbc" require "compat/formula" require "compat/formula_specialties" +require "compat/formula_support" require "compat/global" require "compat/hardware" require "compat/macos" @@ -27,3 +28,4 @@ require "compat/ENV/std" require "compat/ENV/super" require "compat/utils/shell" require "compat/extend/string" +require "compat/gpg" diff --git a/Library/Homebrew/compat/ARGV.rb b/Library/Homebrew/compat/ARGV.rb index e5fa8188f..e56c4e01f 100644 --- a/Library/Homebrew/compat/ARGV.rb +++ b/Library/Homebrew/compat/ARGV.rb @@ -1,6 +1,5 @@ module HomebrewArgvExtension def build_32_bit? - odeprecated "ARGV.build_32_bit?" - include? "--32-bit" + odisabled "ARGV.build_32_bit?" end end diff --git a/Library/Homebrew/compat/ENV/shared.rb b/Library/Homebrew/compat/ENV/shared.rb index c700b1e00..36ee45627 100644 --- a/Library/Homebrew/compat/ENV/shared.rb +++ b/Library/Homebrew/compat/ENV/shared.rb @@ -5,6 +5,6 @@ module SharedEnvExtension end def java_cache - # odeprecated "ENV.java_cache" + odeprecated "ENV.java_cache" end end diff --git a/Library/Homebrew/compat/ENV/std.rb b/Library/Homebrew/compat/ENV/std.rb index 26dabe440..beca4ed6f 100644 --- a/Library/Homebrew/compat/ENV/std.rb +++ b/Library/Homebrew/compat/ENV/std.rb @@ -1,27 +1,25 @@ module Stdenv def fast - odeprecated "ENV.fast" + odisabled "ENV.fast" end def O4 - odeprecated "ENV.O4" + odisabled "ENV.O4" end def Og - odeprecated "ENV.Og" + odisabled "ENV.Og" end def gcc_4_0_1 - odeprecated "ENV.gcc_4_0_1", "ENV.gcc_4_0" - gcc_4_0 + odisabled "ENV.gcc_4_0_1", "ENV.gcc_4_0" end def gcc - odeprecated "ENV.gcc", "ENV.gcc_4_2" - gcc_4_2 + odisabled "ENV.gcc", "ENV.gcc_4_2" end def libpng - odeprecated "ENV.libpng", "ENV.x11" + odisabled "ENV.libpng", "ENV.x11" end end diff --git a/Library/Homebrew/compat/ENV/super.rb b/Library/Homebrew/compat/ENV/super.rb index 2020ad752..53a6bdc4d 100644 --- a/Library/Homebrew/compat/ENV/super.rb +++ b/Library/Homebrew/compat/ENV/super.rb @@ -1,47 +1,45 @@ module Superenv def fast - odeprecated "ENV.fast" + odisabled "ENV.fast" end def O4 - odeprecated "ENV.O4" + odisabled "ENV.O4" end def Og - odeprecated "ENV.Og" + odisabled "ENV.Og" end def gcc_4_0_1 - odeprecated "ENV.gcc_4_0_1", "ENV.gcc_4_0" - gcc_4_0 + odisabled "ENV.gcc_4_0_1", "ENV.gcc_4_0" end def gcc - odeprecated "ENV.gcc", "ENV.gcc_4_2" - gcc_4_2 + odisabled "ENV.gcc", "ENV.gcc_4_2" end def libxml2 - odeprecated "ENV.libxml2" + odisabled "ENV.libxml2" end def minimal_optimization - odeprecated "ENV.minimal_optimization" + odisabled "ENV.minimal_optimization" end def no_optimization - odeprecated "ENV.no_optimization" + odisabled "ENV.no_optimization" end def enable_warnings - odeprecated "ENV.enable_warnings" + odisabled "ENV.enable_warnings" end def macosxsdk - odeprecated "ENV.macosxsdk" + odisabled "ENV.macosxsdk" end def remove_macosxsdk - odeprecated "ENV.remove_macosxsdk" + odisabled "ENV.remove_macosxsdk" end end diff --git a/Library/Homebrew/compat/build_options.rb b/Library/Homebrew/compat/build_options.rb index 73722dadb..6e566a08c 100644 --- a/Library/Homebrew/compat/build_options.rb +++ b/Library/Homebrew/compat/build_options.rb @@ -1,11 +1,9 @@ class BuildOptions def build_32_bit? - odeprecated "build.build_32_bit?" - include?("32-bit") && option_defined?("32-bit") + odisabled "build.build_32_bit?" end def build_bottle? - odeprecated "build.build_bottle?", "build.bottle?" - bottle? + odisabled "build.build_bottle?", "build.bottle?" end end diff --git a/Library/Homebrew/compat/dependency_collector.rb b/Library/Homebrew/compat/dependency_collector.rb index fbcf1c2a0..84d5431f3 100644 --- a/Library/Homebrew/compat/dependency_collector.rb +++ b/Library/Homebrew/compat/dependency_collector.rb @@ -1,42 +1,82 @@ require "dependency_collector" class DependencyCollector - alias _parse_symbol_spec parse_symbol_spec + module Compat + # Define the languages that we can handle as external dependencies. + LANGUAGE_MODULES = Set[ + :lua, :lua51, :perl, :python, :python3, :ruby + ].freeze - def parse_symbol_spec(spec, tags) - case spec - when :clt - odeprecated "'depends_on :clt'" - when :autoconf, :automake, :bsdmake, :libtool - output_deprecation(spec, tags) - autotools_dep(spec, tags) - when :cairo, :fontconfig, :freetype, :libpng, :pixman - output_deprecation(spec, tags) - Dependency.new(spec.to_s, tags) - when :apr - # output_deprecation(spec, tags, "apr-util") - Dependency.new("apr-util", tags) - when :libltdl - tags << :run - output_deprecation("libtool", tags) - Dependency.new("libtool", tags) - else - _parse_symbol_spec(spec, tags) + def parse_string_spec(spec, tags) + if (tag = tags.first) && LANGUAGE_MODULES.include?(tag) + odeprecated "'depends_on ... => #{tag.inspect}'" + LanguageModuleRequirement.new(tag, spec, tags[1]) + else + super + end end - end - def autotools_dep(spec, tags) - tags << :build unless tags.include? :run - Dependency.new(spec.to_s, tags) - end + def parse_symbol_spec(spec, tags) + case spec + when :clt + odeprecated "'depends_on :clt'" + when :tex + odeprecated "'depends_on :tex'" + TeXRequirement.new(tags) + when :autoconf, :automake, :bsdmake, :libtool + output_deprecation(spec) + autotools_dep(spec, tags) + when :cairo, :fontconfig, :freetype, :libpng, :pixman + output_deprecation(spec) + Dependency.new(spec.to_s, tags) + when :ant, :expat + output_deprecation(spec) + Dependency.new(spec.to_s, tags) + when :libltdl + tags << :run + output_deprecation("libtool") + Dependency.new("libtool", tags) + when :apr + output_deprecation(spec, "apr-util") + Dependency.new("apr-util", tags) + when :fortran + output_deprecation(spec, "gcc") + Dependency.new("gcc", tags) + when :gpg + output_deprecation(spec, "gnupg") + Dependency.new("gnupg", tags) + when :hg + output_deprecation(spec, "mercurial") + Dependency.new("mercurial", tags) + when :mpi + output_deprecation(spec, "open-mpi") + Dependency.new("open-mpi", tags) + when :python, :python2 + output_deprecation(spec, "python") + Dependency.new("python", tags) + when :python3 + output_deprecation(spec, "python3") + Dependency.new("python3", tags) + when :emacs, :mysql, :perl, :postgresql, :rbenv, :ruby + output_deprecation(spec) + Dependency.new(spec, tags) + else + super + end + end + + private - def output_deprecation(dependency, tags, new_dependency = dependency) - tags_string = if tags.length > 1 - " => [:#{tags.join ", :"}]" - elsif tags.length == 1 - " => :#{tags.first}" + def autotools_dep(spec, tags) + tags << :build unless tags.include? :run + Dependency.new(spec.to_s, tags) + end + + def output_deprecation(dependency, new_dependency = dependency) + odeprecated "'depends_on :#{dependency}'", + "'depends_on \"#{new_dependency}\"'" end - odeprecated "'depends_on :#{dependency}'", - "'depends_on \"#{new_dependency}\"#{tags_string}'" end + + prepend Compat end diff --git a/Library/Homebrew/compat/extend/string.rb b/Library/Homebrew/compat/extend/string.rb index 6069a6bec..9d1f66557 100644 --- a/Library/Homebrew/compat/extend/string.rb +++ b/Library/Homebrew/compat/extend/string.rb @@ -1,5 +1,6 @@ class String def undent + odeprecated "<<-EOS.undent", "<<~EOS" gsub(/^[ \t]{#{(slice(/^[ \t]+/) || '').length}}/, "") end alias unindent undent diff --git a/Library/Homebrew/compat/fails_with_llvm.rb b/Library/Homebrew/compat/fails_with_llvm.rb index 4e8b94b03..47bda4e0b 100644 --- a/Library/Homebrew/compat/fails_with_llvm.rb +++ b/Library/Homebrew/compat/fails_with_llvm.rb @@ -1,9 +1,9 @@ class Formula def fails_with_llvm(_msg = nil, _data = nil) - odeprecated "Formula#fails_with_llvm in install" + odisabled "Formula#fails_with_llvm in install" end def self.fails_with_llvm(_msg = nil, _data = {}) - odeprecated "Formula.fails_with_llvm" + odisabled "Formula.fails_with_llvm" end end diff --git a/Library/Homebrew/compat/formula.rb b/Library/Homebrew/compat/formula.rb index 57ab84a76..6f740710d 100644 --- a/Library/Homebrew/compat/formula.rb +++ b/Library/Homebrew/compat/formula.rb @@ -1,12 +1,10 @@ module FormulaCompat def x11_installed? - odeprecated "Formula#x11_installed?", "MacOS::X11.installed?" - MacOS::X11.installed? + odisabled "Formula#x11_installed?", "MacOS::X11.installed?" end def snow_leopard_64? - odeprecated "Formula#snow_leopard_64?", "MacOS.prefer_64_bit?" - MacOS.prefer_64_bit? + odisabled "Formula#snow_leopard_64?", "MacOS.prefer_64_bit?" end end @@ -15,48 +13,40 @@ class Formula extend FormulaCompat def std_cmake_parameters - odeprecated "Formula#std_cmake_parameters", "Formula#std_cmake_args" - "-DCMAKE_INSTALL_PREFIX='#{prefix}' -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev" + odisabled "Formula#std_cmake_parameters", "Formula#std_cmake_args" end - def cxxstdlib_check(check_type) - odeprecated "Formula#cxxstdlib_check in install", - "Formula.cxxstdlib_check outside install" - self.class.cxxstdlib_check check_type + def cxxstdlib_check(_) + odisabled "Formula#cxxstdlib_check in install", + "Formula.cxxstdlib_check outside install" end def self.bottle_sha1(*) - odeprecated "Formula.bottle_sha1" + odisabled "Formula.bottle_sha1" end def self.all - odeprecated "Formula.all", "Formula.map" - map + odisabled "Formula.all", "Formula.map" end - def self.canonical_name(name) - odeprecated "Formula.canonical_name", "Formulary.canonical_name" - Formulary.canonical_name(name) + def self.canonical_name(_) + odisabled "Formula.canonical_name", "Formulary.canonical_name" end - def self.class_s(name) - odeprecated "Formula.class_s", "Formulary.class_s" - Formulary.class_s(name) + def self.class_s(_) + odisabled "Formula.class_s", "Formulary.class_s" end - def self.factory(name) - odeprecated "Formula.factory", "Formulary.factory" - Formulary.factory(name) + def self.factory(_) + odisabled "Formula.factory", "Formulary.factory" end def self.require_universal_deps - odeprecated "Formula.require_universal_deps" - define_method(:require_universal_deps?) { true } + odisabled "Formula.require_universal_deps" end - def self.path(name) - odeprecated "Formula.path", "Formulary.core_path" - Formulary.core_path(name) + def self.path(_) + odisabled "Formula.path", "Formulary.core_path" end DATA = :DATA @@ -67,20 +57,18 @@ class Formula {} end - def python(_options = {}, &_block) - odeprecated "Formula#python" - yield if block_given? - PythonRequirement.new + def python(_options = {}, &_) + odisabled "Formula#python" end alias python2 python alias python3 python def startup_plist - odeprecated "Formula#startup_plist", "Formula#plist" + odisabled "Formula#startup_plist", "Formula#plist" end def rake(*args) - # odeprecated "FileUtils#rake", "system \"rake\"" + odeprecated "FileUtils#rake", "system \"rake\"" system "rake", *args end end diff --git a/Library/Homebrew/compat/formula_specialties.rb b/Library/Homebrew/compat/formula_specialties.rb index 3f8102575..bc4d20bea 100644 --- a/Library/Homebrew/compat/formula_specialties.rb +++ b/Library/Homebrew/compat/formula_specialties.rb @@ -1,47 +1,23 @@ class ScriptFileFormula < Formula def install - odeprecated "ScriptFileFormula#install", "Formula#install" - bin.install Dir["*"] + odisabled "ScriptFileFormula#install", "Formula#install" end end class GithubGistFormula < ScriptFileFormula - def self.url(val) - odeprecated "GithubGistFormula.url", "Formula.url" - super - version File.basename(File.dirname(val))[0, 6] + def self.url(_val) + odisabled "GithubGistFormula.url", "Formula.url" end end -# This formula serves as the base class for several very similar -# formulae for Amazon Web Services related tools. class AmazonWebServicesFormula < Formula - # Use this method to perform a standard install for Java-based tools, - # keeping the .jars out of HOMEBREW_PREFIX/lib def install - odeprecated "AmazonWebServicesFormula#install", "Formula#install" - - rm Dir["bin/*.cmd"] # Remove Windows versions - libexec.install Dir["*"] - bin.install_symlink Dir["#{libexec}/bin/*"] - ["#{libexec}/bin/service"] + odisabled "AmazonWebServicesFormula#install", "Formula#install" end alias standard_install install # Use this method to generate standard caveats. - def standard_instructions(home_name, home_value = libexec) - odeprecated "AmazonWebServicesFormula#standard_instructions", "Formula#caveats" - - <<~EOS - Before you can use these tools you must export some variables to your $SHELL. - - To export the needed variables, add them to your dotfiles. - * On Bash, add them to `~/.bash_profile`. - * On Zsh, add them to `~/.zprofile` instead. - - export JAVA_HOME="$(/usr/libexec/java_home)" - export AWS_ACCESS_KEY="<Your AWS Access ID>" - export AWS_SECRET_KEY="<Your AWS Secret Key>" - export #{home_name}="#{home_value}" - EOS + def standard_instructions(_, _) + odisabled "AmazonWebServicesFormula#standard_instructions", "Formula#caveats" end end diff --git a/Library/Homebrew/compat/formula_support.rb b/Library/Homebrew/compat/formula_support.rb new file mode 100644 index 000000000..9cb8d8ff1 --- /dev/null +++ b/Library/Homebrew/compat/formula_support.rb @@ -0,0 +1,20 @@ +require "formula_support" + +class KegOnlyReason + module Compat + def to_s + case @reason + when :provided_by_osx + odeprecated "keg_only :provided_by_osx", "keg_only :provided_by_macos" + @reason = :provided_by_macos + when :shadowed_by_osx + odeprecated "keg_only :shadowed_by_osx", "keg_only :shadowed_by_macos" + @reason = :shadowed_by_macos + end + + super + end + end + + prepend Compat +end diff --git a/Library/Homebrew/compat/global.rb b/Library/Homebrew/compat/global.rb index 82c452cc0..9c8f0624c 100644 --- a/Library/Homebrew/compat/global.rb +++ b/Library/Homebrew/compat/global.rb @@ -3,8 +3,7 @@ module Homebrew def method_missing(method, *args, &block) if instance_methods.include?(method) - odeprecated "#{self}##{method}", "'module_function' or 'def self.#{method}' to convert it to a class method" - return instance_method(method).bind(self).call(*args, &block) + odisabled "#{self}##{method}", "'module_function' or 'def self.#{method}' to convert it to a class method" end super end diff --git a/Library/Homebrew/compat/gpg.rb b/Library/Homebrew/compat/gpg.rb new file mode 100644 index 000000000..e802d939c --- /dev/null +++ b/Library/Homebrew/compat/gpg.rb @@ -0,0 +1,27 @@ +require "utils" + +module Gpg + module_function + + def executable + odeprecated "Gpg.executable", 'which "gpg"' + which "gpg" + end + + def available? + odeprecated "Gpg.available?", 'which "gpg"' + File.executable?(executable.to_s) + end + + def create_test_key(_) + odeprecated "Gpg.create_test_key" + end + + def cleanup_test_processes! + odeprecated "Gpg.cleanup_test_processes!" + end + + def test(_) + odeprecated "Gpg.test" + end +end diff --git a/Library/Homebrew/compat/hardware.rb b/Library/Homebrew/compat/hardware.rb index 07a63f048..28bc79c60 100644 --- a/Library/Homebrew/compat/hardware.rb +++ b/Library/Homebrew/compat/hardware.rb @@ -1,43 +1,35 @@ module Hardware class << self def is_32_bit? - odeprecated "Hardware.is_32_bit?", "Hardware::CPU.is_32_bit?" - !CPU.is_64_bit? + odisabled "Hardware.is_32_bit?", "Hardware::CPU.is_32_bit?" end def is_64_bit? - odeprecated "Hardware.is_64_bit?", "Hardware::CPU.is_64_bit?" - CPU.is_64_bit? + odisabled "Hardware.is_64_bit?", "Hardware::CPU.is_64_bit?" end def bits - odeprecated "Hardware.bits", "Hardware::CPU.bits" - Hardware::CPU.bits + odisabled "Hardware.bits", "Hardware::CPU.bits" end def cpu_type - odeprecated "Hardware.cpu_type", "Hardware::CPU.type" - Hardware::CPU.type + odisabled "Hardware.cpu_type", "Hardware::CPU.type" end def cpu_family - odeprecated "Hardware.cpu_family", "Hardware::CPU.family" - Hardware::CPU.family + odisabled "Hardware.cpu_family", "Hardware::CPU.family" end def intel_family - odeprecated "Hardware.intel_family", "Hardware::CPU.family" - Hardware::CPU.family + odisabled "Hardware.intel_family", "Hardware::CPU.family" end def ppc_family - odeprecated "Hardware.ppc_family", "Hardware::CPU.family" - Hardware::CPU.family + odisabled "Hardware.ppc_family", "Hardware::CPU.family" end def processor_count - odeprecated "Hardware.processor_count", "Hardware::CPU.cores" - Hardware::CPU.cores + odisabled "Hardware.processor_count", "Hardware::CPU.cores" end end end diff --git a/Library/Homebrew/compat/hbc.rb b/Library/Homebrew/compat/hbc.rb index ebf8a9874..608d46e37 100644 --- a/Library/Homebrew/compat/hbc.rb +++ b/Library/Homebrew/compat/hbc.rb @@ -4,7 +4,6 @@ require "compat/hbc/cache" require "compat/hbc/caskroom" require "compat/hbc/cli" require "compat/hbc/dsl" -require "compat/hbc/system_command" module Hbc class << self diff --git a/Library/Homebrew/compat/hbc/cli.rb b/Library/Homebrew/compat/hbc/cli.rb index 60d298ed6..fb17a1d05 100644 --- a/Library/Homebrew/compat/hbc/cli.rb +++ b/Library/Homebrew/compat/hbc/cli.rb @@ -11,9 +11,8 @@ module Hbc EOS end) - option "--caskroom=PATH", (lambda do |value| - Hbc.caskroom = value - odeprecated "`brew cask` with the `--caskroom` flag", disable_on: Time.utc(2017, 10, 31) + option "--caskroom=PATH", (lambda do |*| + odisabled "`brew cask` with the `--caskroom` flag" end) end end diff --git a/Library/Homebrew/compat/hbc/system_command.rb b/Library/Homebrew/compat/hbc/system_command.rb deleted file mode 100644 index bb9187db3..000000000 --- a/Library/Homebrew/compat/hbc/system_command.rb +++ /dev/null @@ -1,18 +0,0 @@ -require "shellwords" - -module SystemCommandCompatibilityLayer - def initialize(executable, args: [], **options) - if args.empty? && !File.exist?(executable) - odeprecated "`system_command` with a shell string", "`system_command` with the `args` parameter" - executable, *args = Shellwords.shellsplit(executable) - end - - super(executable, args: args, **options) - end -end - -module Hbc - class SystemCommand - prepend SystemCommandCompatibilityLayer - end -end diff --git a/Library/Homebrew/compat/json.rb b/Library/Homebrew/compat/json.rb index c8bf1c292..18763b8a6 100644 --- a/Library/Homebrew/compat/json.rb +++ b/Library/Homebrew/compat/json.rb @@ -4,34 +4,16 @@ module Utils module JSON module_function - Error = Class.new(StandardError) - - def load(str) - odeprecated "Utils::JSON.load", "JSON.parse" - ::JSON.parse(str) - rescue ::JSON::ParserError => e - raise Error, e.message + def load(_) + odisabled "Utils::JSON.load", "JSON.parse" end - def dump(obj) - odeprecated "Utils::JSON.dump", "JSON.generate" - ::JSON.generate(obj) + def dump(_) + odisabled "Utils::JSON.dump", "JSON.generate" end - def stringify_keys(obj) - odeprecated "Utils::JSON.stringify_keys" - case obj - when Array - obj.map { |val| stringify_keys(val) } - when Hash - obj.inject({}) do |result, (key, val)| - key = key.respond_to?(:to_s) ? key.to_s : key - val = stringify_keys(val) - result.merge!(key => val) - end - else - obj - end + def stringify_keys(_) + odisabled "Utils::JSON.stringify_keys" end end end diff --git a/Library/Homebrew/compat/keg.rb b/Library/Homebrew/compat/keg.rb index 8f5606d09..81e1cf0b3 100644 --- a/Library/Homebrew/compat/keg.rb +++ b/Library/Homebrew/compat/keg.rb @@ -1,6 +1,5 @@ class Keg def fname - odeprecated "Keg#fname", "Keg#name" - name + odisabled "Keg#fname", "Keg#name" end end diff --git a/Library/Homebrew/compat/language/haskell.rb b/Library/Homebrew/compat/language/haskell.rb index cef97d818..8e5059874 100644 --- a/Library/Homebrew/compat/language/haskell.rb +++ b/Library/Homebrew/compat/language/haskell.rb @@ -2,8 +2,7 @@ module Language module Haskell module Cabal def cabal_clean_lib - odeprecated "Language::Haskell::Cabal#cabal_clean_lib" - rm_rf lib + odisabled "Language::Haskell::Cabal#cabal_clean_lib" end end end diff --git a/Library/Homebrew/compat/macos.rb b/Library/Homebrew/compat/macos.rb index 1f2c651c5..879af8357 100644 --- a/Library/Homebrew/compat/macos.rb +++ b/Library/Homebrew/compat/macos.rb @@ -10,142 +10,115 @@ module OS module_function def xcode_folder - odeprecated "MacOS.xcode_folder", "MacOS::Xcode.folder" - Xcode.folder + odisabled "MacOS.xcode_folder", "MacOS::Xcode.folder" end def xcode_prefix - odeprecated "MacOS.xcode_prefix", "MacOS::Xcode.prefix" - Xcode.prefix + odisabled "MacOS.xcode_prefix", "MacOS::Xcode.prefix" end def xcode_installed? - odeprecated "MacOS.xcode_installed?", "MacOS::Xcode.installed?" - Xcode.installed? + odisabled "MacOS.xcode_installed?", "MacOS::Xcode.installed?" end def xcode_version - odeprecated "MacOS.xcode_version", "MacOS::Xcode.version" - Xcode.version + odisabled "MacOS.xcode_version", "MacOS::Xcode.version" end def clt_installed? - odeprecated "MacOS.clt_installed?", "MacOS::CLT.installed?" - CLT.installed? + odisabled "MacOS.clt_installed?", "MacOS::CLT.installed?" end def clt_version? - odeprecated "MacOS.clt_version?", "MacOS::CLT.version" - CLT.version + odisabled "MacOS.clt_version?", "MacOS::CLT.version" end def x11_installed? - odeprecated "MacOS.x11_installed?", "MacOS::X11.installed?" - X11.installed? + odisabled "MacOS.x11_installed?", "MacOS::X11.installed?" end def x11_prefix - odeprecated "MacOS.x11_prefix", "MacOS::X11.prefix" - X11.prefix + odisabled "MacOS.x11_prefix", "MacOS::X11.prefix" end def leopard? - odeprecated "MacOS.leopard?", "'MacOS.version == :leopard'" - version == :leopard + odisabled "MacOS.leopard?", "'MacOS.version == :leopard'" end def snow_leopard? - odeprecated "MacOS.snow_leopard?", "'MacOS.version >= :snow_leopard'" - version >= :snow_leopard + odisabled "MacOS.snow_leopard?", "'MacOS.version >= :snow_leopard'" end def snow_leopard_or_newer? - odeprecated "MacOS.snow_leopard_or_newer?", "'MacOS.version >= :snow_leopard'" - version >= :snow_leopard + odisabled "MacOS.snow_leopard_or_newer?", "'MacOS.version >= :snow_leopard'" end def lion? - odeprecated "MacOS.lion?", "'MacOS.version >= :lion'" - version >= :lion + odisabled "MacOS.lion?", "'MacOS.version >= :lion'" end def lion_or_newer? - odeprecated "MacOS.lion_or_newer?", "'MacOS.version >= :lion'" - version >= :lion + odisabled "MacOS.lion_or_newer?", "'MacOS.version >= :lion'" end def mountain_lion? - odeprecated "MacOS.mountain_lion?", "'MacOS.version >= :mountain_lion'" - version >= :mountain_lion + odisabled "MacOS.mountain_lion?", "'MacOS.version >= :mountain_lion'" end def mountain_lion_or_newer? - odeprecated "MacOS.mountain_lion_or_newer?", "'MacOS.version >= :mountain_lion'" - version >= :mountain_lion + odisabled "MacOS.mountain_lion_or_newer?", "'MacOS.version >= :mountain_lion'" end def macports_or_fink_installed? - odeprecated "MacOS.macports_or_fink_installed?", "!MacOS.macports_or_fink.empty?" - !macports_or_fink.empty? + odisabled "MacOS.macports_or_fink_installed?", "!MacOS.macports_or_fink.empty?" end - def locate(tool) - odeprecated "MacOS.locate", "DevelopmentTools.locate" - DevelopmentTools.locate(tool) + def locate(_) + odisabled "MacOS.locate", "DevelopmentTools.locate" end def default_cc - odeprecated "MacOS.default_cc", "DevelopmentTools.default_cc" - DevelopmentTools.default_cc + odisabled "MacOS.default_cc", "DevelopmentTools.default_cc" end def default_compiler - odeprecated "MacOS.default_compiler", "DevelopmentTools.default_compiler" - DevelopmentTools.default_compiler + odisabled "MacOS.default_compiler", "DevelopmentTools.default_compiler" end def gcc_40_build_version - odeprecated "MacOS.gcc_40_build_version", "DevelopmentTools.gcc_4_0_build_version" - DevelopmentTools.gcc_4_0_build_version + odisabled "MacOS.gcc_40_build_version", "DevelopmentTools.gcc_4_0_build_version" end def gcc_4_0_build_version - odeprecated "MacOS.gcc_4_0_build_version", "DevelopmentTools.gcc_4_0_build_version" - DevelopmentTools.gcc_4_0_build_version + odisabled "MacOS.gcc_4_0_build_version", "DevelopmentTools.gcc_4_0_build_version" end def gcc_42_build_version - odeprecated "MacOS.gcc_42_build_version", "DevelopmentTools.gcc_4_2_build_version" - DevelopmentTools.gcc_4_2_build_version + odisabled "MacOS.gcc_42_build_version", "DevelopmentTools.gcc_4_2_build_version" end def gcc_build_version - odeprecated "MacOS.gcc_build_version", "DevelopmentTools.gcc_4_2_build_version" - DevelopmentTools.gcc_4_2_build_version + odisabled "MacOS.gcc_build_version", "DevelopmentTools.gcc_4_2_build_version" end def llvm_build_version - odeprecated "MacOS.llvm_build_version" + odisabled "MacOS.llvm_build_version" end def clang_version - odeprecated "MacOS.clang_version", "DevelopmentTools.clang_version" - DevelopmentTools.clang_version + odisabled "MacOS.clang_version", "DevelopmentTools.clang_version" end def clang_build_version - odeprecated "MacOS.clang_build_version", "DevelopmentTools.clang_build_version" - DevelopmentTools.clang_build_version + odisabled "MacOS.clang_build_version", "DevelopmentTools.clang_build_version" end def has_apple_developer_tools? - odeprecated "MacOS.has_apple_developer_tools?", "DevelopmentTools.installed?" - DevelopmentTools.installed? + odisabled "MacOS.has_apple_developer_tools?", "DevelopmentTools.installed?" end def release - odeprecated "MacOS.release", "MacOS.version" - version + odisabled "MacOS.release", "MacOS.version" end end end diff --git a/Library/Homebrew/compat/pathname.rb b/Library/Homebrew/compat/pathname.rb index 58888f017..df4b261a9 100644 --- a/Library/Homebrew/compat/pathname.rb +++ b/Library/Homebrew/compat/pathname.rb @@ -1,17 +1,9 @@ class Pathname - def cp(dst) - odeprecated "Pathname#cp", "FileUtils.cp" - if file? - FileUtils.cp to_s, dst - else - FileUtils.cp_r to_s, dst - end - dst + def cp(_) + odisabled "Pathname#cp", "FileUtils.cp" end - def chmod_R(perms) - odeprecated "Pathname#chmod_R", "FileUtils.chmod_R" - require "fileutils" - FileUtils.chmod_R perms, to_s + def chmod_R(_) + odisabled "Pathname#chmod_R", "FileUtils.chmod_R" end end diff --git a/Library/Homebrew/compat/requirements.rb b/Library/Homebrew/compat/requirements.rb index 3886cd7c7..38344c1fc 100644 --- a/Library/Homebrew/compat/requirements.rb +++ b/Library/Homebrew/compat/requirements.rb @@ -1,20 +1,134 @@ require "requirements" +require "compat/requirements/language_module_requirement" -XcodeDependency = XcodeRequirement -MysqlDependency = MysqlRequirement -PostgresqlDependency = PostgresqlRequirement -GPGDependency = GPG2Requirement -GPGRequirement = GPG2Requirement -TeXDependency = TeXRequirement -MercurialDependency = MercurialRequirement -GitDependency = GitRequirement -FortranDependency = FortranRequirement -JavaDependency = JavaRequirement -LanguageModuleDependency = LanguageModuleRequirement -MPIDependency = MPIRequirement -OsxfuseDependency = OsxfuseRequirement -PythonDependency = PythonRequirement -TuntapDependency = TuntapRequirement -X11Dependency = X11Requirement -ConflictsWithBinaryOsxfuse = NonBinaryOsxfuseRequirement -MinimumMacOSRequirement = MacOSRequirement +class CVSRequirement < Requirement + fatal true + satisfy do + odeprecated("CVSRequirement", "'depends_on \"cvs\"'") + which "cvs" + end +end + +class EmacsRequirement < Requirement + fatal true + satisfy do + odeprecated("EmacsRequirement", "'depends_on \"emacs\"'") + which "emacs" + end +end + +class FortranRequirement < Requirement + fatal true + satisfy do + odeprecated("FortranRequirement", "'depends_on \"gcc\"'") + which "gfortran" + end +end + +class GitRequirement < Requirement + fatal true + satisfy do + odeprecated("GitRequirement", "'depends_on \"git\"'") + which "git" + end +end + +class GPG2Requirement < Requirement + fatal true + satisfy do + odeprecated("GPG2Requirement", "'depends_on \"gnupg\"'") + which "gpg" + end +end + +class MercurialRequirement < Requirement + fatal true + satisfy do + odeprecated("MercurialRequirement", "'depends_on \"mercurial\"'") + which "hg" + end +end + +class MPIRequirement < Requirement + fatal true + satisfy do + odeprecated("MPIRequirement", "'depends_on \"open-mpi\"'") + which "mpicc" + end +end + +class MysqlRequirement < Requirement + fatal true + satisfy do + odeprecated("MysqlRequirement", "'depends_on \"mysql\"'") + which "mysql_config" + end +end + +class PerlRequirement < Requirement + fatal true + satisfy do + odeprecated("PerlRequirement", "'depends_on \"perl\"'") + which "perl" + end +end + +class PostgresqlRequirement < Requirement + fatal true + satisfy do + odeprecated("PostgresqlRequirement", "'depends_on \"postgresql\"'") + which "pg_config" + end +end + +class PythonRequirement < Requirement + fatal true + satisfy do + odeprecated("PythonRequirement", "'depends_on \"python\"'") + which "python" + end +end + +class Python3Requirement < Requirement + fatal true + satisfy do + odeprecated("Python3Requirement", "'depends_on \"python3\"'") + which "python3" + end +end + +class RbenvRequirement < Requirement + fatal true + satisfy do + odeprecated("RbenvRequirement", "'depends_on \"rbenv\"'") + which "rbenv" + end +end + +class RubyRequirement < Requirement + fatal true + satisfy do + odeprecated("RubyRequirement", "'depends_on \"ruby\"'") + which "ruby" + end +end + +class SubversionRequirement < Requirement + fatal true + satisfy do + odeprecated("SubversionRequirement", "'depends_on \"subversion\"'") + which "svn" + end +end + +class TeXRequirement < Requirement + fatal true + cask "mactex" + download "https://www.tug.org/mactex/" + satisfy do + odeprecated("TeXRequirement") + which("tex") || which("latex") + end +end + +MinimumMacOSRequirement = MacOSRequirement diff --git a/Library/Homebrew/requirements/language_module_requirement.rb b/Library/Homebrew/compat/requirements/language_module_requirement.rb index 5ddce7a66..5ddce7a66 100644 --- a/Library/Homebrew/requirements/language_module_requirement.rb +++ b/Library/Homebrew/compat/requirements/language_module_requirement.rb diff --git a/Library/Homebrew/compat/software_spec.rb b/Library/Homebrew/compat/software_spec.rb index 8b0408d02..814c00fa8 100644 --- a/Library/Homebrew/compat/software_spec.rb +++ b/Library/Homebrew/compat/software_spec.rb @@ -1,6 +1,5 @@ class BottleSpecification - def revision(*args) - odeprecated "BottleSpecification.revision", "BottleSpecification.rebuild" - rebuild(*args) + def revision(*) + odisabled "BottleSpecification.revision", "BottleSpecification.rebuild" end end diff --git a/Library/Homebrew/compat/tab.rb b/Library/Homebrew/compat/tab.rb index 2cf71c923..651bcf1e1 100644 --- a/Library/Homebrew/compat/tab.rb +++ b/Library/Homebrew/compat/tab.rb @@ -1,6 +1,5 @@ class Tab < OpenStruct def build_32_bit? - odeprecated "Tab.build_32_bit?" - include?("32-bit") + odisabled "Tab.build_32_bit?" end end diff --git a/Library/Homebrew/compat/tap.rb b/Library/Homebrew/compat/tap.rb index 37b1eeac1..a1e3ce172 100644 --- a/Library/Homebrew/compat/tap.rb +++ b/Library/Homebrew/compat/tap.rb @@ -2,7 +2,6 @@ require "tap" class Tap def core_formula_repository? - odeprecated "Tap#core_formula_repository?", "Tap#core_tap?" - core_tap? + odisabled "Tap#core_formula_repository?", "Tap#core_tap?" end end diff --git a/Library/Homebrew/compat/utils.rb b/Library/Homebrew/compat/utils.rb index 8904f0f2b..f83d07599 100644 --- a/Library/Homebrew/compat/utils.rb +++ b/Library/Homebrew/compat/utils.rb @@ -2,17 +2,14 @@ module Tty module_function def white - odeprecated "Tty.white", "Tty.reset.bold" - reset.bold + odisabled "Tty.white", "Tty.reset.bold" end end -def puts_columns(items) - odeprecated "puts_columns", "puts Formatter.columns" - puts Formatter.columns(items) +def puts_columns(_) + odisabled "puts_columns", "puts Formatter.columns" end -def plural(n, s = "s") - odeprecated "#plural", "Formatter.pluralize" - (n == 1) ? "" : s +def plural(_, _) + odisabled "#plural", "Formatter.pluralize" end diff --git a/Library/Homebrew/compat/utils/shell.rb b/Library/Homebrew/compat/utils/shell.rb index 161f10ebb..2f387d967 100644 --- a/Library/Homebrew/compat/utils/shell.rb +++ b/Library/Homebrew/compat/utils/shell.rb @@ -1,8 +1,7 @@ module Utils module Shell def self.shell_profile - odeprecated "Utils::Shell.shell_profile", "Utils::Shell.profile" - Utils::Shell.profile + odisabled "Utils::Shell.shell_profile", "Utils::Shell.profile" end end end diff --git a/Library/Homebrew/compat/version.rb b/Library/Homebrew/compat/version.rb index 2dd089015..4a6fd7ace 100644 --- a/Library/Homebrew/compat/version.rb +++ b/Library/Homebrew/compat/version.rb @@ -1,6 +1,5 @@ class Version - def slice(*args) - odeprecated "Version#slice", "Version#to_s.slice" - to_s.slice(*args) + def slice(*) + odisabled "Version#slice", "Version#to_s.slice" end end diff --git a/Library/Homebrew/compat/xcode.rb b/Library/Homebrew/compat/xcode.rb index 14150cc7c..f212ada64 100644 --- a/Library/Homebrew/compat/xcode.rb +++ b/Library/Homebrew/compat/xcode.rb @@ -4,8 +4,7 @@ module OS module_function def provides_autotools? - odeprecated "OS::Mac::Xcode.provides_autotools?" - version < "4.3" + odisabled "OS::Mac::Xcode.provides_autotools?" end end end diff --git a/Library/Homebrew/constants.rb b/Library/Homebrew/constants.rb index 529c49feb..9514320ab 100644 --- a/Library/Homebrew/constants.rb +++ b/Library/Homebrew/constants.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true # RuboCop version used for `brew style` and `brew cask style` -HOMEBREW_RUBOCOP_VERSION = "0.51.0" -HOMEBREW_RUBOCOP_CASK_VERSION = "~> 0.15.1" # has to be updated when RuboCop version changes +HOMEBREW_RUBOCOP_VERSION = "0.52.1" +HOMEBREW_RUBOCOP_CASK_VERSION = "~> 0.16.0" # has to be updated when RuboCop version changes diff --git a/Library/Homebrew/dependency_collector.rb b/Library/Homebrew/dependency_collector.rb index f8edbab06..03a86d661 100644 --- a/Library/Homebrew/dependency_collector.rb +++ b/Library/Homebrew/dependency_collector.rb @@ -1,6 +1,5 @@ require "dependency" require "dependencies" -require "ld64_dependency" require "requirement" require "requirements" require "set" @@ -19,11 +18,6 @@ require "extend/cachable" class DependencyCollector extend Cachable - # Define the languages that we can handle as external dependencies. - LANGUAGE_MODULES = Set[ - :lua, :lua51, :perl, :python, :python3, :ruby - ].freeze - attr_reader :deps, :requirements def initialize @@ -58,16 +52,28 @@ class DependencyCollector parse_spec(spec, Array(tags)) end - def ant_dep(tags) - Dependency.new("ant", tags) + def git_dep_if_needed(tags) + return if Utils.git_available? + Dependency.new("git", tags) + end + + def subversion_dep_if_needed(tags) + return if Utils.svn_available? + Dependency.new("subversion", tags) + end + + def cvs_dep_if_needed(tags) + Dependency.new("cvs", tags) end - def xz_dep(tags) + def xz_dep_if_needed(tags) Dependency.new("xz", tags) end + def ld64_dep_if_needed(*); end + def self.tar_needs_xz_dependency? - !new.xz_dep([]).nil? + !new.xz_dep_if_needed([]).nil? end private @@ -94,8 +100,6 @@ class DependencyCollector TapDependency.new(spec, tags) elsif tags.empty? Dependency.new(spec, tags) - elsif (tag = tags.first) && LANGUAGE_MODULES.include?(tag) - LanguageModuleRequirement.new(tag, spec, tags[1]) else Dependency.new(spec, tags) end @@ -107,30 +111,11 @@ class DependencyCollector when :xcode then XcodeRequirement.new(tags) when :linux then LinuxRequirement.new(tags) when :macos then MacOSRequirement.new(tags) - when :mysql then MysqlRequirement.new(tags) - when :postgresql then PostgresqlRequirement.new(tags) - when :gpg then GPG2Requirement.new(tags) - when :fortran then FortranRequirement.new(tags) - when :mpi then MPIRequirement.new(*tags) - when :tex then TeXRequirement.new(tags) when :arch then ArchRequirement.new(tags) - when :hg then MercurialRequirement.new(tags) - when :python then PythonRequirement.new(tags) - when :python3 then Python3Requirement.new(tags) when :java then JavaRequirement.new(tags) - when :rbenv then RbenvRequirement.new(tags) - when :ruby then RubyRequirement.new(tags) when :osxfuse then OsxfuseRequirement.new(tags) - when :perl then PerlRequirement.new(tags) when :tuntap then TuntapRequirement.new(tags) - when :ant then ant_dep(tags) - when :emacs then EmacsRequirement.new(tags) - # Tiger's ld is too old to properly link some software - when :ld64 then LD64Dependency.new if MacOS.version < :leopard - # Tiger doesn't ship expat in /usr/lib - when :expat then Dependency.new("expat", tag) if MacOS.version < :leopard - when :python2 - PythonRequirement.new(tags) + when :ld64 then ld64_dep_if_needed(tags) else raise ArgumentError, "Unsupported special dependency #{spec.inspect}" end @@ -151,17 +136,17 @@ class DependencyCollector if strategy <= CurlDownloadStrategy parse_url_spec(spec.url, tags) elsif strategy <= GitDownloadStrategy - GitRequirement.new(tags) + git_dep_if_needed(tags) + elsif strategy <= SubversionDownloadStrategy + subversion_dep_if_needed(tags) elsif strategy <= MercurialDownloadStrategy - MercurialRequirement.new(tags) + Dependency.new("mercurial", tags) elsif strategy <= FossilDownloadStrategy Dependency.new("fossil", tags) elsif strategy <= BazaarDownloadStrategy Dependency.new("bazaar", tags) elsif strategy <= CVSDownloadStrategy - CVSRequirement.new(tags) - elsif strategy <= SubversionDownloadStrategy - SubversionRequirement.new(tags) + cvs_dep_if_needed(tags) elsif strategy < AbstractDownloadStrategy # allow unknown strategies to pass through else @@ -172,7 +157,7 @@ class DependencyCollector def parse_url_spec(url, tags) case File.extname(url) - when ".xz" then xz_dep(tags) + when ".xz" then xz_dep_if_needed(tags) when ".lha", ".lzh" then Dependency.new("lha", tags) when ".lz" then Dependency.new("lzip", tags) when ".rar" then Dependency.new("unrar", tags) diff --git a/Library/Homebrew/dev-cmd/aspell-dictionaries.rb b/Library/Homebrew/dev-cmd/aspell-dictionaries.rb deleted file mode 100644 index ab0e66d2b..000000000 --- a/Library/Homebrew/dev-cmd/aspell-dictionaries.rb +++ /dev/null @@ -1,47 +0,0 @@ -#: @hide_from_man_page -#: * `aspell_dictionaries`: -#: Generates the new dictionaries for the `aspell` formula. - -require "open-uri" -require "resource" -require "formula" - -module Homebrew - module_function - - def aspell_dictionaries - dict_url = "https://ftpmirror.gnu.org/aspell/dict" - dict_mirror = "https://ftp.gnu.org/gnu/aspell/dict" - languages = {} - - open("#{dict_url}/0index.html") do |content| - content.each_line do |line| - break if %r{^</table} =~ line - next unless /^<tr><td><a/ =~ line - - fields = line.split('"') - lang = fields[1] - path = fields[3] - lang.tr!("-", "_") - languages[lang] = path - end - end - - languages.each do |lang, path| - r = Resource.new(lang) - r.owner = Formulary.factory("aspell") - r.url "#{dict_url}/#{path}" - r.mirror "#{dict_mirror}/#{path}" - r.fetch - puts <<-EOS - option "with-lang-#{r.name}", "Install #{r.name} dictionary" - resource "#{r.name}" do - url "#{r.url}" - mirror "#{r.mirrors.first}" - sha256 "#{r.cached_download.sha256}" - end - - EOS - end - end -end diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index bfe4dbc00..e3fb3a580 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -1,4 +1,4 @@ -#: * `audit` [`--strict`] [`--fix`] [`--online`] [`--new-formula`] [`--display-cop-names`] [`--display-filename`] [`--only=`<method>|`--except=`<method>] [`--only-cops=`[COP1,COP2..]|`--except-cops=`[COP1,COP2..]] [<formulae>]: +#: * `audit` [`--strict`] [`--fix`] [`--online`] [`--new-formula`] [`--display-cop-names`] [`--display-filename`] [`--only=`<method>|`--except=`<method>] [`--only-cops=`<cops>|`--except-cops=`<cops>] [<formulae>]: #: Check <formulae> for Homebrew coding style violations. This should be #: run before submitting a new formula. #: @@ -8,7 +8,7 @@ #: style checks. #: #: If `--fix` is passed, style violations will be -#: automatically fixed using RuboCop's `--auto-correct` feature. +#: automatically fixed using RuboCop's auto-correct feature. #: #: If `--online` is passed, additional slower checks that require a network #: connection are run. @@ -23,23 +23,24 @@ #: If `--display-filename` is passed, every line of output is prefixed with the #: name of the file or formula being audited, to make the output easy to grep. #: -#: If `--only` is passed, only the methods named `audit_<method>` will be run. +#: Passing `--only=`<method> will run only the methods named `audit_<method>`, +#: while `--except=`<method> will skip the methods named `audit_<method>`. +#: For either option <method> should be a comma-separated list. #: -#: If `--except` is passed, the methods named `audit_<method>` will not be run. -#: -#: If `--only-cops` is passed, only the given Rubocop cop(s)' violations would be checked. -#: -#: If `--except-cops` is passed, the given Rubocop cop(s)' checks would be skipped. +#: Passing `--only-cops=`<cops> will check for violations of only the listed +#: RuboCop <cops>, while `--except-cops=`<cops> will skip checking the listed +#: <cops>. For either option <cops> should be a comma-separated list of cop names. #: #: `audit` exits with a non-zero status if any errors are found. This is useful, #: for instance, for implementing pre-commit hooks. # Undocumented options: -# -D activates debugging and profiling of the audit methods (not the same as --debug) +# `-D` activates debugging and profiling of the audit methods (not the same as `--debug`) require "formula" require "formula_versions" require "utils" +require "utils/curl" require "extend/ENV" require "formula_cellar_checks" require "official_taps" @@ -101,7 +102,7 @@ module Homebrew # Check style in a single batch run up front for performance style_results = check_style_json(files, options) - ff.each do |f| + ff.sort.each do |f| options = { new_formula: new_formula, strict: strict, online: online } options[:style_offenses] = style_results.file_offenses(f.path) fa = FormulaAuditor.new(f, options) @@ -188,8 +189,6 @@ class FormulaAuditor swig ].freeze - FILEUTILS_METHODS = FileUtils.singleton_methods(false).map { |m| Regexp.escape(m) }.join "|" - def initialize(formula, options = {}) @formula = formula @new_formula = options[:new_formula] @@ -197,103 +196,13 @@ class FormulaAuditor @online = options[:online] # Accept precomputed style offense results, for efficiency @style_offenses = options[:style_offenses] + # Allow the actual official-ness of a formula to be overridden, for testing purposes + @official_tap = formula.tap&.official? || options[:official_tap] @problems = [] @text = FormulaText.new(formula.path) @specs = %w[stable devel head].map { |s| formula.send(s) }.compact end - def self.check_http_content(url, user_agents: [:default], check_content: false, strict: false, require_http: false) - return unless url.start_with? "http" - - details = nil - user_agent = nil - hash_needed = url.start_with?("http:") && !require_http - user_agents.each do |ua| - details = http_content_headers_and_checksum(url, hash_needed: hash_needed, user_agent: ua) - user_agent = ua - break if details[:status].to_s.start_with?("2") - end - - unless details[:status] - # Hack around https://github.com/Homebrew/brew/issues/3199 - return if MacOS.version == :el_capitan - return "The URL #{url} is not reachable" - end - - unless details[:status].start_with? "2" - return "The URL #{url} is not reachable (HTTP status code #{details[:status]})" - end - - return unless hash_needed - - secure_url = url.sub "http", "https" - secure_details = - http_content_headers_and_checksum(secure_url, hash_needed: true, user_agent: user_agent) - - if !details[:status].to_s.start_with?("2") || - !secure_details[:status].to_s.start_with?("2") - return - end - - etag_match = details[:etag] && - details[:etag] == secure_details[:etag] - content_length_match = - details[:content_length] && - details[:content_length] == secure_details[:content_length] - file_match = details[:file_hash] == secure_details[:file_hash] - - if etag_match || content_length_match || file_match - return "The URL #{url} should use HTTPS rather than HTTP" - end - - return unless check_content - - no_protocol_file_contents = %r{https?:\\?/\\?/} - details[:file] = details[:file].gsub(no_protocol_file_contents, "/") - secure_details[:file] = secure_details[:file].gsub(no_protocol_file_contents, "/") - - # Check for the same content after removing all protocols - if details[:file] == secure_details[:file] - return "The URL #{url} should use HTTPS rather than HTTP" - end - - return unless strict - - # Same size, different content after normalization - # (typical causes: Generated ID, Timestamp, Unix time) - if details[:file].length == secure_details[:file].length - return "The URL #{url} may be able to use HTTPS rather than HTTP. Please verify it in a browser." - end - - lenratio = (100 * secure_details[:file].length / details[:file].length).to_i - return unless (90..110).cover?(lenratio) - "The URL #{url} may be able to use HTTPS rather than HTTP. Please verify it in a browser." - end - - def self.http_content_headers_and_checksum(url, hash_needed: false, user_agent: :default) - max_time = hash_needed ? "600" : "25" - output, = curl_output( - "--connect-timeout", "15", "--include", "--max-time", max_time, "--location", url, - user_agent: user_agent - ) - - status_code = :unknown - while status_code == :unknown || status_code.to_s.start_with?("3") - headers, _, output = output.partition("\r\n\r\n") - status_code = headers[%r{HTTP\/.* (\d+)}, 1] - end - - output_hash = Digest::SHA256.digest(output) if hash_needed - - { - status: status_code, - etag: headers[%r{ETag: ([wW]\/)?"(([^"]|\\")*)"}, 2], - content_length: headers[/Content-Length: (\d+)/, 1], - file_hash: output_hash, - file: output, - } - end - def audit_style return unless @style_offenses display_cop_names = ARGV.include?("--display-cop-names") @@ -395,7 +304,7 @@ class FormulaAuditor def audit_formula_name return unless @strict # skip for non-official taps - return if formula.tap.nil? || !formula.tap.official? + return unless @official_tap name = formula.name @@ -470,26 +379,7 @@ class FormulaAuditor case dep.name when "git" - problem "Don't use git as a dependency" - when "mercurial" - problem "Use `depends_on :hg` instead of `depends_on 'mercurial'`" - when "gfortran" - problem "Use `depends_on :fortran` instead of `depends_on 'gfortran'`" - when "ruby" - problem <<~EOS - Don't use "ruby" as a dependency. If this formula requires a - minimum Ruby version not provided by the system you should - use the RubyRequirement: - depends_on :ruby => "1.8" - where "1.8" is the minimum version of Ruby required. - EOS - when "open-mpi", "mpich" - problem <<~EOS - There are multiple conflicting ways to install MPI. Use an MPIRequirement: - depends_on :mpi => [<lang list>] - Where <lang list> is a comma delimited list that can include: - :cc, :cxx, :f77, :f90 - EOS + problem "Don't use git as a dependency (it's always available)" when *BUILD_TIME_DEPS next if dep.build? || dep.run? problem <<~EOS @@ -558,10 +448,10 @@ class FormulaAuditor return unless @online return unless DevelopmentTools.curl_handles_most_https_certificates? - if http_content_problem = FormulaAuditor.check_http_content(homepage, - user_agents: [:browser, :default], - check_content: true, - strict: @strict) + if http_content_problem = curl_check_http_content(homepage, + user_agents: [:browser, :default], + check_content: true, + strict: @strict) problem http_content_problem end end @@ -828,7 +718,13 @@ class FormulaAuditor return unless @strict - problem "`#{Regexp.last_match(1)}` in formulae is deprecated" if line =~ /(env :(std|userpaths))/ + if @official_tap && line.include?("env :std") + problem "`env :std` in official tap formulae is deprecated" + end + + if line.include?("env :userpaths") + problem "`env :userpaths` in formulae is deprecated" + end if line =~ /system ((["'])[^"' ]*(?:\s[^"' ]*)+\2)/ bad_system = Regexp.last_match(1) @@ -851,7 +747,7 @@ class FormulaAuditor def audit_reverse_migration # Only enforce for new formula being re-added to core and official taps return unless @strict - return unless formula.tap&.official? + return unless @official_tap return unless formula.tap.tap_migrations.key?(formula.name) problem <<~EOS @@ -872,6 +768,18 @@ class FormulaAuditor EOS end + def audit_url_is_not_binary + return unless @official_tap + + urls = @specs.map(&:url) + + urls.each do |url| + if url =~ /darwin/i && (url =~ /x86_64/i || url =~ /amd64/i) + problem "#{url} looks like a binary package, not a source archive. Official taps are source-only." + end + end + end + def quote_dep(dep) dep.is_a?(Symbol) ? dep.inspect : "'#{dep}'" end @@ -1037,7 +945,7 @@ class ResourceAuditor # A `brew mirror`'ed URL is usually not yet reachable at the time of # pull request. next if url =~ %r{^https://dl.bintray.com/homebrew/mirror/} - if http_content_problem = FormulaAuditor.check_http_content(url, require_http: curl_openssl_or_deps) + if http_content_problem = curl_check_http_content(url, require_http: curl_openssl_or_deps) problem http_content_problem end elsif strategy <= GitDownloadStrategy diff --git a/Library/Homebrew/dev-cmd/bottle.rb b/Library/Homebrew/dev-cmd/bottle.rb index 204e7cef9..a233dfb57 100644 --- a/Library/Homebrew/dev-cmd/bottle.rb +++ b/Library/Homebrew/dev-cmd/bottle.rb @@ -25,6 +25,10 @@ #: If `--write` is passed, write the changes to the formula file. A new #: commit will then be generated unless `--no-commit` is passed. +# Undocumented options: +# `--json` writes bottle information to a JSON file, which can be used as +# the argument for `--merge`. + require "formula" require "utils/bottles" require "tab" diff --git a/Library/Homebrew/dev-cmd/bump-formula-pr.rb b/Library/Homebrew/dev-cmd/bump-formula-pr.rb index 6f7cc13c2..1f44fa549 100644 --- a/Library/Homebrew/dev-cmd/bump-formula-pr.rb +++ b/Library/Homebrew/dev-cmd/bump-formula-pr.rb @@ -33,6 +33,9 @@ #: which opens the pull request URL in a browser. Instead, output it to the #: command line. #: +#: If `--quiet` is passed, don't output replacement messages or warn about +#: duplicate pull requests. +#: #: Note that this command cannot be used to transition a formula from a #: URL-and-sha256 style specification into a tag-and-revision style #: specification, nor vice versa. It must use whichever style specification @@ -137,9 +140,16 @@ module Homebrew new_url = ARGV.value("url") if new_url && !formula - is_devel = ARGV.include?("--devel") - base_url = new_url.split("/")[0..4].join("/") + # Split the new URL on / and find any formulae that have the same URL + # except for the last component, but don't try to match any more than the + # first five components since sometimes the last component isn't the only + # one to change. + new_url_split = new_url.split("/") + maximum_url_components_to_match = 5 + components_to_match = [new_url_split.count - 1, maximum_url_components_to_match].min + base_url = new_url_split.first(components_to_match).join("/") base_url = /#{Regexp.escape(base_url)}/ + is_devel = ARGV.include?("--devel") guesses = [] Formula.each do |f| if is_devel && f.devel && f.devel.url && f.devel.url.match(base_url) @@ -180,29 +190,34 @@ module Homebrew elsif new_tag && new_revision false elsif !hash_type - odie "#{formula}: no tag/revision specified!" + odie "#{formula}: no --tag=/--revision= arguments specified!" elsif !new_url - odie "#{formula}: no url specified!" + odie "#{formula}: no --url= argument specified!" else - rsrc_url = if requested_spec != :devel && new_url =~ /.*ftpmirror.gnu.*/ - new_mirror = new_url.sub "ftpmirror.gnu.org", "ftp.gnu.org/gnu" - new_mirror - else - new_url + new_mirror = case new_url + when requested_spec != :devel && %r{.*ftp.gnu.org/gnu.*} + new_url.sub "ftp.gnu.org/gnu", "ftpmirror.gnu.org" + when %r{.*mirrors.ocf.berkeley.edu/debian.*} + new_url.sub "mirrors.ocf.berkeley.edu/debian", "mirrorservice.org/sites/ftp.debian.org/debian" end - rsrc = Resource.new { @url = rsrc_url } - rsrc.download_strategy = CurlDownloadStrategy - rsrc.owner = Resource.new(formula.name) - rsrc.version = forced_version if forced_version - odie "No version specified!" unless rsrc.version - rsrc_path = rsrc.fetch - gnu_tar_gtar_path = HOMEBREW_PREFIX/"opt/gnu-tar/bin/gtar" - gnu_tar_gtar = gnu_tar_gtar_path if gnu_tar_gtar_path.executable? - tar = which("gtar") || gnu_tar_gtar || which("tar") - if Utils.popen_read(tar, "-tf", rsrc_path) =~ %r{/.*\.} - new_hash = rsrc_path.sha256 - elsif new_url.include? ".tar" - odie "#{formula}: no url/#{hash_type} specified!" + resource = Resource.new { @url = new_url } + resource.download_strategy = DownloadStrategyDetector.detect_from_url(new_url) + resource.owner = Resource.new(formula.name) + resource.version = forced_version if forced_version + odie "No --version= argument specified!" unless resource.version + resource_path = resource.fetch + tar_file_extensions = %w[.tar .tb2 .tbz .tbz2 .tgz .tlz .txz .tZ] + if tar_file_extensions.any? { |extension| new_url.include? extension } + gnu_tar_gtar_path = HOMEBREW_PREFIX/"opt/gnu-tar/bin/gtar" + gnu_tar_gtar = gnu_tar_gtar_path if gnu_tar_gtar_path.executable? + tar = which("gtar") || gnu_tar_gtar || which("tar") + if Utils.popen_read(tar, "-tf", resource_path) =~ %r{/.*\.} + new_hash = resource_path.sha256 + else + odie "#{resource_path} is not a valid tar file!" + end + else + new_hash = resource_path.sha256 end end @@ -220,12 +235,12 @@ module Homebrew end replacement_pairs += formula_spec.mirrors.map do |mirror| - [/ +mirror \"#{mirror}\"\n/m, ""] + [/ +mirror \"#{Regexp.escape(mirror)}\"\n/m, ""] end replacement_pairs += if new_url_hash [ - [formula_spec.url, new_url], + [/#{Regexp.escape(formula_spec.url)}/, new_url], [old_hash, new_hash], ] else @@ -238,7 +253,7 @@ module Homebrew backup_file = File.read(formula.path) unless ARGV.dry_run? if new_mirror - replacement_pairs << [/^( +)(url \"#{new_url}\"\n)/m, "\\1\\2\\1mirror \"#{new_mirror}\"\n"] + replacement_pairs << [/^( +)(url \"#{Regexp.escape(new_url)}\"\n)/m, "\\1\\2\\1mirror \"#{new_mirror}\"\n"] end if forced_version && forced_version != "0" @@ -255,7 +270,7 @@ module Homebrew end elsif forced_version && forced_version == "0" if requested_spec == :stable - replacement_pairs << [/^ version \"[a-z\d+\.]+\"\n/m, ""] + replacement_pairs << [/^ version \"[\w\.\-\+]+\"\n/m, ""] elsif requested_spec == :devel replacement_pairs << [/( devel do.+?)^ +version \"[^\n]+\"\n(.+?end\n)/m, "\\1\\2"] end @@ -338,13 +353,19 @@ module Homebrew if reply.to_s.include? "username:" formula.path.atomic_write(backup_file) unless ARGV.dry_run? - odie "You need to configure hub" + git_path = "$(brew --repo #{formula.tap})" if formula.tap + git_path ||= formula.path.parent + odie <<~EOS + Retry after configuring hub by running: + hub -C "#{git_path}" fork + Or setting HOMEBREW_GITHUB_TOKEN with at least 'public_repo' scope. + EOS end remote = reply[/remote:? (\S+)/, 1] # repeat for hub 2.2 backwards compatibility: - remote = Utils.popen_read("hub fork 2>&1")[/remote:? (\S+)/, 1] if remote.to_s.empty? + remote = Utils.popen_read("hub", "fork", err: :out)[/remote:? (\S+)/, 1] if remote.to_s.empty? if remote.to_s.empty? formula.path.atomic_write(backup_file) unless ARGV.dry_run? diff --git a/Library/Homebrew/dev-cmd/create.rb b/Library/Homebrew/dev-cmd/create.rb index e5481b532..122be2593 100644 --- a/Library/Homebrew/dev-cmd/create.rb +++ b/Library/Homebrew/dev-cmd/create.rb @@ -165,77 +165,73 @@ class FormulaCreator path.write ERB.new(template, nil, ">").result(binding) end - def template; <<~EOS - # Documentation: https://docs.brew.sh/Formula-Cookbook.html - # http://www.rubydoc.info/github/Homebrew/brew/master/Formula - # PLEASE REMOVE ALL GENERATED COMMENTS BEFORE SUBMITTING YOUR PULL REQUEST! - - class #{Formulary.class_s(name)} < Formula - desc "#{desc}" - homepage "#{homepage}" - <% if head? %> - head "#{url}" - <% else %> - url "#{url}" - <% unless version.nil? or version.detected_from_url? %> - version "#{version}" - <% end %> - sha256 "#{sha256}" - <% end %> - - <% if mode == :cmake %> - depends_on "cmake" => :build - <% elsif mode == :meson %> - depends_on "meson" => :build - depends_on "ninja" => :build - <% elsif mode.nil? %> - # depends_on "cmake" => :build - <% end %> - - def install - # ENV.deparallelize # if your formula fails when building in parallel - - <% if mode == :cmake %> - system "cmake", ".", *std_cmake_args - <% elsif mode == :autotools %> - # Remove unrecognized options if warned by configure - system "./configure", "--disable-debug", - "--disable-dependency-tracking", - "--disable-silent-rules", - "--prefix=\#{prefix}" - <% elsif mode == :meson %> - mkdir "build" do - system "meson", "--prefix=\#{prefix}", ".." - system "ninja" - system "ninja", "test" - system "ninja", "install" + def template + <<~EOS + # Documentation: https://docs.brew.sh/Formula-Cookbook.html + # http://www.rubydoc.info/github/Homebrew/brew/master/Formula + # PLEASE REMOVE ALL GENERATED COMMENTS BEFORE SUBMITTING YOUR PULL REQUEST! + class #{Formulary.class_s(name)} < Formula + desc "#{desc}" + homepage "#{homepage}" + <% if head? %> + head "#{url}" + <% else %> + url "#{url}" + <% unless version.nil? or version.detected_from_url? %> + version "#{version}" + <% end %> + sha256 "#{sha256}" + <% end %> + <% if mode == :cmake %> + depends_on "cmake" => :build + <% elsif mode == :meson %> + depends_on "meson" => :build + depends_on "ninja" => :build + <% elsif mode.nil? %> + # depends_on "cmake" => :build + <% end %> + def install + # ENV.deparallelize # if your formula fails when building in parallel + <% if mode == :cmake %> + system "cmake", ".", *std_cmake_args + <% elsif mode == :autotools %> + # Remove unrecognized options if warned by configure + system "./configure", "--disable-debug", + "--disable-dependency-tracking", + "--disable-silent-rules", + "--prefix=\#{prefix}" + <% elsif mode == :meson %> + mkdir "build" do + system "meson", "--prefix=\#{prefix}", ".." + system "ninja" + system "ninja", "test" + system "ninja", "install" + end + <% else %> + # Remove unrecognized options if warned by configure + system "./configure", "--disable-debug", + "--disable-dependency-tracking", + "--disable-silent-rules", + "--prefix=\#{prefix}" + # system "cmake", ".", *std_cmake_args + <% end %> + <% if mode != :meson %> + system "make", "install" # if this fails, try separate make/make install steps + <% end %> + end + test do + # `test do` will create, run in and delete a temporary directory. + # + # This test will fail and we won't accept that! For Homebrew/homebrew-core + # this will need to be a test that verifies the functionality of the + # software. Run the test with `brew test #{name}`. Options passed + # to `brew install` such as `--HEAD` also need to be provided to `brew test`. + # + # The installed folder is not in the path, so use the entire path to any + # executables being tested: `system "\#{bin}/program", "do", "something"`. + system "false" end - <% else %> - # Remove unrecognized options if warned by configure - system "./configure", "--disable-debug", - "--disable-dependency-tracking", - "--disable-silent-rules", - "--prefix=\#{prefix}" - # system "cmake", ".", *std_cmake_args - <% end %> - <% if mode != :meson %> - system "make", "install" # if this fails, try separate make/make install steps - <% end %> - end - - test do - # `test do` will create, run in and delete a temporary directory. - # - # This test will fail and we won't accept that! For Homebrew/homebrew-core - # this will need to be a test that verifies the functionality of the - # software. Run the test with `brew test #{name}`. Options passed - # to `brew install` such as `--HEAD` also need to be provided to `brew test`. - # - # The installed folder is not in the path, so use the entire path to any - # executables being tested: `system "\#{bin}/program", "do", "something"`. - system "false" end - end EOS end end diff --git a/Library/Homebrew/dev-cmd/linkage.rb b/Library/Homebrew/dev-cmd/linkage.rb index e4da827f2..31e9bd103 100644 --- a/Library/Homebrew/dev-cmd/linkage.rb +++ b/Library/Homebrew/dev-cmd/linkage.rb @@ -1,4 +1,4 @@ -#: * `linkage` [`--test`] [`--reverse`] <formula>: +#: * `linkage` [`--test`] [`--reverse`] <formula>: #: Checks the library links of an installed formula. #: #: Only works on installed formulae. An error is raised if it is run on diff --git a/Library/Homebrew/dev-cmd/man.rb b/Library/Homebrew/dev-cmd/man.rb index b2bb3c8c3..f06c89863 100644 --- a/Library/Homebrew/dev-cmd/man.rb +++ b/Library/Homebrew/dev-cmd/man.rb @@ -64,8 +64,10 @@ module Homebrew .gsub(/\[([^\]]+)\]\([^)]+\)/, '\1') variables[:core_maintainer] = readme.read[%r{(Homebrew/homebrew-core's lead maintainer .*\.)}, 1] .gsub(/\[([^\]]+)\]\([^)]+\)/, '\1') - variables[:maintainers] = readme.read[/(Homebrew's other current maintainers .*\.)/, 1] - .gsub(/\[([^\]]+)\]\([^)]+\)/, '\1') + variables[:brew_maintainers] = readme.read[%r{(Homebrew/brew's other current maintainers .*\.)}, 1] + .gsub(/\[([^\]]+)\]\([^)]+\)/, '\1') + variables[:core_maintainers] = readme.read[%r{(Homebrew/homebrew-core's other current maintainers .*\.)}, 1] + .gsub(/\[([^\]]+)\]\([^)]+\)/, '\1') variables[:former_maintainers] = readme.read[/(Former maintainers .*\.)/, 1] .gsub(/\[([^\]]+)\]\([^)]+\)/, '\1') @@ -106,7 +108,7 @@ module Homebrew ronn.write markup ronn.close_write ronn_output = ronn.read - ronn_output.gsub!(%r{</?var>}, "`") if format_flag == "--markdown" + ronn_output.gsub!(%r{</var>`(?=[.!?,;:]?\s)}, "").gsub!(%r{</?var>}, "`") if format_flag == "--markdown" target.atomic_write ronn_output end end diff --git a/Library/Homebrew/dev-cmd/pull.rb b/Library/Homebrew/dev-cmd/pull.rb index 5979d87b8..959fbd6c7 100644 --- a/Library/Homebrew/dev-cmd/pull.rb +++ b/Library/Homebrew/dev-cmd/pull.rb @@ -447,7 +447,7 @@ module Homebrew def publish_bottle_file_on_bintray(f, bintray_org, creds) repo = Utils::Bottles::Bintray.repository(f.tap) package = Utils::Bottles::Bintray.package(f.name) - info = FormulaInfoFromJson.lookup(f.name) + info = FormulaInfoFromJson.lookup(f.full_name) if info.nil? raise "Failed publishing bottle: failed reading formula info for #{f.full_name}" end diff --git a/Library/Homebrew/dev-cmd/tap-new.rb b/Library/Homebrew/dev-cmd/tap-new.rb index 1c3bf20eb..38cdb1c2e 100644 --- a/Library/Homebrew/dev-cmd/tap-new.rb +++ b/Library/Homebrew/dev-cmd/tap-new.rb @@ -44,39 +44,28 @@ module Homebrew write_path(tap, "README.md", readme) travis = <<~EOS - language: ruby + language: c os: osx - env: OSX=10.12 - osx_image: xcode8.3 - rvm: system + compiler: clang + osx_image: xcode9.2 cache: directories: - $HOME/.gem/ruby - Library/Homebrew/vendor/bundle + branches: + only: + - master before_install: - - export TRAVIS_COMMIT="$(git rev-parse --verify -q HEAD)" - - if [ -f ".git/shallow" ]; then - travis_retry git fetch --unshallow; - fi - - HOMEBREW_REPOSITORY="$(brew --repo)" - - sudo chown -R "$USER" "$HOMEBREW_REPOSITORY" - - git -C "$HOMEBREW_REPOSITORY" reset --hard origin/master - - brew update || brew update + - sudo chown -R "$USER" "$(brew --repo)" + - travis_retry brew update - HOMEBREW_TAP_DIR="$(brew --repo "$TRAVIS_REPO_SLUG")" - mkdir -p "$HOMEBREW_TAP_DIR" - rm -rf "$HOMEBREW_TAP_DIR" - ln -s "$PWD" "$HOMEBREW_TAP_DIR" - - export HOMEBREW_DEVELOPER="1" - - ulimit -n 1024 script: - brew test-bot - - notifications: - email: - on_success: never - on_failure: always EOS write_path(tap, ".travis.yml", travis) end diff --git a/Library/Homebrew/dev-cmd/tests.rb b/Library/Homebrew/dev-cmd/tests.rb index af9dcc575..db2a6d33e 100644 --- a/Library/Homebrew/dev-cmd/tests.rb +++ b/Library/Homebrew/dev-cmd/tests.rb @@ -82,17 +82,20 @@ module Homebrew ] end + # Generate seed ourselves and output later to avoid multiple different + # seeds being output when running parallel tests. + seed = ARGV.include?("--seed") ? ARGV.next : rand(0xFFFF).to_i + args = ["-I", HOMEBREW_LIBRARY_PATH/"test"] args += %W[ + --seed #{seed} --color --require spec_helper - --format progress + --format NoSeedProgressFormatter --format ParallelTests::RSpec::RuntimeLogger --out #{HOMEBREW_CACHE}/tests/parallel_runtime_rspec.log ] - args << "--seed" << ARGV.next if ARGV.include? "--seed" - unless OS.mac? args << "--tag" << "~needs_macos" files = files.reject { |p| p =~ %r{^test/(os/mac|cask)(/.*|_spec\.rb)$} } @@ -102,6 +105,8 @@ module Homebrew files = files.reject { |p| p =~ %r{^test/os/linux(/.*|_spec\.rb)$} } end + puts "Randomized with seed #{seed}" + if parallel system "bundle", "exec", "parallel_rspec", *opts, "--", *args, "--", *files else diff --git a/Library/Homebrew/development_tools.rb b/Library/Homebrew/development_tools.rb index b7787d849..ba342c435 100644 --- a/Library/Homebrew/development_tools.rb +++ b/Library/Homebrew/development_tools.rb @@ -16,7 +16,7 @@ class DevelopmentTools end def installed? - which("clang") || which("gcc") + locate("clang") || locate("gcc") end def installation_instructions diff --git a/Library/Homebrew/diagnostic.rb b/Library/Homebrew/diagnostic.rb index 61f9b53a3..cc364eaaa 100644 --- a/Library/Homebrew/diagnostic.rb +++ b/Library/Homebrew/diagnostic.rb @@ -339,8 +339,7 @@ module Homebrew by Homebrew. If a formula tries to write a file to this directory, the install will fail during the link step. - You should change the ownership and permissions of these directories. - back to your user account. + You should change the ownership of these directories to your account. sudo chown -R $(whoami) #{not_writable_dirs.join(" ")} EOS end @@ -836,6 +835,17 @@ module Homebrew EOS end + def check_for_large_cache + return unless HOMEBREW_CACHE.exist? + return if ENV["CI"] # CI can be expected to have a large cache. + 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 # Other frameworks that are known to cause problems when present frameworks_to_check = %w[ @@ -1017,16 +1027,6 @@ module Homebrew EOS end - def check_for_old_env_vars - return unless ENV["HOMEBREW_KEEP_INFO"] - - <<~EOS - `HOMEBREW_KEEP_INFO` is no longer used - info files are no longer deleted by default; you may - remove this environment variable. - EOS - end - def check_for_pth_support homebrew_site_packages = Language::Python.homebrew_site_packages return unless homebrew_site_packages.directory? diff --git a/Library/Homebrew/download_strategy.rb b/Library/Homebrew/download_strategy.rb index f9a359450..feb518057 100644 --- a/Library/Homebrew/download_strategy.rb +++ b/Library/Homebrew/download_strategy.rb @@ -217,12 +217,12 @@ class AbstractFileDownloadStrategy < AbstractDownloadStrategy def stage case type = cached_location.compression_type when :zip - with_system_path { quiet_safe_system "unzip", "-qq", cached_location } + quiet_safe_system "unzip", "-qq", cached_location chdir when :gzip_only - with_system_path { buffered_write("gunzip") } + buffered_write "gunzip" when :bzip2_only - with_system_path { buffered_write("bunzip2") } + buffered_write "bunzip2" when :gzip, :bzip2, :xz, :compress, :tar tar_flags = "x" if type == :gzip @@ -233,16 +233,14 @@ class AbstractFileDownloadStrategy < AbstractDownloadStrategy tar_flags << "J" end tar_flags << "f" - with_system_path do - if type == :xz && DependencyCollector.tar_needs_xz_dependency? - pipe_to_tar(xzpath) - else - safe_system "tar", tar_flags, cached_location - end + if type == :xz && DependencyCollector.tar_needs_xz_dependency? + pipe_to_tar xzpath + else + safe_system "tar", tar_flags, cached_location end chdir when :lzip - with_system_path { pipe_to_tar(lzippath) } + pipe_to_tar lzippath chdir when :lha safe_system lhapath, "x", cached_location @@ -1007,11 +1005,11 @@ class MercurialDownloadStrategy < VCSDownloadStrategy end def source_modified_time - Time.parse Utils.popen_read("hg", "tip", "--template", "{date|isodate}", "-R", cached_location.to_s) + Time.parse Utils.popen_read(hgpath, "tip", "--template", "{date|isodate}", "-R", cached_location.to_s) end def last_commit - Utils.popen_read("hg", "parent", "--template", "{node|short}", "-R", cached_location.to_s) + Utils.popen_read(hgpath, "parent", "--template", "{node|short}", "-R", cached_location.to_s) end private diff --git a/Library/Homebrew/exceptions.rb b/Library/Homebrew/exceptions.rb index 7705f9d49..42c62338a 100644 --- a/Library/Homebrew/exceptions.rb +++ b/Library/Homebrew/exceptions.rb @@ -458,7 +458,7 @@ end # if the user passes any flags/environment that would case a bottle-only # installation on a system without build tools to fail class BuildFlagsError < RuntimeError - def initialize(flags) + def initialize(flags, bottled: true) if flags.length > 1 flag_text = "flags" require_text = "require" @@ -467,13 +467,18 @@ class BuildFlagsError < RuntimeError require_text = "requires" end - super <<~EOS + message = <<~EOS.chomp! The following #{flag_text}: #{flags.join(", ")} #{require_text} building tools, but none are installed. #{DevelopmentTools.installation_instructions} + EOS + + message << <<~EOS.chomp! if bottled Alternatively, remove the #{flag_text} to attempt bottle installation. EOS + + super message end end diff --git a/Library/Homebrew/extend/os/linux/extend/pathname.rb b/Library/Homebrew/extend/os/linux/extend/pathname.rb index eb6ea409b..604351da7 100644 --- a/Library/Homebrew/extend/os/linux/extend/pathname.rb +++ b/Library/Homebrew/extend/os/linux/extend/pathname.rb @@ -1,19 +1,5 @@ -class Pathname - # @private - def elf? - # See: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header - read(4) == "\x7fELF" - end +require "os/linux/elf" - # @private - def dynamic_elf? - if which "readelf" - popen_read("readelf", "-l", to_path).include?(" DYNAMIC ") - elsif which "file" - !popen_read("file", "-L", "-b", to_path)[/dynamic|shared/].nil? - else - raise StandardError, "Neither `readelf` nor `file` is available "\ - "to determine whether '#{self}' is dynamically or statically linked." - end - end +class Pathname + prepend ELFShim end diff --git a/Library/Homebrew/extend/os/linux/hardware/cpu.rb b/Library/Homebrew/extend/os/linux/hardware/cpu.rb index 8bf67bec8..0c1078fdf 100644 --- a/Library/Homebrew/extend/os/linux/hardware/cpu.rb +++ b/Library/Homebrew/extend/os/linux/hardware/cpu.rb @@ -1,26 +1,13 @@ module Hardware class CPU class << self - def universal_archs - [].extend ArchitectureListExtension - end - def cpuinfo @cpuinfo ||= File.read("/proc/cpuinfo") end - def type - @type ||= if cpuinfo =~ /Intel|AMD/ - :intel - elsif cpuinfo =~ /ARM|Marvell/ - :arm - else - :dunno - end - end - def family return :arm if arm? + return :ppc if ppc? return :dunno unless intel? # See https://software.intel.com/en-us/articles/intel-architecture-and-processor-identification-with-cpuid-model-and-family-numbers cpu_family = cpuinfo[/^cpu family\s*: ([0-9]+)/, 1].to_i @@ -70,12 +57,9 @@ module Hardware end end - def cores - cpuinfo.scan(/^processor/).size - end - def flags - @flags ||= cpuinfo[/^(flags|Features).*/, 0].split + @flags ||= cpuinfo[/^(flags|Features).*/, 0]&.split + @flags ||= [] end # Compatibility with Mac method, which returns lowercase symbols @@ -95,12 +79,6 @@ module Hardware def sse4? flags.include? "sse4_1" end - - alias is_64_bit? lm? - - def bits - is_64_bit? ? 64 : 32 - end end end end diff --git a/Library/Homebrew/extend/os/linux/requirements/java_requirement.rb b/Library/Homebrew/extend/os/linux/requirements/java_requirement.rb index 7816f6b6f..23a68743d 100644 --- a/Library/Homebrew/extend/os/linux/requirements/java_requirement.rb +++ b/Library/Homebrew/extend/os/linux/requirements/java_requirement.rb @@ -1,8 +1,6 @@ require "language/java" class JavaRequirement < Requirement - default_formula "jdk" - env do env_java_common env_oracle_jdk diff --git a/Library/Homebrew/extend/os/linux/system_config.rb b/Library/Homebrew/extend/os/linux/system_config.rb index e62b12e71..cf0176562 100644 --- a/Library/Homebrew/extend/os/linux/system_config.rb +++ b/Library/Homebrew/extend/os/linux/system_config.rb @@ -1,4 +1,5 @@ require "formula" +require "os/linux/glibc" class SystemConfig class << self @@ -14,17 +15,21 @@ class SystemConfig end end + def host_glibc_version + version = OS::Linux::Glibc.system_version + return "N/A" if version.null? + version + end + def host_gcc_version gcc = Pathname.new "/usr/bin/gcc" return "N/A" unless gcc.executable? `#{gcc} --version 2>/dev/null`[/ (\d+\.\d+\.\d+)/, 1] end - def formula_version(formula) + def formula_linked_version(formula) return "N/A" unless CoreTap.instance.installed? - f = Formulary.factory formula - return "N/A" unless f.installed? - f.version + Formulary.factory(formula).linked_version || "N/A" rescue FormulaUnavailableError return "N/A" end @@ -33,9 +38,10 @@ class SystemConfig dump_generic_verbose_config(out) out.puts "Kernel: #{`uname -mors`.chomp}" out.puts "OS: #{host_os_version}" + out.puts "Host glibc: #{host_glibc_version}" out.puts "/usr/bin/gcc: #{host_gcc_version}" ["glibc", "gcc", "xorg"].each do |f| - out.puts "#{f}: #{formula_version f}" + out.puts "#{f}: #{formula_linked_version f}" end end end diff --git a/Library/Homebrew/extend/os/mac/dependency_collector.rb b/Library/Homebrew/extend/os/mac/dependency_collector.rb index 8d660321e..108b6ccb2 100644 --- a/Library/Homebrew/extend/os/mac/dependency_collector.rb +++ b/Library/Homebrew/extend/os/mac/dependency_collector.rb @@ -1,11 +1,26 @@ +require "os/mac/ld64_dependency" + class DependencyCollector - def ant_dep(tags) - return if MacOS.version < :mavericks - Dependency.new("ant", tags) + def git_dep_if_needed(tags) + return if MacOS.version >= :lion + Dependency.new("git", tags) + end + + def subversion_dep_if_needed(tags); end + + def cvs_dep_if_needed(tags) + return if MacOS.version < :lion + Dependency.new("cvs", tags) end - def xz_dep(tags) + def xz_dep_if_needed(tags) return if MacOS.version >= :mavericks Dependency.new("xz", tags) end + + def ld64_dep_if_needed(*) + # Tiger's ld is too old to properly link some software + return if MacOS.version > :tiger + LD64Dependency.new + end end diff --git a/Library/Homebrew/extend/os/mac/diagnostic.rb b/Library/Homebrew/extend/os/mac/diagnostic.rb index f86155f2e..bb89b2367 100644 --- a/Library/Homebrew/extend/os/mac/diagnostic.rb +++ b/Library/Homebrew/extend/os/mac/diagnostic.rb @@ -262,19 +262,6 @@ module Homebrew EOS end - def check_for_unsupported_curl_vars - # Support for SSL_CERT_DIR seemed to be removed in the 10.10.5 update. - return unless MacOS.version >= :yosemite - return if ENV["SSL_CERT_DIR"].nil? - - <<~EOS - SSL_CERT_DIR support was removed from Apple's curl. - If fetching formulae fails you should: - unset SSL_CERT_DIR - and remove it from #{Utils::Shell.profile} if present. - EOS - end - def check_xcode_license_approved # If the user installs Xcode-only, they have to approve the # license or no "xc*" tool will work. diff --git a/Library/Homebrew/extend/os/mac/extend/pathname.rb b/Library/Homebrew/extend/os/mac/extend/pathname.rb index 5fd59e1e7..4ced5a094 100644 --- a/Library/Homebrew/extend/os/mac/extend/pathname.rb +++ b/Library/Homebrew/extend/os/mac/extend/pathname.rb @@ -1,5 +1,5 @@ require "os/mac/mach" class Pathname - include MachOShim + prepend MachOShim end diff --git a/Library/Homebrew/extend/os/mac/hardware/cpu.rb b/Library/Homebrew/extend/os/mac/hardware/cpu.rb index a216db6ae..cc41ae911 100644 --- a/Library/Homebrew/extend/os/mac/hardware/cpu.rb +++ b/Library/Homebrew/extend/os/mac/hardware/cpu.rb @@ -75,22 +75,6 @@ module Hardware sysctl_int("machdep.cpu.extmodel") end - def cores - sysctl_int("hw.ncpu") - end - - def bits - sysctl_bool("hw.cpu64bit_capable") ? 64 : 32 - end - - def arch_32_bit - intel? ? :i386 : :ppc - end - - def arch_64_bit - intel? ? :x86_64 : :ppc64 - end - # Returns an array that's been extended with ArchitectureListExtension, # which provides helpers like #as_arch_flags and #as_cmake_arch_flags. def universal_archs diff --git a/Library/Homebrew/extend/os/mac/requirements/x11_requirement.rb b/Library/Homebrew/extend/os/mac/requirements/x11_requirement.rb new file mode 100644 index 000000000..0c319d1de --- /dev/null +++ b/Library/Homebrew/extend/os/mac/requirements/x11_requirement.rb @@ -0,0 +1,19 @@ +require "requirement" + +class X11Requirement < Requirement + cask "xquartz" + download "https://xquartz.macosforge.org" + + def min_version + MacOS::XQuartz.minimum_version + end + + satisfy build_env: false do + next false unless MacOS::XQuartz.installed? + min_version <= MacOS::XQuartz.version + end + + def message + "XQuartz #{min_version} (or newer) is required to install this formula. #{super}" + end +end diff --git a/Library/Homebrew/extend/os/requirements/x11_requirement.rb b/Library/Homebrew/extend/os/requirements/x11_requirement.rb new file mode 100644 index 000000000..664b6c7c0 --- /dev/null +++ b/Library/Homebrew/extend/os/requirements/x11_requirement.rb @@ -0,0 +1 @@ +require "extend/os/mac/requirements/x11_requirement" if OS.mac? diff --git a/Library/Homebrew/extend/pathname.rb b/Library/Homebrew/extend/pathname.rb index 82cf10be0..baf47b276 100644 --- a/Library/Homebrew/extend/pathname.rb +++ b/Library/Homebrew/extend/pathname.rb @@ -255,7 +255,7 @@ class Pathname else false end - rescue Errno::EACCES, Errno::ENOENT + rescue Errno::EACCES, Errno::ENOENT, Errno::EBUSY false end @@ -436,11 +436,14 @@ class Pathname end # Writes an exec script that invokes a java jar - def write_jar_script(target_jar, script_name, java_opts = "") + def write_jar_script(target_jar, script_name, java_opts = "", java_version: nil) mkpath + java_home = if java_version + "JAVA_HOME=\"$(#{Language::Java.java_home_cmd(java_version)})\" " + end join(script_name).write <<~EOS #!/bin/bash - exec java #{java_opts} -jar #{target_jar} "$@" + #{java_home}exec java #{java_opts} -jar #{target_jar} "$@" EOS end @@ -470,6 +473,10 @@ class Pathname end } end + + def mach_o_bundle? + false + end end require "extend/os/pathname" @@ -495,7 +502,7 @@ module ObserverPathnameExtension MAXIMUM_VERBOSE_OUTPUT = 100 def verbose? - return ARGV.verbose? unless ENV["TRAVIS"] + return ARGV.verbose? unless ENV["CI"] return false unless ARGV.verbose? if total < MAXIMUM_VERBOSE_OUTPUT diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 4ac66ffc4..1355e5945 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -14,6 +14,7 @@ require "tap" require "keg" require "migrator" require "extend/ENV" +require "language/python" # A formula provides instructions and metadata for Homebrew to install a piece # of software. Every Homebrew formula is a {Formula}. @@ -962,6 +963,7 @@ class Formula "TEMP" => HOMEBREW_TEMP, "TMP" => HOMEBREW_TEMP, "HOMEBREW_PATH" => nil, + "PATH" => ENV["HOMEBREW_PATH"], } with_env(new_env) do @@ -1369,7 +1371,7 @@ class Formula def self.racks @racks ||= if HOMEBREW_CELLAR.directory? HOMEBREW_CELLAR.subdirs.reject do |rack| - rack.symlink? || rack.subdirs.empty? + rack.symlink? || rack.basename.to_s.start_with?(".") || rack.subdirs.empty? end else [] @@ -1485,15 +1487,10 @@ class Formula # Returns a list of Dependency objects that are required at runtime. # @private def runtime_dependencies - runtime_dependencies = recursive_dependencies do |_, dependency| + recursive_dependencies do |_, dependency| Dependency.prune if dependency.build? Dependency.prune if !dependency.required? && build.without?(dependency) end - runtime_requirement_deps = recursive_requirements do |_, requirement| - Requirement.prune if requirement.build? - Requirement.prune if !requirement.required? && build.without?(requirement) - end.map(&:to_dependency).compact - runtime_dependencies + runtime_requirement_deps end # Returns a list of formulae depended on by this formula that aren't @@ -1551,7 +1548,6 @@ class Formula hsh["requirements"] = requirements.map do |req| { "name" => req.name, - "default_formula" => req.default_formula, "cask" => req.cask, "download" => req.download, } @@ -1622,7 +1618,7 @@ class Formula TEMP: HOMEBREW_TEMP, TMP: HOMEBREW_TEMP, TERM: "dumb", - PATH: PATH.new(ENV["PATH"]).append(HOMEBREW_PREFIX/"bin"), + PATH: PATH.new(ENV["PATH"], HOMEBREW_PREFIX/"bin"), HOMEBREW_PATH: nil, _JAVA_OPTIONS: "#{ENV["_JAVA_OPTIONS"]} -Duser.home=#{HOMEBREW_CACHE}/java_cache", } @@ -2193,32 +2189,24 @@ class Formula # <pre># If a dependency is only needed in certain cases: # depends_on "sqlite" if MacOS.version == :leopard # depends_on :xcode # If the formula really needs full Xcode. - # depends_on :tex # Homebrew does not provide a Tex Distribution. - # depends_on :fortran # Checks that `gfortran` is available or `FC` is set. - # depends_on :mpi => :cc # Needs MPI with `cc` - # depends_on :mpi => [:cc, :cxx, :optional] # Is optional. MPI with `cc` and `cxx`. # depends_on :macos => :lion # Needs at least OS X Lion (10.7). - # depends_on :apr # If a formula requires the CLT-provided apr library to exist. # depends_on :arch => :intel # If this formula only builds on Intel architecture. # depends_on :arch => :x86_64 # If this formula only builds on Intel x86 64-bit. # depends_on :arch => :ppc # Only builds on PowerPC? # depends_on :ld64 # Sometimes ld fails on `MacOS.version < :leopard`. Then use this. - # depends_on :x11 # X11/XQuartz components. + # depends_on :x11 => :optional # X11/XQuartz components. # depends_on :osxfuse # Permits the use of the upstream signed binary or our source package. # depends_on :tuntap # Does the same thing as above. This is vital for Yosemite and above. - # depends_on :mysql => :recommended</pre> # <pre># It is possible to only depend on something if # # `build.with?` or `build.without? "another_formula"`: - # depends_on :mysql # allows brewed or external mysql to be used - # depends_on :postgresql if build.without? "sqlite" - # depends_on :hg # Mercurial (external or brewed) is needed</pre> + # depends_on "postgresql" if build.without? "sqlite" # - # <pre># If any Python >= 2.7 < 3.x is okay (either from macOS or brewed): - # depends_on :python</pre> - # <pre># to depend on Python >= 2.7 but use system Python where possible - # depends_on :python if MacOS.version <= :snow_leopard</pre> + # <pre># Python 2.7: + # 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> def depends_on(dep) specs.each { |spec| spec.depends_on(dep) } end diff --git a/Library/Homebrew/formula_assertions.rb b/Library/Homebrew/formula_assertions.rb index 2ba5767a7..f81087a3d 100644 --- a/Library/Homebrew/formula_assertions.rb +++ b/Library/Homebrew/formula_assertions.rb @@ -3,11 +3,6 @@ module Homebrew require "test/unit/assertions" include ::Test::Unit::Assertions - # TODO: remove this when we no longer support Ruby 2.0. - unless defined?(Test::Unit::AssertionFailedError) - Test::Unit::AssertionFailedError = MiniTest::Assertion - end - # Returns the output of running cmd, and asserts the exit status def shell_output(cmd, result = 0) ohai cmd diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index b5c5e7fb5..a89da9ae9 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -9,7 +9,6 @@ require "cleaner" require "formula_cellar_checks" require "install_renamed" require "cmd/postinstall" -require "hooks/bottles" require "debrew" require "sandbox" require "emoji" @@ -33,11 +32,11 @@ class FormulaInstaller attr_reader :formula attr_accessor :options, :build_bottle, :invalid_option_names - attr_accessor :installed_as_dependency, :installed_on_request + attr_accessor :installed_as_dependency, :installed_on_request, :link_keg mode_attr_accessor :show_summary_heading, :show_header mode_attr_accessor :build_from_source, :force_bottle mode_attr_accessor :ignore_deps, :only_deps, :interactive, :git - mode_attr_accessor :verbose, :debug, :quieter, :link_keg + mode_attr_accessor :verbose, :debug, :quieter def initialize(formula) @formula = formula @@ -71,8 +70,10 @@ class FormulaInstaller # can proceed. Only invoked when the user has no developer tools. def self.prevent_build_flags build_flags = ARGV.collect_build_flags + return if build_flags.empty? - raise BuildFlagsError, build_flags unless build_flags.empty? + all_bottled = ARGV.formulae.all?(&:bottled?) + raise BuildFlagsError.new(build_flags, bottled: all_bottled) end def build_bottle? @@ -81,8 +82,6 @@ class FormulaInstaller end def pour_bottle?(install_bottle_options = { warn: false }) - return true if Homebrew::Hooks::Bottles.formula_has_bottle?(formula) - return false if @pour_failed return false if !formula.bottled? && !formula.local_bottle_path @@ -152,7 +151,7 @@ class FormulaInstaller recursive_deps = formula.recursive_dependencies recursive_formulae = recursive_deps.map(&:to_formula) - recursive_runtime_deps = formula.recursive_dependencies.reject(&:build?) + recursive_runtime_deps = formula.runtime_dependencies recursive_runtime_formulae = recursive_runtime_deps.map(&:to_formula) recursive_dependencies = [] @@ -182,6 +181,7 @@ class FormulaInstaller recursive_runtime_formulae.each do |f| name = f.name unversioned_name, = name.split("@") + next if unversioned_name == "python" version_hash[unversioned_name] ||= Set.new version_hash[unversioned_name] << name next if version_hash[unversioned_name].length < 2 @@ -404,8 +404,8 @@ class FormulaInstaller fatals = [] req_map.each_pair do |dependent, reqs| - next if dependent.installed? reqs.each do |req| + next if dependent.installed? && req.name == "maximummacos" @requirement_messages << "#{dependent}: #{req.message}" fatals << req if req.fatal? end @@ -417,15 +417,6 @@ class FormulaInstaller raise UnsatisfiedRequirements, fatals end - def install_requirement_formula?(req_dependency, req, install_bottle_for_dependent) - return false unless req_dependency - return true unless req.satisfied? - return false if req.run? - return true if build_bottle? - return true if req.satisfied_by_formula? - install_bottle_for_dependent - end - def runtime_requirements(formula) runtime_deps = formula.runtime_dependencies.map(&:to_formula) recursive_requirements = formula.recursive_requirements do |dependent, _| @@ -444,17 +435,9 @@ class FormulaInstaller f.recursive_requirements do |dependent, req| build = effective_build_options_for(dependent) install_bottle_for_dependent = install_bottle_for?(dependent, build) - use_default_formula = install_bottle_for_dependent || build_bottle? - req_dependency = req.to_dependency(use_default_formula: use_default_formula) if (req.optional? || req.recommended?) && build.without?(req) Requirement.prune - elsif req.build? && use_default_formula - Requirement.prune - elsif install_requirement_formula?(req_dependency, req, install_bottle_for_dependent) - deps.unshift(req_dependency) - formulae.unshift(req_dependency.to_formula) - Requirement.prune elsif req.satisfied? Requirement.prune elsif !runtime_requirements.include?(req) && install_bottle_for_dependent @@ -485,6 +468,8 @@ class FormulaInstaller Dependency.prune elsif dep.build? && install_bottle_for?(dependent, build) Dependency.prune + elsif dep.build? && dependent.installed? + Dependency.prune elsif dep.satisfied?(inherited_options[dep.name]) Dependency.skip end @@ -552,18 +537,18 @@ class FormulaInstaller end fi = FormulaInstaller.new(df) - fi.options |= tab.used_options - fi.options |= Tab.remap_deprecated_options(df.deprecated_options, dep.options) - fi.options |= inherited_options - fi.options &= df.options - fi.build_from_source = ARGV.build_formula_from_source?(df) - fi.force_bottle = false - fi.verbose = verbose? - fi.quieter = quieter? - fi.debug = debug? - fi.link_keg = keg_was_linked if keg_had_linked_keg + fi.options |= tab.used_options + fi.options |= Tab.remap_deprecated_options(df.deprecated_options, dep.options) + fi.options |= inherited_options + fi.options &= df.options + fi.build_from_source = ARGV.build_formula_from_source?(df) + fi.force_bottle = false + fi.verbose = verbose? + fi.quieter = quieter? + fi.debug = debug? + fi.link_keg ||= keg_was_linked if keg_had_linked_keg fi.installed_as_dependency = true - fi.installed_on_request = false + fi.installed_on_request = df.any_version_installed? && tab.installed_on_request fi.prelude oh1 "Installing #{formula.full_name} dependency: #{Formatter.identifier(dep.name)}" fi.install @@ -855,10 +840,6 @@ class FormulaInstaller end def pour - if Homebrew::Hooks::Bottles.formula_has_bottle?(formula) - return if Homebrew::Hooks::Bottles.pour_formula_bottle(formula) - end - if (bottle_path = formula.local_bottle_path) downloader = LocalBottleDownloadStrategy.new(bottle_path) else diff --git a/Library/Homebrew/formula_support.rb b/Library/Homebrew/formula_support.rb index 53fd61db8..d44cf158f 100644 --- a/Library/Homebrew/formula_support.rb +++ b/Library/Homebrew/formula_support.rb @@ -32,15 +32,16 @@ class KegOnlyReason def to_s return @explanation unless @explanation.empty? + case @reason when :versioned_formula then <<~EOS this is an alternate version of another formula EOS - when :provided_by_macos, :provided_by_osx then <<~EOS + when :provided_by_macos then <<~EOS macOS already provides this software and installing another version in parallel can cause all kinds of trouble EOS - when :shadowed_by_macos, :shadowed_by_osx then <<~EOS + when :shadowed_by_macos then <<~EOS macOS provides similar software and installing this software in parallel can cause all kinds of trouble EOS diff --git a/Library/Homebrew/gpg.rb b/Library/Homebrew/gpg.rb deleted file mode 100644 index 83b525b44..000000000 --- a/Library/Homebrew/gpg.rb +++ /dev/null @@ -1,60 +0,0 @@ -require "utils" - -class Gpg - def self.find_gpg(executable) - which_all(executable).detect do |gpg| - gpg_short_version = Utils.popen_read(gpg, "--version")[/\d\.\d/, 0] - next unless gpg_short_version - gpg_version = Version.create(gpg_short_version.to_s) - @version = gpg_version - gpg_version >= Version.create("2.0") - end - end - - def self.executable - find_gpg("gpg") || find_gpg("gpg2") - end - - def self.available? - File.executable?(executable.to_s) - end - - def self.version - @version if available? - end - - def self.create_test_key(path) - odie "No GPG present to test against!" unless available? - - (path/"batch.gpg").write <<~EOS - Key-Type: RSA - Key-Length: 2048 - Subkey-Type: RSA - Subkey-Length: 2048 - Name-Real: Testing - Name-Email: testing@foo.bar - Expire-Date: 1d - %no-protection - %commit - EOS - system executable, "--batch", "--gen-key", "batch.gpg" - end - - def self.cleanup_test_processes! - odie "No GPG present to test against!" unless available? - gpgconf = Pathname.new(executable).parent/"gpgconf" - - system gpgconf, "--kill", "gpg-agent" - system gpgconf, "--homedir", "keyrings/live", "--kill", - "gpg-agent" - end - - def self.test(path) - create_test_key(path) - begin - yield - ensure - cleanup_test_processes! - end - end -end diff --git a/Library/Homebrew/hardware.rb b/Library/Homebrew/hardware.rb index 997598def..0559ae694 100644 --- a/Library/Homebrew/hardware.rb +++ b/Library/Homebrew/hardware.rb @@ -19,16 +19,48 @@ module Hardware end def arch_32_bit - :i386 + if arm? + :arm + elsif intel? + :i386 + elsif ppc? + :ppc32 + else + :dunno + end end def arch_64_bit - :x86_64 + if arm? + :arm64 + elsif intel? + :x86_64 + elsif ppc? + :ppc64 + else + :dunno + end + end + + def arch + case bits + when 32 + arch_32_bit + when 64 + arch_64_bit + else + :dunno + end + end + + def universal_archs + [arch].extend ArchitectureListExtension end def type case RUBY_PLATFORM when /x86_64/, /i\d86/ then :intel + when /arm/ then :arm when /ppc\d+/ then :ppc else :dunno end @@ -39,13 +71,16 @@ module Hardware end def cores - 1 + return @cores if @cores + @cores = Utils.popen_read("getconf", "_NPROCESSORS_ONLN").chomp.to_i + @cores = 1 unless $CHILD_STATUS.success? + @cores end def bits - case RUBY_PLATFORM - when /x86_64/, /ppc64/ then 64 - when /i\d86/, /ppc/ then 32 + @bits ||= case RUBY_PLATFORM + when /x86_64/, /ppc64/, /aarch64|arm64/ then 64 + when /i\d86/, /ppc/, /arm/ then 32 end end diff --git a/Library/Homebrew/hooks/bottles.rb b/Library/Homebrew/hooks/bottles.rb deleted file mode 100644 index c6612dea6..000000000 --- a/Library/Homebrew/hooks/bottles.rb +++ /dev/null @@ -1,35 +0,0 @@ -# Boxen (and perhaps others) want to override our bottling infrastructure so -# they can avoid declaring checksums in formulae files. -# Instead of periodically breaking their monkeypatches let's add some hooks that -# we can query to allow their own behaviour. - -# PLEASE DO NOT EVER RENAME THIS CLASS OR ADD/REMOVE METHOD ARGUMENTS! -module Homebrew - module Hooks - module Bottles - def self.setup_formula_has_bottle(&block) - @has_bottle = block - true - end - - def self.setup_pour_formula_bottle(&block) - @pour_bottle = block - true - end - - def self.formula_has_bottle?(formula) - return false unless @has_bottle - @has_bottle.call formula - end - - def self.pour_formula_bottle(formula) - return false unless @pour_bottle - @pour_bottle.call formula - end - - def self.reset_hooks - @has_bottle = @pour_bottle = nil - end - end - end -end diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb index bb9778c81..e3b93fa72 100644 --- a/Library/Homebrew/keg.rb +++ b/Library/Homebrew/keg.rb @@ -54,9 +54,10 @@ class Keg end class DirectoryNotWritableError < LinkError - def to_s; <<~EOS - Could not symlink #{src} - #{dst.dirname} is not writable. + def to_s + <<~EOS + Could not symlink #{src} + #{dst.dirname} is not writable. EOS end end diff --git a/Library/Homebrew/keg_relocate.rb b/Library/Homebrew/keg_relocate.rb index 71773db81..f70bbcbac 100644 --- a/Library/Homebrew/keg_relocate.rb +++ b/Library/Homebrew/keg_relocate.rb @@ -96,7 +96,7 @@ class Keg alias generic_recursive_fgrep_args recursive_fgrep_args def each_unique_file_matching(string) - Utils.popen_read("/usr/bin/fgrep", recursive_fgrep_args, string, to_s) do |io| + Utils.popen_read("fgrep", recursive_fgrep_args, string, to_s) do |io| hardlinks = Set.new until io.eof? @@ -113,7 +113,7 @@ class Keg def text_files text_files = [] - return text_files unless File.exist?("/usr/bin/file") + return text_files unless which("file") && which("xargs") # file has known issues with reading files on other locales. Has # been fixed upstream for some time, but a sufficiently new enough @@ -132,7 +132,7 @@ class Keg end false } - output, _status = Open3.capture2("/usr/bin/xargs -0 /usr/bin/file --no-dereference --print0", + output, _status = Open3.capture2("xargs -0 file --no-dereference --print0", stdin_data: files.to_a.join("\0")) # `file` output sometimes contains data from the file, which may include # invalid UTF-8 entities, so tell Ruby this is just a bytestring diff --git a/Library/Homebrew/language/python.rb b/Library/Homebrew/language/python.rb index 49e3d1a46..3908f4b8f 100644 --- a/Library/Homebrew/language/python.rb +++ b/Library/Homebrew/language/python.rb @@ -35,7 +35,7 @@ module Language probe_file = homebrew_site_packages(version)/"homebrew-pth-probe.pth" begin probe_file.atomic_write("import site; site.homebrew_was_here = True") - quiet_system python, "-c", "import site; assert(site.homebrew_was_here)" + with_homebrew_path { quiet_system python, "-c", "import site; assert(site.homebrew_was_here)" } ensure probe_file.unlink if probe_file.exist? end @@ -71,10 +71,6 @@ module Language ] end - def self.package_available?(python, module_name) - quiet_system python, "-c", "import #{module_name}" - end - # Mixin module for {Formula} adding virtualenv support features. module Virtualenv def self.included(base) @@ -138,11 +134,11 @@ module Language def virtualenv_install_with_resources(options = {}) python = options[:using] if python.nil? - wanted = %w[python python3].select { |py| needs_python?(py) } + wanted = %w[python python@2 python@3 python3].select { |py| needs_python?(py) } raise FormulaAmbiguousPythonError, self if wanted.size > 1 - python = wanted.first || "python" + python = wanted.first || "python2.7" end - venv = virtualenv_create(libexec, python) + venv = virtualenv_create(libexec, python.delete("@")) venv.pip_install resources venv.pip_install_and_link buildpath venv diff --git a/Library/Homebrew/manpages/brew-cask.1.md b/Library/Homebrew/manpages/brew-cask.1.md index 1c7c198b0..4b70822ee 100644 --- a/Library/Homebrew/manpages/brew-cask.1.md +++ b/Library/Homebrew/manpages/brew-cask.1.md @@ -86,7 +86,7 @@ names, and other aspects of this manual are still subject to change. If <token> is given, summarize the staged files associated with the given Cask. - * `outdated` [--greedy] [--verbose|--quiet] [ <token> ...]: + * `outdated` [--greedy] [--verbose|--quiet] [ <token> ... ]: Without token arguments, display all the installed Casks that have newer versions available in the tap; otherwise check only the tokens given in the command line. @@ -116,6 +116,13 @@ names, and other aspects of this manual are still subject to change. Uninstall the given Cask. With `--force`, uninstall even if the Cask does not appear to be present. + * `upgrade` [--force] [--greedy] <token> [ <token> ... ]: + Without token arguments, upgrade all the installed Casks that have newer + versions available in the tap; otherwise update the tokens given + in the command line. + If `--greedy` is given then also upgrade the Casks having `auto_updates true` + or `version :latest`. + * `zap` <token> [ <token> ... ]: Unconditionally remove _all_ files associated with the given Cask. @@ -218,7 +225,7 @@ Homebrew-Cask is implemented as a external command for Homebrew. That means this project is entirely built upon the Homebrew infrastructure. For example, upgrades to the Homebrew-Cask tool are received through Homebrew: - brew update; brew cleanup; brew cask cleanup + brew update; brew cask upgrade; brew cleanup; brew cask cleanup And updates to individual Cask definitions are received whenever you issue the Homebrew command: diff --git a/Library/Homebrew/manpages/brew.1.md.erb b/Library/Homebrew/manpages/brew.1.md.erb index 71d93f120..508c90f2d 100644 --- a/Library/Homebrew/manpages/brew.1.md.erb +++ b/Library/Homebrew/manpages/brew.1.md.erb @@ -160,9 +160,13 @@ can take several different forms: directories. TextMate can handle this correctly in project mode, but many editors will do strange things in this case. + * `HOMEBREW_FORCE_BREWED_CURL`: + If set, Homebrew will use a Homebrew-installed `curl` rather than the + system version. + * `HOMEBREW_FORCE_VENDOR_RUBY`: - If set, Homebrew will always use its vendored, relocatable Ruby 2.0 version - even if the system version of Ruby is >=2.0. + If set, Homebrew will always use its vendored, relocatable Ruby version + even if the system version of Ruby is new enough. * `HOMEBREW_GIT`: When using Git, Homebrew will use `GIT` if set, @@ -235,20 +239,38 @@ can take several different forms: * `HOMEBREW_VERBOSE`: If set, Homebrew always assumes `--verbose` when running commands. + * `http_proxy`: + Sets the HTTP proxy to be used by `curl`, `git` and `svn` when downloading + through Homebrew. + + * `https_proxy`: + Sets the HTTPS proxy to be used by `curl`, `git` and `svn` when downloading + through Homebrew. + + * `all_proxy`: + Sets the SOCKS5 proxy to be used by `curl`, `git` and `svn` when downloading + through Homebrew. + + * `ftp_proxy`: + Sets the FTP proxy to be used by `curl`, `git` and `svn` when downloading + through Homebrew. + + * `no_proxy`: + Sets the comma-separated list of hostnames and domain names that should be excluded from proxying + by `curl`, `git` and `svn` when downloading through Homebrew. + ## USING HOMEBREW BEHIND A PROXY +Use the `http_proxy`, `https_proxy`, `all_proxy`, `no_proxy` and/or `ftp_proxy` documented above. -Homebrew uses several commands for downloading files (e.g. `curl`, `git`, `svn`). -Many of these tools can download via a proxy. It's common for these tools -to read proxy parameters from environment variables. +For example for an unauthenticated HTTP or SOCKS5 proxy: -For the majority of cases setting `http_proxy` is enough. You can set this in -your shell profile, or you can use it before a brew command: + export http_proxy=http://<host>:<port> - http_proxy=http://<host>:<port> brew install foo + export all_proxy=socks5://<host>:<port> -If your proxy requires authentication: +And for an authenticated HTTP proxy: - http_proxy=http://<user>:<password>@<host>:<port> brew install foo + export http_proxy=http://<user>:<password>@<host>:<port> ## SEE ALSO @@ -262,7 +284,9 @@ Homebrew Documentation: <https://docs.brew.sh> <%= core_maintainer.concat("\n") %> -<%= maintainers.concat("\n") %> +<%= brew_maintainers.concat("\n") %> + +<%= core_maintainers.concat("\n") %> <%= former_maintainers.concat("\n") %> diff --git a/Library/Homebrew/missing_formula.rb b/Library/Homebrew/missing_formula.rb index 97ed5749a..146c3e984 100644 --- a/Library/Homebrew/missing_formula.rb +++ b/Library/Homebrew/missing_formula.rb @@ -122,7 +122,7 @@ module Homebrew tap.path.cd do unless silent - ohai "Searching for a previously deleted formula..." + ohai "Searching for a previously deleted formula (in the last month)..." if (tap.path/".git/shallow").exist? opoo <<~EOS #{tap} is shallow clone. To get complete history run: @@ -132,7 +132,7 @@ module Homebrew end end - log_command = "git log --name-only --max-count=1 --format=%H\\\\n%h\\\\n%B -- #{relative_path}" + log_command = "git log --since='1 month ago' --diff-filter=D --name-only --max-count=1 --format=%H\\\\n%h\\\\n%B -- #{relative_path}" hash, short_hash, *commit_message, relative_path = Utils.popen_read(log_command).gsub("\\n", "\n").lines.map(&:chomp) diff --git a/Library/Homebrew/official_taps.rb b/Library/Homebrew/official_taps.rb index d2e4753d9..7eace302a 100644 --- a/Library/Homebrew/official_taps.rb +++ b/Library/Homebrew/official_taps.rb @@ -1,6 +1,5 @@ OFFICIAL_TAPS = %w[ php - science ].freeze OFFICIAL_CASK_TAPS = %w[ @@ -27,6 +26,7 @@ DEPRECATED_OFFICIAL_TAPS = %w[ head-only nginx python + science tex versions x11 diff --git a/Library/Homebrew/os/linux/elf.rb b/Library/Homebrew/os/linux/elf.rb new file mode 100644 index 000000000..1a53e50f3 --- /dev/null +++ b/Library/Homebrew/os/linux/elf.rb @@ -0,0 +1,160 @@ +module ELFShim + # See: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header + MAGIC_NUMBER_OFFSET = 0 + MAGIC_NUMBER_ASCII = "\x7fELF".freeze + + OS_ABI_OFFSET = 0x07 + OS_ABI_SYSTEM_V = 0 + OS_ABI_LINUX = 3 + + TYPE_OFFSET = 0x10 + TYPE_EXECUTABLE = 2 + TYPE_SHARED = 3 + + ARCHITECTURE_OFFSET = 0x12 + ARCHITECTURE_I386 = 0x3 + ARCHITECTURE_POWERPC = 0x14 + ARCHITECTURE_ARM = 0x28 + ARCHITECTURE_X86_64 = 0x62 + ARCHITECTURE_AARCH64 = 0xB7 + + def read_uint8(offset) + read(1, offset).unpack("C").first + end + + def read_uint16(offset) + read(2, offset).unpack("v").first + end + + def elf? + return @elf if defined? @elf + return @elf = false unless read(MAGIC_NUMBER_ASCII.size, MAGIC_NUMBER_OFFSET) == MAGIC_NUMBER_ASCII + + # Check that this ELF file is for Linux or System V. + # OS_ABI is often set to 0 (System V), regardless of the target platform. + @elf = [OS_ABI_LINUX, OS_ABI_SYSTEM_V].include? read_uint8(OS_ABI_OFFSET) + end + + def arch + return :dunno unless elf? + + @arch ||= case read_uint16(ARCHITECTURE_OFFSET) + when ARCHITECTURE_I386 then :i386 + when ARCHITECTURE_X86_64 then :x86_64 + when ARCHITECTURE_POWERPC then :powerpc + when ARCHITECTURE_ARM then :arm + when ARCHITECTURE_AARCH64 then :arm64 + else :dunno + end + end + + def elf_type + return :dunno unless elf? + + @elf_type ||= case read_uint16(TYPE_OFFSET) + when TYPE_EXECUTABLE then :executable + when TYPE_SHARED then :dylib + else :dunno + end + end + + def dylib? + elf_type == :dylib + end + + def binary_executable? + elf_type == :executable + end + + def dynamic_elf? + return @dynamic_elf if defined? @dynamic_elf + + if which "readelf" + Utils.popen_read("readelf", "-l", to_path).include?(" DYNAMIC ") + elsif which "file" + !Utils.popen_read("file", "-L", "-b", to_path)[/dynamic|shared/].nil? + else + raise "Please install either readelf (from binutils) or file." + end + end + + class Metadata + attr_reader :path, :dylib_id, :dylibs + + def initialize(path) + @path = path + @dylibs = [] + @dylib_id, needed = needed_libraries path + return if needed.empty? + + ldd = DevelopmentTools.locate "ldd" + ldd_output = Utils.popen_read(ldd, path.expand_path.to_s).split("\n") + return unless $CHILD_STATUS.success? + + ldd_paths = ldd_output.map do |line| + match = line.match(/\t.+ => (.+) \(.+\)|\t(.+) => not found/) + next unless match + match.captures.compact.first + end.compact + @dylibs = ldd_paths.select do |ldd_path| + next true unless ldd_path.start_with? "/" + needed.include? File.basename(ldd_path) + end + end + + private + + def needed_libraries(path) + if DevelopmentTools.locate "readelf" + needed_libraries_using_readelf path + elsif DevelopmentTools.locate "patchelf" + needed_libraries_using_patchelf path + else + raise "patchelf must be installed: brew install patchelf" + end + end + + def needed_libraries_using_patchelf(path) + patchelf = DevelopmentTools.locate "patchelf" + if path.dylib? + command = [patchelf, "--print-soname", path.expand_path.to_s] + soname = Utils.popen_read(*command).chomp + raise ErrorDuringExecution, command unless $CHILD_STATUS.success? + end + command = [patchelf, "--print-needed", path.expand_path.to_s] + needed = Utils.popen_read(*command).split("\n") + raise ErrorDuringExecution, command unless $CHILD_STATUS.success? + [soname, needed] + end + + def needed_libraries_using_readelf(path) + soname = nil + needed = [] + command = ["readelf", "-d", path.expand_path.to_s] + lines = Utils.popen_read(*command).split("\n") + raise ErrorDuringExecution, command unless $CHILD_STATUS.success? + lines.each do |s| + filename = s[/\[(.*)\]/, 1] + next if filename.nil? + if s.include? "(SONAME)" + soname = filename + elsif s.include? "(NEEDED)" + needed << filename + end + end + [soname, needed] + end + end + + def metadata + @metadata ||= Metadata.new(self) + end + + def dylib_id + metadata.dylib_id + end + + def dynamically_linked_libraries(*) + metadata.dylibs + end +end diff --git a/Library/Homebrew/os/linux/glibc.rb b/Library/Homebrew/os/linux/glibc.rb new file mode 100644 index 000000000..710946bbc --- /dev/null +++ b/Library/Homebrew/os/linux/glibc.rb @@ -0,0 +1,14 @@ +module OS + module Linux + module Glibc + module_function + + def system_version + return @system_version if @system_version + version = Utils.popen_read("/usr/bin/ldd", "--version")[/ (\d+\.\d+)/, 1] + return Version::NULL unless version + @system_version = Version.new version + end + end + end +end diff --git a/Library/Homebrew/ld64_dependency.rb b/Library/Homebrew/os/mac/ld64_dependency.rb index a506a0ab2..a506a0ab2 100644 --- a/Library/Homebrew/ld64_dependency.rb +++ b/Library/Homebrew/os/mac/ld64_dependency.rb diff --git a/Library/Homebrew/os/mac/linkage_checker.rb b/Library/Homebrew/os/mac/linkage_checker.rb index f6aa4c2f3..cf6c12f22 100644 --- a/Library/Homebrew/os/mac/linkage_checker.rb +++ b/Library/Homebrew/os/mac/linkage_checker.rb @@ -14,6 +14,7 @@ class LinkageChecker @system_dylibs = Set.new @broken_dylibs = Set.new @variable_dylibs = Set.new + @indirect_deps = [] @undeclared_deps = [] @reverse_links = Hash.new { |h, k| h[k] = Set.new } @unnecessary_deps = [] @@ -23,7 +24,7 @@ class LinkageChecker def check_dylibs @keg.find do |file| next if file.symlink? || file.directory? - next unless file.dylib? || file.mach_o_executable? || file.mach_o_bundle? + next unless file.dylib? || file.binary_executable? || file.mach_o_bundle? # weakly loaded dylibs may not actually exist on disk, so skip them # when checking for broken linkage @@ -52,7 +53,7 @@ class LinkageChecker end end - @undeclared_deps, @unnecessary_deps = check_undeclared_deps if formula + @indirect_deps, @undeclared_deps, @unnecessary_deps = check_undeclared_deps if formula end def check_undeclared_deps @@ -62,14 +63,31 @@ class LinkageChecker formula.build.without?(dep) end declared_deps = formula.deps.reject { |dep| filter_out.call(dep) }.map(&:name) - declared_requirement_deps = formula.requirements.reject { |req| filter_out.call(req) }.map(&:default_formula).compact - declared_dep_names = (declared_deps + declared_requirement_deps).map { |dep| dep.split("/").last } - undeclared_deps = @brewed_dylibs.keys.reject do |full_name| + recursive_deps = keg.to_formula.runtime_dependencies.map { |dep| dep.to_formula.full_name } + declared_dep_names = declared_deps.map { |dep| dep.split("/").last } + indirect_deps = [] + undeclared_deps = [] + @brewed_dylibs.each_key do |full_name| name = full_name.split("/").last - next true if name == formula.name - declared_dep_names.include?(name) + next if name == formula.name + if recursive_deps.include?(name) + indirect_deps << full_name unless declared_dep_names.include?(name) + else + undeclared_deps << full_name + end + end + sort_by_formula_full_name!(indirect_deps) + sort_by_formula_full_name!(undeclared_deps) + unnecessary_deps = declared_dep_names.reject do |full_name| + name = full_name.split("/").last + next true if Formula[name].bin.directory? + @brewed_dylibs.keys.map { |x| x.split("/").last }.include?(name) end - undeclared_deps.sort do |a, b| + [indirect_deps, undeclared_deps, unnecessary_deps] + end + + def sort_by_formula_full_name!(arr) + arr.sort! do |a, b| if a.include?("/") && !b.include?("/") 1 elsif !a.include?("/") && b.include?("/") @@ -78,17 +96,12 @@ class LinkageChecker a <=> b end end - unnecessary_deps = declared_dep_names.reject do |full_name| - name = full_name.split("/").last - next true if Formula[name].bin.directory? - @brewed_dylibs.keys.map { |x| x.split("/").last }.include?(name) - end - [undeclared_deps, unnecessary_deps] end def display_normal_output display_items "System libraries", @system_dylibs display_items "Homebrew libraries", @brewed_dylibs + display_items "Indirect dependencies with linkage", @indirect_deps display_items "Variable-referenced libraries", @variable_dylibs display_items "Missing libraries", @broken_dylibs display_items "Undeclared dependencies with linkage", @undeclared_deps diff --git a/Library/Homebrew/os/mac/mach.rb b/Library/Homebrew/os/mac/mach.rb index 9b53c4979..958618869 100644 --- a/Library/Homebrew/os/mac/mach.rb +++ b/Library/Homebrew/os/mac/mach.rb @@ -103,6 +103,8 @@ module MachOShim mach_data.any? { |m| m.fetch(:type) == :executable } end + alias binary_executable? mach_o_executable? + # @private def mach_o_bundle? mach_data.any? { |m| m.fetch(:type) == :bundle } diff --git a/Library/Homebrew/os/mac/xcode.rb b/Library/Homebrew/os/mac/xcode.rb index 0b1cc7146..f977a066d 100644 --- a/Library/Homebrew/os/mac/xcode.rb +++ b/Library/Homebrew/os/mac/xcode.rb @@ -17,13 +17,13 @@ module OS when "10.9" then "6.2" when "10.10" then "7.2.1" when "10.11" then "8.2.1" - when "10.12" then "9.1" - when "10.13" then "9.1" + when "10.12" then "9.2" + when "10.13" then "9.2" else raise "macOS '#{MacOS.version}' is invalid" unless OS::Mac.prerelease? # Default to newest known version of Xcode for unreleased macOS versions. - "9.1" + "9.2" end end @@ -141,7 +141,11 @@ module OS end end - # The remaining logic provides a fake Xcode version based on the + detect_version_from_clang_version + end + + def detect_version_from_clang_version + # This logic provides a fake Xcode version based on the # installed CLT version. This is useful as they are packaged # simultaneously so workarounds need to apply to both based on their # comparable version. @@ -166,7 +170,7 @@ module OS when 80 then "8.0" when 81 then "8.3" when 90 then "9.0" - else "9.0" + else "9.0" end end @@ -217,14 +221,13 @@ module OS # on the older supported platform for that Xcode release, i.e there's no # CLT package for 10.11 that contains the Clang version from Xcode 8. case MacOS.version - when "10.13" then "900.0.38" - when "10.12" then "900.0.38" + when "10.13" then "900.0.39.2" + when "10.12" then "900.0.39.2" when "10.11" then "800.0.42.1" when "10.10" then "700.1.81" when "10.9" then "600.0.57" when "10.8" then "503.0.40" - else - "425.0.28" + else "425.0.28" end end @@ -232,7 +235,7 @@ module OS case MacOS.version when "10.13" then "9.0.0" when "10.12" then "8.0.0" - else "1.0.0" + else "1.0.0" end end diff --git a/Library/Homebrew/os/mac/xquartz.rb b/Library/Homebrew/os/mac/xquartz.rb index efbb5b738..9148e178b 100644 --- a/Library/Homebrew/os/mac/xquartz.rb +++ b/Library/Homebrew/os/mac/xquartz.rb @@ -51,6 +51,15 @@ module OS end end + def minimum_version + version = guess_system_version + return version unless version == "dunno" + + # Update this a little later than latest_version to give people + # time to upgrade. + "2.7.11" + end + # https://xquartz.macosforge.org/trac/wiki # https://xquartz.macosforge.org/trac/wiki/Releases def latest_version diff --git a/Library/Homebrew/patch.rb b/Library/Homebrew/patch.rb index 1b379ba0f..77021480c 100644 --- a/Library/Homebrew/patch.rb +++ b/Library/Homebrew/patch.rb @@ -119,7 +119,7 @@ class ExternalPatch def initialize(strip, &block) @strip = strip - @resource = Resource::Patch.new(&block) + @resource = Resource::PatchResource.new(&block) end def external? diff --git a/Library/Homebrew/requirement.rb b/Library/Homebrew/requirement.rb index 95807d5ae..f70746c31 100644 --- a/Library/Homebrew/requirement.rb +++ b/Library/Homebrew/requirement.rb @@ -9,13 +9,11 @@ require "build_environment" class Requirement include Dependable - attr_reader :tags, :name, :cask, :download, :default_formula + attr_reader :tags, :name, :cask, :download def initialize(tags = []) - @default_formula = self.class.default_formula @cask ||= self.class.cask @download ||= self.class.download - @formula = nil tags.each do |tag| next unless tag.is_a? Hash @cask ||= tag[:cask] @@ -50,31 +48,22 @@ class Requirement s end - # Overriding #satisfied? is deprecated. + # Overriding #satisfied? is unsupported. # Pass a block or boolean to the satisfy DSL method instead. def satisfied? - result = self.class.satisfy.yielder { |p| instance_eval(&p) } - @satisfied_result = result - return false unless result - - if parent = satisfied_result_parent - parent.to_s =~ %r{(#{Regexp.escape(HOMEBREW_CELLAR)}|#{Regexp.escape(HOMEBREW_PREFIX)}/opt)/([\w+-.@]+)} - @formula = Regexp.last_match(2) - end - + satisfy = self.class.satisfy + return true unless satisfy + @satisfied_result = satisfy.yielder { |p| instance_eval(&p) } + return false unless @satisfied_result true end - # Overriding #fatal? is deprecated. + # Overriding #fatal? is unsupported. # Pass a boolean to the fatal DSL method instead. def fatal? self.class.fatal || false end - def default_formula? - self.class.default_formula || false - end - def satisfied_result_parent return unless @satisfied_result.is_a?(Pathname) parent = @satisfied_result.resolved_path.parent @@ -84,11 +73,10 @@ class Requirement parent end - # Overriding #modify_build_environment is deprecated. + # Overriding #modify_build_environment is unsupported. # Pass a block to the env DSL method instead. - # Note: #satisfied? should be called before invoking this method - # as the env modifications may depend on its side effects. def modify_build_environment + satisfied? instance_eval(&env_proc) if env_proc # XXX If the satisfy block returns a Pathname, then make sure that it @@ -124,24 +112,6 @@ class Requirement "#<#{self.class.name}: #{name.inspect} #{tags.inspect}>" end - def formula - @formula || self.class.default_formula - end - - def satisfied_by_formula? - !@formula.nil? - end - - def to_dependency(use_default_formula: false) - if use_default_formula && default_formula? - Dependency.new(self.class.default_formula, tags, method(:modify_build_environment), name) - elsif formula =~ HOMEBREW_TAP_FORMULA_REGEX - TapDependency.new(formula, tags, method(:modify_build_environment), name) - elsif formula - Dependency.new(formula, tags, method(:modify_build_environment), name) - end - end - def display_s name end @@ -167,11 +137,16 @@ class Requirement include BuildEnvironment::DSL attr_reader :env_proc, :build - attr_rw :fatal, :default_formula - attr_rw :cask, :download + attr_rw :fatal, :cask, :download + + def default_formula(_val = nil) + odeprecated "Requirement.default_formula" + end - def satisfy(options = {}, &block) - @satisfied ||= Requirement::Satisfier.new(options, &block) + def satisfy(options = nil, &block) + return @satisfied if options.nil? && !block_given? + options = {} if options.nil? + @satisfied = Requirement::Satisfier.new(options, &block) end def env(*settings, &block) diff --git a/Library/Homebrew/requirements.rb b/Library/Homebrew/requirements.rb index d5992b88d..6128db516 100644 --- a/Library/Homebrew/requirements.rb +++ b/Library/Homebrew/requirements.rb @@ -1,139 +1,11 @@ require "requirement" -require "requirements/fortran_requirement" -require "requirements/gpg2_requirement" -require "requirements/language_module_requirement" require "requirements/linux_requirement" require "requirements/macos_requirement" require "requirements/maximum_macos_requirement" -require "requirements/mpi_requirement" require "requirements/osxfuse_requirement" -require "requirements/perl_requirement" -require "requirements/python_requirement" require "requirements/java_requirement" -require "requirements/ruby_requirement" require "requirements/tuntap_requirement" require "requirements/unsigned_kext_requirement" require "requirements/x11_requirement" -require "requirements/emacs_requirement" - -class XcodeRequirement < Requirement - fatal true - - satisfy(build_env: false) { xcode_installed_version } - - def initialize(tags) - @version = tags.find { |tag| tags.delete(tag) if tag =~ /(\d\.)+\d/ } - super - end - - def xcode_installed_version - return false unless MacOS::Xcode.installed? - return true unless @version - MacOS::Xcode.version >= @version - end - - def message - version = " #{@version}" if @version - message = <<~EOS - A full installation of Xcode.app#{version} is required to compile this software. - Installing just the Command Line Tools is not sufficient. - EOS - if MacOS.version >= :lion - message + <<~EOS - Xcode can be installed from the App Store. - EOS - else - message + <<~EOS - Xcode can be installed from #{Formatter.url("https://developer.apple.com/download/more/")}. - EOS - end - end - - def inspect - "#<#{self.class.name}: #{name.inspect} #{tags.inspect} version=#{@version.inspect}>" - end -end - -class MysqlRequirement < Requirement - fatal true - default_formula "mysql" - - satisfy { which "mysql_config" } -end - -class PostgresqlRequirement < Requirement - fatal true - default_formula "postgresql" - - satisfy { which "pg_config" } -end - -class RbenvRequirement < Requirement - fatal true - default_formula "rbenv" - - satisfy { which "rbenv" } -end - -class TeXRequirement < Requirement - fatal true - cask "mactex" - download "https://www.tug.org/mactex/" - - satisfy { which("tex") || which("latex") } - - def message - s = <<~EOS - A LaTeX distribution is required for Homebrew to install this formula. - - Make sure that "/usr/texbin", or the location you installed it to, is in - your PATH before proceeding. - EOS - s += super - s - end -end - -class ArchRequirement < Requirement - fatal true - - def initialize(arch) - @arch = arch.pop - super - end - - satisfy(build_env: false) do - case @arch - when :x86_64 then MacOS.prefer_64_bit? - when :intel, :ppc then Hardware::CPU.type == @arch - end - end - - def message - "This formula requires an #{@arch} architecture." - end -end - -class CVSRequirement < Requirement - fatal true - default_formula "cvs" - satisfy { which "cvs" } -end - -class MercurialRequirement < Requirement - fatal true - default_formula "mercurial" - satisfy { which("hg") } -end - -class GitRequirement < Requirement - fatal true - default_formula "git" - satisfy { Utils.git_available? } -end - -class SubversionRequirement < Requirement - fatal true - default_formula "subversion" - satisfy { Utils.svn_available? } -end +require "requirements/arch_requirement" +require "requirements/xcode_requirement" diff --git a/Library/Homebrew/requirements/arch_requirement.rb b/Library/Homebrew/requirements/arch_requirement.rb new file mode 100644 index 000000000..0ff52dfa8 --- /dev/null +++ b/Library/Homebrew/requirements/arch_requirement.rb @@ -0,0 +1,21 @@ +require "requirement" + +class ArchRequirement < Requirement + fatal true + + def initialize(arch) + @arch = arch.pop + super + end + + satisfy(build_env: false) do + case @arch + when :x86_64 then MacOS.prefer_64_bit? + when :intel, :ppc then Hardware::CPU.type == @arch + end + end + + def message + "This formula requires an #{@arch} architecture." + end +end diff --git a/Library/Homebrew/requirements/emacs_requirement.rb b/Library/Homebrew/requirements/emacs_requirement.rb deleted file mode 100644 index c8e2ec274..000000000 --- a/Library/Homebrew/requirements/emacs_requirement.rb +++ /dev/null @@ -1,35 +0,0 @@ -class EmacsRequirement < Requirement - fatal true - default_formula "emacs" - - def initialize(tags) - @version = tags.shift if /\d+\.*\d*/ =~ tags.first - super - end - - satisfy build_env: false do - next false unless which "emacs" - next true unless @version - emacs_version = Utils.popen_read("emacs", "--batch", "--eval", "(princ emacs-version)") - Version.create(emacs_version) >= Version.create(@version) - end - - env do - ENV.prepend_path "PATH", which("emacs").dirname - ENV["EMACS"] = "emacs" - end - - def message - if @version - s = "Emacs #{@version} or later is required." - else - s = "Emacs is required." - end - s += super - s - end - - def inspect - "#<#{self.class.name}: #{name.inspect} #{tags.inspect} version=#{@version.inspect}>" - end -end diff --git a/Library/Homebrew/requirements/fortran_requirement.rb b/Library/Homebrew/requirements/fortran_requirement.rb deleted file mode 100644 index ba3fead6f..000000000 --- a/Library/Homebrew/requirements/fortran_requirement.rb +++ /dev/null @@ -1,13 +0,0 @@ -require "requirement" - -class FortranRequirement < Requirement - fatal true - - default_formula "gcc" - - env { ENV.fortran } - - satisfy build_env: false do - which(ENV["FC"] || "gfortran") - end -end diff --git a/Library/Homebrew/requirements/gpg2_requirement.rb b/Library/Homebrew/requirements/gpg2_requirement.rb deleted file mode 100644 index 04097f9be..000000000 --- a/Library/Homebrew/requirements/gpg2_requirement.rb +++ /dev/null @@ -1,12 +0,0 @@ -require "requirement" -require "gpg" - -class GPG2Requirement < Requirement - fatal true - default_formula "gnupg" - - # GPGTools installs GnuPG 2.0.x as a `gpg` symlink pointing - # to `gpg2`. Our `gnupg` installs only a non-symlink `gpg`. - # The aim is to retain support for any version above 2.0. - satisfy(build_env: false) { Gpg.available? } -end diff --git a/Library/Homebrew/requirements/java_requirement.rb b/Library/Homebrew/requirements/java_requirement.rb index 949978dbd..213203ff3 100644 --- a/Library/Homebrew/requirements/java_requirement.rb +++ b/Library/Homebrew/requirements/java_requirement.rb @@ -10,7 +10,7 @@ class JavaRequirement < Requirement next true end - def initialize(tags) + def initialize(tags = []) @version = tags.shift if /(\d+\.)+\d/ =~ tags.first super end @@ -103,7 +103,7 @@ class JavaRequirement < Requirement end def satisfies_version(java) - java_version_s = Utils.popen_read("#{java} -version 2>&1")[/\d+.\d/] + java_version_s = Utils.popen_read(java, "-version", err: :out)[/\d+.\d/] return false unless java_version_s java_version = Version.create(java_version_s) needed_version = Version.create(version_without_plus) diff --git a/Library/Homebrew/requirements/mpi_requirement.rb b/Library/Homebrew/requirements/mpi_requirement.rb deleted file mode 100644 index 065b56c8b..000000000 --- a/Library/Homebrew/requirements/mpi_requirement.rb +++ /dev/null @@ -1,66 +0,0 @@ -require "requirement" - -# There are multiple implementations of MPI-2 available. -# http://www.mpi-forum.org/ -# This requirement is used to find an appropriate one. -class MPIRequirement < Requirement - attr_reader :lang_list - - fatal true - - default_formula "open-mpi" - - env :userpaths - - # This method must accept varargs rather than an array for - # backwards compatibility with formulae that call it directly. - def initialize(*tags) - @non_functional = [] - @unknown_langs = [] - @lang_list = [:cc, :cxx, :f77, :f90] & tags - tags -= @lang_list - super(tags) - end - - def mpi_wrapper_works?(compiler) - compiler = which compiler - return false if compiler.nil? || !compiler.executable? - - # Some wrappers are non-functional and will return a non-zero exit code - # when invoked for version info. - # - # NOTE: A better test may be to do a small test compilation a la autotools. - quiet_system compiler, "--version" - end - - def inspect - "#<#{self.class.name}: #{name.inspect} #{tags.inspect} lang_list=#{@lang_list.inspect}>" - end - - satisfy do - @lang_list.each do |lang| - case lang - when :cc, :cxx, :f90, :f77 - compiler = "mpi" + lang.to_s - @non_functional << compiler unless mpi_wrapper_works? compiler - else - @unknown_langs << lang.to_s - end - end - @unknown_langs.empty? && @non_functional.empty? - end - - env do - # Set environment variables to help configure scripts find MPI compilers. - # Variable names taken from: - # https://www.gnu.org/software/autoconf-archive/ax_mpi.html - @lang_list.each do |lang| - compiler = "mpi" + lang.to_s - mpi_path = which compiler - - # Fortran 90 environment var has a different name - compiler = "MPIFC" if lang == :f90 - ENV[compiler.upcase] = mpi_path - end - end -end diff --git a/Library/Homebrew/requirements/perl_requirement.rb b/Library/Homebrew/requirements/perl_requirement.rb deleted file mode 100644 index 70eb2a36c..000000000 --- a/Library/Homebrew/requirements/perl_requirement.rb +++ /dev/null @@ -1,36 +0,0 @@ -class PerlRequirement < Requirement - fatal true - default_formula "perl" - - def initialize(tags) - @version = tags.shift if /^\d+\.\d+$/ =~ tags.first - raise "PerlRequirement requires a version!" unless @version - super - end - - satisfy(build_env: false) do - which_all("perl").detect do |perl| - perl_version = Utils.popen_read(perl, "--version")[/v(\d+\.\d+)(?:\.\d+)?/, 1] - next unless perl_version - Version.create(perl_version.to_s) >= Version.create(@version) - end - end - - def message - s = "Perl #{@version} is required to install this formula." - s += super - s - end - - def inspect - "#<#{self.class.name}: #{name.inspect} #{tags.inspect} version=#{@version.inspect}>" - end - - def display_s - if @version - "#{name} >= #{@version}" - else - name - end - end -end diff --git a/Library/Homebrew/requirements/python_requirement.rb b/Library/Homebrew/requirements/python_requirement.rb deleted file mode 100644 index c162b072c..000000000 --- a/Library/Homebrew/requirements/python_requirement.rb +++ /dev/null @@ -1,65 +0,0 @@ -require "language/python" - -class PythonRequirement < Requirement - fatal true - default_formula "python" - - satisfy build_env: false do - python = which_python - next unless python - version = python_short_version - next unless version - # Always use Python 2.7 for consistency on older versions of Mac OS X. - version == Version.create("2.7") - end - - env do - short_version = python_short_version - - if !system_python? && short_version == Version.create("2.7") - ENV.prepend_path "PATH", which_python.dirname - end - - # Homebrew Python should take precedence over other Pythons in the PATH - ENV.prepend_path "PATH", Formula["python"].opt_bin - ENV.prepend_path "PATH", Formula["python"].opt_libexec/"bin" - - ENV["PYTHONPATH"] = "#{HOMEBREW_PREFIX}/lib/python#{short_version}/site-packages" - end - - def python_short_version - @short_version ||= Language::Python.major_minor_version which_python - end - - def which_python - python = which python_binary - return unless python - Pathname.new Utils.popen_read(python, "-c", "import sys; print(sys.executable)").strip - end - - def system_python - "/usr/bin/#{python_binary}" - end - - def system_python? - system_python == which_python.to_s - end - - def python_binary - "python" - end - - # Deprecated - alias to_s python_binary -end - -class Python3Requirement < PythonRequirement - fatal true - default_formula "python3" - - satisfy(build_env: false) { which_python } - - def python_binary - "python3" - end -end diff --git a/Library/Homebrew/requirements/ruby_requirement.rb b/Library/Homebrew/requirements/ruby_requirement.rb deleted file mode 100644 index a9ec8c42d..000000000 --- a/Library/Homebrew/requirements/ruby_requirement.rb +++ /dev/null @@ -1,56 +0,0 @@ -class RubyRequirement < Requirement - fatal true - default_formula "ruby" - - def initialize(tags) - @version = tags.shift if /(\d\.)+\d/ =~ tags.first - raise "RubyRequirement requires a version!" unless @version - super - end - - satisfy(build_env: false) { new_enough_ruby } - - env do - ENV.prepend_path "PATH", new_enough_ruby.dirname - end - - def message - s = "Ruby >= #{@version} is required to install this formula." - s += super - s - end - - def inspect - "#<#{self.class.name}: #{name.inspect} #{tags.inspect} version=#{@version.inspect}>" - end - - def display_s - if @version - "#{name} >= #{@version}" - else - name - end - end - - private - - def new_enough_ruby - rubies.detect { |ruby| new_enough?(ruby) } - end - - def rubies - rubies = which_all("ruby") - ruby_formula = Formula["ruby"] - rubies.unshift ruby_formula.bin/"ruby" if ruby_formula&.installed? - rubies.uniq - end - - def new_enough?(ruby) - version = Utils.popen_read(ruby, "-e", "print RUBY_VERSION").strip - version =~ /^\d+\.\d+/ && Version.create(version) >= min_version - end - - def min_version - @min_version ||= Version.create(@version) - end -end diff --git a/Library/Homebrew/requirements/x11_requirement.rb b/Library/Homebrew/requirements/x11_requirement.rb index 03d0382c5..65ce6396f 100644 --- a/Library/Homebrew/requirements/x11_requirement.rb +++ b/Library/Homebrew/requirements/x11_requirement.rb @@ -2,46 +2,56 @@ require "requirement" class X11Requirement < Requirement include Comparable - attr_reader :min_version fatal true - cask "xquartz" - download "https://xquartz.macosforge.org" env { ENV.x11 } def initialize(name = "x11", tags = []) @name = name - if /(\d\.)+\d/ =~ tags.first - @min_version = Version.create(tags.shift) - @min_version_string = " #{@min_version}" - else - @min_version = Version.create("0.0.0") - @min_version_string = "" - end + # no-op on version specified as a tag argument + tags.shift if /(\d\.)+\d/ =~ tags.first super(tags) end + def min_version + "1.12.2" + end + + def min_xdpyinfo_version + "1.3.0" + end + satisfy build_env: false do - MacOS::XQuartz.installed? && min_version <= Version.create(MacOS::XQuartz.version) + if which_xorg = which("Xorg") + version = Utils.popen_read which_xorg, "-version", err: :out + next false unless $CHILD_STATUS.success? + version = version[/X Server (\d+\.\d+\.\d+)/, 1] + next false unless version + Version.new(version) >= min_version + elsif which_xdpyinfo = which("xdpyinfo") + version = Utils.popen_read which_xdpyinfo, "-version" + next false unless $CHILD_STATUS.success? + version = version[/^xdpyinfo (\d+\.\d+\.\d+)/, 1] + next false unless version + Version.new(version) >= min_xdpyinfo_version + else + false + end end def message - s = "XQuartz#{@min_version_string} is required to install this formula." - s += super - s + "X11 is required to install this formula, either Xorg #{min_version} or xdpyinfo #{min_xdpyinfo_version}, or newer. #{super}" end def <=>(other) return unless other.is_a? X11Requirement - min_version <=> other.min_version - end - - def eql?(other) - super && min_version == other.min_version + 0 end def inspect - "#<#{self.class.name}: #{name.inspect} #{tags.inspect} min_version=#{min_version}>" + "#<#{self.class.name}: #{name.inspect} #{tags.inspect}>" end end + +require "extend/os/requirements/x11_requirement" diff --git a/Library/Homebrew/requirements/xcode_requirement.rb b/Library/Homebrew/requirements/xcode_requirement.rb new file mode 100644 index 000000000..6cb7d45d7 --- /dev/null +++ b/Library/Homebrew/requirements/xcode_requirement.rb @@ -0,0 +1,44 @@ +require "requirement" + +class XcodeRequirement < Requirement + fatal true + + satisfy(build_env: false) { xcode_installed_version } + + def initialize(tags = []) + @version = tags.find { |tag| tags.delete(tag) if tag =~ /(\d\.)+\d/ } + super + end + + def xcode_installed_version + return false unless MacOS::Xcode.installed? + return true unless @version + MacOS::Xcode.version >= @version + end + + def message + version = " #{@version}" if @version + message = <<~EOS + A full installation of Xcode.app#{version} is required to compile this software. + Installing just the Command Line Tools is not sufficient. + EOS + if @version && Version.new(MacOS::Xcode.latest_version) < Version.new(@version) + message + <<~EOS + Xcode#{version} cannot be installed on macOS #{MacOS.version}. + You must upgrade your version of macOS. + EOS + elsif MacOS.version >= :lion + message + <<~EOS + Xcode can be installed from the App Store. + EOS + else + message + <<~EOS + Xcode can be installed from #{Formatter.url("https://developer.apple.com/download/more/")}. + EOS + end + end + + def inspect + "#<#{self.class.name}: #{name.inspect} #{tags.inspect} version=#{@version.inspect}>" + end +end diff --git a/Library/Homebrew/resource.rb b/Library/Homebrew/resource.rb index 1e55b69c5..3dda50f8d 100644 --- a/Library/Homebrew/resource.rb +++ b/Library/Homebrew/resource.rb @@ -8,13 +8,13 @@ require "version" class Resource include FileUtils - attr_reader :mirrors, :specs, :using, :source_modified_time + attr_reader :mirrors, :specs, :using, :source_modified_time, :patches, :owner attr_writer :version attr_accessor :download_strategy, :checksum # Formula name must be set after the DSL, as we have no access to the # formula name before initialization of the formula - attr_accessor :name, :owner + attr_accessor :name class Download def initialize(resource) @@ -46,9 +46,15 @@ class Resource @specs = {} @checksum = nil @using = nil + @patches = [] instance_eval(&block) if block_given? end + def owner=(owner) + @owner = owner + patches.each { |p| p.owner = owner } + end + def downloader download_strategy.new(download_name, Download.new(self)) end @@ -82,9 +88,24 @@ class Resource end verify_download_integrity(fetch) + prepare_patches unpack(target, &block) end + def prepare_patches + patches.grep(DATAPatch) { |p| p.path = owner.owner.path } + + patches.each do |patch| + patch.verify_download_integrity(patch.fetch) if patch.external? + end + end + + def apply_patches + return if patches.empty? + ohai "Patching #{name}" + patches.each(&:apply) + end + # If a target is given, unpack there; else unpack to a temp folder. # If block is given, yield to that block with |stage|, where stage # is a ResourceStagingContext. @@ -93,6 +114,7 @@ class Resource mktemp(download_name) do |staging| downloader.stage @source_modified_time = downloader.source_modified_time + apply_patches if block_given? yield ResourceStageContext.new(self, staging) elsif target @@ -154,6 +176,11 @@ class Resource mirrors << val end + def patch(strip = :p1, src = nil, &block) + p = Patch.create(strip, src, &block) + patches << p + end + private def detect_version(val) @@ -174,7 +201,7 @@ class Resource end end - class Patch < Resource + class PatchResource < Resource attr_reader :patch_files def initialize(&block) diff --git a/Library/Homebrew/rubocops/bottle_block_cop.rb b/Library/Homebrew/rubocops/bottle_block_cop.rb index 77759e427..3cfde01ad 100644 --- a/Library/Homebrew/rubocops/bottle_block_cop.rb +++ b/Library/Homebrew/rubocops/bottle_block_cop.rb @@ -16,8 +16,6 @@ module RuboCop problem "Use rebuild instead of revision in bottle block" if method_called_in_block?(bottle, :revision) end - private - def autocorrect(node) lambda do |corrector| correction = node.source.sub("revision", "rebuild") diff --git a/Library/Homebrew/rubocops/checksum_cop.rb b/Library/Homebrew/rubocops/checksum_cop.rb index 23a787809..4dd8ad91c 100644 --- a/Library/Homebrew/rubocops/checksum_cop.rb +++ b/Library/Homebrew/rubocops/checksum_cop.rb @@ -50,8 +50,6 @@ module RuboCop end end - private - def autocorrect(node) lambda do |corrector| correction = node.source.downcase diff --git a/Library/Homebrew/rubocops/class_cop.rb b/Library/Homebrew/rubocops/class_cop.rb index dad81abfc..6f1ffc144 100644 --- a/Library/Homebrew/rubocops/class_cop.rb +++ b/Library/Homebrew/rubocops/class_cop.rb @@ -16,8 +16,6 @@ module RuboCop problem "#{parent_class} is deprecated, use Formula instead" end - private - def autocorrect(node) lambda do |corrector| corrector.replace(node.source_range, "Formula") diff --git a/Library/Homebrew/rubocops/components_order_cop.rb b/Library/Homebrew/rubocops/components_order_cop.rb index 3bf2ede16..a1a576177 100644 --- a/Library/Homebrew/rubocops/components_order_cop.rb +++ b/Library/Homebrew/rubocops/components_order_cop.rb @@ -62,8 +62,6 @@ module RuboCop end end - private - # Method to format message for reporting component precedence violations def component_problem(c1, c2) problem "`#{format_component(c1)}` (line #{line_number(c1)}) should be put before `#{format_component(c2)}` (line #{line_number(c2)})" @@ -99,7 +97,7 @@ module RuboCop line_breaks = (order_idx > 8) ? "\n\n" : "\n" corrector.insert_before(node2.source_range, node1.source + line_breaks + indentation) end - corrector.remove(range_with_surrounding_space(node1.source_range, :left)) + corrector.remove(range_with_surrounding_space(range: node1.source_range, side: :left)) end # Returns precedence index and component's index to properly reorder and group during autocorrect diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb index 1e7160bbd..e53c02a44 100644 --- a/Library/Homebrew/rubocops/extend/formula_cop.rb +++ b/Library/Homebrew/rubocops/extend/formula_cop.rb @@ -127,10 +127,26 @@ module RuboCop end end + # Matches receiver part of method, + # EX: to match `ARGV.<whatever>()` + # call `find_instance_call(node, "ARGV")` + # yields to a block with parent node of receiver + def find_instance_call(node, name) + node.each_descendant(:send) do |method_node| + next if method_node.receiver.nil? + next if method_node.receiver.const_name != name && + method_node.receiver.method_name != name + @offense_source_range = method_node.receiver.source_range + @offensive_node = method_node.receiver + return true unless block_given? + yield method_node + end + end + # Returns nil if does not depend on dependency_name # args: node - dependency_name - dependency's name def depends_on?(dependency_name, *types) - types = [:required, :build, :optional, :recommended, :run] if types.empty? + types = [:any] if types.empty? dependency_nodes = find_every_method_call_by_name(@body, :depends_on) idx = dependency_nodes.index do |n| types.any? { |type| depends_on_name_type?(n, dependency_name, type) } @@ -152,14 +168,14 @@ module RuboCop case type when :required type_match = required_dependency?(node) - if type_match && !name_match - name_match = required_dependency_name?(node, name) - end + name_match ||= required_dependency_name?(node, name) if type_match when :build, :optional, :recommended, :run type_match = dependency_type_hash_match?(node, type) - if type_match && !name_match - name_match = dependency_name_hash_match?(node, name) - end + name_match ||= dependency_name_hash_match?(node, name) if type_match + when :any + type_match = true + name_match ||= required_dependency_name?(node, name) + name_match ||= dependency_name_hash_match?(node, name) else type_match = false end @@ -198,7 +214,7 @@ module RuboCop EOS def_node_search :dependency_name_hash_match?, <<~EOS - (hash (pair ({str sym} %1) ({str sym} _))) + (hash (pair ({str sym} %1) (...))) EOS # To compare node with appropriate Ruby variable @@ -409,7 +425,7 @@ module RuboCop # Returns the block length of the block node def block_size(block) - block_length(block) + block.loc.end.line - block.loc.begin.line end # Source buffer is required as an argument to report style violations @@ -451,7 +467,7 @@ module RuboCop end def problem(msg) - add_offense(@offensive_node, @offense_source_range, msg) + add_offense(@offensive_node, location: @offense_source_range, message: msg) end private diff --git a/Library/Homebrew/rubocops/formula_desc_cop.rb b/Library/Homebrew/rubocops/formula_desc_cop.rb index 8a35e7d24..240a28072 100644 --- a/Library/Homebrew/rubocops/formula_desc_cop.rb +++ b/Library/Homebrew/rubocops/formula_desc_cop.rb @@ -88,8 +88,6 @@ module RuboCop problem "Description shouldn't end with a full stop" end - private - def autocorrect(node) lambda do |corrector| correction = node.source diff --git a/Library/Homebrew/rubocops/lines_cop.rb b/Library/Homebrew/rubocops/lines_cop.rb index d9e40c2de..4e7aa1adb 100644 --- a/Library/Homebrew/rubocops/lines_cop.rb +++ b/Library/Homebrew/rubocops/lines_cop.rb @@ -6,12 +6,18 @@ module RuboCop # This cop checks for various miscellaneous Homebrew coding styles class Lines < FormulaCop def audit_formula(_node, _class_node, _parent_class_node, _body_node) - [:automake, :autoconf, :libtool].each do |dependency| + [:automake, :ant, :autoconf, :emacs, :expat, :libtool, :mysql, :perl, + :postgresql, :python, :python3, :rbenv, :ruby].each do |dependency| next unless depends_on?(dependency) problem ":#{dependency} is deprecated. Usage should be \"#{dependency}\"." end - problem ':apr is deprecated. Usage should be "apr-util".' if depends_on?(:apr) + { apr: "apr-util", fortran: "gcc", gpg: "gnupg", hg: "mercurial", + mpi: "open-mpi", python2: "python" }.each do |requirement, dependency| + next unless depends_on?(requirement) + problem ":#{requirement} is deprecated. Usage should be \"#{dependency}\"." + end + problem ":tex is deprecated." if depends_on?(:tex) end end @@ -162,10 +168,9 @@ module RuboCop end end - [:debug?, :verbose?, :value].each do |method_name| - find_instance_method_call(body_node, "ARGV", method_name) do - problem "Use build instead of ARGV to check options" - end + find_instance_call(body_node, "ARGV") do |method_node| + next if [:debug?, :verbose?, :value].index(method_node.method_name) + problem "Use build instead of ARGV to check options" end find_instance_method_call(body_node, :man, :+) do |method| @@ -236,11 +241,6 @@ module RuboCop problem "Use 'build.head?' instead of inspecting 'version'" end - find_instance_method_call(body_node, "ENV", :fortran) do - next if depends_on?(:fortran) - problem "Use `depends_on :fortran` instead of `ENV.fortran`" - end - find_instance_method_call(body_node, "ARGV", :include?) do |method| param = parameters(method).first next unless match = regex_match_group(param, /^--(HEAD|devel)/) @@ -276,6 +276,10 @@ module RuboCop problem "'fails_with :llvm' is now a no-op so should be removed" end + find_method_with_args(body_node, :needs, :openmp) do + problem "'needs :openmp' should be replaced with 'depends_on \"gcc\"'" + end + find_method_with_args(body_node, :system, /^(otool|install_name_tool|lipo)/) do next if @formula_name == "cctools" problem "Use ruby-macho instead of calling #{@offensive_node.source}" diff --git a/Library/Homebrew/rubocops/text_cop.rb b/Library/Homebrew/rubocops/text_cop.rb index d56c9bf46..1546a9cc3 100644 --- a/Library/Homebrew/rubocops/text_cop.rb +++ b/Library/Homebrew/rubocops/text_cop.rb @@ -46,7 +46,16 @@ module RuboCop end find_method_with_args(body_node, :system, "go", "get") do - problem "Formulae should not use `go get`. If non-vendored resources are required use `go_resource`s." + problem "Do not use `go get`. Please ask upstream to implement Go vendoring" + end + end + end + end + module FormulaAuditStrict + class Text < FormulaCop + def audit_formula(_node, _class_node, _parent_class_node, body_node) + find_method_with_args(body_node, :go_resource) do + problem "`go_resource`s are deprecated. Please ask upstream to implement Go vendoring" end end end diff --git a/Library/Homebrew/rubocops/urls_cop.rb b/Library/Homebrew/rubocops/urls_cop.rb index 414f633c9..4ef801689 100644 --- a/Library/Homebrew/rubocops/urls_cop.rb +++ b/Library/Homebrew/rubocops/urls_cop.rb @@ -206,8 +206,6 @@ module RuboCop end end - private - def autocorrect(node) lambda do |corrector| url_string_node = parameters(node).first diff --git a/Library/Homebrew/shims/scm/git b/Library/Homebrew/shims/scm/git index bfb779c25..f826e1b60 100755 --- a/Library/Homebrew/shims/scm/git +++ b/Library/Homebrew/shims/scm/git @@ -92,8 +92,11 @@ case "$(lowercase "$SCM_FILE")" in ;; esac -brew_version="$(quiet_safe_cd "$SCM_DIR/../../../../bin" && pwd -P)/$SCM_FILE" -safe_exec "$brew_version" "$@" +brew_prefix_version="$(quiet_safe_cd "$SCM_DIR/../../../../../bin" 2>/dev/null && pwd -P)/$SCM_FILE" +safe_exec "$brew_prefix_version" "$@" + +brew_repo_version="$(quiet_safe_cd "$SCM_DIR/../../../../bin" && pwd -P)/$SCM_FILE" +safe_exec "$brew_repo_version" "$@" IFS=$'\n' for path in $(/usr/bin/which -a "$SCM_FILE" 2>/dev/null) diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb index ed93e1266..d128c68fb 100644 --- a/Library/Homebrew/tap.rb +++ b/Library/Homebrew/tap.rb @@ -211,7 +211,7 @@ class Tap requested_remote = options[:clone_target] || default_remote if official? && DEPRECATED_OFFICIAL_TAPS.include?(repo) - opoo "#{name} was deprecated. This tap is now empty as all its formulae were migrated." + odie "#{name} was deprecated. This tap is now empty as all its formulae were migrated." end if installed? diff --git a/Library/Homebrew/test/Gemfile.lock b/Library/Homebrew/test/Gemfile.lock index 1620d7099..47f51e56b 100644 --- a/Library/Homebrew/test/Gemfile.lock +++ b/Library/Homebrew/test/Gemfile.lock @@ -12,12 +12,10 @@ GEM parallel (1.12.0) parallel_tests (2.17.0) parallel - parser (2.4.0.0) - ast (~> 2.2) + parser (2.4.0.2) + ast (~> 2.3) powerpack (0.1.1) - rainbow (2.2.2) - rake - rake (12.1.0) + rainbow (3.0.0) rspec (3.6.0) rspec-core (~> 3.6.0) rspec-expectations (~> 3.6.0) @@ -36,11 +34,11 @@ GEM rspec-support (3.6.0) rspec-wait (0.0.9) rspec (>= 3, < 4) - rubocop (0.51.0) + rubocop (0.52.1) parallel (~> 1.10) - parser (>= 2.3.3.1, < 3.0) + parser (>= 2.4.0.2, < 3.0) powerpack (~> 0.1) - rainbow (>= 2.2.2, < 3.0) + rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) ruby-progressbar (1.9.0) @@ -61,8 +59,8 @@ DEPENDENCIES rspec rspec-its rspec-wait - rubocop (= 0.51.0) + rubocop (= 0.52.1) simplecov BUNDLED WITH - 1.15.4 + 1.16.0 diff --git a/Library/Homebrew/test/bottle_hooks_spec.rb b/Library/Homebrew/test/bottle_hooks_spec.rb deleted file mode 100644 index eb6617380..000000000 --- a/Library/Homebrew/test/bottle_hooks_spec.rb +++ /dev/null @@ -1,51 +0,0 @@ -require "formula_installer" -require "hooks/bottles" - -describe Homebrew::Hooks::Bottles do - alias_matcher :pour_bottle, :be_pour_bottle - - subject { FormulaInstaller.new formula } - - let(:formula) do - double( - bottled?: false, - local_bottle_path: nil, - bottle_disabled?: false, - some_random_method: true, - keg_only?: false, - ) - end - - after(:each) do - described_class.reset_hooks - end - - describe "#setup_formula_has_bottle" do - context "given a block which evaluates to true" do - before(:each) do - described_class.setup_formula_has_bottle(&:some_random_method) - end - - it { is_expected.to pour_bottle } - end - - context "given a block which evaluates to false" do - before(:each) do - described_class.setup_formula_has_bottle { |f| !f.some_random_method } - end - - it { is_expected.not_to pour_bottle } - end - end - - describe "#setup_pour_formula_bottle" do - before(:each) do - described_class.setup_formula_has_bottle { true } - described_class.setup_pour_formula_bottle(&:some_random_method) - end - - it "does not raise an error" do - expect { subject.pour }.not_to raise_error - end - end -end diff --git a/Library/Homebrew/test/cask/artifact/alt_target_spec.rb b/Library/Homebrew/test/cask/artifact/alt_target_spec.rb index 847bf25fa..2168ac606 100644 --- a/Library/Homebrew/test/cask/artifact/alt_target_spec.rb +++ b/Library/Homebrew/test/cask/artifact/alt_target_spec.rb @@ -11,7 +11,7 @@ describe Hbc::Artifact::App, :cask do } let(:source_path) { cask.staged_path.join("Caffeine.app") } - let(:target_path) { Hbc.appdir.join("AnotherName.app") } + let(:target_path) { Hbc::Config.global.appdir.join("AnotherName.app") } before do InstallHelper.install_without_artifacts(cask) @@ -58,7 +58,7 @@ describe Hbc::Artifact::App, :cask do expect(target_path).to be_a_directory expect(source_path).not_to exist - expect(Hbc.appdir.join("Caffeine Deluxe.app")).not_to exist + expect(Hbc::Config.global.appdir.join("Caffeine Deluxe.app")).not_to exist expect(cask.staged_path.join("Caffeine Deluxe.app")).to be_a_directory end diff --git a/Library/Homebrew/test/cask/artifact/app_spec.rb b/Library/Homebrew/test/cask/artifact/app_spec.rb index 285cc4f31..97e19165b 100644 --- a/Library/Homebrew/test/cask/artifact/app_spec.rb +++ b/Library/Homebrew/test/cask/artifact/app_spec.rb @@ -5,7 +5,7 @@ describe Hbc::Artifact::App, :cask do let(:app) { cask.artifacts.find { |a| a.is_a?(described_class) } } let(:source_path) { cask.staged_path.join("Caffeine.app") } - let(:target_path) { Hbc.appdir.join("Caffeine.app") } + let(:target_path) { Hbc::Config.global.appdir.join("Caffeine.app") } let(:install_phase) { app.install_phase(command: command, force: force) } let(:uninstall_phase) { app.uninstall_phase(command: command, force: force) } @@ -53,7 +53,7 @@ describe Hbc::Artifact::App, :cask do expect(target_path).to be_a_directory expect(source_path).not_to exist - expect(Hbc.appdir.join("Caffeine Deluxe.app")).not_to exist + expect(Hbc::Config.global.appdir.join("Caffeine Deluxe.app")).not_to exist expect(cask.staged_path.join("Caffeine Deluxe.app")).to exist end diff --git a/Library/Homebrew/test/cask/artifact/binary_spec.rb b/Library/Homebrew/test/cask/artifact/binary_spec.rb index 6a3f1da34..d072060cc 100644 --- a/Library/Homebrew/test/cask/artifact/binary_spec.rb +++ b/Library/Homebrew/test/cask/artifact/binary_spec.rb @@ -5,11 +5,7 @@ describe Hbc::Artifact::Binary, :cask do end } let(:artifacts) { cask.artifacts.select { |a| a.is_a?(described_class) } } - let(:expected_path) { Hbc.binarydir.join("binary") } - - before(:each) do - Hbc.binarydir.mkpath - end + let(:expected_path) { Hbc::Config.global.binarydir.join("binary") } after(:each) do FileUtils.rm expected_path if expected_path.exist? @@ -42,7 +38,7 @@ describe Hbc::Artifact::Binary, :cask do end } - let(:expected_path) { Hbc.binarydir.join("naked_non_executable") } + let(:expected_path) { Hbc::Config.global.binarydir.join("naked_non_executable") } it "makes the binary executable" do expect(FileUtils).to receive(:chmod) @@ -80,7 +76,7 @@ describe Hbc::Artifact::Binary, :cask do end it "creates parent directory if it doesn't exist" do - FileUtils.rmdir Hbc.binarydir + FileUtils.rmdir Hbc::Config.global.binarydir artifacts.each do |artifact| artifact.install_phase(command: Hbc::NeverSudoSystemCommand, force: false) diff --git a/Library/Homebrew/test/cask/artifact/generic_artifact_spec.rb b/Library/Homebrew/test/cask/artifact/generic_artifact_spec.rb index ea567abee..7e1285476 100644 --- a/Library/Homebrew/test/cask/artifact/generic_artifact_spec.rb +++ b/Library/Homebrew/test/cask/artifact/generic_artifact_spec.rb @@ -10,7 +10,7 @@ describe Hbc::Artifact::Artifact, :cask do } let(:source_path) { cask.staged_path.join("Caffeine.app") } - let(:target_path) { Hbc.appdir.join("Caffeine.app") } + let(:target_path) { Hbc::Config.global.appdir.join("Caffeine.app") } before do InstallHelper.install_without_artifacts(cask) diff --git a/Library/Homebrew/test/cask/artifact/suite_spec.rb b/Library/Homebrew/test/cask/artifact/suite_spec.rb index 80d3e917f..62a2fbfd7 100644 --- a/Library/Homebrew/test/cask/artifact/suite_spec.rb +++ b/Library/Homebrew/test/cask/artifact/suite_spec.rb @@ -9,7 +9,7 @@ describe Hbc::Artifact::Suite, :cask do end } - let(:target_path) { Hbc.appdir.join("Caffeine") } + let(:target_path) { Hbc::Config.global.appdir.join("Caffeine") } let(:source_path) { cask.staged_path.join("Caffeine") } before(:each) do diff --git a/Library/Homebrew/test/cask/artifact/two_apps_correct_spec.rb b/Library/Homebrew/test/cask/artifact/two_apps_correct_spec.rb index 8367dc27d..0d6f47d13 100644 --- a/Library/Homebrew/test/cask/artifact/two_apps_correct_spec.rb +++ b/Library/Homebrew/test/cask/artifact/two_apps_correct_spec.rb @@ -11,10 +11,10 @@ describe Hbc::Artifact::App, :cask do } let(:source_path_mini) { cask.staged_path.join("Caffeine Mini.app") } - let(:target_path_mini) { Hbc.appdir.join("Caffeine Mini.app") } + let(:target_path_mini) { Hbc::Config.global.appdir.join("Caffeine Mini.app") } let(:source_path_pro) { cask.staged_path.join("Caffeine Pro.app") } - let(:target_path_pro) { Hbc.appdir.join("Caffeine Pro.app") } + let(:target_path_pro) { Hbc::Config.global.appdir.join("Caffeine Pro.app") } before(:each) do InstallHelper.install_without_artifacts(cask) @@ -52,7 +52,7 @@ describe Hbc::Artifact::App, :cask do expect(target_path_mini).to be_a_directory expect(source_path_mini).not_to exist - expect(Hbc.appdir.join("Caffeine Deluxe.app")).not_to exist + expect(Hbc::Config.global.appdir.join("Caffeine Deluxe.app")).not_to exist expect(cask.staged_path.join("Caffeine Deluxe.app")).to exist end diff --git a/Library/Homebrew/test/cask/cli/install_spec.rb b/Library/Homebrew/test/cask/cli/install_spec.rb index 25d6cdc93..cc5450c79 100644 --- a/Library/Homebrew/test/cask/cli/install_spec.rb +++ b/Library/Homebrew/test/cask/cli/install_spec.rb @@ -23,9 +23,9 @@ describe Hbc::CLI::Install, :cask do described_class.run("local-transmission", "local-caffeine") expect(Hbc::CaskLoader.load(cask_path("local-transmission"))).to be_installed - expect(Hbc.appdir.join("Transmission.app")).to be_a_directory + expect(Hbc::Config.global.appdir.join("Transmission.app")).to be_a_directory expect(Hbc::CaskLoader.load(cask_path("local-caffeine"))).to be_installed - expect(Hbc.appdir.join("Caffeine.app")).to be_a_directory + expect(Hbc::Config.global.appdir.join("Caffeine.app")).to be_a_directory end it "skips double install (without nuking existing installation)" do diff --git a/Library/Homebrew/test/cask/cli/list_spec.rb b/Library/Homebrew/test/cask/cli/list_spec.rb index eef233acc..98eb6a8da 100644 --- a/Library/Homebrew/test/cask/cli/list_spec.rb +++ b/Library/Homebrew/test/cask/cli/list_spec.rb @@ -80,9 +80,9 @@ describe Hbc::CLI::List, :cask do described_class.run("local-transmission", "local-caffeine") }.to output(<<~EOS).to_stdout ==> Apps - #{Hbc.appdir.join("Transmission.app")} (#{Hbc.appdir.join("Transmission.app").abv}) + #{Hbc::Config.global.appdir.join("Transmission.app")} (#{Hbc::Config.global.appdir.join("Transmission.app").abv}) ==> Apps - Missing App: #{Hbc.appdir.join("Caffeine.app")} + Missing App: #{Hbc::Config.global.appdir.join("Caffeine.app")} EOS end end diff --git a/Library/Homebrew/test/cask/cli/options_spec.rb b/Library/Homebrew/test/cask/cli/options_spec.rb index 82d830795..8b084113c 100644 --- a/Library/Homebrew/test/cask/cli/options_spec.rb +++ b/Library/Homebrew/test/cask/cli/options_spec.rb @@ -1,106 +1,136 @@ describe Hbc::CLI, :cask do it "supports setting the appdir" do + allow(Hbc::Config.global).to receive(:appdir).and_call_original + described_class.new.process_options("help", "--appdir=/some/path/foo") - expect(Hbc.appdir).to eq(Pathname.new("/some/path/foo")) + expect(Hbc::Config.global.appdir).to eq(Pathname.new("/some/path/foo")) end it "supports setting the appdir from ENV" do + allow(Hbc::Config.global).to receive(:appdir).and_call_original + ENV["HOMEBREW_CASK_OPTS"] = "--appdir=/some/path/bar" described_class.new.process_options("help") - expect(Hbc.appdir).to eq(Pathname.new("/some/path/bar")) + expect(Hbc::Config.global.appdir).to eq(Pathname.new("/some/path/bar")) end it "supports setting the prefpanedir" do + allow(Hbc::Config.global).to receive(:prefpanedir).and_call_original + described_class.new.process_options("help", "--prefpanedir=/some/path/foo") - expect(Hbc.prefpanedir).to eq(Pathname.new("/some/path/foo")) + expect(Hbc::Config.global.prefpanedir).to eq(Pathname.new("/some/path/foo")) end it "supports setting the prefpanedir from ENV" do + allow(Hbc::Config.global).to receive(:prefpanedir).and_call_original + ENV["HOMEBREW_CASK_OPTS"] = "--prefpanedir=/some/path/bar" described_class.new.process_options("help") - expect(Hbc.prefpanedir).to eq(Pathname.new("/some/path/bar")) + expect(Hbc::Config.global.prefpanedir).to eq(Pathname.new("/some/path/bar")) end it "supports setting the qlplugindir" do + allow(Hbc::Config.global).to receive(:qlplugindir).and_call_original + described_class.new.process_options("help", "--qlplugindir=/some/path/foo") - expect(Hbc.qlplugindir).to eq(Pathname.new("/some/path/foo")) + expect(Hbc::Config.global.qlplugindir).to eq(Pathname.new("/some/path/foo")) end it "supports setting the qlplugindir from ENV" do + allow(Hbc::Config.global).to receive(:qlplugindir).and_call_original + ENV["HOMEBREW_CASK_OPTS"] = "--qlplugindir=/some/path/bar" described_class.new.process_options("help") - expect(Hbc.qlplugindir).to eq(Pathname.new("/some/path/bar")) + expect(Hbc::Config.global.qlplugindir).to eq(Pathname.new("/some/path/bar")) end it "supports setting the colorpickerdir" do + allow(Hbc::Config.global).to receive(:colorpickerdir).and_call_original + described_class.new.process_options("help", "--colorpickerdir=/some/path/foo") - expect(Hbc.colorpickerdir).to eq(Pathname.new("/some/path/foo")) + expect(Hbc::Config.global.colorpickerdir).to eq(Pathname.new("/some/path/foo")) end it "supports setting the colorpickerdir from ENV" do + allow(Hbc::Config.global).to receive(:colorpickerdir).and_call_original + ENV["HOMEBREW_CASK_OPTS"] = "--colorpickerdir=/some/path/bar" described_class.new.process_options("help") - expect(Hbc.colorpickerdir).to eq(Pathname.new("/some/path/bar")) + expect(Hbc::Config.global.colorpickerdir).to eq(Pathname.new("/some/path/bar")) end it "supports setting the dictionarydir" do + allow(Hbc::Config.global).to receive(:dictionarydir).and_call_original + described_class.new.process_options("help", "--dictionarydir=/some/path/foo") - expect(Hbc.dictionarydir).to eq(Pathname.new("/some/path/foo")) + expect(Hbc::Config.global.dictionarydir).to eq(Pathname.new("/some/path/foo")) end it "supports setting the dictionarydir from ENV" do + allow(Hbc::Config.global).to receive(:dictionarydir).and_call_original + ENV["HOMEBREW_CASK_OPTS"] = "--dictionarydir=/some/path/bar" described_class.new.process_options("help") - expect(Hbc.dictionarydir).to eq(Pathname.new("/some/path/bar")) + expect(Hbc::Config.global.dictionarydir).to eq(Pathname.new("/some/path/bar")) end it "supports setting the fontdir" do + allow(Hbc::Config.global).to receive(:fontdir).and_call_original + described_class.new.process_options("help", "--fontdir=/some/path/foo") - expect(Hbc.fontdir).to eq(Pathname.new("/some/path/foo")) + expect(Hbc::Config.global.fontdir).to eq(Pathname.new("/some/path/foo")) end it "supports setting the fontdir from ENV" do + allow(Hbc::Config.global).to receive(:fontdir).and_call_original + ENV["HOMEBREW_CASK_OPTS"] = "--fontdir=/some/path/bar" described_class.new.process_options("help") - expect(Hbc.fontdir).to eq(Pathname.new("/some/path/bar")) + expect(Hbc::Config.global.fontdir).to eq(Pathname.new("/some/path/bar")) end it "supports setting the servicedir" do + allow(Hbc::Config.global).to receive(:servicedir).and_call_original + described_class.new.process_options("help", "--servicedir=/some/path/foo") - expect(Hbc.servicedir).to eq(Pathname.new("/some/path/foo")) + expect(Hbc::Config.global.servicedir).to eq(Pathname.new("/some/path/foo")) end it "supports setting the servicedir from ENV" do + allow(Hbc::Config.global).to receive(:servicedir).and_call_original + ENV["HOMEBREW_CASK_OPTS"] = "--servicedir=/some/path/bar" described_class.new.process_options("help") - expect(Hbc.servicedir).to eq(Pathname.new("/some/path/bar")) + expect(Hbc::Config.global.servicedir).to eq(Pathname.new("/some/path/bar")) end it "allows additional options to be passed through" do + allow(Hbc::Config.global).to receive(:appdir).and_call_original + rest = described_class.new.process_options("edit", "foo", "--create", "--appdir=/some/path/qux") - expect(Hbc.appdir).to eq(Pathname.new("/some/path/qux")) + expect(Hbc::Config.global.appdir).to eq(Pathname.new("/some/path/qux")) expect(rest).to eq(%w[edit foo --create]) end diff --git a/Library/Homebrew/test/cask/cli/style_spec.rb b/Library/Homebrew/test/cask/cli/style_spec.rb index 12cd348a0..850f04f8d 100644 --- a/Library/Homebrew/test/cask/cli/style_spec.rb +++ b/Library/Homebrew/test/cask/cli/style_spec.rb @@ -22,7 +22,10 @@ describe Hbc::CLI::Style, :cask do context "when rubocop succeeds" do let(:success) { true } - it { is_expected.to be_truthy } + + it "does not raise an error" do + expect { subject }.not_to raise_error + end end context "when rubocop fails" do @@ -132,7 +135,7 @@ describe Hbc::CLI::Style, :cask do describe "#default_args" do subject { cli.default_args } - it { is_expected.to include("--require", "rubocop-cask", "--format", "simple", "--force-exclusion") } + it { is_expected.to include("--require", "rubocop-cask", "--format", "simple") } end describe "#autocorrect_args" do diff --git a/Library/Homebrew/test/cask/cli/uninstall_spec.rb b/Library/Homebrew/test/cask/cli/uninstall_spec.rb index 345e1b9f2..322394de4 100644 --- a/Library/Homebrew/test/cask/cli/uninstall_spec.rb +++ b/Library/Homebrew/test/cask/cli/uninstall_spec.rb @@ -50,9 +50,9 @@ describe Hbc::CLI::Uninstall, :cask do described_class.run("local-caffeine", "local-transmission") expect(caffeine).not_to be_installed - expect(Hbc.appdir.join("Transmission.app")).not_to exist + expect(Hbc::Config.global.appdir.join("Transmission.app")).not_to exist expect(transmission).not_to be_installed - expect(Hbc.appdir.join("Caffeine.app")).not_to exist + expect(Hbc::Config.global.appdir.join("Caffeine.app")).not_to exist end it "calls `uninstall` before removing artifacts" do @@ -61,14 +61,14 @@ describe Hbc::CLI::Uninstall, :cask do Hbc::Installer.new(cask).install expect(cask).to be_installed - expect(Hbc.appdir.join("MyFancyApp.app")).to exist + expect(Hbc::Config.global.appdir.join("MyFancyApp.app")).to exist expect { described_class.run("with-uninstall-script-app") }.not_to raise_error expect(cask).not_to be_installed - expect(Hbc.appdir.join("MyFancyApp.app")).not_to exist + expect(Hbc::Config.global.appdir.join("MyFancyApp.app")).not_to exist end it "can uninstall Casks when the uninstall script is missing, but only when using `--force`" do @@ -78,7 +78,7 @@ describe Hbc::CLI::Uninstall, :cask do expect(cask).to be_installed - Hbc.appdir.join("MyFancyApp.app").rmtree + Hbc::Config.global.appdir.join("MyFancyApp.app").rmtree expect { described_class.run("with-uninstall-script-app") } .to raise_error(Hbc::CaskError, /uninstall script .* does not exist/) @@ -141,7 +141,7 @@ describe Hbc::CLI::Uninstall, :cask do end describe "when Casks in Taps have been renamed or removed" do - let(:app) { Hbc.appdir.join("ive-been-renamed.app") } + let(:app) { Hbc::Config.global.appdir.join("ive-been-renamed.app") } let(:caskroom_path) { Hbc.caskroom.join("ive-been-renamed").tap(&:mkpath) } let(:saved_caskfile) { caskroom_path.join(".metadata", "latest", "timestamp", "Casks").join("ive-been-renamed.rb") } diff --git a/Library/Homebrew/test/cask/cli/upgrade_spec.rb b/Library/Homebrew/test/cask/cli/upgrade_spec.rb index 49775156e..af026157e 100644 --- a/Library/Homebrew/test/cask/cli/upgrade_spec.rb +++ b/Library/Homebrew/test/cask/cli/upgrade_spec.rb @@ -22,9 +22,9 @@ describe Hbc::CLI::Upgrade, :cask do describe 'without --greedy it ignores the Casks with "version latest" or "auto_updates true"' do it "updates all the installed Casks when no token is provided" do local_caffeine = Hbc::CaskLoader.load("local-caffeine") - local_caffeine_path = Hbc.appdir.join("Caffeine.app") + local_caffeine_path = Hbc::Config.global.appdir.join("Caffeine.app") local_transmission = Hbc::CaskLoader.load("local-transmission") - local_transmission_path = Hbc.appdir.join("Transmission.app") + local_transmission_path = Hbc::Config.global.appdir.join("Transmission.app") expect(local_caffeine).to be_installed expect(local_caffeine_path).to be_a_directory @@ -47,9 +47,9 @@ describe Hbc::CLI::Upgrade, :cask do it "updates only the Casks specified in the command line" do local_caffeine = Hbc::CaskLoader.load("local-caffeine") - local_caffeine_path = Hbc.appdir.join("Caffeine.app") + local_caffeine_path = Hbc::Config.global.appdir.join("Caffeine.app") local_transmission = Hbc::CaskLoader.load("local-transmission") - local_transmission_path = Hbc.appdir.join("Transmission.app") + local_transmission_path = Hbc::Config.global.appdir.join("Transmission.app") expect(local_caffeine).to be_installed expect(local_caffeine_path).to be_a_directory @@ -72,9 +72,9 @@ describe Hbc::CLI::Upgrade, :cask do it 'updates "auto_updates" and "latest" Casks when their tokens are provided in the command line' do local_caffeine = Hbc::CaskLoader.load("local-caffeine") - local_caffeine_path = Hbc.appdir.join("Caffeine.app") + local_caffeine_path = Hbc::Config.global.appdir.join("Caffeine.app") auto_updates = Hbc::CaskLoader.load("auto-updates") - auto_updates_path = Hbc.appdir.join("MyFancyApp.app") + auto_updates_path = Hbc::Config.global.appdir.join("MyFancyApp.app") expect(local_caffeine).to be_installed expect(local_caffeine_path).to be_a_directory @@ -99,14 +99,14 @@ describe Hbc::CLI::Upgrade, :cask do describe "with --greedy it checks additional Casks" do it 'includes the Casks with "auto_updates true" or "version latest"' do local_caffeine = Hbc::CaskLoader.load("local-caffeine") - local_caffeine_path = Hbc.appdir.join("Caffeine.app") + local_caffeine_path = Hbc::Config.global.appdir.join("Caffeine.app") auto_updates = Hbc::CaskLoader.load("auto-updates") - auto_updates_path = Hbc.appdir.join("MyFancyApp.app") + auto_updates_path = Hbc::Config.global.appdir.join("MyFancyApp.app") local_transmission = Hbc::CaskLoader.load("local-transmission") - local_transmission_path = Hbc.appdir.join("Transmission.app") + local_transmission_path = Hbc::Config.global.appdir.join("Transmission.app") version_latest = Hbc::CaskLoader.load("version-latest") - version_latest_path_1 = Hbc.appdir.join("Caffeine Mini.app") - version_latest_path_2 = Hbc.appdir.join("Caffeine Pro.app") + version_latest_path_1 = Hbc::Config.global.appdir.join("Caffeine Mini.app") + version_latest_path_2 = Hbc::Config.global.appdir.join("Caffeine Pro.app") expect(local_caffeine).to be_installed expect(local_caffeine_path).to be_a_directory @@ -147,7 +147,7 @@ describe Hbc::CLI::Upgrade, :cask do it 'does not include the Casks with "auto_updates true" when the version did not change' do cask = Hbc::CaskLoader.load("auto-updates") - cask_path = Hbc.appdir.join("MyFancyApp.app") + cask_path = Hbc::Config.global.appdir.join("MyFancyApp.app") expect(cask).to be_installed expect(cask_path).to be_a_directory @@ -188,7 +188,7 @@ describe Hbc::CLI::Upgrade, :cask do it "restores the old Cask if the upgrade failed" do will_fail_if_upgraded = Hbc::CaskLoader.load("will-fail-if-upgraded") - will_fail_if_upgraded_path = Hbc.appdir.join("container") + will_fail_if_upgraded_path = Hbc::Config.global.appdir.join("container") expect(will_fail_if_upgraded).to be_installed expect(will_fail_if_upgraded_path).to be_a_file @@ -206,7 +206,7 @@ describe Hbc::CLI::Upgrade, :cask do it "does not restore the old Cask if the upgrade failed pre-install" do bad_checksum = Hbc::CaskLoader.load("bad-checksum") - bad_checksum_path = Hbc.appdir.join("Caffeine.app") + bad_checksum_path = Hbc::Config.global.appdir.join("Caffeine.app") expect(bad_checksum).to be_installed expect(bad_checksum_path).to be_a_directory diff --git a/Library/Homebrew/test/cask/cli/zap_spec.rb b/Library/Homebrew/test/cask/cli/zap_spec.rb index 05c882854..e85120f5f 100644 --- a/Library/Homebrew/test/cask/cli/zap_spec.rb +++ b/Library/Homebrew/test/cask/cli/zap_spec.rb @@ -23,9 +23,9 @@ describe Hbc::CLI::Zap, :cask do described_class.run("local-caffeine", "local-transmission") expect(caffeine).not_to be_installed - expect(Hbc.appdir.join("Caffeine.app")).not_to be_a_symlink + expect(Hbc::Config.global.appdir.join("Caffeine.app")).not_to be_a_symlink expect(transmission).not_to be_installed - expect(Hbc.appdir.join("Transmission.app")).not_to be_a_symlink + expect(Hbc::Config.global.appdir.join("Transmission.app")).not_to be_a_symlink end # TODO: Explicit test that both zap and uninstall directives get dispatched. diff --git a/Library/Homebrew/test/cask/cli_spec.rb b/Library/Homebrew/test/cask/cli_spec.rb index 4a61e0088..e88b24ba2 100644 --- a/Library/Homebrew/test/cask/cli_spec.rb +++ b/Library/Homebrew/test/cask/cli_spec.rb @@ -16,10 +16,16 @@ describe Hbc::CLI, :cask do it "ignores the `--language` option, which is handled in `OS::Mac`" do cli = described_class.new("--language=en") expect(cli).to receive(:detect_command_and_arguments).with(no_args) - expect(cli).to receive(:exit).with(1) cli.run end + context "when given no arguments" do + it "exits successfully" do + expect(subject).not_to receive(:exit).with(be_nonzero) + subject.run + end + end + context "when no option is specified" do it "--binaries is true by default" do command = Hbc::CLI::Install.new("some-cask") @@ -51,10 +57,13 @@ describe Hbc::CLI, :cask do end it "respects the env variable when choosing what appdir to create" do - allow(ENV).to receive(:[]) + allow(ENV).to receive(:[]).and_call_original allow(ENV).to receive(:[]).with("HOMEBREW_CASK_OPTS").and_return("--appdir=/custom/appdir") - expect(Hbc).to receive(:appdir=).with(Pathname.new("/custom/appdir")) + allow(Hbc::Config.global).to receive(:appdir).and_call_original + described_class.run("noop") + + expect(Hbc::Config.global.appdir).to eq(Pathname.new("/custom/appdir")) end it "exits with a status of 1 when something goes wrong" do diff --git a/Library/Homebrew/test/cask/dsl_spec.rb b/Library/Homebrew/test/cask/dsl_spec.rb index a17acfca6..d3bb46264 100644 --- a/Library/Homebrew/test/cask/dsl_spec.rb +++ b/Library/Homebrew/test/cask/dsl_spec.rb @@ -232,8 +232,9 @@ describe Hbc::DSL, :cask do expect(cask.caveats).to be_empty cask = Hbc::Cask.new("cask-with-caveats") do - def caveats; <<~EOS - When you install this Cask, you probably want to know this. + def caveats + <<~EOS + When you install this Cask, you probably want to know this. EOS end end @@ -550,14 +551,14 @@ describe Hbc::DSL, :cask do let(:token) { "appdir-interpolation" } it "is allowed" do - expect(cask.artifacts.first.source).to eq(Hbc.appdir/"some/path") + expect(cask.artifacts.first.source).to eq(Hbc::Config.global.appdir/"some/path") end end it "does not include a trailing slash" do begin - original_appdir = Hbc.appdir - Hbc.appdir = "#{original_appdir}/" + original_appdir = Hbc::Config.global.appdir + Hbc::Config.global.appdir = "#{original_appdir}/" cask = Hbc::Cask.new("appdir-trailing-slash") do binary "#{appdir}/some/path" @@ -565,7 +566,7 @@ describe Hbc::DSL, :cask do expect(cask.artifacts.first.source).to eq(original_appdir/"some/path") ensure - Hbc.appdir = original_appdir + Hbc::Config.global.appdir = original_appdir end end end diff --git a/Library/Homebrew/test/cask/installer_spec.rb b/Library/Homebrew/test/cask/installer_spec.rb index 2dc27f04c..5fc730b33 100644 --- a/Library/Homebrew/test/cask/installer_spec.rb +++ b/Library/Homebrew/test/cask/installer_spec.rb @@ -10,7 +10,7 @@ describe Hbc::Installer, :cask do Hbc::Installer.new(caffeine).install expect(Hbc.caskroom.join("local-caffeine", caffeine.version)).to be_a_directory - expect(Hbc.appdir.join("Caffeine.app")).to be_a_directory + expect(Hbc::Config.global.appdir.join("Caffeine.app")).to be_a_directory end it "works with dmg-based Casks" do @@ -19,7 +19,7 @@ describe Hbc::Installer, :cask do Hbc::Installer.new(asset).install expect(Hbc.caskroom.join("container-dmg", asset.version)).to be_a_directory - expect(Hbc.appdir.join("container")).to be_a_file + expect(Hbc::Config.global.appdir.join("container")).to be_a_file end it "works with tar-gz-based Casks" do @@ -28,7 +28,7 @@ describe Hbc::Installer, :cask do Hbc::Installer.new(asset).install expect(Hbc.caskroom.join("container-tar-gz", asset.version)).to be_a_directory - expect(Hbc.appdir.join("container")).to be_a_file + expect(Hbc::Config.global.appdir.join("container")).to be_a_file end it "works with xar-based Casks" do @@ -37,7 +37,7 @@ describe Hbc::Installer, :cask do Hbc::Installer.new(asset).install expect(Hbc.caskroom.join("container-xar", asset.version)).to be_a_directory - expect(Hbc.appdir.join("container")).to be_a_file + expect(Hbc::Config.global.appdir.join("container")).to be_a_file end it "works with pure bzip2-based Casks" do @@ -46,7 +46,7 @@ describe Hbc::Installer, :cask do Hbc::Installer.new(asset).install expect(Hbc.caskroom.join("container-bzip2", asset.version)).to be_a_directory - expect(Hbc.appdir.join("container-bzip2--#{asset.version}")).to be_a_file + expect(Hbc::Config.global.appdir.join("container-bzip2--#{asset.version}")).to be_a_file end it "works with pure gzip-based Casks" do @@ -55,7 +55,7 @@ describe Hbc::Installer, :cask do Hbc::Installer.new(asset).install expect(Hbc.caskroom.join("container-gzip", asset.version)).to be_a_directory - expect(Hbc.appdir.join("container")).to be_a_file + expect(Hbc::Config.global.appdir.join("container")).to be_a_file end it "blows up on a bad checksum" do @@ -183,7 +183,7 @@ describe Hbc::Installer, :cask do Hbc::Installer.new(nested_app).install - expect(Hbc.appdir.join("MyNestedApp.app")).to be_a_directory + expect(Hbc::Config.global.appdir.join("MyNestedApp.app")).to be_a_directory end it "generates and finds a timestamped metadata directory for an installed Cask" do diff --git a/Library/Homebrew/test/cmd/linkapps_spec.rb b/Library/Homebrew/test/cmd/linkapps_spec.rb index 2bca97822..8fc0d5eb9 100644 --- a/Library/Homebrew/test/cmd/linkapps_spec.rb +++ b/Library/Homebrew/test/cmd/linkapps_spec.rb @@ -10,9 +10,11 @@ describe "brew linkapps", :integration_test do source_app = HOMEBREW_CELLAR/"testball/0.1/TestBall.app" source_app.mkpath + ENV.delete "HOMEBREW_DEVELOPER" + expect { brew "linkapps", "--local", "HOME" => home_dir } .to output(/Linking: #{Regexp.escape(source_app)}/).to_stdout - .and output(/`brew linkapps` has been deprecated/).to_stderr + .and output(/'brew linkapps' is deprecated/).to_stderr .and be_a_success expect(apps_dir/"TestBall.app").to be_a_symlink diff --git a/Library/Homebrew/test/cmd/unlinkapps_spec.rb b/Library/Homebrew/test/cmd/unlinkapps_spec.rb index e1170f435..397a8ec5e 100644 --- a/Library/Homebrew/test/cmd/unlinkapps_spec.rb +++ b/Library/Homebrew/test/cmd/unlinkapps_spec.rb @@ -12,9 +12,11 @@ describe "brew unlinkapps", :integration_test do FileUtils.ln_s source_app, apps_dir/"TestBall.app" + ENV.delete "HOMEBREW_DEVELOPER" + expect { brew "unlinkapps", "--local", "HOME" => home_dir } .to output(%r{Unlinking: #{Regexp.escape(apps_dir)}/TestBall.app}).to_stdout - .and output(/`brew unlinkapps` has been deprecated/).to_stderr + .and output(/'brew unlinkapps' is deprecated/).to_stderr .and be_a_success end end diff --git a/Library/Homebrew/test/dependency_collector_spec.rb b/Library/Homebrew/test/dependency_collector_spec.rb index 8feeac4a2..46e859b2d 100644 --- a/Library/Homebrew/test/dependency_collector_spec.rb +++ b/Library/Homebrew/test/dependency_collector_spec.rb @@ -49,9 +49,9 @@ describe DependencyCollector do expect(find_requirement(X11Requirement).tags).to be_empty end - specify "x11 with minimum version" do + specify "x11 with (ignored) minimum version" do subject.add x11: "2.5.1" - expect(find_requirement(X11Requirement).min_version.to_s).to eq("2.5.1") + expect(find_requirement(X11Requirement).min_version.to_s).to_not eq("2.5.1") end specify "x11 with tag" do @@ -59,18 +59,13 @@ describe DependencyCollector do expect(find_requirement(X11Requirement)).to be_optional end - specify "x11 with minimum version and tag" do + specify "x11 with (ignored) minimum version and tag" do subject.add x11: ["2.5.1", :optional] dep = find_requirement(X11Requirement) - expect(dep.min_version.to_s).to eq("2.5.1") + expect(dep.min_version.to_s).to_not eq("2.5.1") expect(dep).to be_optional end - specify "ant dependency" do - subject.add ant: :build - expect(find_dependency("ant")).to eq(Dependency.new("ant", [:build])) - end - it "doesn't mutate the dependency spec" do spec = { "foo" => :optional } copy = spec.dup @@ -78,22 +73,10 @@ describe DependencyCollector do expect(spec).to eq(copy) end - it "creates a resource dependency from a '.git' URL" do - resource = Resource.new - resource.url("git://example.com/foo/bar.git") - expect(subject.add(resource)).to be_an_instance_of(GitRequirement) - end - it "creates a resource dependency from a CVS URL" do resource = Resource.new resource.url(":pserver:anonymous:@example.com:/cvsroot/foo/bar", using: :cvs) - expect(subject.add(resource)).to be_an_instance_of(CVSRequirement) - end - - it "creates a resource dependency from a Subversion URL" do - resource = Resource.new - resource.url("svn://example.com/foo/bar") - expect(subject.add(resource)).to be_an_instance_of(SubversionRequirement) + expect(subject.add(resource)).to eq(Dependency.new("cvs", [:build])) end it "creates a resource dependency from a '.7z' URL" do @@ -145,5 +128,15 @@ describe DependencyCollector do resource.download_strategy = Class.new expect { subject.add(resource) }.to raise_error(TypeError) end + + it "is deprecated when called with a language module", :needs_compat do + expect(subject).to receive(:odeprecated) + subject.add("lpeg" => :lua) + end + + it "is deprecated when called with deprecated requirements", :needs_compat do + expect(subject).to receive(:odeprecated) + subject.add(:python) + end end end diff --git a/Library/Homebrew/test/dev-cmd/audit_spec.rb b/Library/Homebrew/test/dev-cmd/audit_spec.rb index 2381ff1f5..38884222d 100644 --- a/Library/Homebrew/test/dev-cmd/audit_spec.rb +++ b/Library/Homebrew/test/dev-cmd/audit_spec.rb @@ -522,4 +522,82 @@ describe FormulaAuditor do end end end + + describe "#audit_url_is_not_binary" do + specify "it detects a url containing darwin and x86_64" do + fa = formula_auditor "foo", <<~EOS, official_tap: true + class Foo < Formula + url "https://example.com/example-darwin.x86_64.tar.gz" + end + EOS + + fa.audit_url_is_not_binary + + expect(fa.problems.first) + .to match("looks like a binary package, not a source archive. Official taps are source-only.") + end + + specify "it detects a url containing darwin and amd64" do + fa = formula_auditor "foo", <<~EOS, official_tap: true + class Foo < Formula + url "https://example.com/example-darwin.amd64.tar.gz" + end + EOS + + fa.audit_url_is_not_binary + + expect(fa.problems.first) + .to match("looks like a binary package, not a source archive. Official taps are source-only.") + end + + specify "it works on the devel spec" do + fa = formula_auditor "foo", <<~EOS, official_tap: true + class Foo < Formula + url "https://example.com/valid-1.0.tar.gz" + + devel do + url "https://example.com/example-darwin.x86_64.tar.gz" + end + end + EOS + + fa.audit_url_is_not_binary + + expect(fa.problems.first) + .to match("looks like a binary package, not a source archive. Official taps are source-only.") + end + + specify "it works on the head spec" do + fa = formula_auditor "foo", <<~EOS, official_tap: true + class Foo < Formula + url "https://example.com/valid-1.0.tar.gz" + + head do + url "https://example.com/example-darwin.x86_64.tar.gz" + end + end + EOS + + fa.audit_url_is_not_binary + + expect(fa.problems.first) + .to match("looks like a binary package, not a source archive. Official taps are source-only.") + end + + specify "it ignores resource urls" do + fa = formula_auditor "foo", <<~EOS, official_tap: true + class Foo < Formula + url "https://example.com/valid-1.0.tar.gz" + + resource "binary_res" do + url "https://example.com/example-darwin.x86_64.tar.gz" + end + end + EOS + + fa.audit_url_is_not_binary + + expect(fa.problems).to eq([]) + end + end end diff --git a/Library/Homebrew/test/dev-cmd/tap_spec.rb b/Library/Homebrew/test/dev-cmd/tap_spec.rb index 93e9c0ed6..d09d0245f 100644 --- a/Library/Homebrew/test/dev-cmd/tap_spec.rb +++ b/Library/Homebrew/test/dev-cmd/tap_spec.rb @@ -16,7 +16,7 @@ describe "brew tap", :integration_test do .and be_a_success expect { brew "tap", "--list-official" } - .to output(%r{homebrew/science}).to_stdout + .to output(%r{homebrew/php}).to_stdout .and not_to_output.to_stderr .and be_a_success diff --git a/Library/Homebrew/test/formula_installer_spec.rb b/Library/Homebrew/test/formula_installer_spec.rb index 1e3c04b68..93f23b18f 100644 --- a/Library/Homebrew/test/formula_installer_spec.rb +++ b/Library/Homebrew/test/formula_installer_spec.rb @@ -132,50 +132,4 @@ describe FormulaInstaller do fi.check_install_sanity }.to raise_error(CannotInstallFormulaError) end - - describe "#install_requirement_formula?" do - before do - @requirement = Python3Requirement.new - @requirement_dependency = @requirement.to_dependency - @install_bottle_for_dependent = false - allow(@requirement).to receive(:satisfied?).and_return(satisfied?) - allow(@requirement).to receive(:satisfied_by_formula?).and_return(satisfied_by_formula?) - @dependent = formula do - url "foo" - version "0.1" - depends_on :python3 - end - @fi = FormulaInstaller.new(@dependent) - end - - subject { @fi.install_requirement_formula?(@requirement_dependency, @requirement, @install_bottle_for_dependent) } - - context "it returns false when requirement is satisfied" do - let(:satisfied?) { true } - let(:satisfied_by_formula?) { false } - let(:installed?) { false } - it { is_expected.to be false } - end - - context "it returns false when requirement is satisfied but default formula is installed" do - let(:satisfied?) { true } - let(:satisfied_by_formula?) { false } - let(:installed?) { true } - it { is_expected.to be false } - end - - context "it returns true when requirement isn't satisfied" do - let(:satisfied?) { false } - let(:satisfied_by_formula?) { false } - let(:installed?) { false } - it { is_expected.to be true } - end - - context "it returns true when requirement is satisfied by a formula" do - let(:satisfied?) { true } - let(:satisfied_by_formula?) { true } - let(:installed?) { false } - it { is_expected.to be true } - end - end end diff --git a/Library/Homebrew/test/formula_spec.rb b/Library/Homebrew/test/formula_spec.rb index 6ba6af307..a9d09cb00 100644 --- a/Library/Homebrew/test/formula_spec.rb +++ b/Library/Homebrew/test/formula_spec.rb @@ -711,21 +711,21 @@ describe Formula do f1 = formula "f1" do url "f1-1" - depends_on :python + depends_on :java depends_on x11: :recommended depends_on xcode: ["1.0", :optional] end stub_formula_loader(f1) - python = PythonRequirement.new + java = JavaRequirement.new x11 = X11Requirement.new("x11", [:recommended]) xcode = XcodeRequirement.new(["1.0", :optional]) - expect(Set.new(f1.recursive_requirements)).to eq(Set[python, x11]) + expect(Set.new(f1.recursive_requirements)).to eq(Set[java, x11]) f1.build = BuildOptions.new(["--with-xcode", "--without-x11"], f1.options) - expect(Set.new(f1.recursive_requirements)).to eq(Set[python, xcode]) + expect(Set.new(f1.recursive_requirements)).to eq(Set[java, xcode]) f1.build = f1.stable.build f2 = formula "f2" do @@ -734,11 +734,11 @@ describe Formula do depends_on "f1" end - expect(Set.new(f2.recursive_requirements)).to eq(Set[python, x11]) - expect(Set.new(f2.recursive_requirements {})).to eq(Set[python, x11, xcode]) + expect(Set.new(f2.recursive_requirements)).to eq(Set[java, x11]) + expect(Set.new(f2.recursive_requirements {})).to eq(Set[java, x11, xcode]) requirements = f2.recursive_requirements do |_dependent, requirement| - Requirement.prune if requirement.is_a?(PythonRequirement) + Requirement.prune if requirement.is_a?(JavaRequirement) end expect(Set.new(requirements)).to eq(Set[x11, xcode]) diff --git a/Library/Homebrew/test/formula_support_spec.rb b/Library/Homebrew/test/formula_support_spec.rb index f42d61ba9..7239ef352 100644 --- a/Library/Homebrew/test/formula_support_spec.rb +++ b/Library/Homebrew/test/formula_support_spec.rb @@ -3,7 +3,7 @@ require "formula_support" describe KegOnlyReason do describe "#to_s" do it "returns the reason provided" do - r = KegOnlyReason.new :provided_by_osx, "test" + r = KegOnlyReason.new :provided_by_macos, "test" expect(r.to_s).to eq("test") end @@ -11,6 +11,12 @@ describe KegOnlyReason do r = KegOnlyReason.new :provided_by_macos, "" expect(r.to_s).to match(/^macOS already provides/) end + + it "is deprecated when reason mentions 'osx'", :needs_compat do + r = KegOnlyReason.new :provided_by_osx, "test" + expect(r).to receive(:odeprecated) + r.to_s + end end end diff --git a/Library/Homebrew/test/gpg2_requirement_spec.rb b/Library/Homebrew/test/gpg2_requirement_spec.rb deleted file mode 100644 index 8b9040b82..000000000 --- a/Library/Homebrew/test/gpg2_requirement_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -require "requirements/gpg2_requirement" -require "fileutils" - -describe GPG2Requirement do - let(:dir) { mktmpdir } - - describe "#satisfied?" do - it "returns true if GPG2 is installed" do - ENV["PATH"] = dir/"bin" - (dir/"bin/gpg").write <<~EOS - #!/bin/bash - echo 2.1.20 - EOS - FileUtils.chmod 0755, dir/"bin/gpg" - - expect(subject).to be_satisfied - end - end -end diff --git a/Library/Homebrew/test/language_module_requirement_spec.rb b/Library/Homebrew/test/language_module_requirement_spec.rb index 7f2666855..6ca8cbd0e 100644 --- a/Library/Homebrew/test/language_module_requirement_spec.rb +++ b/Library/Homebrew/test/language_module_requirement_spec.rb @@ -1,6 +1,6 @@ -require "requirements/language_module_requirement" +require "compat/requirements/language_module_requirement" -describe LanguageModuleRequirement do +describe LanguageModuleRequirement, :needs_compat do specify "unique dependencies are not equal" do x = described_class.new(:node, "less") y = described_class.new(:node, "coffee-script") diff --git a/Library/Homebrew/test/missing_formula_spec.rb b/Library/Homebrew/test/missing_formula_spec.rb index 830ecb6aa..d16c6116f 100644 --- a/Library/Homebrew/test/missing_formula_spec.rb +++ b/Library/Homebrew/test/missing_formula_spec.rb @@ -140,6 +140,8 @@ describe Homebrew::MissingFormula do tap_path = Tap::TAP_DIRECTORY/"homebrew/homebrew-foo" tap_path.mkpath (tap_path/"deleted-formula.rb").write "placeholder" + ENV.delete "GIT_AUTHOR_DATE" + ENV.delete "GIT_COMMITTER_DATE" tap_path.cd do system "git", "init" diff --git a/Library/Homebrew/test/mpi_requirement_spec.rb b/Library/Homebrew/test/mpi_requirement_spec.rb index f32b27993..aecdb1b66 100644 --- a/Library/Homebrew/test/mpi_requirement_spec.rb +++ b/Library/Homebrew/test/mpi_requirement_spec.rb @@ -1,14 +1,13 @@ -require "requirements/mpi_requirement" +require "compat/requirements" -describe MPIRequirement do +describe MPIRequirement, :needs_compat do describe "::new" do - subject { described_class.new(*(wrappers + tags)) } + subject { described_class.new(wrappers + tags) } let(:wrappers) { [:cc, :cxx, :f77] } let(:tags) { [:optional, "some-other-tag"] } - it "untangles wrappers and tags" do - expect(subject.lang_list).to eq(wrappers) - expect(subject.tags).to eq(tags) + it "stores wrappers as tags" do + expect(subject.tags).to eq(wrappers + tags) end end end diff --git a/Library/Homebrew/test/os/mac/dependency_collector_spec.rb b/Library/Homebrew/test/os/mac/dependency_collector_spec.rb index 688149021..5d260ebf7 100644 --- a/Library/Homebrew/test/os/mac/dependency_collector_spec.rb +++ b/Library/Homebrew/test/os/mac/dependency_collector_spec.rb @@ -22,18 +22,6 @@ describe DependencyCollector do expect(subject.build(:ld64)).to be nil end - specify "ant Mavericks or newer dependency" do - allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.9")) - subject.add ant: :build - expect(subject.deps.find { |dep| dep.name == "ant" }).to eq(Dependency.new("ant", [:build])) - end - - specify "ant pre-Mavericks dependency" do - allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.7")) - subject.add ant: :build - expect(subject.deps.find { |dep| dep.name == "ant" }).to be nil - end - specify "Resource xz pre-Mavericks dependency" do allow(MacOS).to receive(:version).and_return(MacOS::Version.new("10.8")) resource = Resource.new @@ -47,4 +35,16 @@ describe DependencyCollector do resource.url("http://example.com/foo.tar.xz") expect(subject.add(resource)).to be nil end + + specify "Resource dependency from a '.git' URL" do + resource = Resource.new + resource.url("git://example.com/foo/bar.git") + expect(subject.add(resource)).to be nil + end + + specify "Resource dependency from a Subversion URL" do + resource = Resource.new + resource.url("svn://example.com/foo/bar") + expect(subject.add(resource)).to be nil + end end diff --git a/Library/Homebrew/test/os/mac/diagnostic_spec.rb b/Library/Homebrew/test/os/mac/diagnostic_spec.rb index 83d95c2ef..f04652a93 100644 --- a/Library/Homebrew/test/os/mac/diagnostic_spec.rb +++ b/Library/Homebrew/test/os/mac/diagnostic_spec.rb @@ -15,14 +15,6 @@ describe Homebrew::Diagnostic::Checks do .to match("We do not provide support for this pre-release version.") end - specify "#check_for_unsupported_curl_vars" do - allow(MacOS).to receive(:version).and_return(OS::Mac::Version.new("10.10")) - ENV["SSL_CERT_DIR"] = "/some/path" - - expect(subject.check_for_unsupported_curl_vars) - .to match("SSL_CERT_DIR support was removed from Apple's curl.") - end - specify "#check_for_beta_xquartz" do allow(MacOS::XQuartz).to receive(:version).and_return("2.7.10_beta2") diff --git a/Library/Homebrew/test/patch_spec.rb b/Library/Homebrew/test/patch_spec.rb index 22c103662..56f8f7ea8 100644 --- a/Library/Homebrew/test/patch_spec.rb +++ b/Library/Homebrew/test/patch_spec.rb @@ -48,7 +48,7 @@ describe Patch do subject { described_class.create(:p2, nil) } context "empty patch" do - its(:resource) { is_expected.to be_kind_of Resource::Patch } + its(:resource) { is_expected.to be_kind_of Resource::PatchResource } its(:patch_files) { is_expected.to eq(subject.resource.patch_files) } its(:patch_files) { is_expected.to eq([]) } end diff --git a/Library/Homebrew/test/patching_spec.rb b/Library/Homebrew/test/patching_spec.rb index 502f6204c..05aea1c70 100644 --- a/Library/Homebrew/test/patching_spec.rb +++ b/Library/Homebrew/test/patching_spec.rb @@ -30,6 +30,17 @@ describe "patching" do end end + matcher :have_its_resource_patched do + match do |formula| + formula.brew do + formula.resources.first.stage Pathname.pwd/"resource_dir" + s = File.read("resource_dir/libexec/NOOP") + expect(s).not_to include("NOOP"), "libexec/NOOP was not patched as expected" + expect(s).to include("ABCD"), "libexec/NOOP was not patched as expected" + end + end + end + matcher :be_sequentially_patched do match do |formula| formula.brew do @@ -73,6 +84,22 @@ describe "patching" do ).to be_patched end + specify "single_patch_dsl_for_resource" do + expect( + formula do + resource "some_resource" do + url TESTBALL_URL + sha256 TESTBALL_SHA256 + + patch do + url PATCH_URL_A + sha256 PATCH_A_SHA256 + end + end + end, + ).to have_its_resource_patched + end + specify "single_patch_dsl_with_apply" do expect( formula do diff --git a/Library/Homebrew/test/requirement_spec.rb b/Library/Homebrew/test/requirement_spec.rb index 2d0d86c86..1f3d872f3 100644 --- a/Library/Homebrew/test/requirement_spec.rb +++ b/Library/Homebrew/test/requirement_spec.rb @@ -2,7 +2,6 @@ require "extend/ENV" require "requirement" describe Requirement do - alias_matcher :have_a_default_formula, :be_a_default_formula alias_matcher :be_a_build_requirement, :be_a_build subject { klass.new } @@ -173,60 +172,6 @@ describe Requirement do its(:option_names) { are_expected.to eq(["foo"]) } end - describe "#default_formula?" do - context "#default_formula specified" do - let(:klass) do - Class.new(described_class) do - default_formula "foo" - end - end - - it { is_expected.to have_a_default_formula } - end - - context "#default_formula omitted" do - it { is_expected.not_to have_a_default_formula } - end - end - - describe "#to_dependency" do - let(:klass) do - Class.new(described_class) do - default_formula "foo" - end - end - - it "returns a Dependency for its default Formula" do - expect(subject.to_dependency).to eq(Dependency.new("foo")) - end - - context "#modify_build_environment" do - context "with error" do - let(:klass) do - Class.new(described_class) do - class ModifyBuildEnvironmentError < StandardError; end - - default_formula "foo" - - satisfy do - true - end - - env do - raise ModifyBuildEnvironmentError - end - end - end - - it "raises an error" do - expect { - subject.to_dependency.modify_build_environment - }.to raise_error(klass.const_get(:ModifyBuildEnvironmentError)) - end - end - end - end - describe "#modify_build_environment" do context "without env proc" do let(:klass) { Class.new(described_class) } diff --git a/Library/Homebrew/test/resource_spec.rb b/Library/Homebrew/test/resource_spec.rb index 7eef3268d..50e174ed4 100644 --- a/Library/Homebrew/test/resource_spec.rb +++ b/Library/Homebrew/test/resource_spec.rb @@ -119,6 +119,31 @@ describe Resource do end end + describe "#owner" do + it "sets the owner" do + owner = Object.new + subject.owner = owner + expect(subject.owner).to eq(owner) + end + + it "sets its owner to be the patches' owner" do + subject.patch(:p1) { url "file:///my.patch" } + owner = Object.new + subject.owner = owner + subject.patches.each do |p| + expect(p.resource.owner).to eq(owner) + end + end + end + + describe "#patch" do + it "adds a patch" do + subject.patch(:p1, :DATA) + expect(subject.patches.count).to eq(1) + expect(subject.patches.first.strip).to eq(:p1) + end + end + specify "#verify_download_integrity_missing" do fn = Pathname.new("test") diff --git a/Library/Homebrew/test/rubocops/lines_cop_spec.rb b/Library/Homebrew/test/rubocops/lines_cop_spec.rb index de79fd7de..19492c252 100644 --- a/Library/Homebrew/test/rubocops/lines_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/lines_cop_spec.rb @@ -541,13 +541,12 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do end it "Using ARGV to check options" do - expect_offense(<<~RUBY) + expect_no_offenses(<<~RUBY) class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' def install verbose = ARGV.verbose? - ^^^^^^^^^^^^^ Use build instead of ARGV to check options end end RUBY @@ -718,28 +717,27 @@ describe RuboCop::Cop::FormulaAudit::Miscellaneous do RUBY end - it "deprecated ENV.fortran usage" do + it "deprecated ARGV.include? (--HEAD) usage" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' test do - ENV.fortran - ^^^^^^^^^^^ Use `depends_on :fortran` instead of `ENV.fortran` + head = ARGV.include? "--HEAD" + ^^^^^^ Use "if build.head?" instead + ^^^^ Use build instead of ARGV to check options end end RUBY end - it "deprecated ARGV.include? (--HEAD) usage" do + it "deprecated needs :openmp usage" do expect_offense(<<~RUBY) class Foo < Formula desc "foo" url 'http://example.com/foo-1.0.tgz' - test do - head = ARGV.include? "--HEAD" - ^^^^^^ Use "if build.head?" instead - end + needs :openmp + ^^^^^^^^^^^^^ 'needs :openmp' should be replaced with 'depends_on \"gcc\"' end RUBY end diff --git a/Library/Homebrew/test/rubocops/text_cop_spec.rb b/Library/Homebrew/test/rubocops/text_cop_spec.rb index 84e2344c5..1b2d61d0c 100644 --- a/Library/Homebrew/test/rubocops/text_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/text_cop_spec.rb @@ -66,7 +66,7 @@ describe RuboCop::Cop::FormulaAudit::Text do def install system "go", "get", "bar" - ^^^^^^^^^^^^^^^^^^^^^^^^^ Formulae should not use `go get`. If non-vendored resources are required use `go_resource`s. + ^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use `go get`. Please ask upstream to implement Go vendoring end end RUBY @@ -139,7 +139,7 @@ describe RuboCop::Cop::FormulaAudit::Text do def install system "go", "get", "bar" - ^^^^^^^^^^^^^^^^^^^^^^^^^ Formulae should not use `go get`. If non-vendored resources are required use `go_resource`s. + ^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use `go get`. Please ask upstream to implement Go vendoring end end RUBY diff --git a/Library/Homebrew/test/spec_helper.rb b/Library/Homebrew/test/spec_helper.rb index 08766ea37..be184b6e0 100644 --- a/Library/Homebrew/test/spec_helper.rb +++ b/Library/Homebrew/test/spec_helper.rb @@ -5,6 +5,7 @@ require "rspec/wait" require "rubocop" require "rubocop/rspec/support" require "set" +require "support/no_seed_progress_formatter" if ENV["HOMEBREW_TESTS_COVERAGE"] require "simplecov" diff --git a/Library/Homebrew/test/support/fixtures/cask/Casks/generic-artifact-absolute-target.rb b/Library/Homebrew/test/support/fixtures/cask/Casks/generic-artifact-absolute-target.rb index a1844a9c9..dc73ab773 100644 --- a/Library/Homebrew/test/support/fixtures/cask/Casks/generic-artifact-absolute-target.rb +++ b/Library/Homebrew/test/support/fixtures/cask/Casks/generic-artifact-absolute-target.rb @@ -1,3 +1,3 @@ cask 'generic-artifact-absolute-target' do - artifact 'Caffeine.app', target: "#{Hbc.appdir}/Caffeine.app" + artifact 'Caffeine.app', target: "#{Hbc::Config.global.appdir}/Caffeine.app" end diff --git a/Library/Homebrew/test/support/fixtures/cask/Casks/with-generic-artifact.rb b/Library/Homebrew/test/support/fixtures/cask/Casks/with-generic-artifact.rb index d6ce0ce8d..40c0da95a 100644 --- a/Library/Homebrew/test/support/fixtures/cask/Casks/with-generic-artifact.rb +++ b/Library/Homebrew/test/support/fixtures/cask/Casks/with-generic-artifact.rb @@ -5,5 +5,5 @@ cask 'with-generic-artifact' do url "file://#{TEST_FIXTURE_DIR}/cask/caffeine.zip" homepage 'http://example.com/with-generic-artifact' - artifact 'Caffeine.app', target: "#{Hbc.appdir}/Caffeine.app" + artifact 'Caffeine.app', target: "#{Hbc::Config.global.appdir}/Caffeine.app" end diff --git a/Library/Homebrew/test/support/helper/output_as_tty.rb b/Library/Homebrew/test/support/helper/output_as_tty.rb index aa9da73cc..22f96510e 100644 --- a/Library/Homebrew/test/support/helper/output_as_tty.rb +++ b/Library/Homebrew/test/support/helper/output_as_tty.rb @@ -19,7 +19,7 @@ module Test return super(block) unless @tty colored_tty_block = lambda do - instance_eval("$#{@output}").extend(Module.new do + instance_eval("$#{@output}", __FILE__, __LINE__).extend(Module.new do def tty? true end @@ -32,7 +32,7 @@ module Test return super(colored_tty_block) if @colors uncolored_tty_block = lambda do - instance_eval <<-EOS + instance_eval <<-EOS, __FILE__, __LINE__ + 1 begin captured_stream = StringIO.new diff --git a/Library/Homebrew/test/support/helper/spec/shared_context/homebrew_cask.rb b/Library/Homebrew/test/support/helper/spec/shared_context/homebrew_cask.rb index fc83149d0..46303a46e 100644 --- a/Library/Homebrew/test/support/helper/spec/shared_context/homebrew_cask.rb +++ b/Library/Homebrew/test/support/helper/spec/shared_context/homebrew_cask.rb @@ -6,26 +6,26 @@ require "test/support/helper/cask/fake_system_command" require "test/support/helper/cask/install_helper" require "test/support/helper/cask/never_sudo_system_command" -HOMEBREW_CASK_DIRS = [ - :appdir, - :caskroom, - :cache, - :prefpanedir, - :qlplugindir, - :servicedir, - :binarydir, -].freeze +HOMEBREW_CASK_DIRS = { + :appdir => Pathname.new(TEST_TMPDIR).join("cask-appdir"), + :prefpanedir => Pathname.new(TEST_TMPDIR).join("cask-prefpanedir"), + :qlplugindir => Pathname.new(TEST_TMPDIR).join("cask-qlplugindir"), + :servicedir => Pathname.new(TEST_TMPDIR).join("cask-servicedir"), +}.freeze RSpec.shared_context "Homebrew-Cask" do + before(:each) do + HOMEBREW_CASK_DIRS.each do |method, path| + allow(Hbc::Config.global).to receive(method).and_return(path) + end + end + around(:each) do |example| third_party_tap = Tap.fetch("third-party", "tap") begin - dirs = HOMEBREW_CASK_DIRS.map do |dir| - Pathname.new(TEST_TMPDIR).join("cask-#{dir}").tap do |path| - path.mkpath - Hbc.public_send("#{dir}=", path) - end - end + HOMEBREW_CASK_DIRS.values.each(&:mkpath) + + [Hbc::Config.global.binarydir, Hbc.caskroom, Hbc.cache].each(&:mkpath) Hbc.default_tap = Tap.fetch("caskroom", "spec").tap do |tap| FileUtils.mkdir_p tap.path.dirname @@ -39,7 +39,8 @@ RSpec.shared_context "Homebrew-Cask" do example.run ensure - FileUtils.rm_rf dirs + FileUtils.rm_rf HOMEBREW_CASK_DIRS.values + FileUtils.rm_rf [Hbc::Config.global.binarydir, Hbc.caskroom, Hbc.cache] Hbc.default_tap.path.unlink FileUtils.rm_rf Hbc.default_tap.path.parent third_party_tap.path.unlink diff --git a/Library/Homebrew/test/support/helper/spec/shared_examples/hbc_staged.rb b/Library/Homebrew/test/support/helper/spec/shared_examples/hbc_staged.rb index 361179b9e..e7fa172c4 100644 --- a/Library/Homebrew/test/support/helper/spec/shared_examples/hbc_staged.rb +++ b/Library/Homebrew/test/support/helper/spec/shared_examples/hbc_staged.rb @@ -22,7 +22,7 @@ shared_examples Hbc::Staged do end it "can get the Info.plist file for the primary app" do - expect(staged.info_plist_file).to eq Hbc.appdir.join("TestCask.app/Contents/Info.plist") + expect(staged.info_plist_file).to eq Hbc::Config.global.appdir.join("TestCask.app/Contents/Info.plist") end it "can execute commands on the Info.plist file" do diff --git a/Library/Homebrew/test/support/no_seed_progress_formatter.rb b/Library/Homebrew/test/support/no_seed_progress_formatter.rb new file mode 100644 index 000000000..e87a58143 --- /dev/null +++ b/Library/Homebrew/test/support/no_seed_progress_formatter.rb @@ -0,0 +1,7 @@ +require "rspec/core/formatters/progress_formatter" + +class NoSeedProgressFormatter < RSpec::Core::Formatters::ProgressFormatter + RSpec::Core::Formatters.register self, :seed + + def seed(notification); end +end diff --git a/Library/Homebrew/test/utils/popen_spec.rb b/Library/Homebrew/test/utils/popen_spec.rb index 63bbc7b18..d1ae12d1c 100644 --- a/Library/Homebrew/test/utils/popen_spec.rb +++ b/Library/Homebrew/test/utils/popen_spec.rb @@ -15,6 +15,12 @@ describe Utils do ).to eq("success") expect($CHILD_STATUS).to be_a_success end + + it "fails when the command does not exist" do + expect(subject.popen_read("./nonexistent", err: :out)) + .to eq("brew: command not found: ./nonexistent\n") + expect($CHILD_STATUS).to be_a_failure + end end describe "::popen_write" do diff --git a/Library/Homebrew/test/utils/svn_spec.rb b/Library/Homebrew/test/utils/svn_spec.rb index 4edb365a0..503d285f3 100644 --- a/Library/Homebrew/test/utils/svn_spec.rb +++ b/Library/Homebrew/test/utils/svn_spec.rb @@ -7,7 +7,11 @@ describe Utils do end it "returns svn version if svn available" do - expect(described_class.svn_available?).to be_truthy + if File.executable? "/usr/bin/svn" + expect(described_class.svn_available?).to be_truthy + else + expect(described_class.svn_available?).to be_falsey + end end end diff --git a/Library/Homebrew/test/x11_requirement_spec.rb b/Library/Homebrew/test/x11_requirement_spec.rb index bc02dc75a..ef50fdc76 100644 --- a/Library/Homebrew/test/x11_requirement_spec.rb +++ b/Library/Homebrew/test/x11_requirement_spec.rb @@ -19,11 +19,6 @@ describe X11Requirement do other = described_class.new("foo") expect(subject).not_to eql(other) end - - it "returns false if the minimum version differs" do - other = described_class.new(default_name, ["2.5"]) - expect(subject).not_to eql(other) - end end describe "#modify_build_environment" do diff --git a/Library/Homebrew/utils.rb b/Library/Homebrew/utils.rb index 48ab94c4f..03924dcef 100644 --- a/Library/Homebrew/utils.rb +++ b/Library/Homebrew/utils.rb @@ -82,6 +82,14 @@ def odeprecated(method, replacement = nil, disable: false, disable_on: nil, call # - Location of caller of deprecated method (if all else fails). backtrace = caller tap_message = nil + + # Don't throw deprecations at all for cached, .brew or .metadata files. + return if backtrace.any? do |line| + line.include?(HOMEBREW_CACHE) || + line.include?("/.brew/") || + line.include?("/.metadata/") + end + caller_message = backtrace.detect do |line| next unless line =~ %r{^#{Regexp.escape(HOMEBREW_LIBRARY)}/Taps/([^/]+/[^/]+)/} tap = Tap.fetch Regexp.last_match(1) @@ -101,7 +109,8 @@ def odeprecated(method, replacement = nil, disable: false, disable_on: nil, call if ARGV.homebrew_developer? || disable || Homebrew.raise_deprecation_exceptions? - raise MethodDeprecatedError, message + developer_message = message + "Or, even better, submit a PR to fix it!" + raise MethodDeprecatedError, developer_message elsif !Homebrew.auditing? opoo "#{message}\n" end @@ -154,6 +163,7 @@ def interactive_shell(f = nil) end if ENV["SHELL"].include?("zsh") && ENV["HOME"].start_with?(HOMEBREW_TEMP.resolved_path.to_s) + FileUtils.mkdir_p ENV["HOME"] FileUtils.touch "#{ENV["HOME"]}/.zshrc" end @@ -188,15 +198,9 @@ module Homebrew end def install_gem_setup_path!(name, version = nil, executable = name) - # Respect user's preferences for where gems should be installed. - ENV["GEM_HOME"] = if ENV["HOMEBREW_GEM_HOME"].to_s.empty? - Gem.user_dir - else - ENV["HOMEBREW_GEM_HOME"] - end - unless ENV["HOMEBREW_GEM_PATH"].to_s.empty? - ENV["GEM_PATH"] = ENV["HOMEBREW_GEM_PATH"] - end + # Match where our bundler gems are. + ENV["GEM_HOME"] = "#{ENV["HOMEBREW_LIBRARY"]}/Homebrew/vendor/bundle/ruby/#{RbConfig::CONFIG["ruby_version"]}" + ENV["GEM_PATH"] = ENV["GEM_HOME"] # Make rubygems notice env changes. Gem.clear_paths @@ -267,12 +271,6 @@ module Homebrew # rubocop:enable Style/GlobalVars end -def with_system_path - with_env(PATH: PATH.new("/usr/bin", "/bin")) do - yield - end -end - def with_homebrew_path with_env(PATH: PATH.new(ENV["HOMEBREW_PATH"])) do yield @@ -344,7 +342,7 @@ def which_editor editor = %w[atom subl mate edit vim].find do |candidate| candidate if which(candidate, ENV["HOMEBREW_PATH"]) end - editor ||= "/usr/bin/vim" + editor ||= "vim" opoo <<~EOS Using #{editor} because no editor was set in the environment. @@ -376,7 +374,7 @@ end # GZips the given paths, and returns the gzipped paths def gzip(*paths) paths.collect do |path| - with_system_path { safe_system "gzip", path } + safe_system "gzip", path Pathname.new("#{path}.gz") end end diff --git a/Library/Homebrew/utils/curl.rb b/Library/Homebrew/utils/curl.rb index eaa81352c..65edd85df 100644 --- a/Library/Homebrew/utils/curl.rb +++ b/Library/Homebrew/utils/curl.rb @@ -2,10 +2,13 @@ require "pathname" require "open3" def curl_executable - curl = Pathname.new ENV["HOMEBREW_CURL"] - curl = Pathname.new "/usr/bin/curl" unless curl.exist? - return curl if curl.executable? - raise "#{curl} is not executable" + @curl ||= [ + ENV["HOMEBREW_CURL"], + which("curl"), + "/usr/bin/curl", + ].map { |c| Pathname(c) }.find(&:executable?) + raise "curl is not executable" unless @curl + @curl end def curl_args(*extra_args, show_output: false, user_agent: :default) @@ -59,3 +62,95 @@ end def curl_output(*args, **options) Open3.capture3(*curl_args(*args, show_output: true, **options)) end + +def curl_check_http_content(url, user_agents: [:default], check_content: false, strict: false, require_http: false) + return unless url.start_with? "http" + + details = nil + user_agent = nil + hash_needed = url.start_with?("http:") && !require_http + user_agents.each do |ua| + details = curl_http_content_headers_and_checksum(url, hash_needed: hash_needed, user_agent: ua) + user_agent = ua + break if details[:status].to_s.start_with?("2") + end + + unless details[:status] + # Hack around https://github.com/Homebrew/brew/issues/3199 + return if MacOS.version == :el_capitan + return "The URL #{url} is not reachable" + end + + unless details[:status].start_with? "2" + return "The URL #{url} is not reachable (HTTP status code #{details[:status]})" + end + + return unless hash_needed + + secure_url = url.sub "http", "https" + secure_details = + curl_http_content_headers_and_checksum(secure_url, hash_needed: true, user_agent: user_agent) + + if !details[:status].to_s.start_with?("2") || + !secure_details[:status].to_s.start_with?("2") + return + end + + etag_match = details[:etag] && + details[:etag] == secure_details[:etag] + content_length_match = + details[:content_length] && + details[:content_length] == secure_details[:content_length] + file_match = details[:file_hash] == secure_details[:file_hash] + + if etag_match || content_length_match || file_match + return "The URL #{url} should use HTTPS rather than HTTP" + end + + return unless check_content + + no_protocol_file_contents = %r{https?:\\?/\\?/} + details[:file] = details[:file].gsub(no_protocol_file_contents, "/") + secure_details[:file] = secure_details[:file].gsub(no_protocol_file_contents, "/") + + # Check for the same content after removing all protocols + if details[:file] == secure_details[:file] + return "The URL #{url} should use HTTPS rather than HTTP" + end + + return unless strict + + # Same size, different content after normalization + # (typical causes: Generated ID, Timestamp, Unix time) + if details[:file].length == secure_details[:file].length + return "The URL #{url} may be able to use HTTPS rather than HTTP. Please verify it in a browser." + end + + lenratio = (100 * secure_details[:file].length / details[:file].length).to_i + return unless (90..110).cover?(lenratio) + "The URL #{url} may be able to use HTTPS rather than HTTP. Please verify it in a browser." +end + +def curl_http_content_headers_and_checksum(url, hash_needed: false, user_agent: :default) + max_time = hash_needed ? "600" : "25" + output, = curl_output( + "--connect-timeout", "15", "--include", "--max-time", max_time, "--location", url, + user_agent: user_agent + ) + + status_code = :unknown + while status_code == :unknown || status_code.to_s.start_with?("3") + headers, _, output = output.partition("\r\n\r\n") + status_code = headers[%r{HTTP\/.* (\d+)}, 1] + end + + output_hash = Digest::SHA256.digest(output) if hash_needed + + { + status: status_code, + etag: headers[%r{ETag: ([wW]\/)?"(([^"]|\\")*)"}, 2], + content_length: headers[/Content-Length: (\d+)/, 1], + file_hash: output_hash, + file: output, + } +end diff --git a/Library/Homebrew/utils/git.rb b/Library/Homebrew/utils/git.rb index f1113af66..ac17967c5 100644 --- a/Library/Homebrew/utils/git.rb +++ b/Library/Homebrew/utils/git.rb @@ -50,7 +50,7 @@ module Utils # we cannot install brewed git if homebrew/core is unavailable. if CoreTap.instance.installed? begin - oh1 "Installing git" + oh1 "Installing #{Formatter.identifier("git")}" safe_system HOMEBREW_BREW_FILE, "install", "git" rescue raise "Git is unavailable" diff --git a/Library/Homebrew/utils/github.rb b/Library/Homebrew/utils/github.rb index be9bf4dd3..016676323 100644 --- a/Library/Homebrew/utils/github.rb +++ b/Library/Homebrew/utils/github.rb @@ -129,7 +129,7 @@ module GitHub # This is a no-op if the user is opting out of using the GitHub API. return block_given? ? yield({}) : {} if ENV["HOMEBREW_NO_GITHUB_API"] - args = %W[--header application/vnd.github.v3+json --write-out \n%{http_code}] + args = %W[--header application/vnd.github.v3+json --write-out \n%{http_code}] # rubocop:disable Lint/NestedPercentLiteral args += curl_args token, username = api_credentials diff --git a/Library/Homebrew/utils/popen.rb b/Library/Homebrew/utils/popen.rb index 2fa3ade46..21dceec06 100644 --- a/Library/Homebrew/utils/popen.rb +++ b/Library/Homebrew/utils/popen.rb @@ -14,7 +14,15 @@ module Utils yield pipe else options[:err] ||= :close unless ENV["HOMEBREW_STDERR"] - exec(*args, options) + begin + exec(*args, options) + rescue Errno::ENOENT + $stderr.puts "brew: command not found: #{args[0]}" unless options[:err] == :close + exit! 127 + rescue SystemCallError + $stderr.puts "brew: exec failed: #{args[0]}" unless options[:err] == :close + exit! 1 + end end end end diff --git a/Library/Homebrew/utils/ruby.sh b/Library/Homebrew/utils/ruby.sh index b16531e9f..2fb780c65 100644 --- a/Library/Homebrew/utils/ruby.sh +++ b/Library/Homebrew/utils/ruby.sh @@ -2,7 +2,7 @@ setup-ruby-path() { local vendor_dir local vendor_ruby_current_version local vendor_ruby_path - local ruby_old_version + local ruby_version_new_enough local minimum_ruby_version="2.3.3" vendor_dir="$HOMEBREW_LIBRARY/Homebrew/vendor" @@ -35,12 +35,12 @@ setup-ruby-path() { HOMEBREW_RUBY_PATH="$(which ruby)" fi - if [[ -n "$HOMEBREW_RUBY_PATH" ]] + if [[ -n "$HOMEBREW_RUBY_PATH" && -z "$HOMEBREW_FORCE_VENDOR_RUBY" ]] then - ruby_old_version="$("$HOMEBREW_RUBY_PATH" -rrubygems -e "puts Gem::Version.new('$minimum_ruby_version') > Gem::Version.new(RUBY_VERSION)")" + ruby_version_new_enough="$("$HOMEBREW_RUBY_PATH" -rrubygems -e "puts Gem::Version.new(RUBY_VERSION.to_s.dup) >= Gem::Version.new('$minimum_ruby_version')")" fi - if [[ -z "$HOMEBREW_RUBY_PATH" || "$ruby_old_version" == "true" || -n "$HOMEBREW_FORCE_VENDOR_RUBY" ]] + if [[ -z "$HOMEBREW_RUBY_PATH" || -n "$HOMEBREW_FORCE_VENDOR_RUBY" || "$ruby_version_new_enough" != "true" ]] then brew vendor-install ruby if [[ ! -x "$vendor_ruby_path" ]] diff --git a/Library/Homebrew/version/null.rb b/Library/Homebrew/version/null.rb index 65e3d56c0..9549ba328 100644 --- a/Library/Homebrew/version/null.rb +++ b/Library/Homebrew/version/null.rb @@ -30,6 +30,10 @@ class Version Float::NAN end + def to_i + 0 + end + def to_s "" end @@ -5,7 +5,7 @@ Features, usage and installation instructions are [summarised on the homepage](h ## What Packages Are Available? 1. Type `brew search` for a list. -2. Or visit [braumeister.org](http://braumeister.org) to browse packages online. +2. Or visit [formulae.brew.sh](http://formulae.brew.sh) to browse packages online. 3. Or use `brew search --desc <keyword>` to browse packages from the command line. ## More Documentation @@ -26,7 +26,11 @@ 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. -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. Good luck! +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. + +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). + +Good luck! ## Security Please report security issues to our [HackerOne](https://hackerone.com/homebrew/). @@ -36,9 +40,11 @@ Homebrew's lead maintainer is [Mike McQuaid](https://github.com/mikemcquaid). Homebrew/homebrew-core's lead maintainer is [ilovezfs](https://github.com/ilovezfs). -Homebrew's other current maintainers are [Alyssa Ross](https://github.com/alyssais), [Andrew Janke](https://github.com/apjanke), [Alex Dunn](https://github.com/dunn), [FX Coudert](https://github.com/fxcoudert), [Josh Hagins](https://github.com/jawshooah), [JCount](https://github.com/jcount), [Misty De Meo](https://github.com/mistydemeo), [neutric](https://github.com/neutric), [Tomasz Pajor](https://github.com/nijikon), [Markus Reiter](https://github.com/reitermarkus), [Tim Smith](https://github.com/tdsmith), [Tom Schoonjans](https://github.com/tschoonj), [Uladzislau Shablinski](https://github.com/vladshablinsky) and [William Woodruff](https://github.com/woodruffw). +Homebrew/brew's other current maintainers are [ilovezfs](https://github.com/ilovezfs), [Alyssa Ross](https://github.com/alyssais), [JCount](https://github.com/jcount), [Misty De Meo](https://github.com/mistydemeo), [Gautham Goli](https://github.com/GauthamGoli), [Markus Reiter](https://github.com/reitermarkus) and [William Woodruff](https://github.com/woodruffw). + +Homebrew/homebrew-core's other current maintainers are [FX Coudert](https://github.com/fxcoudert), [JCount](https://github.com/jcount), [Misty De Meo](https://github.com/mistydemeo) and [Tom Schoonjans](https://github.com/tschoonj). -Former maintainers with significant contributions include [Baptiste Fontaine](https://github.com/bfontaine), [Xu Cheng](https://github.com/xu-cheng), [Martin Afanasjew](https://github.com/UniqMartin), [Dominyk Tiller](https://github.com/DomT4), [Brett Koonce](https://github.com/asparagui), [Charlie Sharpsteen](https://github.com/Sharpie), [Jack Nagel](https://github.com/jacknagel), [Adam Vandenberg](https://github.com/adamv) and Homebrew's creator: [Max Howell](https://github.com/mxcl). +Former maintainers with significant contributions include [Tim Smith](https://github.com/tdsmith), [Baptiste Fontaine](https://github.com/bfontaine), [Xu Cheng](https://github.com/xu-cheng), [Martin Afanasjew](https://github.com/UniqMartin), [Dominyk Tiller](https://github.com/DomT4), [Brett Koonce](https://github.com/asparagui), [Charlie Sharpsteen](https://github.com/Sharpie), [Jack Nagel](https://github.com/jacknagel), [Adam Vandenberg](https://github.com/adamv), [Andrew Janke](https://github.com/apjanke), [Alex Dunn](https://github.com/dunn), [neutric](https://github.com/neutric), [Tomasz Pajor](https://github.com/nijikon), [Uladzislau Shablinski](https://github.com/vladshablinsky) and Homebrew's creator: [Max Howell](https://github.com/mxcl). ## Community - [discourse.brew.sh (forum)](https://discourse.brew.sh) @@ -56,6 +62,18 @@ Please consider a regular donation through Patreon: [](https://www.patreon.com/homebrew) +Alternatively, if you'd rather make a one-off payment: + +- [Donate with PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=V6ZE57MJRYC8L) +- Donate by USA $ check from a USA bank: + - Make check payable to "Software Freedom Conservancy, Inc." and place "Directed donation: Homebrew" in the memo field. Checks should then be mailed to: + - Software Freedom Conservancy, Inc. + 137 Montague ST STE 380 + BROOKLYN, NY 11201 USA +- Donate by wire transfer: contact accounting@sfconservancy.org for wire transfer details. + +Homebrew is a member of the [Software Freedom Conservancy](https://sfconservancy.org) which provides us with an ability to receive tax-deductible, Homebrew earmarked donations (and [many other services](https://sfconservancy.org/members/services/)). Software Freedom Conservancy, Inc. is a 501(c)(3) organization incorporated in New York, and donations made to it are fully tax-deductible to the extent permitted by law. + ## Sponsors Our Xserve ESXi boxes for CI are hosted by [MacStadium](https://www.macstadium.com). @@ -77,10 +95,10 @@ Our bottles (binary packages) are hosted by [Bintray](https://bintray.com/homebr [](https://www.netlify.com) -Secure password storage and syncing provided by [1Password for Teams](https://1password.com/teams/) by [AgileBits](https://agilebits.com) +Secure password storage and syncing provided by [1Password for Teams](https://1password.com/teams/) by [AgileBits](https://agilebits.com). [](https://agilebits.com) -Homebrew is a member of the [Software Freedom Conservancy](https://sfconservancy.org) +Homebrew is a member of the [Software Freedom Conservancy](https://sfconservancy.org). [](https://sfconservancy.org) @@ -59,37 +59,15 @@ do export "$VAR_NEW"="${!VAR}" done -# Set HOMEBREW_DEVELOPER for users who have run a development command -if [[ -z "$HOMEBREW_DEVELOPER" ]] -then - export HOMEBREW_GIT_CONFIG_FILE="$HOMEBREW_REPOSITORY/.git/config" - HOMEBREW_GIT_CONFIG_DEVELOPERMODE="$(git config --file="$HOMEBREW_GIT_CONFIG_FILE" --get homebrew.devcmdrun 2>/dev/null)" - if [[ "$HOMEBREW_GIT_CONFIG_DEVELOPERMODE" = "true" ]] - then - export HOMEBREW_DEV_CMD_RUN="1" - fi -fi - -if [[ -z "$HOMEBREW_NO_ENV_FILTERING" ]] -then - if [[ -n "$HOMEBREW_DEVELOPER" || -n "$HOMEBREW_DEV_CMD_RUN" ]] - then - # Use env filtering by default for users who have run a development command - # This will be enabled by default for all users in future. - export HOMEBREW_ENV_FILTERING="1" - fi -else - unset HOMEBREW_ENV_FILTERING -fi - -# test-bot sets environment filtering itself -if [[ -n "$HOMEBREW_ENV_FILTERING" && "$1" != "test-bot" ]] +# test-bot does environment filtering itself +if [[ -z "$HOMEBREW_NO_ENV_FILTERING" && "$1" != "test-bot" ]] then PATH="/usr/bin:/bin:/usr/sbin:/sbin" FILTERED_ENV=() + # Filter all but the specific variables. for VAR in HOME SHELL PATH TERM LOGNAME USER CI TRAVIS SSH_AUTH_SOCK SUDO_ASKPASS \ - http_proxy https_proxy ftp_proxy HTTPS_PROXY FTP_PROXY \ + http_proxy https_proxy ftp_proxy no_proxy all_proxy HTTPS_PROXY FTP_PROXY ALL_PROXY \ "${!HOMEBREW_@}" "${!TRAVIS_@}" "${!JENKINS_@}" do # Skip if variable value is empty. diff --git a/completions/bash/brew b/completions/bash/brew index 60c272f73..02c862bbd 100644 --- a/completions/bash/brew +++ b/completions/bash/brew @@ -1,5 +1,10 @@ # Bash completion script for brew(1) +# Indicates there are no completions +__brewcomp_null() { + COMPREPLY="" +} + __brewcomp_words_include() { local i=1 while [[ "$i" -lt "$COMP_CWORD" ]] @@ -46,7 +51,7 @@ __brewcomp() { __brew_complete_formulae() { local cur="${COMP_WORDS[COMP_CWORD]}" local formulas="$(brew search)" - local shortnames="$(echo "$formulas" | grep / | cut -d / -f 3)" + local shortnames="$(echo "$formulas" | \grep / | \cut -d / -f 3)" COMPREPLY=($(compgen -W "$formulas $shortnames" -- "$cur")) } @@ -399,6 +404,7 @@ _brew_search() { return ;; esac + __brewcomp_null } _brew_style() { @@ -539,6 +545,234 @@ _brew_uses() { __brew_complete_formulae } +__brew_caskcomp_words_include () +{ + local i=1 + while [[ $i -lt $COMP_CWORD ]]; do + if [[ "${COMP_WORDS[i]}" = "$1" ]]; then + return 0 + fi + i=$((++i)) + done + return 1 +} + +# Find the previous non-switch word +__brew_caskcomp_prev () +{ + local idx=$((COMP_CWORD - 1)) + local prv="${COMP_WORDS[idx]}" + while [[ $prv == -* ]]; do + idx=$((--idx)) + prv="${COMP_WORDS[idx]}" + done + echo "$prv" +} + +__brew_caskcomp () +{ + # break $1 on space, tab, and newline characters, + # and turn it into a newline separated list of words + local list s sep=$'\n' IFS=$' '$'\t'$'\n' + local cur="${COMP_WORDS[COMP_CWORD]}" + + for s in $1; do + __brew_caskcomp_words_include "$s" && continue + list="$list$s$sep" + done + + IFS=$sep + COMPREPLY=($(compgen -W "$list" -- "$cur")) +} + +# Don't use __brew_caskcomp() in any of the __brew_cask_complete_foo functions, as +# it is too slow and is not worth it just for duplicate elimination. +__brew_cask_complete_formulae () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + local lib=$(brew --repository)/Library + local taps=${lib}/Taps + local casks=${lib}/Taps/caskroom/homebrew-cask/Casks + local ff=$(\ls ${casks} 2>/dev/null | \sed 's/\.rb//g') + + COMPREPLY=($(compgen -W "$ff" -- "$cur")) +} + +__brew_cask_complete_installed () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + local inst=$(brew cask list -1) + COMPREPLY=($(compgen -W "$inst" -- "$cur")) +} + +__brew_cask_complete_caskroom () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + local caskroom_dir=/opt/homebrew-cask/Caskroom/ + local files=$(\ls ${caskroom_dir} 2>/dev/null) + COMPREPLY=($(compgen -W "$files" -- "$cur")) +} + +__brew_cask_complete_outdated () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + local outdated=$(brew cask outdated --quiet) + COMPREPLY=($(compgen -W "$outdated" -- "$cur")) +} + +_brew_cask_cleanup () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + -*) + __brew_caskcomp "--force" + return + ;; + esac + __brew_cask_complete_installed +} + +_brew_cask_fetch () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + local prv=$(__brew_caskcomp_prev) + case "$cur" in + -*) + __brew_caskcomp "--force" + return + ;; + esac + __brew_cask_complete_formulae +} + +_brew_cask_install () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + local prv=$(__brew_caskcomp_prev) + case "$cur" in + -*) + __brew_caskcomp "--force --skip-cask-deps --require-sha --language" + return + ;; + esac + __brew_cask_complete_formulae +} + +_brew_cask_list () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + -*) + __brew_caskcomp "-1 --versions" + return + ;; + esac + + __brew_cask_complete_installed +} + +_brew_cask_outdated () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + -*) + __brew_caskcomp "--greedy --verbose --quiet" + return + ;; + esac + __brew_cask_complete_installed +} + +_brew_cask_style () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + -*) + __brew_caskcomp "--fix" + return + ;; + esac + __brew_cask_complete_installed +} + +_brew_cask_uninstall () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + -*) + __brew_caskcomp "--force" + return + ;; + esac + __brew_cask_complete_installed +} + +_brew_cask_upgrade () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + -*) + __brew_caskcomp "--force --greedy" + return + ;; + esac + __brew_cask_complete_outdated +} + +_brew_cask () +{ + local i=1 cmd + + # find the subcommand + while [[ $i -lt $COMP_CWORD ]]; do + local s="${COMP_WORDS[i]}" + case "$s" in + --*) + cmd="$s" + break + ;; + -*) + ;; + cask) + ;; + *) + cmd="$s" + break + ;; + esac + i=$((++i)) + done + + if [[ $i -eq $COMP_CWORD ]]; then + __brew_caskcomp "abv audit cat cleanup create doctor edit fetch home info install list ls outdated reinstall remove rm search style uninstall upgrade zap -S --force --caskroom --verbose --appdir --colorpickerdir --prefpanedir --qlplugindir --fontdir --servicedir --input_methoddir --internet_plugindir --screen_saverdir --no-binaries --debug --version" + return + fi + + # subcommands have their own completion functions + case "$cmd" in + --version) __brewcomp_null ;; + audit) __brew_cask_complete_formulae ;; + cat) __brew_cask_complete_formulae ;; + cleanup) _brew_cask_cleanup ;; + create) ;; + doctor) __brewcomp_null ;; + edit) __brew_cask_complete_formulae ;; + fetch) _brew_cask_fetch ;; + home) __brew_cask_complete_formulae ;; + info|abv) __brew_cask_complete_formulae ;; + install|instal) _brew_cask_install ;; + list|ls) _brew_cask_list ;; + outdated) _brew_cask_outdated ;; + reinstall) __brew_cask_complete_installed ;; + search) __brewcomp_null ;; + style) _brew_cask_style ;; + uninstall|remove|rm) _brew_cask_uninstall ;; + upgrade) _brew_cask_upgrade ;; + zap) __brew_cask_complete_caskroom ;; + *) ;; + esac +} + _brew() { local i=1 cmd @@ -565,7 +799,7 @@ _brew() { then # Do not auto-complete "*instal" or "*uninstal" aliases for "*install" commands. # Prefix newline to prevent not checking the first command. - local cmds=$'\n'"$(brew commands --quiet --include-aliases | grep -v instal$)" + local cmds=$'\n'"$(brew commands --quiet --include-aliases | \grep -v instal$)" __brewcomp "${cmds}" return fi @@ -578,6 +812,7 @@ _brew() { analytics) _brew_analytics ;; audit) __brew_complete_formulae ;; bottle) _brew_bottle ;; + cask) _brew_cask ;; cat) __brew_complete_formulae ;; cleanup) _brew_cleanup ;; create) _brew_create ;; diff --git a/completions/zsh/_brew b/completions/zsh/_brew index 22792860d..e4f874bfb 100644 --- a/completions/zsh/_brew +++ b/completions/zsh/_brew @@ -711,7 +711,7 @@ _brew_uninstall() { # brew unlink [--dry-run] formula: _brew_unlink() { _arguments \ - '(--dry-run =n)'{--dry-run,=n}'[don''t unlink or delete any files]' \ + '(--dry-run -n)'{--dry-run,-n}'[don''t unlink or delete any files]' \ ':formula:__brew_installed_formulae' } @@ -719,7 +719,7 @@ _brew_unlink() { _brew_unlinkapps() { _arguments \ '(--local)--local[remove symlinks from ~/Applications instead of the system directory]' \ - '(--dry-run =n)'{--dry-run,-n}'[don''t unlink or delete any files]' \ + '(--dry-run -n)'{--dry-run,-n}'[don''t unlink or delete any files]' \ ':formula:__brew_installed_formulae' } diff --git a/completions/zsh/_brew_cask b/completions/zsh/_brew_cask index ff277ea60..d702ea093 100644 --- a/completions/zsh/_brew_cask +++ b/completions/zsh/_brew_cask @@ -12,17 +12,21 @@ zstyle -T ':completion:*:*:*:brew-cask:*' tag-order && \ zstyle ':completion:*:*:*:brew-cask:*' tag-order 'commands' +__brew_cask() { + [ -d "$(brew --repo caskroom/cask)" ] && brew cask $@ +} + __brew_all_casks() { local -a list local expl - list=( $(brew cask search) ) + list=( $(__brew_cask search) ) _wanted list expl 'all casks' compadd -a list } __brew_installed_casks() { local -a list local expl - list=( $(brew cask list|sed 's/(!)//') ) + list=( $(__brew_cask list|sed 's/(!)//') ) _wanted list expl 'installed casks' compadd -a list } diff --git a/docs/.ruby-version b/docs/.ruby-version index bec3a35ee..005119baa 100644 --- a/docs/.ruby-version +++ b/docs/.ruby-version @@ -1 +1 @@ -system +2.4.1 diff --git a/docs/Brew-Test-Bot.md b/docs/Brew-Test-Bot.md index 4a3a639d5..46e2f9e71 100644 --- a/docs/Brew-Test-Bot.md +++ b/docs/Brew-Test-Bot.md @@ -3,7 +3,7 @@ `brew test-bot` is the name for the automated review and testing system funded by [our Kickstarter in 2013](https://www.kickstarter.com/projects/homebrew/brew-test-bot). -It comprises four Mac Minis running in a data centre in England which host +It comprises four Mac Minis and three Xserves running in two data centres which host [a Jenkins instance at https://jenkins.brew.sh](https://jenkins.brew.sh) and run the [`brew-test-bot.rb`](https://github.com/Homebrew/homebrew-test-bot/blob/master/cmd/brew-test-bot.rb) Ruby script to perform automated testing of commits to the master branch, pull @@ -36,8 +36,6 @@ A passed build looks like this: On failed or passed builds you can click the "Details" link to view the result in Jenkins. -When you click this you'll see the results. - A passed build looks like this:  diff --git a/docs/Building-Against-Non-Homebrew-Dependencies.md b/docs/Building-Against-Non-Homebrew-Dependencies.md new file mode 100644 index 000000000..4e85757a1 --- /dev/null +++ b/docs/Building-Against-Non-Homebrew-Dependencies.md @@ -0,0 +1,11 @@ +# Building Against Non-Homebrew Dependencies + +## History + +Originally Homebrew was a build-from-source package manager and all user environment variables and non-Homebrew-installed software were available to builds. Since then Homebrew added `Requirement`s to specify dependencies on non-Homebrew software (such as those provided by `brew cask` like X11/XQuartz), the `superenv` build system to strip out unspecified dependencies, environment filtering to stop the user environment leaking into Homebrew builds and `default_formula` to specify that a `Requirement` can be satisifed by a particular formula. + +As Homebrew became primarily a binary package manager, most users were fulfilling `Requirement`s with the `default_formula`, not with arbitrary alternatives. To improve quality and reduce variation, Homebrew now exclusively supports using the default formula, as an ordinary dependency, and no longer supports using arbitrary alternatives. + +## Today + +If you wish to build against custom non-Homebrew dependencies that are provided by Homebrew (e.g. a non-Homebrew, non-macOS `ruby`) then you must [create and maintain your own tap](How-to-Create-and-Maintain-a-Tap.md) as these formulae will not be accepted in Homebrew/homebrew-core. Once you have done that you can specify `env :std` in the formula which will allow a e.g. `which ruby` to access your existing `PATH` variable and allow compilation to link against this Ruby. diff --git a/docs/External-Commands.md b/docs/External-Commands.md index 881a1293a..65282fcb1 100644 --- a/docs/External-Commands.md +++ b/docs/External-Commands.md @@ -16,7 +16,7 @@ In both cases, the command file should be executable (`chmod +x`) and live somew ### Ruby commands An external command `extcmd` implemented as a Ruby command should be named `brew-extcmd.rb`. The command is executed by doing a `require` on the full pathname. As the command is `require`d, it has full access to the Homebrew "environment", i.e. all global variables and modules that any internal command has access to. -The command may `Kernel.exit` with a status code if it needs to; if it doesn't explicitly exit then Homebrew will return 0. +The command may `Kernel.exit` with a status code if it needs to; if it doesn't explicitly exit then Homebrew will return `0`. ### Shell scripts A shell script for a command named `extcmd` should be named `brew-extcmd`. This file will be run via `exec` with some Homebrew variables set as environment variables, and passed any additional command-line arguments. diff --git a/docs/Formula-Cookbook.md b/docs/Formula-Cookbook.md index b40c765c6..c4db9e9f8 100644 --- a/docs/Formula-Cookbook.md +++ b/docs/Formula-Cookbook.md @@ -106,8 +106,8 @@ The `README` probably tells you about dependencies and Homebrew or macOS probabl * `libiconv` * `libpcap` * `libxml2` -* `Python` -* `Ruby` +* `python` +* `ruby` There are plenty of others; check `/usr/lib` for them. @@ -132,7 +132,6 @@ to favour finding `keg_only` formulae first. class Foo < Formula depends_on "pkg-config" => :run depends_on "jpeg" - depends_on "boost" => "with-icu" depends_on "readline" => :recommended depends_on "gtk+" => :optional depends_on :x11 => :optional @@ -165,19 +164,6 @@ A Hash (e.g. `=>`) specifies a formula dependency with some additional informati depends_on "foo" => :optional # Generated description is "Build with foo support" ``` -* a String or an Array - - String values are interpreted as options to be passed to the dependency. - You can also pass an array of strings, or an array of symbols and strings, - in which case the symbols are interpreted as described above, and the - strings are passed to the dependency as options. - - ```ruby - depends_on "foo" => "with-bar" - depends_on "foo" => %w{with-bar with-baz} - depends_on "foo" => [:optional, "with-bar"] - ``` - ### Specifying conflicts with other formulae Sometimes there’s hard conflict between formulae, and it can’t be avoided or circumvented with [`keg_only`](http://www.rubydoc.info/github/Homebrew/brew/master/Formula#keg_only-class_method). @@ -426,7 +412,7 @@ Note that values *can* contain unescaped spaces if you use the multiple-argument ## Patches -While [`patch`](http://www.rubydoc.info/github/Homebrew/brew/master/Formula#patch-class_method)es should generally be avoided, sometimes they are necessary. +While [`patch`](http://www.rubydoc.info/github/Homebrew/brew/master/Formula#patch-class_method)es should generally be avoided, sometimes they are temporarily necessary. When [`patch`](http://www.rubydoc.info/github/Homebrew/brew/master/Formula#patch-class_method)ing (i.e. fixing header file inclusion, fixing compiler warnings, etc.) the first thing to do is check whether or not the upstream project is aware of the issue. If not, file a bug report and/or submit your patch for inclusion. We may sometimes still accept your patch before it was submitted upstream but by getting the ball rolling on fixing the upstream issue you reduce the length of time we have to carry the patch around. @@ -551,14 +537,9 @@ end Sometimes a package fails to build when using a certain compiler. Since recent [Xcode versions](Xcode.md) no longer include a GCC compiler we cannot simply force the use of GCC. Instead, the correct way to declare this is the [`fails_with` DSL method](http://www.rubydoc.info/github/Homebrew/brew/master/Formula#fails_with-class_method). A properly constructed [`fails_with`](http://www.rubydoc.info/github/Homebrew/brew/master/Formula#fails_with-class_method) block documents the latest compiler build version known to cause compilation to fail, and the cause of the failure. For example: ```ruby -fails_with :llvm do - build 2335 - cause <<~EOS - The "cause" field should include a short summary of the error. Include - the URLs of any relevant information, such as upstream bug reports. Wrap - the text at a sensible boundary (~72-80 characters), but do not break - URLs over multiple lines. - EOS +fails_with :clang do + build 211 + cause "Miscompilation resulting in segfault on queries" end ``` @@ -767,13 +748,7 @@ brew -S --fink foo ## Fortran -Some software requires a Fortran compiler. This can be declared by adding `depends_on :fortran` to a formula. `:fortran` is a `Requirement` that does several things. - -First, it looks to see if you have set the `FC` environment variable. If it is set, Homebrew will use this value during compilation. If it is not set, it will check to see if `gfortran` is found in `PATH`. If it is, Homebrew will use its location as the value of `FC`. Otherwise, the `gcc` formula will be treated as a dependency and installed prior to compilation. - -If you have set `FC` to a custom Fortran compiler, you may additionally set `FCFLAGS` and `FFLAGS`. Alternatively, you can pass `--default-fortran-flags` to `brew install` to use Homebrew's standard `CFLAGS`. - -When using Homebrew's `gfortran` compiler, the standard `CFLAGS` are used and user-supplied values of `FCFLAGS` and `FFLAGS` are ignored for consistency and reproducibility reasons. +Some software requires a Fortran compiler. This can be declared by adding `depends_on "gcc"` to a formula. ## How to start over (reset to upstream `master`) diff --git a/docs/Gemfile b/docs/Gemfile index fac2f802d..0c8671cde 100644 --- a/docs/Gemfile +++ b/docs/Gemfile @@ -1,6 +1,3 @@ source "https://rubygems.org" gem "github-pages", group: :jekyll_plugins - -# Nokogiri >=1.7 requires Ruby >=2.1 -gem "nokogiri", "<1.7" diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock new file mode 100644 index 000000000..b5fc90306 --- /dev/null +++ b/docs/Gemfile.lock @@ -0,0 +1,219 @@ +GEM + remote: https://rubygems.org/ + specs: + activesupport (4.2.8) + i18n (~> 0.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + addressable (2.5.2) + public_suffix (>= 2.0.2, < 4.0) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.12.2) + colorator (1.1.0) + concurrent-ruby (1.0.5) + ethon (0.11.0) + ffi (>= 1.3.0) + execjs (2.7.0) + faraday (0.13.1) + multipart-post (>= 1.2, < 3) + ffi (1.9.18) + forwardable-extended (2.6.0) + gemoji (3.0.0) + github-pages (158) + activesupport (= 4.2.8) + github-pages-health-check (= 1.3.5) + jekyll (= 3.5.2) + jekyll-avatar (= 0.4.2) + jekyll-coffeescript (= 1.0.1) + jekyll-default-layout (= 0.1.4) + jekyll-feed (= 0.9.2) + jekyll-gist (= 1.4.1) + jekyll-github-metadata (= 2.9.1) + jekyll-mentions (= 1.2.0) + jekyll-optional-front-matter (= 0.2.0) + jekyll-paginate (= 1.1.0) + jekyll-readme-index (= 0.1.0) + jekyll-redirect-from (= 0.12.1) + jekyll-relative-links (= 0.4.1) + jekyll-sass-converter (= 1.5.0) + jekyll-seo-tag (= 2.3.0) + jekyll-sitemap (= 1.0.0) + jekyll-swiss (= 0.4.0) + jekyll-theme-architect (= 0.1.0) + jekyll-theme-cayman (= 0.1.0) + jekyll-theme-dinky (= 0.1.0) + jekyll-theme-hacker (= 0.1.0) + jekyll-theme-leap-day (= 0.1.0) + jekyll-theme-merlot (= 0.1.0) + jekyll-theme-midnight (= 0.1.0) + jekyll-theme-minimal (= 0.1.0) + jekyll-theme-modernist (= 0.1.0) + jekyll-theme-primer (= 0.5.2) + jekyll-theme-slate (= 0.1.0) + jekyll-theme-tactile (= 0.1.0) + jekyll-theme-time-machine (= 0.1.0) + jekyll-titles-from-headings (= 0.4.0) + jemoji (= 0.8.0) + kramdown (= 1.13.2) + liquid (= 4.0.0) + listen (= 3.0.6) + mercenary (~> 0.3) + minima (= 2.1.1) + rouge (= 1.11.1) + terminal-table (~> 1.4) + github-pages-health-check (1.3.5) + addressable (~> 2.3) + net-dns (~> 0.8) + octokit (~> 4.0) + public_suffix (~> 2.0) + typhoeus (~> 0.7) + html-pipeline (2.7.1) + activesupport (>= 2) + nokogiri (>= 1.4) + i18n (0.9.1) + concurrent-ruby (~> 1.0) + jekyll (3.5.2) + addressable (~> 2.4) + colorator (~> 1.0) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 1.1) + kramdown (~> 1.3) + liquid (~> 4.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (~> 1.7) + safe_yaml (~> 1.0) + jekyll-avatar (0.4.2) + jekyll (~> 3.0) + jekyll-coffeescript (1.0.1) + coffee-script (~> 2.2) + jekyll-default-layout (0.1.4) + jekyll (~> 3.0) + jekyll-feed (0.9.2) + jekyll (~> 3.3) + jekyll-gist (1.4.1) + octokit (~> 4.2) + jekyll-github-metadata (2.9.1) + jekyll (~> 3.1) + octokit (~> 4.0, != 4.4.0) + jekyll-mentions (1.2.0) + activesupport (~> 4.0) + html-pipeline (~> 2.3) + jekyll (~> 3.0) + jekyll-optional-front-matter (0.2.0) + jekyll (~> 3.0) + jekyll-paginate (1.1.0) + jekyll-readme-index (0.1.0) + jekyll (~> 3.0) + jekyll-redirect-from (0.12.1) + jekyll (~> 3.3) + jekyll-relative-links (0.4.1) + jekyll (~> 3.3) + jekyll-sass-converter (1.5.0) + sass (~> 3.4) + jekyll-seo-tag (2.3.0) + jekyll (~> 3.3) + jekyll-sitemap (1.0.0) + jekyll (~> 3.3) + jekyll-swiss (0.4.0) + jekyll-theme-architect (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-cayman (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-dinky (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-hacker (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-leap-day (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-merlot (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-midnight (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-minimal (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-modernist (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-primer (0.5.2) + jekyll (~> 3.5) + jekyll-github-metadata (~> 2.9) + jekyll-seo-tag (~> 2.2) + jekyll-theme-slate (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-tactile (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-time-machine (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-titles-from-headings (0.4.0) + jekyll (~> 3.3) + jekyll-watch (1.5.1) + listen (~> 3.0) + jemoji (0.8.0) + activesupport (~> 4.0) + gemoji (~> 3.0) + html-pipeline (~> 2.2) + jekyll (>= 3.0) + kramdown (1.13.2) + liquid (4.0.0) + listen (3.0.6) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9.7) + mercenary (0.3.6) + mini_portile2 (2.3.0) + minima (2.1.1) + jekyll (~> 3.3) + minitest (5.11.1) + multipart-post (2.0.0) + net-dns (0.8.0) + nokogiri (1.8.1) + mini_portile2 (~> 2.3.0) + octokit (4.8.0) + sawyer (~> 0.8.0, >= 0.5.3) + pathutil (0.16.1) + forwardable-extended (~> 2.6) + public_suffix (2.0.5) + rb-fsevent (0.10.2) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) + rouge (1.11.1) + safe_yaml (1.0.4) + sass (3.5.5) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + sawyer (0.8.1) + addressable (>= 2.3.5, < 2.6) + faraday (~> 0.8, < 1.0) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + thread_safe (0.3.6) + typhoeus (0.8.0) + ethon (>= 0.8.0) + tzinfo (1.2.4) + thread_safe (~> 0.1) + unicode-display_width (1.3.0) + +PLATFORMS + ruby + +DEPENDENCIES + github-pages + +BUNDLED WITH + 1.16.0 diff --git a/docs/Homebrew-and-Python.md b/docs/Homebrew-and-Python.md index 740e973d2..eb96e5758 100644 --- a/docs/Homebrew-and-Python.md +++ b/docs/Homebrew-and-Python.md @@ -69,7 +69,7 @@ Homebrew builds bindings against the first `python` (and `python-config`) in you **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`). ## Policy for non-brewed Python bindings -These should be installed via `pip install <package>`. To discover, you can use `pip search` or <https://pypi.python.org/pypi>. (**Note:** System Python does not provide `pip`. Follow the instructions at <https://pip.readthedocs.io/en/stable/installing/#install-pip> to install it for your system Python if you would like it.) +These should be installed via `pip install <package>`. To discover, you can use `pip search` or <https://pypi.python.org/pypi>. (**Note:** System Python does not provide `pip`. Follow the [pip documentation](https://pip.readthedocs.io/en/stable/installing/#install-pip) to install it for your system Python if you would like it.) ## Brewed Python modules For brewed Python, modules installed with `pip` or `python setup.py install` will be installed to the `$(brew --prefix)/lib/pythonX.Y/site-packages` directory (explained above). Executable Python scripts will be in `$(brew --prefix)/bin`. @@ -89,4 +89,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. ## Why is Homebrew's Python being installed as a dependency? -Formulae that depend on the special `:python` target are bottled against the Homebrew Python and require it to be installed. You can avoid installing Homebrew's Python by building these formulae with `--build-from-source`. +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. diff --git a/docs/How-To-Open-a-Homebrew-Pull-Request.md b/docs/How-To-Open-a-Homebrew-Pull-Request.md index 173ea4e1d..812d990e0 100644 --- a/docs/How-To-Open-a-Homebrew-Pull-Request.md +++ b/docs/How-To-Open-a-Homebrew-Pull-Request.md @@ -25,7 +25,7 @@ Depending on the change you want to make, you need to send the pull request to t 3. Add your pushable forked repository with `git remote add <YOUR_USERNAME> https://github.com/<YOUR_USERNAME>/homebrew-core.git` * `<YOUR_USERNAME>` is your GitHub username, not your local machine username. -For formulae in central taps other than `homebrew/core`, such as `homebrew/science` or `homebrew/php`, substitute that tap's name for `homebrew/core` in each step, and alter the GitHub repository URLs as necessary. +For formulae in central taps other than `homebrew/core`, such as `homebrew/php`, substitute that tap's name for `homebrew/core` in each step, and alter the GitHub repository URLs as necessary. ## Create your pull request from a new branch diff --git a/docs/Interesting-Taps-and-Forks.md b/docs/Interesting-Taps-and-Forks.md index b49238674..4d569e6c0 100644 --- a/docs/Interesting-Taps-and-Forks.md +++ b/docs/Interesting-Taps-and-Forks.md @@ -7,8 +7,6 @@ Homebrew has the capability to add (and remove) multiple taps to your local inst * [homebrew/php](https://github.com/Homebrew/homebrew-php): Repository for PHP-related formulae. -* [homebrew/science](https://github.com/Homebrew/homebrew-science): A collection of scientific libraries and tools. - `brew search` looks in these taps as well as in [homebrew/core](https://github.com/Homebrew/homebrew-core) so don't worry about missing stuff. You can be added as a maintainer for one of the Homebrew organization taps and aid the project! If you are interested please feel free to ask in an issue or pull request after submitting multiple high-quality pull requests. We want your help! @@ -31,11 +29,19 @@ You can be added as a maintainer for one of the Homebrew organization taps and a * [osrf/simulation](https://github.com/osrf/homebrew-simulation): Tools for robotics simulation. +* [brewsci/bio](https://github.com/brewsci/homebrew-bio): Bioinformatics formulae. + +* [brewsci/science](https://github.com/brewsci/homebrew-science): Software tailored to scientific endeavours. + +* [davidchall/hep](https://github.com/davidchall/homebrew-hep): High energy physics formulae. + +* [lifepillar/appleii](https://github.com/lifepillar/homebrew-appleii): Formulae for vintage Apple emulation. + ## Interesting forks -* [mistydemeo/tigerbrew](https://github.com/mistydemeo/tigerbrew): Experimental Tiger PowerPC version +* [mistydemeo/tigerbrew](https://github.com/mistydemeo/tigerbrew): Experimental Tiger PowerPC version. -* [Linuxbrew/brew](https://github.com/Linuxbrew/brew): Experimental Linux version +* [Linuxbrew/brew](https://github.com/Linuxbrew/brew): Experimental Linux version. ## Technical details diff --git a/docs/Manpage.md b/docs/Manpage.md index d94cec30a..920518376 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -126,11 +126,12 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note * `desc` `formula`: Display `formula`'s name and one-line description. - * `desc` [`-s`|`-n`|`-d`] (`text`|`/``text``/`): - Search both name and description (`-s`), just the names (`-n`), or just the - descriptions (`-d`) for `text`. If `text` is flanked by slashes, it is interpreted - as a regular expression. Formula descriptions are cached; the cache is created on - the first search, making that search slower than subsequent ones. + * `desc` [`--search`|`--name`|`--description`] (`text`|`/``text``/`): + Search both name and description (`--search` or `-s`), just the names + (`--name` or `-n`), or just the descriptions (`--description` or `-d`) for + `text`. If `text` is flanked by slashes, it is interpreted as a regular + expression. Formula descriptions are cached; the cache is created on the + first search, making that search slower than subsequent ones. * `diy` [`--name=``name`] [`--version=``version`]: Automatically determine the installation prefix for non-Homebrew software. @@ -144,7 +145,10 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note * `doctor`: Check your system for potential problems. Doctor exits with a non-zero status - if any problems are found. + if any potential problems are found. Please note that these warnings are just + used to help the Homebrew maintainers with debugging if you file an issue. If + everything you use Homebrew for is working fine: please don't worry or file + an issue; just ignore this. * `fetch` [`--force`] [`--retry`] [`-v`] [`--devel`|`--HEAD`] [`--deps`] [`--build-from-source`|`--force-bottle`] `formulae`: Download the source packages for the given `formulae`. @@ -176,6 +180,8 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note `formula` is usually the name of the formula to install, but it can be specified in several different ways. See [SPECIFYING FORMULAE](#specifying-formulae). + If `--with-hostname` is passed, include the hostname in the Gist. + If `--new-issue` is passed, automatically create a new issue in the appropriate GitHub repository as well as creating the Gist. @@ -187,13 +193,16 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note * `home` `formula`: Open `formula`'s homepage in a browser. + * `info`: + Display brief statistics for your Homebrew installation. + * `info` `formula`: Display information about `formula`. * `info` `--github` `formula`: - Open a browser to the GitHub History page for formula `formula`. + Open a browser to the GitHub History page for `formula`. - To view formula history locally: `brew log -p `formula`` + To view formula history locally: `brew log -p `formula * `info` `--json=``version` (`--all`|`--installed`|`formulae`): Print a JSON representation of `formulae`. Currently the only accepted value @@ -205,7 +214,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note See the docs for examples of using the JSON output: <https://docs.brew.sh/Querying-Brew.html> - * `install` [`--debug`] [`--env=`(`std`|`super`)] [`--ignore-dependencies`|`--only-dependencies`] [`--cc=``compiler`] [`--build-from-source`|`--force-bottle`] [`--devel`|`--HEAD`] [`--keep-tmp`] [`--build-bottle`] `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`. `formula` is usually the name of the formula to install, but it can be specified @@ -254,6 +263,11 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note If `--build-bottle` is passed, prepare the formula for eventual bottling during installation. + If `--force` (or `-f`) is passed, install without checking for previously + installed keg-only or non-migrated versions + + If `--verbose` (or `-v`) is passed, print the verification and postinstall steps. + Installation options specific to `formula` may be appended to the command, and can be listed with `brew options` `formula`. @@ -288,20 +302,6 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note If `--force` (or `-f`) is passed, Homebrew will allow keg-only formulae to be linked. - * `linkapps` [`--local`] [`formulae`]: - Find installed formulae that provide `.app`-style macOS apps and symlink them - into `/Applications`, allowing for easier access (deprecated). - - Unfortunately `brew linkapps` cannot behave nicely with e.g. Spotlight using - either aliases or symlinks and Homebrew formulae do not build "proper" `.app` - bundles that can be relocated. Instead, please consider using `brew cask` and - migrate formulae using `.app`s to casks. - - If no `formulae` are provided, all of them will have their apps symlinked. - - If provided, `--local` will symlink them into the user's `~/Applications` - directory instead of the system directory. - * `list`, `ls` [`--full-name`]: List all installed formulae. If `--full-name` is passed, print formulae with fully-qualified names. If `--full-name` is not passed, any other @@ -310,7 +310,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note * `list`, `ls` `--unbrewed`: List all files in the Homebrew prefix not installed by Homebrew. - * `list`, `ls` [`--versions` [`--multiple`]] [`--pinned`] [`formulae`]: + * `list`, `ls` [`--verbose`] [`--versions` [`--multiple`]] [`--pinned`] [`formulae`]: List the installed files for `formulae`. Combined with `--verbose`, recursively list the contents of all subdirectories in each `formula`'s keg. @@ -361,8 +361,8 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note If `--verbose` (or `-v`) is passed, display detailed version information. - If `--json=``version` is passed, the output will be in JSON format. The only - valid version is `v1`. + If `--json=``version` is passed, the output will be in JSON format. + Currently the only accepted value for `version` is `v1`. If `--fetch-HEAD` is passed, fetch the upstream repository to detect if the HEAD installation of the formula is outdated. Otherwise, the @@ -371,8 +371,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note * `pin` `formulae`: Pin the specified `formulae`, preventing them from being upgraded when - issuing the `brew upgrade `formulae`` command (but can still be upgraded - as dependencies for other formulae). See also `unpin`. + issuing the `brew upgrade `formulae command. See also `unpin`. * `postinstall` `formula`: Rerun the post-install steps for `formula`. @@ -386,15 +385,19 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note If `--dry-run` or `-n` is passed, show what would be removed, but do not actually remove anything. - * `readall` [tap]: - Import all formulae from specified taps (defaults to all installed taps). + * `readall` [`--aliases`] [`--syntax`] [`taps`]: + Import all formulae from specified `taps` (defaults to all installed taps). This can be useful for debugging issues across all formulae when making significant changes to `formula.rb`, testing the performance of loading all formulae or to determine if any current formulae have Ruby issues. + If `--aliases` is passed, also verify any alias symlinks in each tap. + + If `--syntax` is passed, also syntax-check all of Homebrew's Ruby files. + * `reinstall` `formula`: - Uninstall and then install `formula`. + Uninstall and then install `formula` (with existing install options). * `search`, `-S`: Display all locally available formulae for brewing (including tapped ones). @@ -420,22 +423,22 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note If `--env=std` is passed, use the standard `PATH` instead of superenv's. - * `style` [`--fix`] [`--display-cop-names`] [`--only-cops=`[COP1,COP2..]|`--except-cops=`[COP1,COP2..]] [`files`|`taps`|`formulae`]: + * `style` [`--fix`] [`--display-cop-names`] [`--only-cops=``cops`|`--except-cops=``cops`] [`files`|`taps`|`formulae`]: Check formulae or files for conformance to Homebrew style guidelines. - `formulae` and `files` may not be combined. If both are omitted, style will run - style checks on the whole Homebrew `Library`, including core code and all - formulae. + Lists of `files`, `taps` and `formulae` may not be combined. If none are + provided, `style` will run style checks on the whole Homebrew library, + including core code and all formulae. - If `--fix` is passed, style violations will be automatically fixed using - RuboCop's `--auto-correct` feature. + If `--fix` is passed, automatically fix style violations using RuboCop's + auto-correct feature. - If `--display-cop-names` is passed, the RuboCop cop name for each violation - is included in the output. + If `--display-cop-names` is passed, include the RuboCop cop name for each + violation in the output. - If `--only-cops` is passed, only the given Rubocop cop(s)' violations would be checked. - - If `--except-cops` is passed, the given Rubocop cop(s)' checks would be skipped. + Passing `--only-cops=``cops` will check for violations of only the listed + RuboCop `cops`, while `--except-cops=``cops` will skip checking the listed + `cops`. For either option `cops` should be a comma-separated list of cop names. Exits with a non-zero status if any style violations are found. @@ -450,7 +453,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note With `URL` unspecified, taps a formula repository from GitHub using HTTPS. Since so many taps are hosted on GitHub, this command is a shortcut for - `tap `user`/`repo` https://github.com/`user`/homebrew-`repo``. + `tap `user`/`repo` https://github.com/`user`/homebrew-`repo. With `URL` specified, taps a formula repository from anywhere, using any transport protocol that `git` handles. The one-argument form of `tap` @@ -511,27 +514,11 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note * `unlink` [`--dry-run`] `formula`: Remove symlinks for `formula` from the Homebrew prefix. This can be useful for temporarily disabling a formula: - `brew unlink `formula` && `commands` && brew link `formula`` + `brew unlink `formula` && `commands` && brew link `formula If `--dry-run` or `-n` is passed, Homebrew will list all files which would be unlinked, but will not actually unlink or delete any files. - * `unlinkapps` [`--local`] [`--dry-run`] [`formulae`]: - Remove symlinks created by `brew linkapps` from `/Applications` (deprecated). - - Unfortunately `brew linkapps` cannot behave nicely with e.g. Spotlight using - either aliases or symlinks and Homebrew formulae do not build "proper" `.app` - bundles that can be relocated. Instead, please consider using `brew cask` and - migrate formulae using `.app`s to casks. - - If no `formulae` are provided, all linked apps will be removed. - - If provided, `--local` will remove symlinks from the user's `~/Applications` - directory instead of the system directory. - - If `--dry-run` or `-n` is passed, Homebrew will list all symlinks which - would be removed, but will not actually delete any files. - * `unpack` [`--git`|`--patch`] [`--destdir=``path`] `formulae`: Unpack the source files for `formulae` into subdirectories of the current working directory. If `--destdir=``path` is given, the subdirectories will @@ -544,7 +531,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note source. This is useful for creating patches for the software. * `unpin` `formulae`: - Unpin `formulae`, allowing them to be upgraded by `brew upgrade `formulae``. + Unpin `formulae`, allowing them to be upgraded by `brew upgrade `formulae. See also `pin`. * `untap` `tap`: @@ -566,7 +553,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note or committed changes. * `upgrade` [`install-options`] [`--cleanup`] [`--fetch-HEAD`] [`formulae`]: - Upgrade outdated, unpinned brews. + Upgrade outdated, unpinned brews (with existing install options). Options for the `install` command are also valid here. @@ -612,8 +599,14 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note Display the location in the cellar where `formula` would be installed, without any sort of versioned directory as the last path. - * `--env`: - Show a summary of the Homebrew build environment. + * `--env` [`--shell=`(`shell`|`auto`)|`--plain`]: + Show a summary of the Homebrew build environment as a plain list. + + Pass `--shell=``shell` to generate a list of environment variables for the + specified shell, or `--shell=auto` to detect the current shell. + + If the command's output is sent through a pipe and no shell is specified, + the list is formatted for export to `bash`(1) unless `--plain` is passed. * `--prefix`: Display Homebrew's install path. *Default:* `/usr/local` @@ -632,7 +625,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note ## DEVELOPER COMMANDS - * `audit` [`--strict`] [`--fix`] [`--online`] [`--new-formula`] [`--display-cop-names`] [`--display-filename`] [`--only=``method`|`--except=``method`] [`--only-cops=`[COP1,COP2..]|`--except-cops=`[COP1,COP2..]] [`formulae`]: + * `audit` [`--strict`] [`--fix`] [`--online`] [`--new-formula`] [`--display-cop-names`] [`--display-filename`] [`--only=``method`|`--except=``method`] [`--only-cops=``cops`|`--except-cops=``cops`] [`formulae`]: Check `formulae` for Homebrew coding style violations. This should be run before submitting a new formula. @@ -642,7 +635,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note style checks. If `--fix` is passed, style violations will be - automatically fixed using RuboCop's `--auto-correct` feature. + automatically fixed using RuboCop's auto-correct feature. If `--online` is passed, additional slower checks that require a network connection are run. @@ -657,13 +650,13 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note If `--display-filename` is passed, every line of output is prefixed with the name of the file or formula being audited, to make the output easy to grep. - If `--only` is passed, only the methods named `audit_`method`` will be run. - - If `--except` is passed, the methods named `audit_`method`` will not be run. + Passing `--only=``method` will run only the methods named `audit_`method, + while `--except=``method` will skip the methods named `audit_`method. + For either option `method` should be a comma-separated list. - If `--only-cops` is passed, only the given Rubocop cop(s)' violations would be checked. - - If `--except-cops` is passed, the given Rubocop cop(s)' checks would be skipped. + Passing `--only-cops=``cops` will check for violations of only the listed + RuboCop `cops`, while `--except-cops=``cops` will skip checking the listed + `cops`. For either option `cops` should be a comma-separated list of cop names. `audit` exits with a non-zero status if any errors are found. This is useful, for instance, for implementing pre-commit hooks. @@ -730,6 +723,9 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note which opens the pull request URL in a browser. Instead, output it to the command line. + If `--quiet` is passed, don't output replacement messages or warn about + duplicate pull requests. + Note that this command cannot be used to transition a formula from a URL-and-sha256 style specification into a tag-and-revision style specification, nor vice versa. It must use whichever style specification @@ -765,7 +761,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note * `formula` `formula`: Display the path where `formula` is located. - * `linkage` [`--test`] [`--reverse`] `formula`: + * `linkage` [`--test`] [`--reverse`] `formula`: Checks the library links of an installed formula. Only works on installed formulae. An error is raised if it is run on @@ -1002,9 +998,13 @@ can take several different forms: directories. TextMate can handle this correctly in project mode, but many editors will do strange things in this case. + * `HOMEBREW_FORCE_BREWED_CURL`: + If set, Homebrew will use a Homebrew-installed `curl` rather than the + system version. + * `HOMEBREW_FORCE_VENDOR_RUBY`: - If set, Homebrew will always use its vendored, relocatable Ruby 2.0 version - even if the system version of Ruby is >=2.0. + If set, Homebrew will always use its vendored, relocatable Ruby version + even if the system version of Ruby is new enough. * `HOMEBREW_GIT`: When using Git, Homebrew will use `GIT` if set, @@ -1077,20 +1077,38 @@ can take several different forms: * `HOMEBREW_VERBOSE`: If set, Homebrew always assumes `--verbose` when running commands. + * `http_proxy`: + Sets the HTTP proxy to be used by `curl`, `git` and `svn` when downloading + through Homebrew. + + * `https_proxy`: + Sets the HTTPS proxy to be used by `curl`, `git` and `svn` when downloading + through Homebrew. + + * `all_proxy`: + Sets the SOCKS5 proxy to be used by `curl`, `git` and `svn` when downloading + through Homebrew. + + * `ftp_proxy`: + Sets the FTP proxy to be used by `curl`, `git` and `svn` when downloading + through Homebrew. + + * `no_proxy`: + Sets the comma-separated list of hostnames and domain names that should be excluded from proxying + by `curl`, `git` and `svn` when downloading through Homebrew. + ## USING HOMEBREW BEHIND A PROXY +Use the `http_proxy`, `https_proxy`, `all_proxy`, `no_proxy` and/or `ftp_proxy` documented above. -Homebrew uses several commands for downloading files (e.g. `curl`, `git`, `svn`). -Many of these tools can download via a proxy. It's common for these tools -to read proxy parameters from environment variables. +For example for an unauthenticated HTTP or SOCKS5 proxy: -For the majority of cases setting `http_proxy` is enough. You can set this in -your shell profile, or you can use it before a brew command: + export http_proxy=http://`host`:`port` - http_proxy=http://`host`:`port` brew install foo + export all_proxy=socks5://`host`:`port` -If your proxy requires authentication: +And for an authenticated HTTP proxy: - http_proxy=http://`user`:`password`@`host`:`port` brew install foo + export http_proxy=http://`user`:`password`@`host`:`port` ## SEE ALSO @@ -1104,9 +1122,11 @@ Homebrew's lead maintainer is Mike McQuaid. Homebrew/homebrew-core's lead maintainer is ilovezfs. -Homebrew's other current maintainers are Alyssa Ross, Andrew Janke, Alex Dunn, FX Coudert, Josh Hagins, JCount, Misty De Meo, neutric, Tomasz Pajor, Markus Reiter, Tim Smith, Tom Schoonjans, Uladzislau Shablinski and William Woodruff. +Homebrew/brew's other current maintainers are ilovezfs, Alyssa Ross, JCount, Misty De Meo, Gautham Goli, Markus Reiter and William Woodruff. + +Homebrew/homebrew-core's other current maintainers are FX Coudert, JCount, Misty De Meo and Tom Schoonjans. -Former maintainers with significant contributions include Baptiste Fontaine, Xu Cheng, Martin Afanasjew, Dominyk Tiller, Brett Koonce, Charlie Sharpsteen, Jack Nagel, Adam Vandenberg and Homebrew's creator: Max Howell. +Former maintainers with significant contributions include Tim Smith, Baptiste Fontaine, Xu Cheng, Martin Afanasjew, Dominyk Tiller, Brett Koonce, Charlie Sharpsteen, Jack Nagel, Adam Vandenberg, Andrew Janke, Alex Dunn, neutric, Tomasz Pajor, Uladzislau Shablinski and Homebrew's creator: Max Howell. ## BUGS diff --git a/docs/Migrating-A-Formula-To-A-Tap.md b/docs/Migrating-A-Formula-To-A-Tap.md index 08ba2df37..7e1431adb 100644 --- a/docs/Migrating-A-Formula-To-A-Tap.md +++ b/docs/Migrating-A-Formula-To-A-Tap.md @@ -3,7 +3,7 @@ There are times when we may wish to migrate a formula from one tap into another tap. To do this: 1. Create a pull request to the new tap adding the formula file as-is from the original tap. Fix any test failures that may occur due to the stricter requirements for new formulae than existing formula (e.g. `brew audit --strict` must pass for that formula). -2. Create a pull request to the original tap deleting the formula file and add it to `tap_migrations.json` with a commit message like `gv: migrating to homebrew/science`. +2. Create a pull request to the original tap deleting the formula file and add it to `tap_migrations.json` with a commit message like `gv: migrate to homebrew/core`. 3. Put a link for each pull request in the other pull request so the maintainers can merge them both at once. Congratulations, you've moved a formula to a tap! diff --git a/docs/New-Maintainer-Checklist.md b/docs/New-Maintainer-Checklist.md index 2fd9b8497..72abf2ddb 100644 --- a/docs/New-Maintainer-Checklist.md +++ b/docs/New-Maintainer-Checklist.md @@ -2,7 +2,7 @@ **This is a guide used by existing maintainers to invite new maintainers. You might find it interesting but there's nothing here users should have to know.** -So, there's someone who has been making consistently high-quality contributions to Homebrew for a long time and shown themselves able to make slightly more advanced contributions than just e.g. formula updates? Let's invite them to be a maintainer! +There's someone who has been making consistently high-quality contributions to Homebrew for a long time and shown themselves able to make slightly more advanced contributions than just e.g. formula updates? Let's invite them to be a maintainer! First, send them the invitation email: @@ -10,11 +10,16 @@ First, send them the invitation email: The Homebrew team and I really appreciate your help on issues, pull requests and your contributions around $THEIR_CONTRIBUTIONS. -We would like to invite you to have commit access. There are no obligations, -but we'd appreciate your continuing help in keeping on top of contributions. -The easiest way to do this is to watch the Homebrew/brew and -Homebrew/homebrew-core repositories on GitHub to provide help and code review -and to pull suitable changes. +We would like to invite you to have commit access and be a Homebrew maintainer. +If you agree to be a maintainer, you should spend a significant proportion of +the time you are working on Homebrew fixing user-reported issues, resolving any +issues that arise from your code in a timely fashion and reviewing user +contributions. You should also be making contributions to Homebrew every month +unless you are ill or on vacation (and please let another maintainer know if +that's the case so we're aware you won't be able to help while you are out). +You will need to watch Homebrew/brew and/or Homebrew/homebrew-core. If you're +no longer able to perform all of these tasks, please continue to contribute to +Homebrew, but we will ask you to step down as a maintainer. A few requests: @@ -36,7 +41,7 @@ A few requests: - please read: - https://docs.brew.sh/Brew-Test-Bot-For-Core-Contributors.html - https://docs.brew.sh/Maintainer-Guidelines.html - - possibly everything else on https://docs.brew.sh + - anything else you haven't read on https://docs.brew.sh How does that sound? @@ -53,8 +58,7 @@ If they accept, follow a few steps to get them set up: - Invite them to the [`machomebrew` private maintainers Slack](https://machomebrew.slack.com/admin/invites) - Invite them to the [`homebrew` private maintainers 1Password](https://homebrew.1password.com/signin) - Invite them to [Google Analytics](https://analytics.google.com/analytics/web/?authuser=1#management/Settings/a76679469w115400090p120682403/%3Fm.page%3DAccountUsers/) -- Add them to [Homebrew's README](https://github.com/Homebrew/brew/edit/master/README.md) -After a few weeks/months with no problems consider making them [owners on the Homebrew GitHub organisation](https://github.com/orgs/Homebrew/people). +After a month-long trial period with no problems make them [owners on the Homebrew GitHub organisation](https://github.com/orgs/Homebrew/people) and add them to [Homebrew's README](https://github.com/Homebrew/brew/edit/master/README.md). If there are problems, ask them to step down as a maintainer and revoke their access to the above. Now sit back, relax and let the new maintainers handle more of our contributions. diff --git a/docs/Node-for-Formula-Authors.md b/docs/Node-for-Formula-Authors.md index f1a50a8c3..4053706c1 100644 --- a/docs/Node-for-Formula-Authors.md +++ b/docs/Node-for-Formula-Authors.md @@ -34,10 +34,10 @@ If your formula requires being executed with an older Node version you should us ### Special requirements for native addons -If your Node module is a native addon or has a native addon somewhere in its dependency tree you have to declare an additional dependency. Since the compilation of the native addon results in an invocation of `node-gyp` we need an additional build time dependency on `:python` (because gyp depends on Python 2.7). +If your Node module is a native addon or has a native addon somewhere in its dependency tree you have to declare an additional dependency. Since the compilation of the native addon results in an invocation of `node-gyp` we need an additional build time dependency on `"python"` (because GYP depends on Python 2.7). ```ruby -depends_on :python => :build +depends_on "python" => :build ``` Also note that such a formula would only be compatible with the same Node major version it originally was compiled with. This means that we need to revision every formula with a Node native addon with every major version bump of the `node` formula. To make sure we don't overlook your formula on a Node major version bump, write a meaningful test which would fail in such a case (invoked with an ABI-incompatible Node version). @@ -99,7 +99,7 @@ class Foo < Formula depends_on "node" # uncomment if there is a native addon inside the dependency tree - # depends_on :python => :build + # depends_on "python" => :build def install system "npm", "install", *Language::Node.std_npm_install_args(libexec) diff --git a/docs/Python-for-Formula-Authors.md b/docs/Python-for-Formula-Authors.md index 129f5ba5e..a530dbef7 100644 --- a/docs/Python-for-Formula-Authors.md +++ b/docs/Python-for-Formula-Authors.md @@ -19,12 +19,12 @@ Applications should unconditionally bundle all of their Python-language dependen 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 -depends_on :python if MacOS.version <= :snow_leopard +depends_on "python" 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 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`, which will cause the formula to use the first python3 discovered in `PATH` at install time (or install Homebrew's if there isn't one). These apps **must** work with the current Homebrew python3 formula. +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 @@ -51,7 +51,7 @@ poet some_package deactivate ``` -Homebrew provides helper methods for instantiating and populating virtualenvs. You can use them by putting `include Language::Python::Virtualenv` on the `Formula` class definition, above `def install`. +Homebrew provides helper methods for instantiating and populating virtualenvs. You can use them by putting `include Language::Python::Virtualenv` at the top of the `Formula` class definition. For most applications, all you will need to write is: @@ -66,7 +66,7 @@ This is exactly the same as writing: ```ruby def install # 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 "python3"` is declared, and use `virtualenv_create(libexec, "python3")`. venv = virtualenv_create(libexec) # Install all of the resources declared on the formula into the virtualenv. venv.pip_install resources @@ -85,6 +85,8 @@ Installing a formula with dependencies will look like this: ```ruby class Foo < Formula + include Language::Python::Virtualenv + url "..." resource "six" do @@ -97,8 +99,6 @@ class Foo < Formula sha256 "09bfcd8f3c239c75e77b3ff05d782ab2c1aed0892f250ce2adf948d4308fe9dc" end - include Language::Python::Virtualenv - def install virtualenv_install_with_resources end @@ -121,9 +121,9 @@ in case you need to do different things for different resources. ## Bindings -Build bindings with 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/). +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 :python3 => :optional` and make the bindings conditional on `build.with?("python3")`. +To add bindings for Python 3, please add `depends_on "python3" => :optional` and make the bindings conditional on `build.with?("python3")`. ### Dependencies @@ -153,7 +153,7 @@ Sometimes we have to `inreplace` a `Makefile` to use our prefix for the Python b ### Python declarations -Python 2 libraries do not need a `depends_on :python` declaration; they will be built with 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 python3, and use the first python3 discovered in `PATH` at build time when installing from source with `brew install --build-from-source`. 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 Homebrew Python. +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. ### Installing @@ -165,8 +165,6 @@ Most formulae presently just install to `prefix`. The dependencies of libraries must be installed so that they are importable. To minimize the potential for linking conflicts, dependencies should be installed to `libexec/"vendor"` and added to `sys.path` by writing a second .pth file (named like "homebrew-foo-dependencies.pth") to the `prefix` site-packages. -The [matplotlib](https://github.com/Homebrew/homebrew-science/blob/master/matplotlib.rb) formula in [homebrew/science](https://github.com/Homebrew/homebrew-science) deploys this strategy. - ## Further down the rabbit hole Additional commentary that explains why Homebrew does some of the things it does. diff --git a/docs/README.md b/docs/README.md index f069ae562..fe227291b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -33,6 +33,7 @@ - [Python for Formula Authors](Python-for-Formula-Authors.md) - [Migrating A Formula To A Tap](Migrating-A-Formula-To-A-Tap.md) - [Rename A Formula](Rename-A-Formula.md) +- [Building Against Non-Homebrew Dependencies](Building-Against-Non-Homebrew-Dependencies.md) - [How To Create (And Maintain) A Tap](How-to-Create-and-Maintain-a-Tap.md) - [Brew Test Bot](Brew-Test-Bot.md) - [Prose Style Guidelines](Prose-Style-Guidelines.md) diff --git a/docs/Tips-N'-Tricks.md b/docs/Tips-N'-Tricks.md index ab72f541e..a88940f0e 100644 --- a/docs/Tips-N'-Tricks.md +++ b/docs/Tips-N'-Tricks.md @@ -55,23 +55,6 @@ run `mv the_tarball $(brew --cache -s <formula>)`. You can also pre-cache the download by using the command `brew fetch formula` which also displays the SHA-256 hash. This can be useful for updating formulae to new versions. -## Using Homebrew behind a proxy -Behind the scenes, Homebrew uses several commands for downloading files (e.g. `curl`, `git`, `svn`). Many of these tools can download via a proxy. It's a common (though not universal) convention for these command-line tools to observe getting the proxy parameters from environment variables (e.g. `http_proxy`). Unfortunately, most tools are inconsistent in their use of these environment parameters (e.g. `curl` supports `http_proxy`, `HTTPS_PROXY`, `FTP_PROXY`, `GOPHER_PROXY`, `ALL_PROXY`, `NO_PROXY`). - -Luckily, for the majority of cases setting `http_proxy` is enough. -You can set this environment variable in several ways (search on the -internet for details), including at runtime: - -```sh -http_proxy=http://<proxyhost>:<proxyport> brew install <formula> -``` - -To use proxy authentication: - -```sh -http_proxy=http://<user>:<password>@<proxyhost>:<proxyport> brew install <formula> -``` - ## Installing stuff without the Xcode CLT ```sh diff --git a/docs/Troubleshooting.md b/docs/Troubleshooting.md index 2ffa256d1..8b1bd7312 100644 --- a/docs/Troubleshooting.md +++ b/docs/Troubleshooting.md @@ -17,7 +17,7 @@ Follow these steps to fix common problems: ## Check to see if the issue has been reported * Search the [issue tracker](https://github.com/Homebrew/homebrew-core/issues) to see if someone else has already reported the same issue. -* Make sure you search issues on the correct repository. If a formula that has failed to build is part of a tap like [homebrew/science](https://github.com/Homebrew/homebrew-science/issues) or a cask is part of [caskroom/cask](https://github.com/caskroom/homebrew-cask/issues) check those issue trackers instead. +* Make sure you search issues on the correct repository. If a formula that has failed to build is part of a tap like [homebrew/php](https://github.com/Homebrew/homebrew-php/issues) or a cask is part of [caskroom/cask](https://github.com/caskroom/homebrew-cask/issues) check those issue trackers instead. ## Create an issue diff --git a/docs/Versions.md b/docs/Versions.md index 865b1acc4..282640a1f 100644 --- a/docs/Versions.md +++ b/docs/Versions.md @@ -5,12 +5,16 @@ Now that [homebrew/versions](https://github.com/homebrew/homebrew-versions) has In [homebrew/versions](https://github.com/homebrew/homebrew-versions) the formula for GCC 6 was named `gcc6.rb` and began with `class Gcc6 < Formula`. In [homebrew/core](https://github.com/homebrew/homebrew-core) this same formula is named `gcc@6.rb` and begins with `class GccAT6 < Formula`. ## Acceptable versioned formulae -Homebrew's versions are not intended to be used for any old versions you personally require for your project; formulae submitted should be expected to be used by a large number of people and still supported by their upstream projects. - -Versioned formulae we include must meet the following standards: +Versioned formulae we include in [homebrew/core](https://github.com/homebrew/homebrew-core) must meet the following standards: +* Versioned software should build on all Homebrew's supported versions of macOS. * 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 * 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. +* 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 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/). +* 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. -You should create your own [tap](How-to-Create-and-Maintain-a-Tap.md) for formulae you or your organisation wishes to control the versioning of or those that do not meet the above standards. +We may temporarily add versioned formulae for our own needs that do not meet these standards in [homebrew/core](https://github.com/homebrew/homebrew-core). The presence of a versioned formula there does not imply it will be maintained indefinitely or that we are willing to accept any more versions that do not meet the requirements above. diff --git a/docs/Xcode.md b/docs/Xcode.md index 6c8626095..7fcc48877 100644 --- a/docs/Xcode.md +++ b/docs/Xcode.md @@ -2,88 +2,19 @@ ## Supported Xcode versions Homebrew supports and recommends the latest Xcode and/or Command Line -Tools available for your platform: +Tools available for your platform (see `OS::Mac::Xcode.latest_version` and `OS::Mac::CLT.latest_version` in [`Library/Homebrew/os/mac/xcode.rb`](https://github.com/Homebrew/brew/blob/master/Library/Homebrew/os/mac/xcode.rb)). -| macOS | Xcode | Command Line Tools | -|-------|-------|--------------------| -| 10.6 | 3.2.6 | N/A | -| 10.7 | 4.6.3 | April 2013 | -| 10.8 | 5.1.1 | April 2014 | -| 10.9 | 6.2 | 6.2 | -| 10.10 | 7.2.1 | 7.2 | -| 10.11 | 8.2.1 | 8.2 | -| 10.12 | 9.1 | 9.0.1 | -| 10.13 | 9.1 | 9.0.1 | +## Xcode compiler versions -## Compiler version database +See `OS::Mac::STANDARD_COMPILERS` in [`Library/Homebrew/os/mac.rb`](https://github.com/Homebrew/brew/blob/master/Library/Homebrew/os/mac.rb). -| Xcode | GCC 4.0 | GCC 4.2 | LLVM-GCC 4.2 | LLVM | Clang | LLVM (SVN) | -|-------|---------|---------|--------------|------------|-----------------|------------| -| 2.5.0 | 5370 | — | — | — | — | — | -| 3.1.4 | 5493 | 5577 | 5555 | 2064.3 | — | — | -| 3.2.0 | 5493 | 5646 | 5646 | 2118 | — | — | -| 3.2.1 | 5493 | 5646 | 5646 | 2206 | — | — | -| 3.2.2 | 5493 | 5659 | 5646 | 2207.5 | 1.0.2 | — | -| 3.2.3 | 5494 | 5664 | 5658 | 2326.10 | 1.5 (60) | — | -| 3.2.4 | 5494 | 5664 | 5658 | 2326.10 | 1.5 (60) | — | -| 3.2.5 | 5494 | 5664 | 5658 | 2333.4 | 1.6 (70) | — | -| 3.2.6 | 5494 | 5666 | 5658 | 2335.6 | 1.7 (77) | 2.9 | -| 4.0.0 | 5494 | 5666 | 5658 | 2335.9 | 2.0 (137) | 2.9 | -| 4.0.2 | 5494 | 5666 | 5658 | 2335.9 | 2.0 (137) | 2.9 | -| 4.1.0 | — | 5666 | 5658 | 2335.15.00 | 2.1 (163.7.1) | 3.0 | -| 4.2.0 | — | — | 5658 | 2336.1.00 | 3.0 (211.10.1) | 3.0 | -| 4.3.0 | — | — | 5658 | 2336.9.00 | 3.1 (318.0.45) | 3.1 | -| 4.3.1 | — | — | 5658 | 2336.9.00 | 3.1 (318.0.54) | 3.1 | -| 4.3.2 | — | — | 5658 | 2336.9.00 | 3.1 (318.0.58) | 3.1 | -| 4.3.3 | — | — | 5658 | 2336.9.00 | 3.1 (318.0.61) | 3.1 | -| 4.4.0 | — | — | 5658 | 2336.11.00 | 4.0 (421.0.57) | 3.1 | -| 4.4.1 | — | — | 5658 | 2336.11.00 | 4.0 (421.0.60) | 3.1 | -| 4.5.0 | — | — | 5658 | 2336.11.00 | 4.1 (421.11.65) | 3.1 | -| 4.5.1 | — | — | 5658 | 2336.11.00 | 4.1 (421.11.66) | 3.1 | -| 4.5.2 | — | — | 5658 | 2336.11.00 | 4.1 (421.11.66) | 3.1 | -| 4.6.0 | — | — | 5658 | 2336.11.00 | 4.2 (425.0.24) | 3.2 | -| 4.6.1 | — | — | 5658 | 2336.11.00 | 4.2 (425.0.27) | 3.2 | -| 4.6.2 | — | — | 5658 | 2336.11.00 | 4.2 (425.0.28) | 3.2 | -| 4.6.3 | — | — | 5658 | 2336.11.00 | 4.2 (425.0.28) | 3.2 | -| 5.0.0 | — | — | — | — | 5.0 (500.2.76) | 3.3 | -| 5.0.1 | — | — | — | — | 5.0 (500.2.78) | 3.3 | -| 5.0.1 | — | — | — | — | 5.0 (500.2.79) | 3.3 | -| 5.1 | — | — | — | — | 5.1 (503.0.38) | 3.4 | -| 5.1.1 | — | — | — | — | 5.1 (503.0.40) | 3.4 | -| 6.0 | — | — | — | — | 6.0 (600.0.51) | 3.5 | -| 6.0.1 | — | — | — | — | 6.0 (600.0.51) | 3.5 | -| 6.1 | — | — | — | — | 6.0 (600.0.54) | 3.5 | -| 6.2 | — | — | — | — | 6.0 (600.0.57) | 3.5 | -| 6.3 | — | — | — | — | 6.1 (602.0.49) | 3.6 | -| 6.3.1 | — | — | — | — | 6.1 (602.0.49) | 3.6 | -| 6.3.2 | — | — | — | — | 6.1 (602.0.53) | 3.6 | -| 6.4 | — | — | — | — | 6.1 (602.0.53) | 3.6 | -| 7.0 | — | — | — | — | 7.0 (700.0.72) | — | -| 7.0.1 | — | — | — | — | 7.0 (700.0.72) | — | -| 7.1 | — | — | — | — | 7.0 (700.1.76) | — | -| 7.1.1 | — | — | — | — | 7.0 (700.1.76) | — | -| 7.2 | — | — | — | — | 7.0 (700.1.81) | — | -| 7.2.1 | — | — | — | — | 7.0 (700.1.81) | — | -| 7.3 | — | — | — | — | 7.3 (703.0.29) | — | -| 7.3.1 | — | — | — | — | 7.3 (703.0.31) | — | -| 8.0 | — | — | — | — | 8.0 (800.0.38) | — | -| 8.1 | — | — | — | — | 8.0 (800.0.42.1)| — | -| 8.2 | — | — | — | — | 8.0 (800.0.42.1)| — | -| 8.2.1 | — | — | — | — | 8.0 (800.0.42.1)| — | -| 8.3 | — | — | — | — | 8.1 (802.0.38) | — | -| 8.3.1 | — | — | — | — | 8.1 (802.0.41) | — | -| 8.3.2 | — | — | — | — | 8.1 (802.0.42) | — | -| 8.3.3 | — | — | — | — | 8.1 (802.0.42) | — | -| 9.0.0 | — | — | — | — | 9.0 (900.0.37) | — | -| 9.0.1 | — | — | — | — | 9.0 (900.0.38) | — | -| 9.1 | — | — | — | — | 9.0 (900.0.38) | — | - -## References to Xcode and compiler versions in code +## Updating for new Xcode releases When a new Xcode release is made, the following things need to be updated: -* `MacOS::Xcode.latest_version` -* `MacOS::CLT.latest_version` -* `MacOS::STANDARD_COMPILERS` -* `MacOS::Xcode.version fallback logic` -* ensure compiler version Regexps continue to work (`MacOS` module) +- In [`Library/Homebrew/os/mac/xcode.rb`](https://github.com/Homebrew/brew/blob/master/Library/Homebrew/os/mac/xcode.rb) + * `OS::Mac::Xcode.latest_version` + * `OS::Mac::CLT.latest_version` + * `OS::Mac::Xcode.detect_version_from_clang_version` +- In [`Library/Homebrew/os/mac.rb`](https://github.com/Homebrew/brew/blob/master/Library/Homebrew/os/mac.rb) + * `OS::Mac::STANDARD_COMPILERS` diff --git a/manpages/brew-cask.1 b/manpages/brew-cask.1 index 720fa4154..29905fcce 100644 --- a/manpages/brew-cask.1 +++ b/manpages/brew-cask.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BREW\-CASK" "1" "November 2017" "Homebrew" "brew-cask" +.TH "BREW\-CASK" "1" "February 2018" "Homebrew" "brew-cask" . .SH "NAME" \fBbrew\-cask\fR \- a friendly binary installer for macOS @@ -88,7 +88,7 @@ Without any arguments, list all installed Casks\. With \fB\-1\fR, always format If \fItoken\fR is given, summarize the staged files associated with the given Cask\. . .TP -\fBoutdated\fR [\-\-greedy] [\-\-verbose|\-\-quiet] [ \fItoken\fR \.\.\.] +\fBoutdated\fR [\-\-greedy] [\-\-verbose|\-\-quiet] [ \fItoken\fR \.\.\. ] Without token arguments, display all the installed Casks that have newer versions available in the tap; otherwise check only the tokens given in the command line\. If \fB\-\-greedy\fR is given then also include in the output the Casks having \fBauto_updates true\fR or \fBversion :latest\fR\. Otherwise they are skipped because there is no reliable way to know when updates are available for them\. . .br @@ -114,6 +114,10 @@ Check the given Casks for correct style using RuboCop Cask \fIhttps://github\.co Uninstall the given Cask\. With \fB\-\-force\fR, uninstall even if the Cask does not appear to be present\. . .TP +\fBupgrade\fR [\-\-force] [\-\-greedy] \fItoken\fR [ \fItoken\fR \.\.\. ] +Without token arguments, upgrade all the installed Casks that have newer versions available in the tap; otherwise update the tokens given in the command line\. If \fB\-\-greedy\fR is given then also upgrade the Casks having \fBauto_updates true\fR or \fBversion :latest\fR\. +. +.TP \fBzap\fR \fItoken\fR [ \fItoken\fR \.\.\. ] Unconditionally remove \fIall\fR files associated with the given Cask\. . @@ -235,7 +239,7 @@ Homebrew\-Cask is implemented as a external command for Homebrew\. That means th . .nf -brew update; brew cleanup; brew cask cleanup +brew update; brew cask upgrade; brew cleanup; brew cask cleanup . .fi . diff --git a/manpages/brew.1 b/manpages/brew.1 index 449d20a3e..56581bfc0 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "BREW" "1" "November 2017" "Homebrew" "brew" +.TH "BREW" "1" "February 2018" "Homebrew" "brew" . .SH "NAME" \fBbrew\fR \- The missing package manager for macOS @@ -137,8 +137,8 @@ The \fIfilters\fR placeholder is any combination of options \fB\-\-include\-buil Display \fIformula\fR\'s name and one\-line description\. . .TP -\fBdesc\fR [\fB\-s\fR|\fB\-n\fR|\fB\-d\fR] (\fItext\fR|\fB/\fR\fItext\fR\fB/\fR) -Search both name and description (\fB\-s\fR), just the names (\fB\-n\fR), or just the descriptions (\fB\-d\fR) for \fItext\fR\. If \fItext\fR is flanked by slashes, it is interpreted as a regular expression\. Formula descriptions are cached; the cache is created on the first search, making that search slower than subsequent ones\. +\fBdesc\fR [\fB\-\-search\fR|\fB\-\-name\fR|\fB\-\-description\fR] (\fItext\fR|\fB/\fR\fItext\fR\fB/\fR) +Search both name and description (\fB\-\-search\fR or \fB\-s\fR), just the names (\fB\-\-name\fR or \fB\-n\fR), or just the descriptions (\fB\-\-description\fR or \fB\-d\fR) for \fItext\fR\. If \fItext\fR is flanked by slashes, it is interpreted as a regular expression\. Formula descriptions are cached; the cache is created on the first search, making that search slower than subsequent ones\. . .TP \fBdiy\fR [\fB\-\-name=\fR\fIname\fR] [\fB\-\-version=\fR\fIversion\fR] @@ -152,7 +152,7 @@ The options \fB\-\-name=\fR\fIname\fR and \fB\-\-version=\fR\fIversion\fR each t . .TP \fBdoctor\fR -Check your system for potential problems\. Doctor exits with a non\-zero status if any problems are found\. +Check your system for potential problems\. Doctor exits with a non\-zero status if any potential problems are found\. Please note that these warnings are just used to help the Homebrew maintainers with debugging if you file an issue\. If everything you use Homebrew for is working fine: please don\'t worry or file an issue; just ignore this\. . .TP \fBfetch\fR [\fB\-\-force\fR] [\fB\-\-retry\fR] [\fB\-v\fR] [\fB\-\-devel\fR|\fB\-\-HEAD\fR] [\fB\-\-deps\fR] [\fB\-\-build\-from\-source\fR|\fB\-\-force\-bottle\fR] \fIformulae\fR @@ -187,6 +187,9 @@ Upload logs for a failed build of \fIformula\fR to a new Gist\. \fIformula\fR is usually the name of the formula to install, but it can be specified in several different ways\. See \fISPECIFYING FORMULAE\fR\. . .IP +If \fB\-\-with\-hostname\fR is passed, include the hostname in the Gist\. +. +.IP If \fB\-\-new\-issue\fR is passed, automatically create a new issue in the appropriate GitHub repository as well as creating the Gist\. . .IP @@ -201,12 +204,16 @@ Open Homebrew\'s own homepage in a browser\. Open \fIformula\fR\'s homepage in a browser\. . .TP +\fBinfo\fR +Display brief statistics for your Homebrew installation\. +. +.TP \fBinfo\fR \fIformula\fR Display information about \fIformula\fR\. . .TP \fBinfo\fR \fB\-\-github\fR \fIformula\fR -Open a browser to the GitHub History page for formula \fIformula\fR\. +Open a browser to the GitHub History page for \fIformula\fR\. . .IP To view formula history locally: \fBbrew log \-p <formula>\fR @@ -222,7 +229,7 @@ Pass \fB\-\-all\fR to get information on all formulae, or \fB\-\-installed\fR to See the docs for examples of using the JSON output: \fIhttps://docs\.brew\.sh/Querying\-Brew\.html\fR . .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] \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 \.\.\.] Install \fIformula\fR\. . .IP @@ -268,6 +275,12 @@ If \fB\-\-keep\-tmp\fR is passed, the temporary files created during installatio If \fB\-\-build\-bottle\fR is passed, prepare the formula for eventual bottling during installation\. . .IP +If \fB\-\-force\fR (or \fB\-f\fR) is passed, install without checking for previously installed keg\-only or non\-migrated versions +. +.IP +If \fB\-\-verbose\fR (or \fB\-v\fR) is passed, print the verification and postinstall steps\. +. +.IP Installation options specific to \fIformula\fR may be appended to the command, and can be listed with \fBbrew options\fR \fIformula\fR\. . .TP @@ -302,19 +315,6 @@ If \fB\-\-dry\-run\fR or \fB\-n\fR is passed, Homebrew will list all files which If \fB\-\-force\fR (or \fB\-f\fR) is passed, Homebrew will allow keg\-only formulae to be linked\. . .TP -\fBlinkapps\fR [\fB\-\-local\fR] [\fIformulae\fR] -Find installed formulae that provide \fB\.app\fR\-style macOS apps and symlink them into \fB/Applications\fR, allowing for easier access (deprecated)\. -. -.IP -Unfortunately \fBbrew linkapps\fR cannot behave nicely with e\.g\. Spotlight using either aliases or symlinks and Homebrew formulae do not build "proper" \fB\.app\fR bundles that can be relocated\. Instead, please consider using \fBbrew cask\fR and migrate formulae using \fB\.app\fRs to casks\. -. -.IP -If no \fIformulae\fR are provided, all of them will have their apps symlinked\. -. -.IP -If provided, \fB\-\-local\fR will symlink them into the user\'s \fB~/Applications\fR directory instead of the system directory\. -. -.TP \fBlist\fR, \fBls\fR [\fB\-\-full\-name\fR] List all installed formulae\. If \fB\-\-full\-name\fR is passed, print formulae with fully\-qualified names\. If \fB\-\-full\-name\fR is not passed, any other options (e\.g\. \fB\-t\fR) are passed to \fBls\fR which produces the actual output\. . @@ -323,7 +323,7 @@ List all installed formulae\. If \fB\-\-full\-name\fR is passed, print formulae List all files in the Homebrew prefix not installed by Homebrew\. . .TP -\fBlist\fR, \fBls\fR [\fB\-\-versions\fR [\fB\-\-multiple\fR]] [\fB\-\-pinned\fR] [\fIformulae\fR] +\fBlist\fR, \fBls\fR [\fB\-\-verbose\fR] [\fB\-\-versions\fR [\fB\-\-multiple\fR]] [\fB\-\-pinned\fR] [\fIformulae\fR] List the installed files for \fIformulae\fR\. Combined with \fB\-\-verbose\fR, recursively list the contents of all subdirectories in each \fIformula\fR\'s keg\. . .IP @@ -377,14 +377,14 @@ If \fB\-\-quiet\fR is passed, list only the names of outdated brews (takes prece If \fB\-\-verbose\fR (or \fB\-v\fR) is passed, display detailed version information\. . .IP -If \fB\-\-json=\fR\fIversion\fR is passed, the output will be in JSON format\. The only valid version is \fBv1\fR\. +If \fB\-\-json=\fR\fIversion\fR is passed, the output will be in JSON format\. Currently the only accepted value for \fIversion\fR is \fBv1\fR\. . .IP If \fB\-\-fetch\-HEAD\fR is passed, fetch the upstream repository to detect if the HEAD installation of the formula is outdated\. Otherwise, the repository\'s HEAD will be checked for updates when a new stable or devel version has been released\. . .TP \fBpin\fR \fIformulae\fR -Pin the specified \fIformulae\fR, preventing them from being upgraded when issuing the \fBbrew upgrade <formulae>\fR command (but can still be upgraded as dependencies for other formulae)\. See also \fBunpin\fR\. +Pin the specified \fIformulae\fR, preventing them from being upgraded when issuing the \fBbrew upgrade <formulae>\fR command\. See also \fBunpin\fR\. . .TP \fBpostinstall\fR \fIformula\fR @@ -398,15 +398,21 @@ Remove dead symlinks from the Homebrew prefix\. This is generally not needed, bu If \fB\-\-dry\-run\fR or \fB\-n\fR is passed, show what would be removed, but do not actually remove anything\. . .TP -\fBreadall\fR [tap] -Import all formulae from specified taps (defaults to all installed taps)\. +\fBreadall\fR [\fB\-\-aliases\fR] [\fB\-\-syntax\fR] [\fItaps\fR] +Import all formulae from specified \fItaps\fR (defaults to all installed taps)\. . .IP This can be useful for debugging issues across all formulae when making significant changes to \fBformula\.rb\fR, testing the performance of loading all formulae or to determine if any current formulae have Ruby issues\. . +.IP +If \fB\-\-aliases\fR is passed, also verify any alias symlinks in each tap\. +. +.IP +If \fB\-\-syntax\fR is passed, also syntax\-check all of Homebrew\'s Ruby files\. +. .TP \fBreinstall\fR \fIformula\fR -Uninstall and then install \fIformula\fR\. +Uninstall and then install \fIformula\fR (with existing install options)\. . .TP \fBsearch\fR, \fB\-S\fR @@ -431,23 +437,20 @@ Start a Homebrew build environment shell\. Uses our years\-battle\-hardened Home If \fB\-\-env=std\fR is passed, use the standard \fBPATH\fR instead of superenv\'s\. . .TP -\fBstyle\fR [\fB\-\-fix\fR] [\fB\-\-display\-cop\-names\fR] [\fB\-\-only\-cops=\fR[COP1,COP2\.\.]|\fB\-\-except\-cops=\fR[COP1,COP2\.\.]] [\fIfiles\fR|\fItaps\fR|\fIformulae\fR] +\fBstyle\fR [\fB\-\-fix\fR] [\fB\-\-display\-cop\-names\fR] [\fB\-\-only\-cops=\fR\fIcops\fR|\fB\-\-except\-cops=\fR\fIcops\fR] [\fIfiles\fR|\fItaps\fR|\fIformulae\fR] Check formulae or files for conformance to Homebrew style guidelines\. . .IP -\fIformulae\fR and \fIfiles\fR may not be combined\. If both are omitted, style will run style checks on the whole Homebrew \fBLibrary\fR, including core code and all formulae\. -. -.IP -If \fB\-\-fix\fR is passed, style violations will be automatically fixed using RuboCop\'s \fB\-\-auto\-correct\fR feature\. +Lists of \fIfiles\fR, \fItaps\fR and \fIformulae\fR may not be combined\. If none are provided, \fBstyle\fR will run style checks on the whole Homebrew library, including core code and all formulae\. . .IP -If \fB\-\-display\-cop\-names\fR is passed, the RuboCop cop name for each violation is included in the output\. +If \fB\-\-fix\fR is passed, automatically fix style violations using RuboCop\'s auto\-correct feature\. . .IP -If \fB\-\-only\-cops\fR is passed, only the given Rubocop cop(s)\' violations would be checked\. +If \fB\-\-display\-cop\-names\fR is passed, include the RuboCop cop name for each violation in the output\. . .IP -If \fB\-\-except\-cops\fR is passed, the given Rubocop cop(s)\' checks would be skipped\. +Passing \fB\-\-only\-cops=\fR\fIcops\fR will check for violations of only the listed RuboCop \fIcops\fR, while \fB\-\-except\-cops=\fR\fIcops\fR will skip checking the listed \fIcops\fR\. For either option \fIcops\fR should be a comma\-separated list of cop names\. . .IP Exits with a non\-zero status if any style violations are found\. @@ -535,22 +538,6 @@ Remove symlinks for \fIformula\fR from the Homebrew prefix\. This can be useful If \fB\-\-dry\-run\fR or \fB\-n\fR is passed, Homebrew will list all files which would be unlinked, but will not actually unlink or delete any files\. . .TP -\fBunlinkapps\fR [\fB\-\-local\fR] [\fB\-\-dry\-run\fR] [\fIformulae\fR] -Remove symlinks created by \fBbrew linkapps\fR from \fB/Applications\fR (deprecated)\. -. -.IP -Unfortunately \fBbrew linkapps\fR cannot behave nicely with e\.g\. Spotlight using either aliases or symlinks and Homebrew formulae do not build "proper" \fB\.app\fR bundles that can be relocated\. Instead, please consider using \fBbrew cask\fR and migrate formulae using \fB\.app\fRs to casks\. -. -.IP -If no \fIformulae\fR are provided, all linked apps will be removed\. -. -.IP -If provided, \fB\-\-local\fR will remove symlinks from the user\'s \fB~/Applications\fR directory instead of the system directory\. -. -.IP -If \fB\-\-dry\-run\fR or \fB\-n\fR is passed, Homebrew will list all symlinks which would be removed, but will not actually delete any files\. -. -.TP \fBunpack\fR [\fB\-\-git\fR|\fB\-\-patch\fR] [\fB\-\-destdir=\fR\fIpath\fR] \fIformulae\fR Unpack the source files for \fIformulae\fR into subdirectories of the current working directory\. If \fB\-\-destdir=\fR\fIpath\fR is given, the subdirectories will be created in the directory named by \fIpath\fR instead\. . @@ -584,7 +571,7 @@ Fetches and resets Homebrew and all tap repositories using \fBgit\fR(1) to their . .TP \fBupgrade\fR [\fIinstall\-options\fR] [\fB\-\-cleanup\fR] [\fB\-\-fetch\-HEAD\fR] [\fIformulae\fR] -Upgrade outdated, unpinned brews\. +Upgrade outdated, unpinned brews (with existing install options)\. . .IP Options for the \fBinstall\fR command are also valid here\. @@ -631,8 +618,14 @@ Display Homebrew\'s Cellar path\. \fIDefault:\fR \fB$(brew \-\-prefix)/Cellar\fR Display the location in the cellar where \fIformula\fR would be installed, without any sort of versioned directory as the last path\. . .TP -\fB\-\-env\fR -Show a summary of the Homebrew build environment\. +\fB\-\-env\fR [\fB\-\-shell=\fR(\fIshell\fR|\fBauto\fR)|\fB\-\-plain\fR] +Show a summary of the Homebrew build environment as a plain list\. +. +.IP +Pass \fB\-\-shell=\fR\fIshell\fR to generate a list of environment variables for the specified shell, or \fB\-\-shell=auto\fR to detect the current shell\. +. +.IP +If the command\'s output is sent through a pipe and no shell is specified, the list is formatted for export to \fBbash\fR(1) unless \fB\-\-plain\fR is passed\. . .TP \fB\-\-prefix\fR @@ -657,7 +650,7 @@ Print the version number of Homebrew to standard output and exit\. .SH "DEVELOPER COMMANDS" . .TP -\fBaudit\fR [\fB\-\-strict\fR] [\fB\-\-fix\fR] [\fB\-\-online\fR] [\fB\-\-new\-formula\fR] [\fB\-\-display\-cop\-names\fR] [\fB\-\-display\-filename\fR] [\fB\-\-only=\fR\fImethod\fR|\fB\-\-except=\fR\fImethod\fR] [\fB\-\-only\-cops=\fR[COP1,COP2\.\.]|\fB\-\-except\-cops=\fR[COP1,COP2\.\.]] [\fIformulae\fR] +\fBaudit\fR [\fB\-\-strict\fR] [\fB\-\-fix\fR] [\fB\-\-online\fR] [\fB\-\-new\-formula\fR] [\fB\-\-display\-cop\-names\fR] [\fB\-\-display\-filename\fR] [\fB\-\-only=\fR\fImethod\fR|\fB\-\-except=\fR\fImethod\fR] [\fB\-\-only\-cops=\fR\fIcops\fR|\fB\-\-except\-cops=\fR\fIcops\fR] [\fIformulae\fR] Check \fIformulae\fR for Homebrew coding style violations\. This should be run before submitting a new formula\. . .IP @@ -667,7 +660,7 @@ If no \fIformulae\fR are provided, all of them are checked\. If \fB\-\-strict\fR is passed, additional checks are run, including RuboCop style checks\. . .IP -If \fB\-\-fix\fR is passed, style violations will be automatically fixed using RuboCop\'s \fB\-\-auto\-correct\fR feature\. +If \fB\-\-fix\fR is passed, style violations will be automatically fixed using RuboCop\'s auto\-correct feature\. . .IP If \fB\-\-online\fR is passed, additional slower checks that require a network connection are run\. @@ -682,16 +675,10 @@ If \fB\-\-display\-cop\-names\fR is passed, the RuboCop cop name for each violat If \fB\-\-display\-filename\fR is passed, every line of output is prefixed with the name of the file or formula being audited, to make the output easy to grep\. . .IP -If \fB\-\-only\fR is passed, only the methods named \fBaudit_<method>\fR will be run\. +Passing \fB\-\-only=\fR\fImethod\fR will run only the methods named \fBaudit_<method>\fR, while \fB\-\-except=\fR\fImethod\fR will skip the methods named \fBaudit_<method>\fR\. For either option \fImethod\fR should be a comma\-separated list\. . .IP -If \fB\-\-except\fR is passed, the methods named \fBaudit_<method>\fR will not be run\. -. -.IP -If \fB\-\-only\-cops\fR is passed, only the given Rubocop cop(s)\' violations would be checked\. -. -.IP -If \fB\-\-except\-cops\fR is passed, the given Rubocop cop(s)\' checks would be skipped\. +Passing \fB\-\-only\-cops=\fR\fIcops\fR will check for violations of only the listed RuboCop \fIcops\fR, while \fB\-\-except\-cops=\fR\fIcops\fR will skip checking the listed \fIcops\fR\. For either option \fIcops\fR should be a comma\-separated list of cop names\. . .IP \fBaudit\fR exits with a non\-zero status if any errors are found\. This is useful, for instance, for implementing pre\-commit hooks\. @@ -760,6 +747,9 @@ If \fB\-\-message=\fR\fImessage\fR is passed, append \fImessage\fR to the defaul If \fB\-\-no\-browse\fR is passed, don\'t pass the \fB\-\-browse\fR argument to \fBhub\fR which opens the pull request URL in a browser\. Instead, output it to the command line\. . .IP +If \fB\-\-quiet\fR is passed, don\'t output replacement messages or warn about duplicate pull requests\. +. +.IP Note that this command cannot be used to transition a formula from a URL\-and\-sha256 style specification into a tag\-and\-revision style specification, nor vice versa\. It must use whichever style specification the preexisting formula already uses\. . .TP @@ -1028,8 +1018,12 @@ If set, Homebrew will use this editor when editing a single formula, or several \fINote:\fR \fBbrew edit\fR will open all of Homebrew as discontinuous files and directories\. TextMate can handle this correctly in project mode, but many editors will do strange things in this case\. . .TP +\fBHOMEBREW_FORCE_BREWED_CURL\fR +If set, Homebrew will use a Homebrew\-installed \fBcurl\fR rather than the system version\. +. +.TP \fBHOMEBREW_FORCE_VENDOR_RUBY\fR -If set, Homebrew will always use its vendored, relocatable Ruby 2\.0 version even if the system version of Ruby is >=2\.0\. +If set, Homebrew will always use its vendored, relocatable Ruby version even if the system version of Ruby is new enough\. . .TP \fBHOMEBREW_GIT\fR @@ -1104,30 +1098,52 @@ This issue typically occurs when using FileVault or custom SSD configurations\. \fBHOMEBREW_VERBOSE\fR If set, Homebrew always assumes \fB\-\-verbose\fR when running commands\. . +.TP +\fBhttp_proxy\fR +Sets the HTTP proxy to be used by \fBcurl\fR, \fBgit\fR and \fBsvn\fR when downloading through Homebrew\. +. +.TP +\fBhttps_proxy\fR +Sets the HTTPS proxy to be used by \fBcurl\fR, \fBgit\fR and \fBsvn\fR when downloading through Homebrew\. +. +.TP +\fBall_proxy\fR +Sets the SOCKS5 proxy to be used by \fBcurl\fR, \fBgit\fR and \fBsvn\fR when downloading through Homebrew\. +. +.TP +\fBftp_proxy\fR +Sets the FTP proxy to be used by \fBcurl\fR, \fBgit\fR and \fBsvn\fR when downloading through Homebrew\. +. +.TP +\fBno_proxy\fR +Sets the comma\-separated list of hostnames and domain names that should be excluded from proxying by \fBcurl\fR, \fBgit\fR and \fBsvn\fR when downloading through Homebrew\. +. .SH "USING HOMEBREW BEHIND A PROXY" -Homebrew uses several commands for downloading files (e\.g\. \fBcurl\fR, \fBgit\fR, \fBsvn\fR)\. Many of these tools can download via a proxy\. It\'s common for these tools to read proxy parameters from environment variables\. +Use the \fBhttp_proxy\fR, \fBhttps_proxy\fR, \fBall_proxy\fR, \fBno_proxy\fR and/or \fBftp_proxy\fR documented above\. . .P -For the majority of cases setting \fBhttp_proxy\fR is enough\. You can set this in your shell profile, or you can use it before a brew command: +For example for an unauthenticated HTTP or SOCKS5 proxy: . .IP "" 4 . .nf -http_proxy=http://<host>:<port> brew install foo +export http_proxy=http://<host>:<port> + +export all_proxy=socks5://<host>:<port> . .fi . .IP "" 0 . .P -If your proxy requires authentication: +And for an authenticated HTTP proxy: . .IP "" 4 . .nf -http_proxy=http://<user>:<password>@<host>:<port> brew install foo +export http_proxy=http://<user>:<password>@<host>:<port> . .fi . @@ -1146,10 +1162,13 @@ Homebrew\'s lead maintainer is Mike McQuaid\. Homebrew/homebrew\-core\'s lead maintainer is ilovezfs\. . .P -Homebrew\'s other current maintainers are Alyssa Ross, Andrew Janke, Alex Dunn, FX Coudert, Josh Hagins, JCount, Misty De Meo, neutric, Tomasz Pajor, Markus Reiter, Tim Smith, Tom Schoonjans, Uladzislau Shablinski and William Woodruff\. +Homebrew/brew\'s other current maintainers are ilovezfs, Alyssa Ross, JCount, Misty De Meo, Gautham Goli, Markus Reiter and William Woodruff\. +. +.P +Homebrew/homebrew\-core\'s other current maintainers are FX Coudert, JCount, Misty De Meo and Tom Schoonjans\. . .P -Former maintainers with significant contributions include Baptiste Fontaine, Xu Cheng, Martin Afanasjew, Dominyk Tiller, Brett Koonce, Charlie Sharpsteen, Jack Nagel, Adam Vandenberg and Homebrew\'s creator: Max Howell\. +Former maintainers with significant contributions include Tim Smith, Baptiste Fontaine, Xu Cheng, Martin Afanasjew, Dominyk Tiller, Brett Koonce, Charlie Sharpsteen, Jack Nagel, Adam Vandenberg, Andrew Janke, Alex Dunn, neutric, Tomasz Pajor, Uladzislau Shablinski and Homebrew\'s creator: Max Howell\. . .SH "BUGS" See our issues on GitHub: |
