Merge branch 'master' into integrate-uninstall-reinstall
This commit is contained in:
		
						commit
						bb939323a7
					
				@ -17,7 +17,7 @@ GEM
 | 
			
		||||
      term-ansicolor (~> 1.3)
 | 
			
		||||
      thor (>= 0.19.4, < 2.0)
 | 
			
		||||
      tins (~> 1.6)
 | 
			
		||||
    diff-lcs (1.4.2)
 | 
			
		||||
    diff-lcs (1.4.3)
 | 
			
		||||
    docile (1.3.2)
 | 
			
		||||
    domain_name (0.5.20190701)
 | 
			
		||||
      unf (>= 0.0.5, < 1.0.0)
 | 
			
		||||
@ -26,7 +26,7 @@ GEM
 | 
			
		||||
      domain_name (~> 0.5)
 | 
			
		||||
    i18n (1.8.3)
 | 
			
		||||
      concurrent-ruby (~> 1.0)
 | 
			
		||||
    json (2.3.0)
 | 
			
		||||
    json (2.3.1)
 | 
			
		||||
    mechanize (2.7.6)
 | 
			
		||||
      domain_name (~> 0.5, >= 0.5.1)
 | 
			
		||||
      http-cookie (~> 1.0)
 | 
			
		||||
@ -91,7 +91,7 @@ GEM
 | 
			
		||||
      rubocop-ast (>= 0.0.3, < 1.0)
 | 
			
		||||
      ruby-progressbar (~> 1.7)
 | 
			
		||||
      unicode-display_width (>= 1.4.0, < 2.0)
 | 
			
		||||
    rubocop-ast (0.0.3)
 | 
			
		||||
    rubocop-ast (0.1.0)
 | 
			
		||||
      parser (>= 2.7.0.1)
 | 
			
		||||
    rubocop-performance (1.6.1)
 | 
			
		||||
      rubocop (>= 0.71.0)
 | 
			
		||||
@ -118,7 +118,7 @@ GEM
 | 
			
		||||
    unf_ext (0.0.7.7)
 | 
			
		||||
    unicode-display_width (1.7.0)
 | 
			
		||||
    webrobots (0.1.2)
 | 
			
		||||
    zeitwerk (2.3.0)
 | 
			
		||||
    zeitwerk (2.3.1)
 | 
			
		||||
 | 
			
		||||
PLATFORMS
 | 
			
		||||
  ruby
 | 
			
		||||
 | 
			
		||||
@ -267,6 +267,7 @@ module Homebrew
 | 
			
		||||
    # Need to rescue before `FormulaUnavailableError` (superclass of this)
 | 
			
		||||
    # is handled, as searching for a formula doesn't make sense here (the
 | 
			
		||||
    # formula was found, but there's a problem with its implementation).
 | 
			
		||||
    $stderr.puts e.backtrace if Homebrew::EnvConfig.developer?
 | 
			
		||||
    ofail e.message
 | 
			
		||||
  rescue FormulaUnavailableError => e
 | 
			
		||||
    if e.name == "updog"
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@
 | 
			
		||||
require "formula"
 | 
			
		||||
require "options"
 | 
			
		||||
require "cli/parser"
 | 
			
		||||
require "commands"
 | 
			
		||||
 | 
			
		||||
module Homebrew
 | 
			
		||||
  module_function
 | 
			
		||||
@ -20,8 +21,10 @@ module Homebrew
 | 
			
		||||
             description: "Show options for formulae that are currently installed."
 | 
			
		||||
      switch "--all",
 | 
			
		||||
             description: "Show options for all available formulae."
 | 
			
		||||
      flag   "--command=",
 | 
			
		||||
             description: "Show options for the specified <command>."
 | 
			
		||||
      switch :debug
 | 
			
		||||
      conflicts "--installed", "--all"
 | 
			
		||||
      conflicts "--installed", "--all", "--command"
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -32,6 +35,22 @@ module Homebrew
 | 
			
		||||
      puts_options Formula.to_a.sort
 | 
			
		||||
    elsif args.installed?
 | 
			
		||||
      puts_options Formula.installed.sort
 | 
			
		||||
    elsif !args.command.nil?
 | 
			
		||||
      path = Commands.path(args.command)
 | 
			
		||||
      odie "Unknown command: #{args.command}" unless path
 | 
			
		||||
      cmd_options = if cmd_parser = CLI::Parser.from_cmd_path(path)
 | 
			
		||||
        cmd_parser.processed_options.map do |short, long, _, desc|
 | 
			
		||||
          [long || short, desc]
 | 
			
		||||
        end
 | 
			
		||||
      else
 | 
			
		||||
        cmd_comment_options(path)
 | 
			
		||||
      end
 | 
			
		||||
      if args.compact?
 | 
			
		||||
        puts cmd_options.sort.map(&:first) * " "
 | 
			
		||||
      else
 | 
			
		||||
        cmd_options.sort.each { |option, desc| puts "#{option}\n\t#{desc}" }
 | 
			
		||||
        puts
 | 
			
		||||
      end
 | 
			
		||||
    elsif args.no_named?
 | 
			
		||||
      raise FormulaUnspecifiedError
 | 
			
		||||
    else
 | 
			
		||||
@ -39,6 +58,20 @@ module Homebrew
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def cmd_comment_options(cmd_path)
 | 
			
		||||
    options = []
 | 
			
		||||
    comment_lines = cmd_path.read.lines.grep(/^#:/)
 | 
			
		||||
    return options if comment_lines.empty?
 | 
			
		||||
 | 
			
		||||
    # skip the comment's initial usage summary lines
 | 
			
		||||
    comment_lines.slice(2..-1).each do |line|
 | 
			
		||||
      if / (?<option>-[-\w]+) +(?<desc>.*)$/ =~ line
 | 
			
		||||
        options << [option, desc]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    options
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def puts_options(formulae)
 | 
			
		||||
    formulae.each do |f|
 | 
			
		||||
      next if f.options.empty?
 | 
			
		||||
 | 
			
		||||
@ -168,14 +168,6 @@ module Homebrew
 | 
			
		||||
      @text.split("\n__END__").first
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def data?
 | 
			
		||||
      /^[^#]*\bDATA\b/ =~ @text
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def end?
 | 
			
		||||
      /^__END__$/ =~ @text
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def trailing_newline?
 | 
			
		||||
      /\Z\n/ =~ @text
 | 
			
		||||
    end
 | 
			
		||||
@ -234,12 +226,6 @@ module Homebrew
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def audit_file
 | 
			
		||||
      # TODO: check could be in RuboCop
 | 
			
		||||
      problem "'DATA' was found, but no '__END__'" if text.data? && !text.end?
 | 
			
		||||
 | 
			
		||||
      # TODO: check could be in RuboCop
 | 
			
		||||
      problem "'__END__' was found, but 'DATA' is not used" if text.end? && !text.data?
 | 
			
		||||
 | 
			
		||||
      # TODO: check could be in RuboCop
 | 
			
		||||
      if text.to_s.match?(/inreplace [^\n]* do [^\n]*\n[^\n]*\.gsub![^\n]*\n\ *end/m)
 | 
			
		||||
        problem "'inreplace ... do' was used for a single substitution (use the non-block form instead)."
 | 
			
		||||
@ -567,6 +553,7 @@ module Homebrew
 | 
			
		||||
    THROTTLED_DENYLIST = {
 | 
			
		||||
      "aws-sdk-cpp" => "10",
 | 
			
		||||
      "awscli@1"    => "10",
 | 
			
		||||
      "balena-cli"  => "10",
 | 
			
		||||
      "quicktype"   => "10",
 | 
			
		||||
      "vim"         => "50",
 | 
			
		||||
    }.freeze
 | 
			
		||||
 | 
			
		||||
@ -147,7 +147,6 @@ module Homebrew
 | 
			
		||||
    raise FormulaUnspecifiedError unless formula
 | 
			
		||||
 | 
			
		||||
    tap_full_name, origin_branch, previous_branch = use_correct_linux_tap(formula)
 | 
			
		||||
    check_for_duplicate_pull_requests(formula, tap_full_name)
 | 
			
		||||
 | 
			
		||||
    requested_spec, formula_spec = if args.devel?
 | 
			
		||||
      devel_message = " (devel)"
 | 
			
		||||
@ -315,6 +314,8 @@ module Homebrew
 | 
			
		||||
 | 
			
		||||
    new_formula_version = formula_version(formula, requested_spec, new_contents)
 | 
			
		||||
 | 
			
		||||
    check_for_duplicate_pull_requests(formula, tap_full_name, new_formula_version.to_s)
 | 
			
		||||
 | 
			
		||||
    if !new_mirrors && !formula_spec.mirrors.empty?
 | 
			
		||||
      if args.force?
 | 
			
		||||
        opoo "#{formula}: Removing all mirrors because a --mirror= argument was not specified."
 | 
			
		||||
@ -468,23 +469,26 @@ module Homebrew
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def fetch_pull_requests(formula, tap_full_name)
 | 
			
		||||
    GitHub.issues_for_formula(formula.name, tap_full_name: tap_full_name).select do |pr|
 | 
			
		||||
  def fetch_pull_requests(query, tap_full_name, state: nil)
 | 
			
		||||
    GitHub.issues_for_formula(query, tap_full_name: tap_full_name, state: state).select do |pr|
 | 
			
		||||
      pr["html_url"].include?("/pull/") &&
 | 
			
		||||
        /(^|\s)#{Regexp.quote(formula.name)}(:|\s|$)/i =~ pr["title"]
 | 
			
		||||
        /(^|\s)#{Regexp.quote(query)}(:|\s|$)/i =~ pr["title"]
 | 
			
		||||
    end
 | 
			
		||||
  rescue GitHub::RateLimitExceededError => e
 | 
			
		||||
    opoo e.message
 | 
			
		||||
    []
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def check_for_duplicate_pull_requests(formula, tap_full_name)
 | 
			
		||||
    pull_requests = fetch_pull_requests(formula, tap_full_name)
 | 
			
		||||
    return unless pull_requests
 | 
			
		||||
    return if pull_requests.empty?
 | 
			
		||||
  def check_for_duplicate_pull_requests(formula, tap_full_name, version)
 | 
			
		||||
    # check for open requests
 | 
			
		||||
    pull_requests = fetch_pull_requests(formula.name, tap_full_name, state: "open")
 | 
			
		||||
 | 
			
		||||
    # if we haven't already found open requests, try for an exact match across all requests
 | 
			
		||||
    pull_requests = fetch_pull_requests("#{formula.name} #{version}", tap_full_name) if pull_requests.blank?
 | 
			
		||||
    return if pull_requests.blank?
 | 
			
		||||
 | 
			
		||||
    duplicates_message = <<~EOS
 | 
			
		||||
      These open pull requests may be duplicates:
 | 
			
		||||
      These pull requests may be duplicates:
 | 
			
		||||
      #{pull_requests.map { |pr| "#{pr["title"]} #{pr["html_url"]}" }.join("\n")}
 | 
			
		||||
    EOS
 | 
			
		||||
    error_message = "Duplicate PRs should not be opened. Use --force to override this error."
 | 
			
		||||
 | 
			
		||||
@ -360,7 +360,7 @@ class BuildError < RuntimeError
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def fetch_issues
 | 
			
		||||
    GitHub.issues_for_formula(formula.name, tap: formula.tap)
 | 
			
		||||
    GitHub.issues_for_formula(formula.name, tap: formula.tap, state: "open")
 | 
			
		||||
  rescue GitHub::RateLimitExceededError => e
 | 
			
		||||
    opoo e.message
 | 
			
		||||
    []
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,7 @@ class Keg
 | 
			
		||||
    # patchelf requires that the ELF file have a .dynstr section.
 | 
			
		||||
    # Skip ELF files that do not have a .dynstr section.
 | 
			
		||||
    return if ["cannot find section .dynstr", "strange: no string table"].include?(old_rpath)
 | 
			
		||||
 | 
			
		||||
    unless $CHILD_STATUS.success?
 | 
			
		||||
      raise ErrorDuringExecution.new(cmd_rpath, status: $CHILD_STATUS, output: [[:stderr, old_rpath]])
 | 
			
		||||
    end
 | 
			
		||||
@ -41,15 +42,15 @@ class Keg
 | 
			
		||||
    new_rpath = rpath.join(":")
 | 
			
		||||
    cmd = [patchelf, "--force-rpath", "--set-rpath", new_rpath]
 | 
			
		||||
 | 
			
		||||
    if file.with_interpreter?
 | 
			
		||||
      old_interpreter = Utils.safe_popen_read(patchelf, "--print-interpreter", file).strip
 | 
			
		||||
      new_interpreter = if File.readable? "#{new_prefix}/lib/ld.so"
 | 
			
		||||
    old_interpreter = file.interpreter
 | 
			
		||||
    new_interpreter = if old_interpreter.nil?
 | 
			
		||||
      nil
 | 
			
		||||
    elsif File.readable? "#{new_prefix}/lib/ld.so"
 | 
			
		||||
      "#{new_prefix}/lib/ld.so"
 | 
			
		||||
    else
 | 
			
		||||
      old_interpreter.sub old_prefix, new_prefix
 | 
			
		||||
    end
 | 
			
		||||
    cmd << "--set-interpreter" << new_interpreter if old_interpreter != new_interpreter
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    return if old_rpath == new_rpath && old_interpreter == new_interpreter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,7 @@ module Formulary
 | 
			
		||||
    begin
 | 
			
		||||
      mod.module_eval(contents, path)
 | 
			
		||||
    rescue NameError, ArgumentError, ScriptError => e
 | 
			
		||||
      $stderr.puts e.backtrace if Homebrew::EnvConfig.developer?
 | 
			
		||||
      raise FormulaUnreadableError.new(name, e)
 | 
			
		||||
    end
 | 
			
		||||
    class_name = class_s(name)
 | 
			
		||||
 | 
			
		||||
@ -68,28 +68,24 @@ module ELFShim
 | 
			
		||||
    elf_type == :executable
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def with_interpreter?
 | 
			
		||||
    return @with_interpreter if defined? @with_interpreter
 | 
			
		||||
  def interpreter
 | 
			
		||||
    return @interpreter if defined? @interpreter
 | 
			
		||||
 | 
			
		||||
    @with_interpreter = if binary_executable?
 | 
			
		||||
      true
 | 
			
		||||
    elsif dylib?
 | 
			
		||||
      if HOMEBREW_PATCHELF_RB
 | 
			
		||||
    @interpreter = if HOMEBREW_PATCHELF_RB
 | 
			
		||||
      begin
 | 
			
		||||
          patchelf_patcher.interpreter.present?
 | 
			
		||||
        patchelf_patcher.interpreter
 | 
			
		||||
      rescue PatchELF::PatchError => e
 | 
			
		||||
        opoo e unless e.to_s.start_with? "No interpreter found"
 | 
			
		||||
          false
 | 
			
		||||
        nil
 | 
			
		||||
      end
 | 
			
		||||
      elsif which "readelf"
 | 
			
		||||
        Utils.popen_read("readelf", "-l", to_path).include?(" INTERP ")
 | 
			
		||||
      elsif which "file"
 | 
			
		||||
        Utils.popen_read("file", "-L", "-b", to_path).include?(" interpreter ")
 | 
			
		||||
    elsif (patchelf = DevelopmentTools.locate "patchelf")
 | 
			
		||||
      interp = Utils.popen_read(patchelf, "--print-interpreter", to_s, err: :out).strip
 | 
			
		||||
      $CHILD_STATUS.success? ? interp : nil
 | 
			
		||||
    elsif (file = DevelopmentTools.locate("file"))
 | 
			
		||||
      output = Utils.popen_read(file, "-L", "-b", to_s, err: :out).strip
 | 
			
		||||
      output[/^ELF.*, interpreter (.+?), /, 1]
 | 
			
		||||
    else
 | 
			
		||||
        raise "Please install either readelf (from binutils) or file."
 | 
			
		||||
      end
 | 
			
		||||
    else
 | 
			
		||||
      false
 | 
			
		||||
      raise "Please install either patchelf or file."
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -22,5 +22,6 @@ require "rubocops/uses_from_macos"
 | 
			
		||||
require "rubocops/files"
 | 
			
		||||
require "rubocops/keg_only"
 | 
			
		||||
require "rubocops/version"
 | 
			
		||||
require "rubocops/deprecate"
 | 
			
		||||
 | 
			
		||||
require "rubocops/rubocop-cask"
 | 
			
		||||
 | 
			
		||||
@ -226,11 +226,10 @@ module RuboCop
 | 
			
		||||
              next if succeeding_component.empty?
 | 
			
		||||
 | 
			
		||||
              offensive_nodes = check_precedence(preceding_component, succeeding_component)
 | 
			
		||||
              break if offensive_nodes
 | 
			
		||||
              return [present_components, offensive_nodes] if offensive_nodes
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          [present_components, offensive_nodes]
 | 
			
		||||
          nil
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Method to format message for reporting component precedence violations
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								Library/Homebrew/rubocops/deprecate.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								Library/Homebrew/rubocops/deprecate.rb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
require "rubocops/extend/formula"
 | 
			
		||||
 | 
			
		||||
module RuboCop
 | 
			
		||||
  module Cop
 | 
			
		||||
    module FormulaAudit
 | 
			
		||||
      # This cop audits deprecate!
 | 
			
		||||
      class Deprecate < FormulaCop
 | 
			
		||||
        def audit_formula(_node, _class_node, _parent_class_node, body_node)
 | 
			
		||||
          deprecate_node = find_node_method_by_name(body_node, :deprecate!)
 | 
			
		||||
 | 
			
		||||
          return if deprecate_node.nil? || deprecate_node.children.length < 3
 | 
			
		||||
 | 
			
		||||
          date_node = find_strings(deprecate_node).first
 | 
			
		||||
 | 
			
		||||
          begin
 | 
			
		||||
            Date.iso8601(string_content(date_node))
 | 
			
		||||
          rescue ArgumentError
 | 
			
		||||
            fixed_date_string = Date.parse(string_content(date_node)).iso8601
 | 
			
		||||
            offending_node(date_node)
 | 
			
		||||
            problem "Use `#{fixed_date_string}` to comply with ISO 8601"
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def autocorrect(node)
 | 
			
		||||
          lambda do |corrector|
 | 
			
		||||
            fixed_fixed_date_string = Date.parse(string_content(node)).iso8601
 | 
			
		||||
            corrector.replace(node.source_range, "\"#{fixed_fixed_date_string}\"")
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
@ -195,7 +195,7 @@ module RuboCop
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      class ShellCmd < FormulaCop
 | 
			
		||||
      class SafePopenCommands < FormulaCop
 | 
			
		||||
        def audit_formula(_node, _class_node, _parent_class_node, body_node)
 | 
			
		||||
          test = find_block(body_node, :test)
 | 
			
		||||
 | 
			
		||||
@ -223,6 +223,35 @@ module RuboCop
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      class ShellVariables < FormulaCop
 | 
			
		||||
        def audit_formula(_node, _class_node, _parent_class_node, body_node)
 | 
			
		||||
          popen_commands = [
 | 
			
		||||
            :popen,
 | 
			
		||||
            :popen_read,
 | 
			
		||||
            :safe_popen_read,
 | 
			
		||||
            :popen_write,
 | 
			
		||||
            :safe_popen_write,
 | 
			
		||||
          ]
 | 
			
		||||
 | 
			
		||||
          popen_commands.each do |command|
 | 
			
		||||
            find_instance_method_call(body_node, "Utils", command) do |method|
 | 
			
		||||
              next unless match = regex_match_group(parameters(method).first, /^([^"' ]+)=([^"' ]+)(?: (.*))?$/)
 | 
			
		||||
 | 
			
		||||
              good_args = "Utils.#{command}({ \"#{match[1]}\" => \"#{match[2]}\" }, \"#{match[3]}\")"
 | 
			
		||||
 | 
			
		||||
              problem "Use `#{good_args}` instead of `#{method.source}`"
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def autocorrect(node)
 | 
			
		||||
          lambda do |corrector|
 | 
			
		||||
            match = regex_match_group(node, /^([^"' ]+)=([^"' ]+)(?: (.*))?$/)
 | 
			
		||||
            corrector.replace(node.source_range, "{ \"#{match[1]}\" => \"#{match[2]}\" }, \"#{match[3]}\"")
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      class Miscellaneous < FormulaCop
 | 
			
		||||
        def audit_formula(_node, _class_node, _parent_class_node, body_node)
 | 
			
		||||
          # FileUtils is included in Formula
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,9 @@ module RuboCop
 | 
			
		||||
    module FormulaAudit
 | 
			
		||||
      # This cop audits patches in Formulae.
 | 
			
		||||
      class Patches < FormulaCop
 | 
			
		||||
        def audit_formula(_node, _class_node, _parent_class_node, body)
 | 
			
		||||
        def audit_formula(node, _class_node, _parent_class_node, body)
 | 
			
		||||
          @full_source_content = source_buffer(node).source
 | 
			
		||||
 | 
			
		||||
          external_patches = find_all_blocks(body, :patch)
 | 
			
		||||
          external_patches.each do |patch_block|
 | 
			
		||||
            url_node = find_every_method_call_by_name(patch_block, :url).first
 | 
			
		||||
@ -16,6 +18,14 @@ module RuboCop
 | 
			
		||||
            patch_problems(url_string)
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          inline_patches = find_every_method_call_by_name(body, :patch)
 | 
			
		||||
          inline_patches.each { |patch| inline_patch_problems(patch) }
 | 
			
		||||
 | 
			
		||||
          if inline_patches.empty? && patch_end?
 | 
			
		||||
            offending_patch_end_node(node)
 | 
			
		||||
            problem "patch is missing 'DATA'"
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          patches_node = find_method_def(body, :patches)
 | 
			
		||||
          return if patches_node.nil?
 | 
			
		||||
 | 
			
		||||
@ -84,6 +94,30 @@ module RuboCop
 | 
			
		||||
              #{patch_url}
 | 
			
		||||
          EOS
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def inline_patch_problems(patch)
 | 
			
		||||
          return unless patch_data?(patch) && !patch_end?
 | 
			
		||||
 | 
			
		||||
          offending_node(patch)
 | 
			
		||||
          problem "patch is missing '__END__'"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def_node_search :patch_data?, <<~AST
 | 
			
		||||
          (send nil? :patch (:sym :DATA))
 | 
			
		||||
        AST
 | 
			
		||||
 | 
			
		||||
        def patch_end?
 | 
			
		||||
          /^__END__$/.match?(@full_source_content)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def offending_patch_end_node(node)
 | 
			
		||||
          @offensive_node = node
 | 
			
		||||
          @source_buf = source_buffer(node)
 | 
			
		||||
          @line_no = node.loc.last_line + 1
 | 
			
		||||
          @column = 0
 | 
			
		||||
          @length = 7 # "__END__".size
 | 
			
		||||
          @offense_source_range = source_range(@source_buf, @line_no, @column, @length)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -115,6 +115,8 @@ class SoftwareSpec
 | 
			
		||||
      raise DuplicateResourceError, name if resource_defined?(name)
 | 
			
		||||
 | 
			
		||||
      res = klass.new(name, &block)
 | 
			
		||||
      return unless res.url
 | 
			
		||||
 | 
			
		||||
      resources[name] = res
 | 
			
		||||
      dependency_collector.add(res)
 | 
			
		||||
    else
 | 
			
		||||
 | 
			
		||||
@ -652,6 +652,7 @@ false:
 | 
			
		||||
  - ./test/rubocops/components_redundancy_spec.rb
 | 
			
		||||
  - ./test/rubocops/conflicts_spec.rb
 | 
			
		||||
  - ./test/rubocops/dependency_order_spec.rb
 | 
			
		||||
  - ./test/rubocops/deprecate_spec.rb
 | 
			
		||||
  - ./test/rubocops/formula_desc_spec.rb
 | 
			
		||||
  - ./test/rubocops/homepage_spec.rb
 | 
			
		||||
  - ./test/rubocops/lines_spec.rb
 | 
			
		||||
@ -884,6 +885,7 @@ true:
 | 
			
		||||
  - ./rubocops/cask/ast/stanza.rb
 | 
			
		||||
  - ./rubocops/cask/constants/stanza.rb
 | 
			
		||||
  - ./rubocops/cask/extend/string.rb
 | 
			
		||||
  - ./rubocops/deprecate.rb
 | 
			
		||||
  - ./tap_constants.rb
 | 
			
		||||
  - ./test/support/helper/fixtures.rb
 | 
			
		||||
  - ./test/support/lib/config.rb
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
# This file is autogenerated. Do not edit it by hand. Regenerate it with:
 | 
			
		||||
#   tapioca sync
 | 
			
		||||
#   tapioca sync --exclude json
 | 
			
		||||
 | 
			
		||||
# typed: true
 | 
			
		||||
 | 
			
		||||
@ -344,6 +344,28 @@ class RuboCop::AST::IfNode < ::RuboCop::AST::Node
 | 
			
		||||
  def unless?; end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
class RuboCop::AST::IndexNode < ::RuboCop::AST::Node
 | 
			
		||||
  include(::RuboCop::AST::ParameterizedNode)
 | 
			
		||||
  include(::RuboCop::AST::MethodIdentifierPredicates)
 | 
			
		||||
  include(::RuboCop::AST::MethodDispatchNode)
 | 
			
		||||
 | 
			
		||||
  def arguments; end
 | 
			
		||||
  def assignment_method?; end
 | 
			
		||||
  def attribute_accessor?; end
 | 
			
		||||
  def method_name; end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
class RuboCop::AST::IndexasgnNode < ::RuboCop::AST::Node
 | 
			
		||||
  include(::RuboCop::AST::ParameterizedNode)
 | 
			
		||||
  include(::RuboCop::AST::MethodIdentifierPredicates)
 | 
			
		||||
  include(::RuboCop::AST::MethodDispatchNode)
 | 
			
		||||
 | 
			
		||||
  def arguments; end
 | 
			
		||||
  def assignment_method?; end
 | 
			
		||||
  def attribute_accessor?; end
 | 
			
		||||
  def method_name; end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
class RuboCop::AST::IntNode < ::RuboCop::AST::Node
 | 
			
		||||
  include(::RuboCop::AST::NumericNode)
 | 
			
		||||
end
 | 
			
		||||
@ -359,6 +381,19 @@ end
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::KeywordSplatNode::DOUBLE_SPLAT = T.let(T.unsafe(nil), String)
 | 
			
		||||
 | 
			
		||||
class RuboCop::AST::LambdaNode < ::RuboCop::AST::Node
 | 
			
		||||
  include(::RuboCop::AST::ParameterizedNode)
 | 
			
		||||
  include(::RuboCop::AST::MethodIdentifierPredicates)
 | 
			
		||||
  include(::RuboCop::AST::MethodDispatchNode)
 | 
			
		||||
 | 
			
		||||
  def arguments; end
 | 
			
		||||
  def assignment_method?; end
 | 
			
		||||
  def attribute_accessor?; end
 | 
			
		||||
  def lambda?; end
 | 
			
		||||
  def lambda_literal?; end
 | 
			
		||||
  def method_name; end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
module RuboCop::AST::MethodDispatchNode
 | 
			
		||||
  include(::RuboCop::AST::MethodIdentifierPredicates)
 | 
			
		||||
  extend(::RuboCop::AST::NodePattern::Macros)
 | 
			
		||||
@ -409,9 +444,16 @@ module RuboCop::AST::MethodIdentifierPredicates
 | 
			
		||||
  def camel_case_method?; end
 | 
			
		||||
  def comparison_method?; end
 | 
			
		||||
  def const_receiver?; end
 | 
			
		||||
  def enumerable_method?; end
 | 
			
		||||
  def enumerator_method?; end
 | 
			
		||||
  def method?(name); end
 | 
			
		||||
  def negation_method?; end
 | 
			
		||||
  def nonmutating_array_method?; end
 | 
			
		||||
  def nonmutating_binary_operator_method?; end
 | 
			
		||||
  def nonmutating_hash_method?; end
 | 
			
		||||
  def nonmutating_operator_method?; end
 | 
			
		||||
  def nonmutating_string_method?; end
 | 
			
		||||
  def nonmutating_unary_operator_method?; end
 | 
			
		||||
  def operator_method?; end
 | 
			
		||||
  def predicate_method?; end
 | 
			
		||||
  def prefix_bang?; end
 | 
			
		||||
@ -419,9 +461,23 @@ module RuboCop::AST::MethodIdentifierPredicates
 | 
			
		||||
  def self_receiver?; end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::MethodIdentifierPredicates::ENUMERATOR_METHODS = T.let(T.unsafe(nil), Array)
 | 
			
		||||
RuboCop::AST::MethodIdentifierPredicates::ENUMERABLE_METHODS = T.let(T.unsafe(nil), Set)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::MethodIdentifierPredicates::OPERATOR_METHODS = T.let(T.unsafe(nil), Array)
 | 
			
		||||
RuboCop::AST::MethodIdentifierPredicates::ENUMERATOR_METHODS = T.let(T.unsafe(nil), Set)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::MethodIdentifierPredicates::NONMUTATING_ARRAY_METHODS = T.let(T.unsafe(nil), Set)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::MethodIdentifierPredicates::NONMUTATING_BINARY_OPERATOR_METHODS = T.let(T.unsafe(nil), Set)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::MethodIdentifierPredicates::NONMUTATING_HASH_METHODS = T.let(T.unsafe(nil), Set)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::MethodIdentifierPredicates::NONMUTATING_OPERATOR_METHODS = T.let(T.unsafe(nil), Set)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::MethodIdentifierPredicates::NONMUTATING_STRING_METHODS = T.let(T.unsafe(nil), Set)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::MethodIdentifierPredicates::NONMUTATING_UNARY_OPERATOR_METHODS = T.let(T.unsafe(nil), Set)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::MethodIdentifierPredicates::OPERATOR_METHODS = T.let(T.unsafe(nil), Set)
 | 
			
		||||
 | 
			
		||||
module RuboCop::AST::ModifierNode
 | 
			
		||||
  def modifier_form?; end
 | 
			
		||||
@ -450,6 +506,7 @@ class RuboCop::AST::Node < ::Parser::AST::Node
 | 
			
		||||
  def arg_type?; end
 | 
			
		||||
  def args_type?; end
 | 
			
		||||
  def argument?; end
 | 
			
		||||
  def argument_type?; end
 | 
			
		||||
  def array_pattern_type?; end
 | 
			
		||||
  def array_pattern_with_tail_type?; end
 | 
			
		||||
  def array_type?; end
 | 
			
		||||
@ -506,9 +563,11 @@ class RuboCop::AST::Node < ::Parser::AST::Node
 | 
			
		||||
  def erange_type?; end
 | 
			
		||||
  def false_type?; end
 | 
			
		||||
  def falsey_literal?; end
 | 
			
		||||
  def find_pattern_type?; end
 | 
			
		||||
  def first_line; end
 | 
			
		||||
  def float_type?; end
 | 
			
		||||
  def for_type?; end
 | 
			
		||||
  def forward_arg_type?; end
 | 
			
		||||
  def forward_args_type?; end
 | 
			
		||||
  def forwarded_args_type?; end
 | 
			
		||||
  def guard_clause?; end
 | 
			
		||||
@ -542,6 +601,7 @@ class RuboCop::AST::Node < ::Parser::AST::Node
 | 
			
		||||
  def last_line; end
 | 
			
		||||
  def line_count; end
 | 
			
		||||
  def literal?; end
 | 
			
		||||
  def loop_keyword?; end
 | 
			
		||||
  def lvar_type?; end
 | 
			
		||||
  def lvasgn_type?; end
 | 
			
		||||
  def masgn_type?; end
 | 
			
		||||
@ -582,6 +642,7 @@ class RuboCop::AST::Node < ::Parser::AST::Node
 | 
			
		||||
  def parent_module_name; end
 | 
			
		||||
  def parenthesized_call?; end
 | 
			
		||||
  def pin_type?; end
 | 
			
		||||
  def post_condition_loop?; end
 | 
			
		||||
  def postexe_type?; end
 | 
			
		||||
  def preexe_type?; end
 | 
			
		||||
  def proc?(node = _); end
 | 
			
		||||
@ -654,6 +715,8 @@ class RuboCop::AST::Node < ::Parser::AST::Node
 | 
			
		||||
  def while_until_value_used?; end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::Node::ARGUMENT_TYPES = T.let(T.unsafe(nil), Array)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::Node::ASSIGNMENTS = T.let(T.unsafe(nil), Array)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::Node::BASIC_CONDITIONALS = T.let(T.unsafe(nil), Array)
 | 
			
		||||
@ -676,10 +739,14 @@ RuboCop::AST::Node::KEYWORDS = T.let(T.unsafe(nil), Array)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::Node::LITERALS = T.let(T.unsafe(nil), Array)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::Node::LOOP_TYPES = T.let(T.unsafe(nil), Array)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::Node::MUTABLE_LITERALS = T.let(T.unsafe(nil), Array)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::Node::OPERATOR_KEYWORDS = T.let(T.unsafe(nil), Array)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::Node::POST_CONDITION_LOOP_TYPES = T.let(T.unsafe(nil), Array)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::Node::REFERENCES = T.let(T.unsafe(nil), Array)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::Node::SHORTHAND_ASSIGNMENTS = T.let(T.unsafe(nil), Array)
 | 
			
		||||
@ -697,7 +764,7 @@ class RuboCop::AST::NodePattern
 | 
			
		||||
  def eql?(other); end
 | 
			
		||||
  def marshal_dump; end
 | 
			
		||||
  def marshal_load(pattern); end
 | 
			
		||||
  def match(*args); end
 | 
			
		||||
  def match(*args, **rest); end
 | 
			
		||||
  def pattern; end
 | 
			
		||||
  def to_s; end
 | 
			
		||||
 | 
			
		||||
@ -708,12 +775,8 @@ class RuboCop::AST::NodePattern::Invalid < ::StandardError
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
module RuboCop::AST::NodePattern::Macros
 | 
			
		||||
  def def_node_matcher(method_name, pattern_str); end
 | 
			
		||||
  def def_node_search(method_name, pattern_str); end
 | 
			
		||||
  def node_search(method_name, compiler, on_match, prelude, called_from); end
 | 
			
		||||
  def node_search_all(method_name, compiler, called_from); end
 | 
			
		||||
  def node_search_body(method_name, trailing_params, prelude, match_code, on_match); end
 | 
			
		||||
  def node_search_first(method_name, compiler, called_from); end
 | 
			
		||||
  def def_node_matcher(method_name, pattern_str, **keyword_defaults); end
 | 
			
		||||
  def def_node_search(method_name, pattern_str, **keyword_defaults); end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
module RuboCop::AST::NumericNode
 | 
			
		||||
@ -825,8 +888,22 @@ end
 | 
			
		||||
 | 
			
		||||
class RuboCop::AST::RegexpNode < ::RuboCop::AST::Node
 | 
			
		||||
  def content; end
 | 
			
		||||
  def delimiter?(char); end
 | 
			
		||||
  def delimiters; end
 | 
			
		||||
  def extended?; end
 | 
			
		||||
  def ignore_case?; end
 | 
			
		||||
  def interpolation?; end
 | 
			
		||||
  def multiline_mode?; end
 | 
			
		||||
  def no_encoding?; end
 | 
			
		||||
  def percent_r_literal?; end
 | 
			
		||||
  def regopt; end
 | 
			
		||||
  def single_interpolation?; end
 | 
			
		||||
  def slash_literal?; end
 | 
			
		||||
  def to_regexp; end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
  def regopt_include?(option); end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::RegexpNode::OPTIONS = T.let(T.unsafe(nil), Hash)
 | 
			
		||||
@ -920,6 +997,7 @@ class RuboCop::AST::Token
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
module RuboCop::AST::Traversal
 | 
			
		||||
  def on___ENCODING__(node); end
 | 
			
		||||
  def on_alias(node); end
 | 
			
		||||
  def on_and(node); end
 | 
			
		||||
  def on_and_asgn(node); end
 | 
			
		||||
@ -958,6 +1036,7 @@ module RuboCop::AST::Traversal
 | 
			
		||||
  def on_false(node); end
 | 
			
		||||
  def on_float(node); end
 | 
			
		||||
  def on_for(node); end
 | 
			
		||||
  def on_forward_arg(node); end
 | 
			
		||||
  def on_forward_args(node); end
 | 
			
		||||
  def on_forwarded_args(node); end
 | 
			
		||||
  def on_gvar(node); end
 | 
			
		||||
@ -969,6 +1048,8 @@ module RuboCop::AST::Traversal
 | 
			
		||||
  def on_iflipflop(node); end
 | 
			
		||||
  def on_in_match(node); end
 | 
			
		||||
  def on_in_pattern(node); end
 | 
			
		||||
  def on_index(node); end
 | 
			
		||||
  def on_indexasgn(node); end
 | 
			
		||||
  def on_int(node); end
 | 
			
		||||
  def on_irange(node); end
 | 
			
		||||
  def on_ivar(node); end
 | 
			
		||||
@ -1005,6 +1086,7 @@ module RuboCop::AST::Traversal
 | 
			
		||||
  def on_pin(node); end
 | 
			
		||||
  def on_postexe(node); end
 | 
			
		||||
  def on_preexe(node); end
 | 
			
		||||
  def on_procarg0(node); end
 | 
			
		||||
  def on_rational(node); end
 | 
			
		||||
  def on_redo(node); end
 | 
			
		||||
  def on_regexp(node); end
 | 
			
		||||
@ -1095,6 +1177,8 @@ RuboCop::AST::NodePattern::Compiler::CAPTURED_REST = T.let(T.unsafe(nil), String
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::NodePattern::Compiler::CLOSING = T.let(T.unsafe(nil), Regexp)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::NodePattern::Compiler::CONST = T.let(T.unsafe(nil), Regexp)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::NodePattern::Compiler::CUR_ELEMENT = T.let(T.unsafe(nil), String)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::NodePattern::Compiler::CUR_NODE = T.let(T.unsafe(nil), String)
 | 
			
		||||
@ -1105,6 +1189,10 @@ RuboCop::AST::NodePattern::Compiler::FUNCALL = T.let(T.unsafe(nil), Regexp)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::NodePattern::Compiler::IDENTIFIER = T.let(T.unsafe(nil), Regexp)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::NodePattern::Compiler::KEYWORD = T.let(T.unsafe(nil), Regexp)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::NodePattern::Compiler::KEYWORD_NAME = T.let(T.unsafe(nil), Regexp)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::NodePattern::Compiler::LITERAL = T.let(T.unsafe(nil), Regexp)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::NodePattern::Compiler::META = T.let(T.unsafe(nil), Regexp)
 | 
			
		||||
@ -1117,6 +1205,8 @@ RuboCop::AST::NodePattern::Compiler::NUMBER = T.let(T.unsafe(nil), Regexp)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::NodePattern::Compiler::PARAM = T.let(T.unsafe(nil), Regexp)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::NodePattern::Compiler::PARAM_CONST = T.let(T.unsafe(nil), Regexp)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::NodePattern::Compiler::PARAM_NUMBER = T.let(T.unsafe(nil), Regexp)
 | 
			
		||||
 | 
			
		||||
RuboCop::AST::NodePattern::Compiler::PREDICATE = T.let(T.unsafe(nil), Regexp)
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
# This file is autogenerated. Do not edit it by hand. Regenerate it with:
 | 
			
		||||
#   tapioca sync
 | 
			
		||||
#   tapioca sync --exclude json
 | 
			
		||||
 | 
			
		||||
# typed: true
 | 
			
		||||
 | 
			
		||||
@ -19429,10 +19429,6 @@ class RuboCop::AST::Node
 | 
			
		||||
 | 
			
		||||
  def cask_block?(node=T.unsafe(nil)); end
 | 
			
		||||
 | 
			
		||||
  def find_pattern_type?(); end
 | 
			
		||||
 | 
			
		||||
  def forward_arg_type?(); end
 | 
			
		||||
 | 
			
		||||
  def key_node(node=T.unsafe(nil)); end
 | 
			
		||||
 | 
			
		||||
  def method_node(node=T.unsafe(nil)); end
 | 
			
		||||
@ -19604,6 +19600,10 @@ class RuboCop::Cop::FormulaAudit::Miscellaneous
 | 
			
		||||
  def languageNodeModule?(node0); end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
class RuboCop::Cop::FormulaAudit::Patches
 | 
			
		||||
  def patch_data?(node0); end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
class RuboCop::Cop::FormulaAudit::Test
 | 
			
		||||
  def test_calls(node0); end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@ -71,9 +71,82 @@ describe Cask::Cmd::Upgrade, :cask do
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'updates "auto_updates" and "latest" Casks when their tokens are provided in the command line' do
 | 
			
		||||
        local_caffeine = Cask::CaskLoader.load("local-caffeine")
 | 
			
		||||
        local_caffeine_path = Cask::Config.global.appdir.join("Caffeine.app")
 | 
			
		||||
        auto_updates = Cask::CaskLoader.load("auto-updates")
 | 
			
		||||
        auto_updates_path = Cask::Config.global.appdir.join("MyFancyApp.app")
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.57")
 | 
			
		||||
 | 
			
		||||
        described_class.run("local-caffeine", "auto-updates")
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.3")
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.61")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe "with --greedy it checks additional Casks" do
 | 
			
		||||
      it 'includes the Casks with "auto_updates true" or "version latest"' do
 | 
			
		||||
        local_caffeine = Cask::CaskLoader.load("local-caffeine")
 | 
			
		||||
        local_caffeine_path = Cask::Config.global.appdir.join("Caffeine.app")
 | 
			
		||||
        auto_updates = Cask::CaskLoader.load("auto-updates")
 | 
			
		||||
        auto_updates_path = Cask::Config.global.appdir.join("MyFancyApp.app")
 | 
			
		||||
        local_transmission = Cask::CaskLoader.load("local-transmission")
 | 
			
		||||
        local_transmission_path = Cask::Config.global.appdir.join("Transmission.app")
 | 
			
		||||
        version_latest = Cask::CaskLoader.load("version-latest")
 | 
			
		||||
        version_latest_path_1 = Cask::Config.global.appdir.join("Caffeine Mini.app")
 | 
			
		||||
        version_latest_path_2 = Cask::Config.global.appdir.join("Caffeine Pro.app")
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.57")
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
 | 
			
		||||
        expect(version_latest).to be_installed
 | 
			
		||||
        expect(version_latest_path_1).to be_a_directory
 | 
			
		||||
        expect(version_latest_path_2).to be_a_directory
 | 
			
		||||
        expect(version_latest.versions).to include("latest")
 | 
			
		||||
 | 
			
		||||
        described_class.run("--greedy")
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.3")
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.61")
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.61")
 | 
			
		||||
 | 
			
		||||
        expect(version_latest).to be_installed
 | 
			
		||||
        expect(version_latest_path_1).to be_a_directory
 | 
			
		||||
        expect(version_latest_path_2).to be_a_directory
 | 
			
		||||
        expect(version_latest.versions).to include("latest")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'does not include the Casks with "auto_updates true" when the version did not change' do
 | 
			
		||||
        cask = Cask::CaskLoader.load("auto-updates")
 | 
			
		||||
        cask_path = cask.config.appdir.join("MyFancyApp.app")
 | 
			
		||||
@ -97,6 +170,179 @@ describe Cask::Cmd::Upgrade, :cask do
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  context "dry run upgrade" do
 | 
			
		||||
    let(:installed) {
 | 
			
		||||
      [
 | 
			
		||||
        "outdated/local-caffeine",
 | 
			
		||||
        "outdated/local-transmission",
 | 
			
		||||
        "outdated/auto-updates",
 | 
			
		||||
        "outdated/version-latest",
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    before do
 | 
			
		||||
      installed.each { |cask| Cask::Cmd::Install.run(cask) }
 | 
			
		||||
 | 
			
		||||
      allow_any_instance_of(described_class).to receive(:verbose?).and_return(true)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe 'without --greedy it ignores the Casks with "version latest" or "auto_updates true"' do
 | 
			
		||||
      it "would update all the installed Casks when no token is provided" do
 | 
			
		||||
        local_caffeine = Cask::CaskLoader.load("local-caffeine")
 | 
			
		||||
        local_caffeine_path = Cask::Config.global.appdir.join("Caffeine.app")
 | 
			
		||||
        local_transmission = Cask::CaskLoader.load("local-transmission")
 | 
			
		||||
        local_transmission_path = Cask::Config.global.appdir.join("Transmission.app")
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
 | 
			
		||||
        described_class.run("--dry-run")
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
        expect(local_caffeine.versions).not_to include("1.2.3")
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
        expect(local_transmission.versions).not_to include("2.61")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "would update only the Casks specified in the command line" do
 | 
			
		||||
        local_caffeine = Cask::CaskLoader.load("local-caffeine")
 | 
			
		||||
        local_caffeine_path = Cask::Config.global.appdir.join("Caffeine.app")
 | 
			
		||||
        local_transmission = Cask::CaskLoader.load("local-transmission")
 | 
			
		||||
        local_transmission_path = Cask::Config.global.appdir.join("Transmission.app")
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
 | 
			
		||||
        described_class.run("--dry-run", "local-caffeine")
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
        expect(local_caffeine.versions).not_to include("1.2.3")
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
        expect(local_transmission.versions).not_to include("2.61")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'would update "auto_updates" and "latest" Casks when their tokens are provided in the command line' do
 | 
			
		||||
        local_caffeine = Cask::CaskLoader.load("local-caffeine")
 | 
			
		||||
        local_caffeine_path = Cask::Config.global.appdir.join("Caffeine.app")
 | 
			
		||||
        auto_updates = Cask::CaskLoader.load("auto-updates")
 | 
			
		||||
        auto_updates_path = Cask::Config.global.appdir.join("MyFancyApp.app")
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.57")
 | 
			
		||||
 | 
			
		||||
        described_class.run("--dry-run", "local-caffeine", "auto-updates")
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
        expect(local_caffeine.versions).not_to include("1.2.3")
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.57")
 | 
			
		||||
        expect(auto_updates.versions).not_to include("2.61")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe "with --greedy it checks additional Casks" do
 | 
			
		||||
      it 'would include the Casks with "auto_updates true" or "version latest"' do
 | 
			
		||||
        local_caffeine = Cask::CaskLoader.load("local-caffeine")
 | 
			
		||||
        local_caffeine_path = Cask::Config.global.appdir.join("Caffeine.app")
 | 
			
		||||
        auto_updates = Cask::CaskLoader.load("auto-updates")
 | 
			
		||||
        auto_updates_path = Cask::Config.global.appdir.join("MyFancyApp.app")
 | 
			
		||||
        local_transmission = Cask::CaskLoader.load("local-transmission")
 | 
			
		||||
        local_transmission_path = Cask::Config.global.appdir.join("Transmission.app")
 | 
			
		||||
        version_latest = Cask::CaskLoader.load("version-latest")
 | 
			
		||||
        version_latest_path_1 = Cask::Config.global.appdir.join("Caffeine Mini.app")
 | 
			
		||||
        version_latest_path_2 = Cask::Config.global.appdir.join("Caffeine Pro.app")
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.57")
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
 | 
			
		||||
        expect(version_latest).to be_installed
 | 
			
		||||
        expect(version_latest_path_1).to be_a_directory
 | 
			
		||||
        expect(version_latest.versions).to include("latest")
 | 
			
		||||
 | 
			
		||||
        described_class.run("--greedy", "--dry-run")
 | 
			
		||||
 | 
			
		||||
        expect(local_caffeine).to be_installed
 | 
			
		||||
        expect(local_caffeine_path).to be_a_directory
 | 
			
		||||
        expect(local_caffeine.versions).to include("1.2.2")
 | 
			
		||||
        expect(local_caffeine.versions).not_to include("1.2.3")
 | 
			
		||||
 | 
			
		||||
        expect(auto_updates).to be_installed
 | 
			
		||||
        expect(auto_updates_path).to be_a_directory
 | 
			
		||||
        expect(auto_updates.versions).to include("2.57")
 | 
			
		||||
        expect(auto_updates.versions).not_to include("2.61")
 | 
			
		||||
 | 
			
		||||
        expect(local_transmission).to be_installed
 | 
			
		||||
        expect(local_transmission_path).to be_a_directory
 | 
			
		||||
        expect(local_transmission.versions).to include("2.60")
 | 
			
		||||
        expect(local_transmission.versions).not_to include("2.61")
 | 
			
		||||
 | 
			
		||||
        expect(version_latest).to be_installed
 | 
			
		||||
        expect(version_latest_path_2).to be_a_directory
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it 'does not include the Casks with "auto_updates true" when the version did not change' do
 | 
			
		||||
        cask = Cask::CaskLoader.load("auto-updates")
 | 
			
		||||
        cask_path = cask.config.appdir.join("MyFancyApp.app")
 | 
			
		||||
 | 
			
		||||
        expect(cask).to be_installed
 | 
			
		||||
        expect(cask_path).to be_a_directory
 | 
			
		||||
        expect(cask.versions).to include("2.57")
 | 
			
		||||
 | 
			
		||||
        described_class.run("--dry-run", "auto-updates", "--greedy")
 | 
			
		||||
 | 
			
		||||
        expect(cask).to be_installed
 | 
			
		||||
        expect(cask_path).to be_a_directory
 | 
			
		||||
        expect(cask.versions).to include("2.57")
 | 
			
		||||
        expect(cask.versions).not_to include("2.61")
 | 
			
		||||
 | 
			
		||||
        described_class.run("--dry-run", "auto-updates", "--greedy")
 | 
			
		||||
 | 
			
		||||
        expect(cask).to be_installed
 | 
			
		||||
        expect(cask_path).to be_a_directory
 | 
			
		||||
        expect(cask.versions).to include("2.57")
 | 
			
		||||
        expect(cask.versions).not_to include("2.61")
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  context "failed upgrade" do
 | 
			
		||||
    let(:installed) {
 | 
			
		||||
      [
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,34 @@ describe Cask::Pkg, :cask do
 | 
			
		||||
    let(:empty_response) { double(stdout: "", plist: { "volume" => "/", "install-location" => "", "paths" => {} }) }
 | 
			
		||||
    let(:pkg) { described_class.new("my.fake.pkg", fake_system_command) }
 | 
			
		||||
 | 
			
		||||
    it "removes files and dirs referenced by the pkg" do
 | 
			
		||||
      some_files = Array.new(3) { Pathname.new(Tempfile.new("plain_file").path) }
 | 
			
		||||
      allow(pkg).to receive(:pkgutil_bom_files).and_return(some_files)
 | 
			
		||||
 | 
			
		||||
      some_specials = Array.new(3) { Pathname.new(Tempfile.new("special_file").path) }
 | 
			
		||||
      allow(pkg).to receive(:pkgutil_bom_specials).and_return(some_specials)
 | 
			
		||||
 | 
			
		||||
      some_dirs = Array.new(3) { mktmpdir }
 | 
			
		||||
      allow(pkg).to receive(:pkgutil_bom_dirs).and_return(some_dirs)
 | 
			
		||||
 | 
			
		||||
      root_dir = Pathname.new(mktmpdir)
 | 
			
		||||
      allow(pkg).to receive(:root).and_return(root_dir)
 | 
			
		||||
 | 
			
		||||
      allow(pkg).to receive(:forget)
 | 
			
		||||
 | 
			
		||||
      pkg.uninstall
 | 
			
		||||
 | 
			
		||||
      some_files.each do |file|
 | 
			
		||||
        expect(file).not_to exist
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      some_dirs.each do |dir|
 | 
			
		||||
        expect(dir).not_to exist
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      expect(root_dir).not_to exist
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context "pkgutil" do
 | 
			
		||||
      it "forgets the pkg" do
 | 
			
		||||
        allow(fake_system_command).to receive(:run!).with(
 | 
			
		||||
 | 
			
		||||
@ -41,8 +41,6 @@ module Homebrew
 | 
			
		||||
        url "https://www.brew.sh/valid-1.0.tar.gz"
 | 
			
		||||
      RUBY
 | 
			
		||||
 | 
			
		||||
      expect(ft).not_to have_data
 | 
			
		||||
      expect(ft).not_to have_end
 | 
			
		||||
      expect(ft).to have_trailing_newline
 | 
			
		||||
 | 
			
		||||
      expect(ft =~ /\burl\b/).to be_truthy
 | 
			
		||||
@ -55,20 +53,6 @@ module Homebrew
 | 
			
		||||
      ft = formula_text "newline"
 | 
			
		||||
      expect(ft).to have_trailing_newline
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    specify "#data?" do
 | 
			
		||||
      ft = formula_text "data", <<~RUBY
 | 
			
		||||
        patch :DATA
 | 
			
		||||
      RUBY
 | 
			
		||||
 | 
			
		||||
      expect(ft).to have_data
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    specify "#end?" do
 | 
			
		||||
      ft = formula_text "end", "", patch: "__END__\na patch here"
 | 
			
		||||
      expect(ft).to have_end
 | 
			
		||||
      expect(ft.without_patch).to eq("class End < Formula\n  \nend")
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe FormulaAuditor do
 | 
			
		||||
@ -96,31 +80,6 @@ module Homebrew
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    describe "#audit_file" do
 | 
			
		||||
      specify "DATA but no __END__" do
 | 
			
		||||
        fa = formula_auditor "foo", <<~RUBY
 | 
			
		||||
          class Foo < Formula
 | 
			
		||||
            url "https://brew.sh/foo-1.0.tgz"
 | 
			
		||||
            patch :DATA
 | 
			
		||||
          end
 | 
			
		||||
        RUBY
 | 
			
		||||
 | 
			
		||||
        fa.audit_file
 | 
			
		||||
        expect(fa.problems).to eq(["'DATA' was found, but no '__END__'"])
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      specify "__END__ but no DATA" do
 | 
			
		||||
        fa = formula_auditor "foo", <<~RUBY
 | 
			
		||||
          class Foo < Formula
 | 
			
		||||
            url "https://brew.sh/foo-1.0.tgz"
 | 
			
		||||
          end
 | 
			
		||||
          __END__
 | 
			
		||||
          a patch goes here
 | 
			
		||||
        RUBY
 | 
			
		||||
 | 
			
		||||
        fa.audit_file
 | 
			
		||||
        expect(fa.problems).to eq(["'__END__' was found, but 'DATA' is not used"])
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      specify "no issue" do
 | 
			
		||||
        fa = formula_auditor "foo", <<~RUBY
 | 
			
		||||
          class Foo < Formula
 | 
			
		||||
 | 
			
		||||
@ -77,6 +77,37 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
 | 
			
		||||
      RUBY
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "When `install` precedes `depends_on`" do
 | 
			
		||||
      expect_offense(<<~RUBY)
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          url "https://brew.sh/foo-1.0.tgz"
 | 
			
		||||
 | 
			
		||||
          def install
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          depends_on "openssl"
 | 
			
		||||
          ^^^^^^^^^^^^^^^^^^^^ `depends_on` (line 7) should be put before `install` (line 4)
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "When `test` precedes `depends_on`" do
 | 
			
		||||
      expect_offense(<<~RUBY)
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          url "https://brew.sh/foo-1.0.tgz"
 | 
			
		||||
 | 
			
		||||
          def install
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          def test
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          depends_on "openssl"
 | 
			
		||||
          ^^^^^^^^^^^^^^^^^^^^ `depends_on` (line 10) should be put before `install` (line 4)
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "When only one of many `depends_on` precedes `conflicts_with`" do
 | 
			
		||||
      expect_offense(<<~RUBY)
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										56
									
								
								Library/Homebrew/test/rubocops/deprecate_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								Library/Homebrew/test/rubocops/deprecate_spec.rb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
require "rubocops/deprecate"
 | 
			
		||||
 | 
			
		||||
describe RuboCop::Cop::FormulaAudit::Deprecate do
 | 
			
		||||
  subject(:cop) { described_class.new }
 | 
			
		||||
 | 
			
		||||
  context "When auditing formula for deprecate!" do
 | 
			
		||||
    it "deprecation date is not ISO 8601 compliant" do
 | 
			
		||||
      expect_offense(<<~RUBY)
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          url 'https://brew.sh/foo-1.0.tgz'
 | 
			
		||||
          deprecate! :date => "June 25, 2020"
 | 
			
		||||
                              ^^^^^^^^^^^^^^^ Use `2020-06-25` to comply with ISO 8601
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "deprecation date is ISO 8601 compliant" do
 | 
			
		||||
      expect_no_offenses(<<~RUBY)
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          url 'https://brew.sh/foo-1.0.tgz'
 | 
			
		||||
          deprecate! :date => "2020-06-25"
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "no deprecation date" do
 | 
			
		||||
      expect_no_offenses(<<~RUBY)
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          url 'https://brew.sh/foo-1.0.tgz'
 | 
			
		||||
          deprecate!
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "auto corrects to ISO 8601 format" do
 | 
			
		||||
      source = <<~RUBY
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          url 'https://brew.sh/foo-1.0.tgz'
 | 
			
		||||
          deprecate! :date => "June 25, 2020"
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
 | 
			
		||||
      corrected_source = <<~RUBY
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          url 'https://brew.sh/foo-1.0.tgz'
 | 
			
		||||
          deprecate! :date => "2020-06-25"
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
 | 
			
		||||
      new_source = autocorrect_source(source)
 | 
			
		||||
      expect(new_source).to eq(corrected_source)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
@ -345,10 +345,10 @@ describe RuboCop::Cop::FormulaAudit::MpiCheck do
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
describe RuboCop::Cop::FormulaAudit::ShellCmd do
 | 
			
		||||
describe RuboCop::Cop::FormulaAudit::SafePopenCommands do
 | 
			
		||||
  subject(:cop) { described_class.new }
 | 
			
		||||
 | 
			
		||||
  context "When auditing shell commands" do
 | 
			
		||||
  context "When auditing popen commands" do
 | 
			
		||||
    it "Utils.popen_read should become Utils.safe_popen_read" do
 | 
			
		||||
      expect_offense(<<~RUBY)
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
@ -440,6 +440,140 @@ describe RuboCop::Cop::FormulaAudit::ShellCmd do
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
describe RuboCop::Cop::FormulaAudit::ShellVariables do
 | 
			
		||||
  subject(:cop) { described_class.new }
 | 
			
		||||
 | 
			
		||||
  context "When auditing shell variables" do
 | 
			
		||||
    it "Shell variables should be expanded in Utils.popen" do
 | 
			
		||||
      expect_offense(<<~RUBY)
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          def install
 | 
			
		||||
            Utils.popen "SHELL=bash foo"
 | 
			
		||||
                         ^^^^^^^^^^^^^^ Use `Utils.popen({ "SHELL" => "bash" }, "foo")` instead of `Utils.popen "SHELL=bash foo"`
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "Shell variables should be expanded in Utils.safe_popen_read" do
 | 
			
		||||
      expect_offense(<<~RUBY)
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          def install
 | 
			
		||||
            Utils.safe_popen_read "SHELL=bash foo"
 | 
			
		||||
                                   ^^^^^^^^^^^^^^ Use `Utils.safe_popen_read({ "SHELL" => "bash" }, "foo")` instead of `Utils.safe_popen_read "SHELL=bash foo"`
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "Shell variables should be expanded in Utils.safe_popen_write" do
 | 
			
		||||
      expect_offense(<<~RUBY)
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          def install
 | 
			
		||||
            Utils.safe_popen_write "SHELL=bash foo"
 | 
			
		||||
                                    ^^^^^^^^^^^^^^ Use `Utils.safe_popen_write({ "SHELL" => "bash" }, "foo")` instead of `Utils.safe_popen_write "SHELL=bash foo"`
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "Shell variables should be expanded and keep inline string variables in the arguments" do
 | 
			
		||||
      expect_offense(<<~RUBY)
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          def install
 | 
			
		||||
            Utils.popen "SHELL=bash \#{bin}/foo"
 | 
			
		||||
                         ^^^^^^^^^^^^^^^^^^^^^ Use `Utils.popen({ "SHELL" => "bash" }, "\#{bin}/foo")` instead of `Utils.popen "SHELL=bash \#{bin}/foo"`
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "corrects shell variables in Utils.popen" do
 | 
			
		||||
      source = <<~RUBY
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          def install
 | 
			
		||||
            Utils.popen("SHELL=bash foo")
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
 | 
			
		||||
      corrected_source = <<~RUBY
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          def install
 | 
			
		||||
            Utils.popen({ "SHELL" => "bash" }, "foo")
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
 | 
			
		||||
      new_source = autocorrect_source(source)
 | 
			
		||||
      expect(new_source).to eq(corrected_source)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "corrects shell variables in Utils.safe_popen_read" do
 | 
			
		||||
      source = <<~RUBY
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          def install
 | 
			
		||||
            Utils.safe_popen_read("SHELL=bash foo")
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
 | 
			
		||||
      corrected_source = <<~RUBY
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          def install
 | 
			
		||||
            Utils.safe_popen_read({ "SHELL" => "bash" }, "foo")
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
 | 
			
		||||
      new_source = autocorrect_source(source)
 | 
			
		||||
      expect(new_source).to eq(corrected_source)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "corrects shell variables in Utils.safe_popen_write" do
 | 
			
		||||
      source = <<~RUBY
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          def install
 | 
			
		||||
            Utils.safe_popen_write("SHELL=bash foo")
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
 | 
			
		||||
      corrected_source = <<~RUBY
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          def install
 | 
			
		||||
            Utils.safe_popen_write({ "SHELL" => "bash" }, "foo")
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
 | 
			
		||||
      new_source = autocorrect_source(source)
 | 
			
		||||
      expect(new_source).to eq(corrected_source)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "corrects shell variables with inline string variable in arguments" do
 | 
			
		||||
      source = <<~RUBY
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          def install
 | 
			
		||||
            Utils.popen("SHELL=bash \#{bin}/foo")
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
 | 
			
		||||
      corrected_source = <<~RUBY
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          def install
 | 
			
		||||
            Utils.popen({ "SHELL" => "bash" }, "\#{bin}/foo")
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
 | 
			
		||||
      new_source = autocorrect_source(source)
 | 
			
		||||
      expect(new_source).to eq(corrected_source)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
describe RuboCop::Cop::FormulaAudit::Miscellaneous do
 | 
			
		||||
  subject(:cop) { described_class.new }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -163,6 +163,53 @@ describe RuboCop::Cop::FormulaAudit::Patches do
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  context "When auditing inline patches" do
 | 
			
		||||
    it "reports no offenses for valid inline patches" do
 | 
			
		||||
      expect_no_offenses(<<~RUBY)
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          url 'https://brew.sh/foo-1.0.tgz'
 | 
			
		||||
          patch :DATA
 | 
			
		||||
        end
 | 
			
		||||
        __END__
 | 
			
		||||
        patch content here
 | 
			
		||||
      RUBY
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "reports no offenses for valid nested inline patches" do
 | 
			
		||||
      expect_no_offenses(<<~RUBY)
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          url 'https://brew.sh/foo-1.0.tgz'
 | 
			
		||||
          stable do
 | 
			
		||||
            patch :DATA
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
        __END__
 | 
			
		||||
        patch content here
 | 
			
		||||
      RUBY
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "reports an offense when DATA is found with no __END__" do
 | 
			
		||||
      expect_offense(<<~RUBY)
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          url 'https://brew.sh/foo-1.0.tgz'
 | 
			
		||||
          patch :DATA
 | 
			
		||||
          ^^^^^^^^^^^ patch is missing '__END__'
 | 
			
		||||
        end
 | 
			
		||||
      RUBY
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "reports an offense when __END__ is found with no DATA" do
 | 
			
		||||
      expect_offense(<<~RUBY)
 | 
			
		||||
        class Foo < Formula
 | 
			
		||||
          url 'https://brew.sh/foo-1.0.tgz'
 | 
			
		||||
        end
 | 
			
		||||
        __END__
 | 
			
		||||
        ^^^^^^^ patch is missing 'DATA'
 | 
			
		||||
        patch content here
 | 
			
		||||
      RUBY
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  context "When auditing external patches" do
 | 
			
		||||
    it "Patch URLs" do
 | 
			
		||||
      patch_urls = [
 | 
			
		||||
 | 
			
		||||
@ -78,6 +78,17 @@ RSpec.configure do |config|
 | 
			
		||||
    c.max_formatted_output_length = 200
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Use rspec-retry in CI.
 | 
			
		||||
  if ENV["CI"]
 | 
			
		||||
    config.verbose_retry = true
 | 
			
		||||
    config.display_try_failure_messages = true
 | 
			
		||||
    config.default_retry_count = 2
 | 
			
		||||
 | 
			
		||||
    config.around(:each, :needs_network) do |example|
 | 
			
		||||
      example.run_with_retry retry: 3, retry_wait: 3
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Never truncate output objects.
 | 
			
		||||
  RSpec::Support::ObjectFormatter.default_instance.max_formatted_output_length = nil
 | 
			
		||||
 | 
			
		||||
@ -124,10 +135,6 @@ RSpec.configure do |config|
 | 
			
		||||
    skip "Requires network connection." unless ENV["HOMEBREW_TEST_ONLINE"]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  config.around(:each, :needs_network) do |example|
 | 
			
		||||
    example.run_with_retry retry: 3, retry_wait: 1
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  config.before(:each, :needs_svn) do
 | 
			
		||||
    skip "subversion not installed." unless quiet_system "#{HOMEBREW_SHIMS_PATH}/scm/svn", "--version"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -173,6 +173,16 @@ describe Version do
 | 
			
		||||
    expect(versions.sort_by { |v| described_class.create(v) }).to eq(versions)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "#empty?" do
 | 
			
		||||
    it "returns true if version is empty" do
 | 
			
		||||
      expect(described_class.create("").empty?).to eq(true)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "returns false if version is not empty" do
 | 
			
		||||
      expect(described_class.create("1.2.3").empty?).to eq(false)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  specify "hash equality" do
 | 
			
		||||
    v1 = described_class.create("0.1.0")
 | 
			
		||||
    v2 = described_class.create("0.1.0")
 | 
			
		||||
 | 
			
		||||
@ -293,10 +293,8 @@ module GitHub
 | 
			
		||||
    search("code", **qualifiers)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def issues_for_formula(name, options = {})
 | 
			
		||||
    tap = options[:tap] || CoreTap.instance
 | 
			
		||||
    tap_full_name = options[:tap_full_name] || tap.full_name
 | 
			
		||||
    search_issues(name, state: "open", repo: tap_full_name, in: "title")
 | 
			
		||||
  def issues_for_formula(name, tap: CoreTap.instance, tap_full_name: tap.full_name, state: nil)
 | 
			
		||||
    search_issues(name, repo: tap_full_name, state: state, in: "title")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def user
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/i18n-1.8.3/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/minitest-5.14.1/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/thread_safe-0.3.6/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/tzinfo-1.2.7/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/zeitwerk-2.3.0/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/zeitwerk-2.3.1/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/activesupport-6.0.3.2/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ast-2.4.1/lib"
 | 
			
		||||
$:.unshift "#{path}/"
 | 
			
		||||
@ -25,7 +25,7 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/tins-1.25.0/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/term-ansicolor-1.7.1/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/thor-1.0.1/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/coveralls-0.8.23/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/diff-lcs-1.3/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/diff-lcs-1.4.2/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwin-19/2.6.0/unf_ext-0.0.7.7"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unf_ext-0.0.7.7/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unf-0.1.4/lib"
 | 
			
		||||
@ -62,7 +62,7 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-3.9.0/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-its-1.3.0/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-retry-0.6.2/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-wait-0.0.9/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-ast-0.0.3/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-ast-0.1.0/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-progressbar-1.10.1/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unicode-display_width-1.7.0/lib"
 | 
			
		||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-0.86.0/lib"
 | 
			
		||||
 | 
			
		||||
@ -1,33 +0,0 @@
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
module Kernel
 | 
			
		||||
  module_function
 | 
			
		||||
 | 
			
		||||
  # We cannot decorate with prepend + super because Kernel has already been
 | 
			
		||||
  # included in Object, and changes in ancestors don't get propagated into
 | 
			
		||||
  # already existing ancestor chains.
 | 
			
		||||
  alias_method :zeitwerk_original_require, :require
 | 
			
		||||
 | 
			
		||||
  # @param path [String]
 | 
			
		||||
  # @return [Boolean]
 | 
			
		||||
  def require(path)
 | 
			
		||||
    if loader = Zeitwerk::Registry.loader_for(path)
 | 
			
		||||
      if path.end_with?(".rb")
 | 
			
		||||
        zeitwerk_original_require(path).tap do |required|
 | 
			
		||||
          loader.on_file_autoloaded(path) if required
 | 
			
		||||
        end
 | 
			
		||||
      else
 | 
			
		||||
        loader.on_dir_autoloaded(path)
 | 
			
		||||
      end
 | 
			
		||||
    else
 | 
			
		||||
      zeitwerk_original_require(path).tap do |required|
 | 
			
		||||
        if required
 | 
			
		||||
          realpath = $LOADED_FEATURES.last
 | 
			
		||||
          if loader = Zeitwerk::Registry.loader_for(realpath)
 | 
			
		||||
            loader.on_file_autoloaded(realpath)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										64
									
								
								Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.3.1/lib/zeitwerk/kernel.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.3.1/lib/zeitwerk/kernel.rb
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,64 @@
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
module Kernel
 | 
			
		||||
  module_function
 | 
			
		||||
 | 
			
		||||
  # We are going to decorate Kerner#require with two goals.
 | 
			
		||||
  #
 | 
			
		||||
  # First, by intercepting Kernel#require calls, we are able to autovivify
 | 
			
		||||
  # modules on required directories, and also do internal housekeeping when
 | 
			
		||||
  # managed files are loaded.
 | 
			
		||||
  #
 | 
			
		||||
  # On the other hand, if you publish a new version of a gem that is now managed
 | 
			
		||||
  # by Zeitwerk, client code can reference directly your classes and modules and
 | 
			
		||||
  # should not require anything. But if someone has legacy require calls around,
 | 
			
		||||
  # they will work as expected, and in a compatible way.
 | 
			
		||||
  #
 | 
			
		||||
  # We cannot decorate with prepend + super because Kernel has already been
 | 
			
		||||
  # included in Object, and changes in ancestors don't get propagated into
 | 
			
		||||
  # already existing ancestor chains.
 | 
			
		||||
  alias_method :zeitwerk_original_require, :require
 | 
			
		||||
 | 
			
		||||
  # @param path [String]
 | 
			
		||||
  # @return [Boolean]
 | 
			
		||||
  def require(path)
 | 
			
		||||
    if loader = Zeitwerk::Registry.loader_for(path)
 | 
			
		||||
      if path.end_with?(".rb")
 | 
			
		||||
        zeitwerk_original_require(path).tap do |required|
 | 
			
		||||
          loader.on_file_autoloaded(path) if required
 | 
			
		||||
        end
 | 
			
		||||
      else
 | 
			
		||||
        loader.on_dir_autoloaded(path)
 | 
			
		||||
      end
 | 
			
		||||
    else
 | 
			
		||||
      zeitwerk_original_require(path).tap do |required|
 | 
			
		||||
        if required
 | 
			
		||||
          realpath = $LOADED_FEATURES.last
 | 
			
		||||
          if loader = Zeitwerk::Registry.loader_for(realpath)
 | 
			
		||||
            loader.on_file_autoloaded(realpath)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # By now, I have seen no way so far to decorate require_relative.
 | 
			
		||||
  #
 | 
			
		||||
  # For starters, at least in CRuby, require_relative does not delegate to
 | 
			
		||||
  # require. Both require and require_relative delegate the bulk of their work
 | 
			
		||||
  # to an internal C function called rb_require_safe. So, our require wrapper is
 | 
			
		||||
  # not executed.
 | 
			
		||||
  #
 | 
			
		||||
  # On the other hand, we cannot use the aliasing technique above because
 | 
			
		||||
  # require_relative receives a path relative to the directory of the file in
 | 
			
		||||
  # which the call is performed. If a wrapper here invoked the original method,
 | 
			
		||||
  # Ruby would resolve the relative path taking lib/zeitwerk as base directory.
 | 
			
		||||
  #
 | 
			
		||||
  # A workaround could be to extract the base directory from caller_locations,
 | 
			
		||||
  # but what if someone else decorated require_relative before us? You can't
 | 
			
		||||
  # really know with certainty where's the original call site in the stack.
 | 
			
		||||
  #
 | 
			
		||||
  # However, the main use case for require_relative is to load files from your
 | 
			
		||||
  # own project. Projects managed by Zeitwerk don't do this for files managed by
 | 
			
		||||
  # Zeitwerk, precisely.
 | 
			
		||||
end
 | 
			
		||||
@ -464,7 +464,7 @@ module Zeitwerk
 | 
			
		||||
      #   require "zeitwerk"
 | 
			
		||||
      #   loader = Zeitwerk::Loader.new
 | 
			
		||||
      #   loader.tag = File.basename(__FILE__, ".rb")
 | 
			
		||||
      #   loader.inflector = Zeitwerk::GemInflector.new
 | 
			
		||||
      #   loader.inflector = Zeitwerk::GemInflector.new(__FILE__)
 | 
			
		||||
      #   loader.push_dir(__dir__)
 | 
			
		||||
      #
 | 
			
		||||
      # except that this method returns the same object in subsequent calls from
 | 
			
		||||
@ -616,7 +616,10 @@ module Zeitwerk
 | 
			
		||||
      # $LOADED_FEATURES stores real paths since Ruby 2.4.4. We set and save the
 | 
			
		||||
      # real path to be able to delete it from $LOADED_FEATURES on unload, and to
 | 
			
		||||
      # be able to do a lookup later in Kernel#require for manual require calls.
 | 
			
		||||
      realpath = File.realpath(abspath)
 | 
			
		||||
      #
 | 
			
		||||
      # We freeze realpath because that saves allocations in Module#autoload.
 | 
			
		||||
      # See #125.
 | 
			
		||||
      realpath = File.realpath(abspath).freeze
 | 
			
		||||
      parent.autoload(cname, realpath)
 | 
			
		||||
      if logger
 | 
			
		||||
        if ruby?(realpath)
 | 
			
		||||
@ -719,8 +722,13 @@ module Zeitwerk
 | 
			
		||||
    def ls(dir)
 | 
			
		||||
      Dir.foreach(dir) do |basename|
 | 
			
		||||
        next if basename.start_with?(".")
 | 
			
		||||
 | 
			
		||||
        abspath = File.join(dir, basename)
 | 
			
		||||
        yield basename, abspath unless ignored_paths.member?(abspath)
 | 
			
		||||
        next if ignored_paths.member?(abspath)
 | 
			
		||||
 | 
			
		||||
        # We freeze abspath because that saves allocations when passed later to
 | 
			
		||||
        # File methods. See #125.
 | 
			
		||||
        yield basename, abspath.freeze
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
module Zeitwerk
 | 
			
		||||
  VERSION = "2.3.0"
 | 
			
		||||
  VERSION = "2.3.1"
 | 
			
		||||
end
 | 
			
		||||
@ -429,6 +429,10 @@ class Version
 | 
			
		||||
  end
 | 
			
		||||
  alias eql? ==
 | 
			
		||||
 | 
			
		||||
  def empty?
 | 
			
		||||
    version.empty?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def hash
 | 
			
		||||
    version.hash
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@ -45,20 +45,19 @@ __brew_completion_caching_policy() {
 | 
			
		||||
  tmp=( $1(mw-2N) )
 | 
			
		||||
  (( $#tmp )) || return 0
 | 
			
		||||
 | 
			
		||||
  # otherwise, invalidate if latest tap index file is missing or newer than
 | 
			
		||||
  # cache file
 | 
			
		||||
  # otherwise, invalidate if latest tap index file is missing or newer than cache file
 | 
			
		||||
  tmp=( ${HOMEBREW_REPOSITORY:-/usr/local/Homebrew}/Library/Taps/*/*/.git/index(om[1]N) )
 | 
			
		||||
  [[ -z $tmp || $tmp -nt $1 ]]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__brew_formulae() {
 | 
			
		||||
  local -a formulae
 | 
			
		||||
  local -a list
 | 
			
		||||
  local comp_cachename=brew_formulae
 | 
			
		||||
  if _cache_invalid $comp_cachename || ! _retrieve_cache $comp_cachename; then
 | 
			
		||||
    formulae=($(brew search))
 | 
			
		||||
    _store_cache $comp_cachename formulae
 | 
			
		||||
  if ! _retrieve_cache $comp_cachename; then
 | 
			
		||||
    list=( $(brew search) )
 | 
			
		||||
    _store_cache $comp_cachename list
 | 
			
		||||
  fi
 | 
			
		||||
  _describe -t formulae 'all formulae' formulae
 | 
			
		||||
  _describe -t formulae 'all formulae' list
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__brew_installed_formulae() {
 | 
			
		||||
@ -145,18 +144,17 @@ __brew_common_commands() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__brew_all_commands() {
 | 
			
		||||
  local -a commands
 | 
			
		||||
  local -a list
 | 
			
		||||
  local comp_cachename=brew_all_commands
 | 
			
		||||
  if _cache_invalid $comp_cachename || ! _retrieve_cache $comp_cachename; then
 | 
			
		||||
    HOMEBREW_CACHE=$(brew --cache)
 | 
			
		||||
    HOMEBREW_REPOSITORY=$(brew --repo)
 | 
			
		||||
    [[ -f "$HOMEBREW_CACHE/all_commands_list.txt" ]] &&
 | 
			
		||||
      commands=($(cat "$HOMEBREW_CACHE/all_commands_list.txt")) ||
 | 
			
		||||
      commands=($(cat "$HOMEBREW_REPOSITORY/completions/internal_commands_list.txt"))
 | 
			
		||||
    commands=(${commands:#*instal}) # Exclude instal, uninstal, etc.
 | 
			
		||||
    _store_cache $comp_cachename commands
 | 
			
		||||
  if ! _retrieve_cache $comp_cachename; then
 | 
			
		||||
    local cache_dir=$(brew --cache)
 | 
			
		||||
    [[ -f $cache_dir/all_commands_list.txt ]] &&
 | 
			
		||||
      list=( $(<$cache_dir/all_commands_list.txt) ) ||
 | 
			
		||||
      list=( $(<$(brew --repo)/completions/internal_commands_list.txt) )
 | 
			
		||||
    list=( ${list:#*instal} ) # Exclude instal, uninstal, etc.
 | 
			
		||||
    _store_cache $comp_cachename list
 | 
			
		||||
  fi
 | 
			
		||||
  _describe -t all-commands 'all commands' commands
 | 
			
		||||
  _describe -t all-commands 'all commands' list
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__brew_commands() {
 | 
			
		||||
@ -857,10 +855,10 @@ _brew() {
 | 
			
		||||
  case "$state" in
 | 
			
		||||
    command)
 | 
			
		||||
      # set default cache policy
 | 
			
		||||
      zstyle -s ":completion:${curcontext%:*}:*" cache-policy tmp
 | 
			
		||||
      [[ -n $tmp ]] ||
 | 
			
		||||
      zstyle ":completion:${curcontext%:*}:*" cache-policy \
 | 
			
		||||
        __brew_completion_caching_policy
 | 
			
		||||
      zstyle -s ":completion:${curcontext%:*}:*" cache-policy tmp ||
 | 
			
		||||
         zstyle ":completion:${curcontext%:*}:*" cache-policy __brew_completion_caching_policy
 | 
			
		||||
      zstyle -s ":completion:${curcontext%:*}:*" use-cache tmp ||
 | 
			
		||||
         zstyle ":completion:${curcontext%:*}:*" use-cache true
 | 
			
		||||
 | 
			
		||||
      __brew_commands && return 0
 | 
			
		||||
      ;;
 | 
			
		||||
@ -878,10 +876,10 @@ _brew() {
 | 
			
		||||
 | 
			
		||||
      # set default cache policy (we repeat this dance because the context
 | 
			
		||||
      # service differs from above)
 | 
			
		||||
      zstyle -s ":completion:${curcontext%:*}:*" cache-policy tmp
 | 
			
		||||
      [[ -n $tmp ]] ||
 | 
			
		||||
      zstyle ":completion:${curcontext%:*}:*" cache-policy \
 | 
			
		||||
        __brew_completion_caching_policy
 | 
			
		||||
      zstyle -s ":completion:${curcontext%:*}:*" cache-policy tmp ||
 | 
			
		||||
         zstyle ":completion:${curcontext%:*}:*" cache-policy __brew_completion_caching_policy
 | 
			
		||||
      zstyle -s ":completion:${curcontext%:*}:*" use-cache tmp ||
 | 
			
		||||
         zstyle ":completion:${curcontext%:*}:*" use-cache true
 | 
			
		||||
 | 
			
		||||
      # call completion for named command e.g. _brew_list
 | 
			
		||||
      local completion_func="_brew_${command//-/_}"
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,7 @@ __brew_all_casks() {
 | 
			
		||||
  local expl
 | 
			
		||||
  local comp_cachename=brew_casks
 | 
			
		||||
 | 
			
		||||
  if _cache_invalid $comp_cachename || ! _retrieve_cache $comp_cachename; then
 | 
			
		||||
  if ! _retrieve_cache $comp_cachename; then
 | 
			
		||||
    list=( $(brew search --casks) )
 | 
			
		||||
    _store_cache $comp_cachename list
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
@ -261,7 +261,7 @@ We want tests that don't require any user input and test the basic functionality
 | 
			
		||||
 | 
			
		||||
See [`cmake`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/cmake.rb) for an example of a formula with a good test. The formula writes a basic `CMakeLists.txt` file into the test directory then calls CMake to generate Makefiles. This test checks that CMake doesn't e.g. segfault during basic operation.
 | 
			
		||||
 | 
			
		||||
You can check that the output is as expected with `assert_equal` or `assert_match` on the output of shell_output such as in this example from the [envv formula](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/envv.rb):
 | 
			
		||||
You can check that the output is as expected with `assert_equal` or `assert_match` on the output of the [Formula assertions](https://rubydoc.brew.sh/Homebrew/Assertions.html) such as in this example from the [envv formula](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/envv.rb):
 | 
			
		||||
 | 
			
		||||
```ruby
 | 
			
		||||
assert_equal "mylist=A:C; export mylist", shell_output("#{bin}/envv del mylist B").strip
 | 
			
		||||
 | 
			
		||||
@ -250,7 +250,7 @@ GEM
 | 
			
		||||
      thread_safe (~> 0.1)
 | 
			
		||||
    unicode-display_width (1.7.0)
 | 
			
		||||
    yell (2.2.2)
 | 
			
		||||
    zeitwerk (2.3.0)
 | 
			
		||||
    zeitwerk (2.3.1)
 | 
			
		||||
 | 
			
		||||
PLATFORMS
 | 
			
		||||
  ruby
 | 
			
		||||
 | 
			
		||||
@ -340,6 +340,8 @@ Show install options specific to *`formula`*.
 | 
			
		||||
  Show options for formulae that are currently installed.
 | 
			
		||||
* `--all`:
 | 
			
		||||
  Show options for all available formulae.
 | 
			
		||||
* `--command`:
 | 
			
		||||
  Show options for the specified *`command`*.
 | 
			
		||||
 | 
			
		||||
### `outdated` [*`options`*] [*`formula`*]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -456,6 +456,10 @@ Show options for formulae that are currently installed\.
 | 
			
		||||
\fB\-\-all\fR
 | 
			
		||||
Show options for all available formulae\.
 | 
			
		||||
.
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-\-command\fR
 | 
			
		||||
Show options for the specified \fIcommand\fR\.
 | 
			
		||||
.
 | 
			
		||||
.SS "\fBoutdated\fR [\fIoptions\fR] [\fIformula\fR]"
 | 
			
		||||
List installed formulae that have an updated version available\. By default, version information is displayed in interactive shells, and suppressed otherwise\.
 | 
			
		||||
.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user