diff options
Diffstat (limited to 'Library')
210 files changed, 2052 insertions, 2200 deletions
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 |
