diff options
| author | Markus Reiter | 2017-10-07 00:31:28 +0200 | 
|---|---|---|
| committer | Markus Reiter | 2017-10-08 16:10:37 +0200 | 
| commit | 175ca909ee1a5b57aa0cae2c879920511f311b14 (patch) | |
| tree | 067464b4c08f4c16ca3439b533f06669a78c370c /Library | |
| parent | 91ab116ace7f4f97d3440190463c93be9ec6d675 (diff) | |
| download | brew-175ca909ee1a5b57aa0cae2c879920511f311b14.tar.bz2 | |
Clean up code style and remove `.rubocop_todo.yml`.
Diffstat (limited to 'Library')
44 files changed, 295 insertions, 420 deletions
| diff --git a/Library/Homebrew/.rubocop.yml b/Library/Homebrew/.rubocop.yml index 3b440c33c..143468643 100644 --- a/Library/Homebrew/.rubocop.yml +++ b/Library/Homebrew/.rubocop.yml @@ -1,6 +1,5 @@  inherit_from:    - ../.rubocop.yml -  - .rubocop_todo.yml  AllCops:    Include: @@ -26,9 +25,26 @@ Lint/NestedMethodDefinition:  Lint/ParenthesesAsGroupedExpression:    Enabled: true +Metrics/BlockNesting: +  Max: 5 + +Metrics/ModuleLength: +  Max: 360 +  Metrics/ParameterLists:    CountKeywordArgs: false +# we won't change backward compatible method names +Naming/MethodName: +  Exclude: +    - 'compat/**/*' + +# we won't change backward compatible predicate names +Naming/PredicateName: +  Exclude: +    - 'compat/**/*' +  NameWhitelist: is_32_bit?, is_64_bit? +  Style/BlockDelimiters:    Exclude:      - '**/*_spec.rb' @@ -41,14 +57,3 @@ Style/GuardClause:  # hash-rockets preferred for formulae, a: 1 preferred elsewhere  Style/HashSyntax:    EnforcedStyle: ruby19_no_mixed_keys - -# we won't change backward compatible method names -Naming/MethodName: -  Exclude: -    - 'compat/**/*' - -# we won't change backward compatible predicate names -Naming/PredicateName: -  Exclude: -    - 'compat/**/*' -  NameWhitelist: is_32_bit?, is_64_bit? diff --git a/Library/Homebrew/.rubocop_todo.yml b/Library/Homebrew/.rubocop_todo.yml deleted file mode 100644 index 96c2f3676..000000000 --- a/Library/Homebrew/.rubocop_todo.yml +++ /dev/null @@ -1,138 +0,0 @@ -# This configuration was generated by -# `rubocop --auto-gen-config --exclude-limit 100` -# on 2017-01-27 21:44:55 +0000 using RuboCop version 0.47.1. -# The point is for the user to remove these configuration records -# one by one as the offenses are removed from the code base. -# Note that changes in the inspected code, or installation of new -# versions of RuboCop, may require this file to be generated again. - -# Offense count: 17 -Lint/HandleExceptions: -  Exclude: -    - 'cmd/install.rb' -    - 'cmd/reinstall.rb' -    - 'cmd/tap.rb' -    - 'cmd/update-report.rb' -    - 'cmd/upgrade.rb' -    - 'cmd/uses.rb' -    - 'descriptions.rb' -    - 'diagnostic.rb' -    - 'extend/ENV/super.rb' -    - 'extend/pathname.rb' -    - 'formula.rb' -    - 'formula_versions.rb' -    - 'test/ENV_test.rb' - -# Offense count: 3 -Lint/IneffectiveAccessModifier: -  Exclude: -    - 'formula.rb' -    - 'version.rb' - -# Offense count: 1 -Lint/Loop: -  Exclude: -    - 'patch.rb' - -# Offense count: 28 -Lint/RescueException: -  Exclude: -    - 'brew.rb' -    - 'build.rb' -    - 'cmd/fetch.rb' -    - 'cmd/reinstall.rb' -    - 'cmd/update-report.rb' -    - 'debrew.rb' -    - 'dev-cmd/pull.rb' -    - 'dev-cmd/test.rb' -    - 'formula.rb' -    - 'formula_installer.rb' -    - 'migrator.rb' -    - 'postinstall.rb' -    - 'readall.rb' -    - 'test.rb' -    - 'test/ENV_test.rb' -    - 'utils/fork.rb' - -# Offense count: 1 -Lint/ShadowedException: -  Exclude: -    - 'utils/fork.rb' - -# Offense count: 13 -# Configuration parameters: CountBlocks. -Metrics/BlockNesting: -  Max: 5 - -# Offense count: 19 -# Configuration parameters: CountComments. -Metrics/ModuleLength: -  Max: 400 - -# Offense count: 1 -# Configuration parameters: CountKeywordArgs. -Metrics/ParameterLists: -  Max: 6 - -# Offense count: 2 -Security/MarshalLoad: -  Exclude: -    - 'dependency.rb' -    - 'utils/fork.rb' - -# Offense count: 1 -Naming/AccessorMethodName: -  Exclude: -    - 'extend/ENV/super.rb' - -# Offense count: 6 -Style/ClassVars: -  Exclude: -    - 'dev-cmd/audit.rb' -    - 'formula_installer.rb' -    - 'test/support/helper/fs_leak_logger.rb' - -# Offense count: 13 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: compact, expanded -Style/EmptyMethod: -  Exclude: -    - 'debrew/irb.rb' -    - 'download_strategy.rb' -    - 'extend/ENV/super.rb' -    - 'formula.rb' -    - 'patch.rb' - -# Offense count: 13 -# Configuration parameters: AllowedVariables. -Style/GlobalVars: -  Exclude: -    - 'diagnostic.rb' -    - 'utils.rb' - -# Offense count: 1 -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: module_function, extend_self -Style/ModuleFunction: -  Exclude: -    - 'os/mac/xcode.rb' - -# Offense count: 8 -Style/MultilineBlockChain: -  Exclude: -    - 'cmd/search.rb' -    - 'dev-cmd/aspell-dictionaries.rb' -    - 'dev-cmd/audit.rb' -    - 'dev-cmd/man.rb' -    - 'diagnostic.rb' -    - 'test/patching_test.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -Style/MutableConstant: -  Exclude: -    - 'dependency_collector.rb' -    - 'formulary.rb' -    - 'tab.rb' -    - 'tap.rb' diff --git a/Library/Homebrew/brew.rb b/Library/Homebrew/brew.rb index 41955e60e..86b40a79d 100644 --- a/Library/Homebrew/brew.rb +++ b/Library/Homebrew/brew.rb @@ -146,7 +146,7 @@ rescue MethodDeprecatedError => e      $stderr.puts "  #{Formatter.url(e.issues_url)}"    end    exit 1 -rescue Exception => e +rescue Exception => e # rubocop:disable Lint/RescueException    onoe e    if internal_cmd && defined?(OS::ISSUES_URL) &&       !ENV["HOMEBREW_NO_AUTO_UPDATE"] diff --git a/Library/Homebrew/build.rb b/Library/Homebrew/build.rb index cd2fa4c02..836b360da 100644 --- a/Library/Homebrew/build.rb +++ b/Library/Homebrew/build.rb @@ -190,7 +190,7 @@ begin    options = Options.create(ARGV.flags_only)    build   = Build.new(formula, options)    build.install -rescue Exception => e +rescue Exception => e # rubocop:disable Lint/RescueException    Marshal.dump(e, error_pipe)    error_pipe.close    exit! 1 diff --git a/Library/Homebrew/cmd/fetch.rb b/Library/Homebrew/cmd/fetch.rb index 006c63746..411753992 100644 --- a/Library/Homebrew/cmd/fetch.rb +++ b/Library/Homebrew/cmd/fetch.rb @@ -49,8 +49,10 @@ module Homebrew        if fetch_bottle?(f)          begin            fetch_formula(f.bottle) -        rescue Exception => e -          raise if ARGV.homebrew_developer? || e.is_a?(Interrupt) +        rescue Interrupt +          raise +        rescue => e +          raise if ARGV.homebrew_developer?            fetched_bottle = false            onoe e.message            opoo "Bottle fetch failed: fetching the source." diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb index 732e96b00..ca8f29477 100644 --- a/Library/Homebrew/cmd/install.rb +++ b/Library/Homebrew/cmd/install.rb @@ -339,6 +339,7 @@ module Homebrew    rescue FormulaInstallationAlreadyAttemptedError      # We already attempted to install f as part of the dependency tree of      # another formula. In that case, don't generate an error, just move on. +    return    rescue CannotInstallFormulaError => e      ofail e.message    end diff --git a/Library/Homebrew/cmd/reinstall.rb b/Library/Homebrew/cmd/reinstall.rb index 94096d2dd..6727c0b6b 100644 --- a/Library/Homebrew/cmd/reinstall.rb +++ b/Library/Homebrew/cmd/reinstall.rb @@ -47,8 +47,8 @@ module Homebrew      fi.install      fi.finish    rescue FormulaInstallationAlreadyAttemptedError -    # next -  rescue Exception +    return +  rescue Exception # rubocop:disable Lint/RescueException      ignore_interrupts { restore_backup(keg, keg_was_linked) }      raise    else diff --git a/Library/Homebrew/cmd/style.rb b/Library/Homebrew/cmd/style.rb index e816db5dc..58f430a27 100644 --- a/Library/Homebrew/cmd/style.rb +++ b/Library/Homebrew/cmd/style.rb @@ -117,6 +117,7 @@ module Homebrew      case output_type      when :print +      args << "--debug" if ARGV.debug?        args << "--display-cop-names" if ARGV.include? "--display-cop-names"        args << "--format" << "simple" if files        system(cache_env, "rubocop", "_#{HOMEBREW_RUBOCOP_VERSION}_", *args) diff --git a/Library/Homebrew/cmd/tap.rb b/Library/Homebrew/cmd/tap.rb index 2a07c1b2f..fa520e2c5 100644 --- a/Library/Homebrew/cmd/tap.rb +++ b/Library/Homebrew/cmd/tap.rb @@ -54,8 +54,7 @@ module Homebrew                      quiet: ARGV.quieter?        rescue TapRemoteMismatchError => e          odie e -      rescue TapAlreadyTappedError, TapAlreadyUnshallowError -        # Do nothing. +      rescue TapAlreadyTappedError, TapAlreadyUnshallowError # rubocop:disable Lint/HandleExceptions        end      end    end diff --git a/Library/Homebrew/cmd/update-report.rb b/Library/Homebrew/cmd/update-report.rb index 781ee8808..0974df0b4 100644 --- a/Library/Homebrew/cmd/update-report.rb +++ b/Library/Homebrew/cmd/update-report.rb @@ -372,7 +372,7 @@ class Reporter            new_version = formula.pkg_version            old_version = FormulaVersions.new(formula).formula_at_revision(@initial_revision, &:pkg_version)            next if new_version == old_version -        rescue Exception => e +        rescue Exception => e # rubocop:disable Lint/RescueException            onoe "#{e.message}\n#{e.backtrace.join "\n"}" if ARGV.homebrew_developer?          end          @report[:M] << tap.formula_file_to_name(src) @@ -460,7 +460,7 @@ class Reporter            unless Formulary.factory(new_full_name).keg_only?              system HOMEBREW_BREW_FILE, "link", new_full_name, "--overwrite"            end -        rescue Exception => e +        rescue Exception => e # rubocop:disable Lint/RescueException            onoe "#{e.message}\n#{e.backtrace.join "\n"}" if ARGV.homebrew_developer?          end          next @@ -521,7 +521,7 @@ class Reporter        begin          f = Formulary.factory(new_full_name) -      rescue Exception => e +      rescue Exception => e # rubocop:disable Lint/RescueException          onoe "#{e.message}\n#{e.backtrace.join "\n"}" if ARGV.homebrew_developer?          next        end diff --git a/Library/Homebrew/cmd/upgrade.rb b/Library/Homebrew/cmd/upgrade.rb index 1cdb497cf..f1ce3c7da 100644 --- a/Library/Homebrew/cmd/upgrade.rb +++ b/Library/Homebrew/cmd/upgrade.rb @@ -150,6 +150,7 @@ module Homebrew    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. +    return    rescue CannotInstallFormulaError => e      ofail e    rescue BuildError => e diff --git a/Library/Homebrew/cmd/uses.rb b/Library/Homebrew/cmd/uses.rb index 24684c3b6..0b09e1bf1 100644 --- a/Library/Homebrew/cmd/uses.rb +++ b/Library/Homebrew/cmd/uses.rb @@ -74,12 +74,13 @@ module Homebrew                end              end -            dep_formulae = deps.map do |dep| +            dep_formulae = deps.flat_map do |dep|                begin                  dep.to_formula                rescue +                []                end -            end.compact +            end              reqs_by_formula = ([f] + dep_formulae).flat_map do |formula|                formula.requirements.map { |req| [formula, req] } @@ -118,6 +119,7 @@ module Homebrew          rescue FormulaUnavailableError            # Silently ignore this case as we don't care about things used in            # taps that aren't currently tapped. +          next          end        end      end diff --git a/Library/Homebrew/debrew.rb b/Library/Homebrew/debrew.rb index 5bc3d2daa..6206eb8a2 100644 --- a/Library/Homebrew/debrew.rb +++ b/Library/Homebrew/debrew.rb @@ -9,7 +9,7 @@ module Debrew    module Raise      def raise(*)        super -    rescue Exception => e +    rescue Exception => e # rubocop:disable Lint/RescueException        e.extend(Ignorable)        super(e) unless Debrew.debug(e) == :ignore      end @@ -92,7 +92,7 @@ module Debrew        yield      rescue SystemExit        original_raise -    rescue Exception => e +    rescue Exception => e # rubocop:disable Lint/RescueException        debug(e)      ensure        @active = false @@ -119,7 +119,7 @@ module Debrew            if e.is_a?(Ignorable)              menu.choice(:irb) do                puts "When you exit this IRB session, execution will continue." -              set_trace_func proc { |event, _, _, id, binding, klass| +              set_trace_func proc { |event, _, _, id, binding, klass| # rubocop:disable Metrics/ParameterLists                  if klass == Raise && id == :raise && event == "return"                    set_trace_func(nil)                    synchronize { IRB.start_within(binding) } diff --git a/Library/Homebrew/debrew/irb.rb b/Library/Homebrew/debrew/irb.rb index 069dbe676..eeb3758a9 100644 --- a/Library/Homebrew/debrew/irb.rb +++ b/Library/Homebrew/debrew/irb.rb @@ -4,8 +4,7 @@ module IRB    @setup_done = false    extend Module.new { -    def parse_opts -    end +    def parse_opts; end      def start_within(binding)        unless @setup_done diff --git a/Library/Homebrew/dependency.rb b/Library/Homebrew/dependency.rb index 0fbc2625b..7f0e7fbff 100644 --- a/Library/Homebrew/dependency.rb +++ b/Library/Homebrew/dependency.rb @@ -64,7 +64,7 @@ class Dependency    end    def self._load(marshaled) -    new(*Marshal.load(marshaled)) +    new(*Marshal.load(marshaled)) # rubocop:disable Security/MarshalLoad    end    class << self diff --git a/Library/Homebrew/dependency_collector.rb b/Library/Homebrew/dependency_collector.rb index fff80a28c..f855669e0 100644 --- a/Library/Homebrew/dependency_collector.rb +++ b/Library/Homebrew/dependency_collector.rb @@ -4,6 +4,7 @@ require "ld64_dependency"  require "requirement"  require "requirements"  require "set" +require "extend/cachable"  ## A dependency is a formula that another formula needs to install.  ## A requirement is something other than a formula that another formula @@ -16,17 +17,13 @@ require "set"  # This class is used by `depends_on` in the formula DSL to turn dependency  # specifications into the proper kinds of dependencies and requirements.  class DependencyCollector +  extend Cachable +    # Define the languages that we can handle as external dependencies.    LANGUAGE_MODULES = Set[      :lua, :lua51, :perl, :python, :python3, :ruby    ].freeze -  CACHE = {} - -  def self.clear_cache -    CACHE.clear -  end -    attr_reader :deps, :requirements    def initialize @@ -45,7 +42,7 @@ class DependencyCollector    end    def fetch(spec) -    CACHE.fetch(cache_key(spec)) { |key| CACHE[key] = build(spec) } +    self.class.cache.fetch(cache_key(spec)) { |key| self.class.cache[key] = build(spec) }    end    def cache_key(spec) diff --git a/Library/Homebrew/descriptions.rb b/Library/Homebrew/descriptions.rb index ac1d68216..bc1982673 100644 --- a/Library/Homebrew/descriptions.rb +++ b/Library/Homebrew/descriptions.rb @@ -78,10 +78,10 @@ class Descriptions      formula_names.each do |name|        begin -        desc = Formulary.factory(name).desc +        @cache[name] = Formulary.factory(name).desc        rescue FormulaUnavailableError, *FormulaVersions::IGNORED_EXCEPTIONS +        @cache.delete(name)        end -      @cache[name] = desc      end      save_cache if options[:save]    end diff --git a/Library/Homebrew/dev-cmd/aspell-dictionaries.rb b/Library/Homebrew/dev-cmd/aspell-dictionaries.rb index 955e41b01..ab0e66d2b 100644 --- a/Library/Homebrew/dev-cmd/aspell-dictionaries.rb +++ b/Library/Homebrew/dev-cmd/aspell-dictionaries.rb @@ -27,13 +27,12 @@ module Homebrew        end      end -    languages.inject([]) do |resources, (lang, path)| +    languages.each do |lang, path|        r = Resource.new(lang)        r.owner = Formulary.factory("aspell")        r.url "#{dict_url}/#{path}"        r.mirror "#{dict_mirror}/#{path}" -      resources << r -    end.each(&:fetch).each do |r| +      r.fetch        puts <<-EOS          option "with-lang-#{r.name}", "Install #{r.name} dictionary"          resource "#{r.name}" do diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index 16ae7cba1..6afd1f802 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -53,7 +53,7 @@ module Homebrew    module_function    def audit -    Homebrew.inject_dump_stats!(FormulaAuditor, /^audit_/) if ARGV.switch? "D" +    inject_dump_stats!(FormulaAuditor, /^audit_/) if ARGV.switch? "D"      Homebrew.auditing = true      formula_count = 0 @@ -387,8 +387,10 @@ class FormulaAuditor      end    end -  # core aliases + tap alias names + tap alias full name -  @@aliases ||= Formula.aliases + Formula.tap_aliases +  def self.aliases +    # core aliases + tap alias names + tap alias full name +    @aliases ||= Formula.aliases + Formula.tap_aliases +  end    def audit_formula_name      return unless @strict @@ -442,7 +444,7 @@ class FormulaAuditor            problem "Dependency '#{dep.name}' was renamed; use new name '#{dep_f.name}'."          end -        if @@aliases.include?(dep.name) && +        if self.class.aliases.include?(dep.name) &&             (dep_f.core_formula? || !dep_f.versioned_formula?)            problem "Dependency '#{dep.name}' is an alias; use the canonical name '#{dep.to_formula.full_name}'."          end @@ -453,16 +455,16 @@ class FormulaAuditor            problem "Dependency '#{dep.name}' may be unnecessary as it is provided by macOS; try to build this formula without it."          end -        dep.options.reject do |opt| -          next true if dep_f.option_defined?(opt) -          dep_f.requirements.detect do |r| +        dep.options.each do |opt| +          next if dep_f.option_defined?(opt) +          next if dep_f.requirements.detect do |r|              if r.recommended?                opt.name == "with-#{r.name}"              elsif r.optional?                opt.name == "without-#{r.name}"              end            end -        end.each do |opt| +            problem "Dependency #{dep} does not define option #{opt.name.inspect}"          end diff --git a/Library/Homebrew/dev-cmd/bottle.rb b/Library/Homebrew/dev-cmd/bottle.rb index 8dfd0d12c..fb862c773 100644 --- a/Library/Homebrew/dev-cmd/bottle.rb +++ b/Library/Homebrew/dev-cmd/bottle.rb @@ -75,7 +75,7 @@ module Homebrew        @put_filenames ||= [] -      return if @put_filenames.include? filename +      return if @put_filenames.include?(filename)        puts Formatter.error(filename.to_s)        @put_filenames << filename @@ -84,8 +84,7 @@ module Homebrew      result = false      keg.each_unique_file_matching(string) do |file| -      # skip document file. -      next if Metafiles::EXTENSIONS.include? file.extname +      next if Metafiles::EXTENSIONS.include?(file.extname) # Skip document files.        linked_libraries = Keg.file_linked_libraries(file, string)        result ||= !linked_libraries.empty? @@ -156,9 +155,7 @@ module Homebrew        return ofail "Formula not installed or up-to-date: #{f.full_name}"      end -    tap = f.tap - -    unless tap +    unless tap = f.tap        unless ARGV.include?("--force-core-tap")          return ofail "Formula not from core or any taps: #{f.full_name}"        end diff --git a/Library/Homebrew/dev-cmd/man.rb b/Library/Homebrew/dev-cmd/man.rb index 472bb7c2b..b2bb3c8c3 100644 --- a/Library/Homebrew/dev-cmd/man.rb +++ b/Library/Homebrew/dev-cmd/man.rb @@ -48,12 +48,9 @@ module Homebrew    def path_glob_commands(glob)      Pathname.glob(glob)              .sort_by { |source_file| sort_key_for_path(source_file) } -            .map do |source_file| -      source_file.read.lines -                 .grep(/^#:/) -                 .map { |line| line.slice(2..-1) } -                 .join -    end.reject { |s| s.strip.empty? || s.include?("@hide_from_man_page") } +            .map(&:read).map(&:lines) +            .map { |lines| lines.grep(/^#:/).map { |line| line.slice(2..-1) }.join } +            .reject { |s| s.strip.empty? || s.include?("@hide_from_man_page") }    end    def build_man_page diff --git a/Library/Homebrew/dev-cmd/pull.rb b/Library/Homebrew/dev-cmd/pull.rb index cd0d6fbd0..8cb270303 100644 --- a/Library/Homebrew/dev-cmd/pull.rb +++ b/Library/Homebrew/dev-cmd/pull.rb @@ -154,8 +154,8 @@ module Homebrew          begin            f = Formula[name] -        # Make sure we catch syntax errors. -        rescue Exception +        rescue Exception # rubocop:disable Lint/RescueException +          # Make sure we catch syntax errors.            next          end diff --git a/Library/Homebrew/dev-cmd/test.rb b/Library/Homebrew/dev-cmd/test.rb index ab2b0edb0..6622a8c25 100644 --- a/Library/Homebrew/dev-cmd/test.rb +++ b/Library/Homebrew/dev-cmd/test.rb @@ -84,7 +84,7 @@ module Homebrew        rescue ::Test::Unit::AssertionFailedError => e          ofail "#{f.full_name}: failed"          puts e.message -      rescue Exception => e +      rescue Exception => e # rubocop:disable Lint/RescueException          ofail "#{f.full_name}: failed"          puts e, e.backtrace        ensure diff --git a/Library/Homebrew/diagnostic.rb b/Library/Homebrew/diagnostic.rb index 88aa4dbc9..3edf31012 100644 --- a/Library/Homebrew/diagnostic.rb +++ b/Library/Homebrew/diagnostic.rb @@ -151,8 +151,10 @@ module Homebrew          return unless File.directory?(dir)          files = Dir.chdir(dir) do -          Dir[pattern].select { |f| File.file?(f) && !File.symlink?(f) } - Dir.glob(white_list) -        end.map { |file| File.join(dir, file) } +          (Dir.glob(pattern) - Dir.glob(white_list)) +            .select { |f| File.file?(f) && !File.symlink?(f) } +            .map { |f| File.join(dir, f) } +        end          return if files.empty?          inject_file_list(files, message) @@ -427,15 +429,15 @@ module Homebrew        end        def check_user_path_1 -        $seen_prefix_bin = false -        $seen_prefix_sbin = false +        @seen_prefix_bin = false +        @seen_prefix_sbin = false          message = ""          paths(ENV["HOMEBREW_PATH"]).each do |p|            case p            when "/usr/bin" -            unless $seen_prefix_bin +            unless @seen_prefix_bin                # only show the doctor message if there are any conflicts                # rationale: a default install should not trigger any brew doctor messages                conflicts = Dir["#{HOMEBREW_PREFIX}/bin/*"] @@ -458,9 +460,9 @@ module Homebrew                end              end            when "#{HOMEBREW_PREFIX}/bin" -            $seen_prefix_bin = true +            @seen_prefix_bin = true            when "#{HOMEBREW_PREFIX}/sbin" -            $seen_prefix_sbin = true +            @seen_prefix_sbin = true            end          end @@ -468,7 +470,7 @@ module Homebrew        end        def check_user_path_2 -        return if $seen_prefix_bin +        return if @seen_prefix_bin          <<-EOS.undent            Homebrew's bin was not found in your PATH. @@ -478,7 +480,7 @@ module Homebrew        end        def check_user_path_3 -        return if $seen_prefix_sbin +        return if @seen_prefix_sbin          # Don't complain about sbin not being in the path if it doesn't exist          sbin = HOMEBREW_PREFIX/"sbin" @@ -952,6 +954,7 @@ module Homebrew            Putting non-prefixed coreutils in your path can cause gmp builds to fail.          EOS        rescue FormulaUnavailableError +        return        end        def check_for_non_prefixed_findutils @@ -966,6 +969,7 @@ module Homebrew            Putting non-prefixed findutils in your path can cause python builds to fail.          EOS        rescue FormulaUnavailableError +        return        end        def check_for_pydistutils_cfg_in_home diff --git a/Library/Homebrew/download_strategy.rb b/Library/Homebrew/download_strategy.rb index 7012fccc8..e69a56ddf 100644 --- a/Library/Homebrew/download_strategy.rb +++ b/Library/Homebrew/download_strategy.rb @@ -18,8 +18,7 @@ class AbstractDownloadStrategy    end    # Download and cache the resource as {#cached_location}. -  def fetch -  end +  def fetch; end    # Suppress output    def shutup! @@ -37,13 +36,11 @@ class AbstractDownloadStrategy    # Unpack {#cached_location} into the current working directory, and possibly    # chdir into the newly-unpacked directory.    # Unlike {Resource#stage}, this does not take a block. -  def stage -  end +  def stage; end    # @!attribute [r] cached_location    # The path to the cached file or directory associated with the resource. -  def cached_location -  end +  def cached_location; end    # @!attribute [r]    # return most recent modified time for all files in the current working directory after stage. @@ -204,14 +201,11 @@ class VCSDownloadStrategy < AbstractDownloadStrategy      true    end -  def clone_repo -  end +  def clone_repo; end -  def update -  end +  def update; end -  def current_revision -  end +  def current_revision; end    def extract_ref(specs)      key = REF_TYPES.find { |type| specs.key?(type) } diff --git a/Library/Homebrew/extend/ENV/super.rb b/Library/Homebrew/extend/ENV/super.rb index b518c22a1..b4f0dfcac 100644 --- a/Library/Homebrew/extend/ENV/super.rb +++ b/Library/Homebrew/extend/ENV/super.rb @@ -24,8 +24,7 @@ module Superenv    end    # @private -  def self.bin -  end +  def self.bin; end    def reset      super @@ -324,11 +323,9 @@ module Superenv      end    end -  def set_x11_env_if_installed -  end +  def set_x11_env_if_installed; end -  def set_cpu_flags(*) -  end +  def set_cpu_flags(_, _ = "", _ = {}); end  end  require "extend/os/extend/ENV/super" diff --git a/Library/Homebrew/extend/cachable.rb b/Library/Homebrew/extend/cachable.rb new file mode 100644 index 000000000..69d86ccb7 --- /dev/null +++ b/Library/Homebrew/extend/cachable.rb @@ -0,0 +1,9 @@ +module Cachable +  def cache +    @cache ||= {} +  end + +  def clear_cache +    cache.clear +  end +end diff --git a/Library/Homebrew/extend/pathname.rb b/Library/Homebrew/extend/pathname.rb index e1acd1f77..e3d6880ba 100644 --- a/Library/Homebrew/extend/pathname.rb +++ b/Library/Homebrew/extend/pathname.rb @@ -186,7 +186,7 @@ class Pathname        begin          tf.chown(uid, gid)          tf.chmod(old_stat.mode) -      rescue Errno::EPERM +      rescue Errno::EPERM # rubocop:disable Lint/HandleExceptions        end        File.rename(tf.path, self) diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index d999b9c5f..61042aae7 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -1041,14 +1041,14 @@ class Formula      # keg's formula is deleted.      begin        keg = Keg.for(path) -    rescue NotAKegError, Errno::ENOENT +    rescue NotAKegError, Errno::ENOENT # rubocop:disable Lint/HandleExceptions        # file doesn't belong to any keg.      else        tab_tap = Tab.for_keg(keg).tap        return false if tab_tap.nil? # this keg doesn't below to any core/tap formula, most likely coming from a DIY install.        begin          Formulary.factory(keg.name) -      rescue FormulaUnavailableError +      rescue FormulaUnavailableError # rubocop:disable Lint/HandleExceptions          # formula for this keg is deleted, so defer to whitelist        rescue TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError          return false # this keg belongs to another formula @@ -1379,12 +1379,13 @@ class Formula    # An array of all installed {Formula}    # @private    def self.installed -    @installed ||= racks.map do |rack| +    @installed ||= racks.flat_map do |rack|        begin          Formulary.from_rack(rack)        rescue FormulaUnavailableError, TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError +        []        end -    end.compact.uniq(&:name) +    end.uniq(&:name)    end    def self.installed_with_alias_path(alias_path) @@ -1642,7 +1643,7 @@ class Formula          with_logging("test") do            test          end -      rescue Exception +      rescue Exception # rubocop:disable Lint/RescueException          staging.retain! if ARGV.debug?          raise        end @@ -1667,8 +1668,7 @@ class Formula    end    # @private -  def test -  end +  def test; end    # @private    def test_fixtures(file) @@ -1683,8 +1683,7 @@ class Formula    #   system "./configure", "--prefix=#{prefix}"    #   system "make", "install"    # end</pre> -  def install -  end +  def install; end    protected @@ -1932,28 +1931,28 @@ class Formula      end    end -  def self.method_added(method) -    case method -    when :brew -      raise "You cannot override Formula#brew in class #{name}" -    when :test -      define_method(:test_defined?) { true } -    when :options -      instance = allocate +  # The methods below define the formula DSL. +  class << self +    include BuildEnvironment::DSL -      specs.each do |spec| -        instance.options.each do |opt, desc| -          spec.option(opt[/^--(.+)$/, 1], desc) +    def method_added(method) +      case method +      when :brew +        raise "You cannot override Formula#brew in class #{name}" +      when :test +        define_method(:test_defined?) { true } +      when :options +        instance = allocate + +        specs.each do |spec| +          instance.options.each do |opt, desc| +            spec.option(opt[/^--(.+)$/, 1], desc) +          end          end -      end -      remove_method(:options) +        remove_method(:options) +      end      end -  end - -  # The methods below define the formula DSL. -  class << self -    include BuildEnvironment::DSL      # The reason for why this software is not linked (by default) to      # {::HOMEBREW_PREFIX}. diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index 56238ad73..7cd87e751 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -58,13 +58,14 @@ class FormulaInstaller      @options = Options.new      @invalid_option_names = []      @requirement_messages = [] - -    @@attempted ||= Set.new -      @poured_bottle = false      @pour_failed   = false    end +  def self.attempted +    @attempted ||= Set.new +  end +    # When no build tools are available and build flags are passed through ARGV,    # it's necessary to interrupt the user before any sort of installation    # can proceed. Only invoked when the user has no developer tools. @@ -145,7 +146,7 @@ class FormulaInstaller    end    def check_install_sanity -    raise FormulaInstallationAlreadyAttemptedError, formula if @@attempted.include?(formula) +    raise FormulaInstallationAlreadyAttemptedError, formula if self.class.attempted.include?(formula)      return if ignore_deps? @@ -287,12 +288,12 @@ class FormulaInstaller        end      end -    @@attempted << formula +    self.class.attempted << formula      if pour_bottle?(warn: true)        begin          pour -      rescue Exception => e +      rescue Exception => e # rubocop:disable Lint/RescueException          # any exceptions must leave us with nothing installed          ignore_interrupts do            formula.prefix.rmtree if formula.prefix.directory? @@ -567,7 +568,7 @@ class FormulaInstaller      oh1 "Installing #{formula.full_name} dependency: #{Formatter.identifier(dep.name)}"      fi.install      fi.finish -  rescue Exception +  rescue Exception # rubocop:disable Lint/RescueException      ignore_interrupts do        tmp_keg.rename(installed_keg) if tmp_keg && !installed_keg.directory?        linked_keg.link if keg_was_linked @@ -723,7 +724,7 @@ class FormulaInstaller      if !formula.prefix.directory? || Keg.new(formula.prefix).empty_installation?        raise "Empty installation"      end -  rescue Exception => e +  rescue Exception => e # rubocop:disable Lint/RescueException      e.options = display_options(formula) if e.is_a?(BuildError)      ignore_interrupts do        # any exceptions must leave us with nothing installed @@ -784,7 +785,7 @@ class FormulaInstaller        puts "  brew link #{formula.name}"        @show_summary_heading = true        Homebrew.failed = true -    rescue Exception => e +    rescue Exception => e # rubocop:disable Lint/RescueException        onoe "An unexpected error occurred during the `brew link` step"        puts "The formula built, but is not symlinked into #{HOMEBREW_PREFIX}"        puts e @@ -815,7 +816,7 @@ class FormulaInstaller      formula.plist_path.chmod 0644      log = formula.var/"log"      log.mkpath if formula.plist.include? log.to_s -  rescue Exception => e +  rescue Exception => e # rubocop:disable Lint/RescueException      onoe "Failed to install plist file"      ohai e, e.backtrace if debug?      Homebrew.failed = true @@ -823,7 +824,7 @@ class FormulaInstaller    def fix_dynamic_linkage(keg)      keg.fix_dynamic_linkage -  rescue Exception => e +  rescue Exception => e # rubocop:disable Lint/RescueException      onoe "Failed to fix install linkage"      puts "The formula built, but you may encounter issues using it or linking other"      puts "formula against it." @@ -835,7 +836,7 @@ class FormulaInstaller    def clean      ohai "Cleaning" if verbose?      Cleaner.new(formula).clean -  rescue Exception => e +  rescue Exception => e # rubocop:disable Lint/RescueException      opoo "The cleaning step did not complete successfully"      puts "Still, the installation was successful, so we will link it into your prefix"      ohai e, e.backtrace if debug? @@ -845,7 +846,7 @@ class FormulaInstaller    def post_install      Homebrew.run_post_install(formula) -  rescue Exception => e +  rescue Exception => e # rubocop:disable Lint/RescueException      opoo "The post-install step did not complete successfully"      puts "You can try again using `brew postinstall #{formula.full_name}`"      ohai e, e.backtrace if debug? @@ -905,27 +906,31 @@ class FormulaInstaller      super    end +  def self.locked +    @locked ||= [] +  end +    private    attr_predicate :hold_locks?    def lock -    return unless (@@locked ||= []).empty? +    return unless self.class.locked.empty?      unless ignore_deps?        formula.recursive_dependencies.each do |dep| -        @@locked << dep.to_formula +        self.class.locked << dep.to_formula        end      end -    @@locked.unshift(formula) -    @@locked.uniq! -    @@locked.each(&:lock) +    self.class.locked.unshift(formula) +    self.class.locked.uniq! +    self.class.locked.each(&:lock)      @hold_locks = true    end    def unlock      return unless hold_locks? -    @@locked.each(&:unlock) -    @@locked.clear +    self.class.locked.each(&:unlock) +    self.class.locked.clear      @hold_locks = false    end diff --git a/Library/Homebrew/formula_versions.rb b/Library/Homebrew/formula_versions.rb index bb6803567..c10c69e67 100644 --- a/Library/Homebrew/formula_versions.rb +++ b/Library/Homebrew/formula_versions.rb @@ -44,7 +44,7 @@ class FormulaVersions      # continue walking the history      ohai "#{e} in #{name} at revision #{rev}", e.backtrace if ARGV.debug?    rescue FormulaUnavailableError -    # Suppress this error +    return    ensure      Homebrew.raise_deprecation_exceptions = false    end diff --git a/Library/Homebrew/formulary.rb b/Library/Homebrew/formulary.rb index 0eb34ee2a..fddeac631 100644 --- a/Library/Homebrew/formulary.rb +++ b/Library/Homebrew/formulary.rb @@ -1,18 +1,19 @@  require "digest/md5"  require "tap" +require "extend/cachable"  # The Formulary is responsible for creating instances of Formula.  # It is not meant to be used directly from formulae.  module Formulary -  FORMULAE = {} +  extend Cachable    def self.formula_class_defined?(path) -    FORMULAE.key?(path) +    cache.key?(path)    end    def self.formula_class_get(path) -    FORMULAE.fetch(path) +    cache.fetch(path)    end    def self.load_formula(name, path, contents, namespace) @@ -44,7 +45,7 @@ module Formulary      contents = path.open("r") { |f| ensure_utf8_encoding(f).read }      namespace = "FormulaNamespace#{Digest::MD5.hexdigest(path.to_s)}"      klass = load_formula(name, path, contents, namespace) -    FORMULAE[path] = klass +    cache[path] = klass    end    if IO.method_defined?(:set_encoding) diff --git a/Library/Homebrew/migrator.rb b/Library/Homebrew/migrator.rb index 7ecdafe2f..0eb7492df 100644 --- a/Library/Homebrew/migrator.rb +++ b/Library/Homebrew/migrator.rb @@ -100,7 +100,7 @@ class Migrator      begin        migrator = Migrator.new(formula)        migrator.migrate -    rescue Exception => e +    rescue => e        onoe e      end    end @@ -196,7 +196,7 @@ class Migrator      update_tabs    rescue Interrupt      ignore_interrupts { backup_oldname } -  rescue Exception => e +  rescue Exception => e # rubocop:disable Lint/RescueException      onoe "Error occurred while migrating."      puts e      puts e.backtrace if ARGV.debug? @@ -304,7 +304,7 @@ class Migrator        puts        puts "You can try again using:"        puts "  brew link #{formula.name}" -    rescue Exception => e +    rescue Exception => e # rubocop:disable Lint/RescueException        onoe "An unexpected error occurred during linking"        puts e        puts e.backtrace if ARGV.debug? diff --git a/Library/Homebrew/os/mac/xcode.rb b/Library/Homebrew/os/mac/xcode.rb index 59e7026bd..5071aafcf 100644 --- a/Library/Homebrew/os/mac/xcode.rb +++ b/Library/Homebrew/os/mac/xcode.rb @@ -183,7 +183,7 @@ module OS      end      module CLT -      extend self +      module_function        STANDALONE_PKG_ID = "com.apple.pkg.DeveloperToolsCLILeo".freeze        FROM_XCODE_PKG_ID = "com.apple.pkg.DeveloperToolsCLI".freeze diff --git a/Library/Homebrew/patch.rb b/Library/Homebrew/patch.rb index 7045adf5e..8a1b00930 100644 --- a/Library/Homebrew/patch.rb +++ b/Library/Homebrew/patch.rb @@ -60,8 +60,7 @@ class EmbeddedPatch      false    end -  def contents -  end +  def contents; end    def apply      data = contents.gsub("HOMEBREW_PREFIX", HOMEBREW_PREFIX) @@ -87,10 +86,13 @@ class DATAPatch < EmbeddedPatch    def contents      data = ""      path.open("rb") do |f| -      begin +      loop do          line = f.gets -      end until line.nil? || line =~ /^__END__$/ -      data << line while line = f.gets +        break if line.nil? || line =~ /^__END__$/ +      end +      while line = f.gets +        data << line +      end      end      data    end diff --git a/Library/Homebrew/postinstall.rb b/Library/Homebrew/postinstall.rb index 0b6d8f6b0..53a5b7e75 100644 --- a/Library/Homebrew/postinstall.rb +++ b/Library/Homebrew/postinstall.rb @@ -14,7 +14,7 @@ begin    formula = ARGV.resolved_formulae.first    formula.extend(Debrew::Formula) if ARGV.debug?    formula.run_post_install -rescue Exception => e +rescue Exception => e # rubocop:disable Lint/RescueException    Marshal.dump(e, error_pipe)    error_pipe.close    exit! 1 diff --git a/Library/Homebrew/readall.rb b/Library/Homebrew/readall.rb index 3595c16be..5f4fd947c 100644 --- a/Library/Homebrew/readall.rb +++ b/Library/Homebrew/readall.rb @@ -52,7 +52,7 @@ module Readall            Formulary.factory(file)          rescue Interrupt            raise -        rescue Exception => e +        rescue Exception => e # rubocop:disable Lint/RescueException            onoe "Invalid formula: #{file}"            puts e            failed = true diff --git a/Library/Homebrew/tab.rb b/Library/Homebrew/tab.rb index af19cabe6..aa0208d51 100644 --- a/Library/Homebrew/tab.rb +++ b/Library/Homebrew/tab.rb @@ -3,18 +3,16 @@ require "ostruct"  require "options"  require "json"  require "development_tools" +require "extend/cachable"  # Inherit from OpenStruct to gain a generic initialization method that takes a  # hash and creates an attribute for each key and value. `Tab.new` probably  # should not be called directly, instead use one of the class methods like  # `Tab.create`.  class Tab < OpenStruct -  FILENAME = "INSTALL_RECEIPT.json".freeze -  CACHE = {} +  extend Cachable -  def self.clear_cache -    CACHE.clear -  end +  FILENAME = "INSTALL_RECEIPT.json".freeze    # Instantiates a Tab for a new installation of a formula.    def self.create(formula, compiler, stdlib) @@ -57,7 +55,7 @@ class Tab < OpenStruct    # Returns the Tab for an install receipt at `path`.    # Results are cached.    def self.from_file(path) -    CACHE.fetch(path) { |p| CACHE[p] = from_file_content(File.read(p), p) } +    cache.fetch(path) { |p| cache[p] = from_file_content(File.read(p), p) }    end    # Like Tab.from_file, but bypass the cache. @@ -343,7 +341,7 @@ class Tab < OpenStruct      # will no longer be valid.      Formula.clear_installed_formulae_cache unless tabfile.exist? -    CACHE[tabfile] = self +    self.class.cache[tabfile] = self      tabfile.atomic_write(to_json)    end diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb index f4e7631b4..78dc4cf4e 100644 --- a/Library/Homebrew/tap.rb +++ b/Library/Homebrew/tap.rb @@ -1,4 +1,5 @@  require "extend/string" +require "extend/cachable"  require "readall"  # a {Tap} is used to extend the formulae provided by Homebrew core. @@ -8,13 +9,9 @@ require "readall"  # {#user} represents Github username and {#repo} represents repository  # name without leading `homebrew-`.  class Tap -  TAP_DIRECTORY = HOMEBREW_LIBRARY/"Taps" - -  CACHE = {} +  extend Cachable -  def self.clear_cache -    CACHE.clear -  end +  TAP_DIRECTORY = HOMEBREW_LIBRARY/"Taps"    def self.fetch(*args)      case args.length @@ -38,7 +35,7 @@ class Tap      end      cache_key = "#{user}/#{repo}".downcase -    CACHE.fetch(cache_key) { |key| CACHE[key] = Tap.new(user, repo) } +    cache.fetch(cache_key) { |key| cache[key] = Tap.new(user, repo) }    end    def self.from_path(path) diff --git a/Library/Homebrew/test.rb b/Library/Homebrew/test.rb index d9ec8250e..3d5e62a88 100644 --- a/Library/Homebrew/test.rb +++ b/Library/Homebrew/test.rb @@ -27,7 +27,7 @@ begin    Timeout.timeout TEST_TIMEOUT_SECONDS do      raise "test returned false" if formula.run_test == false    end -rescue Exception => e +rescue Exception => e # rubocop:disable Lint/RescueException    Marshal.dump(e, error_pipe)    error_pipe.close    exit! 1 diff --git a/Library/Homebrew/test/formula_installer_spec.rb b/Library/Homebrew/test/formula_installer_spec.rb index 7365b2758..7b729312b 100644 --- a/Library/Homebrew/test/formula_installer_spec.rb +++ b/Library/Homebrew/test/formula_installer_spec.rb @@ -107,7 +107,7 @@ describe FormulaInstaller do        end      EOS -    Formulary::FORMULAE.delete(dep_path) +    Formulary.cache.delete(dep_path)      dependency = Formulary.factory(dep_name)      dependent = formula do diff --git a/Library/Homebrew/utils.rb b/Library/Homebrew/utils.rb index d293b2a6f..237ffa74e 100644 --- a/Library/Homebrew/utils.rb +++ b/Library/Homebrew/utils.rb @@ -229,10 +229,9 @@ module Homebrew      EOS    end -  # Hash of Module => Set(method_names) -  @injected_dump_stat_modules = {} - +  # rubocop:disable Style/GlobalVars    def inject_dump_stats!(the_module, pattern) +    @injected_dump_stat_modules ||= {}      @injected_dump_stat_modules[the_module] ||= []      injected_methods = @injected_dump_stat_modules[the_module]      the_module.module_eval do @@ -260,6 +259,7 @@ module Homebrew        end      end    end +  # rubocop:enable Style/GlobalVars  end  def with_system_path diff --git a/Library/Homebrew/utils/fork.rb b/Library/Homebrew/utils/fork.rb index 2f2a403e2..57ddbfae2 100644 --- a/Library/Homebrew/utils/fork.rb +++ b/Library/Homebrew/utils/fork.rb @@ -14,7 +14,7 @@ module Utils              read.close              write.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)              yield -          rescue Exception => e +          rescue Exception => e # rubocop:disable Lint/RescueException              Marshal.dump(e, write)              write.close              exit! @@ -26,8 +26,11 @@ module Utils          ignore_interrupts(:quietly) do # the child will receive the interrupt and marshal it back            begin              socket = server.accept_nonblock +          # rubocop:disable Lint/ShadowedException +          # FIXME: https://github.com/bbatsov/rubocop/issues/4843            rescue Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::ECONNABORTED, Errno::EPROTO, Errno::EINTR              retry unless Process.waitpid(pid, Process::WNOHANG) +          # rubocop:enable Lint/ShadowedException            else              socket.send_io(write)              socket.close @@ -36,7 +39,7 @@ module Utils            data = read.read            read.close            Process.wait(pid) unless socket.nil? -          raise Marshal.load(data) unless data.nil? || data.empty? +          raise Marshal.load(data) unless data.nil? || data.empty? # rubocop:disable Security/MarshalLoad            raise Interrupt if $CHILD_STATUS.exitstatus == 130            raise "Forked child process failed: #{$CHILD_STATUS}" unless $CHILD_STATUS.success?          end diff --git a/Library/Homebrew/version.rb b/Library/Homebrew/version.rb index 3ac748037..d43e0c665 100644 --- a/Library/Homebrew/version.rb +++ b/Library/Homebrew/version.rb @@ -213,110 +213,6 @@ class Version      end    end -  def initialize(val) -    unless val.respond_to?(:to_str) -      raise TypeError, "Version value must be a string; got a #{val.class} (#{val})" -    end -    @version = val.to_str -  end - -  def detected_from_url? -    false -  end - -  def head? -    false -  end - -  def null? -    false -  end - -  def <=>(other) -    # Needed to retain API compatibility with older string comparisons -    # for compiler versions, etc. -    other = Version.new(other) if other.is_a? String -    # Used by the *_build_version comparisons, which formerly returned Fixnum -    other = Version.new(other.to_s) if other.is_a? Integer -    return 1 if other.nil? - -    return unless other.is_a?(Version) -    return 0 if version == other.version -    return 1 if head? && !other.head? -    return -1 if !head? && other.head? -    return 0 if head? && other.head? - -    ltokens = tokens -    rtokens = other.tokens -    max = max(ltokens.length, rtokens.length) -    l = r = 0 - -    while l < max -      a = ltokens[l] || NULL_TOKEN -      b = rtokens[r] || NULL_TOKEN - -      if a == b -        l += 1 -        r += 1 -        next -      elsif a.numeric? && b.numeric? -        return a <=> b -      elsif a.numeric? -        return 1 if a > NULL_TOKEN -        l += 1 -      elsif b.numeric? -        return -1 if b > NULL_TOKEN -        r += 1 -      else -        return a <=> b -      end -    end - -    0 -  end -  alias eql? == - -  def hash -    version.hash -  end - -  def to_f -    version.to_f -  end - -  def to_s -    version.dup -  end -  alias to_str to_s - -  protected - -  attr_reader :version - -  def tokens -    @tokens ||= tokenize -  end - -  private - -  def max(a, b) -    (a > b) ? a : b -  end - -  def tokenize -    version.scan(SCAN_PATTERN).map! do |token| -      case token -      when /\A#{AlphaToken::PATTERN}\z/o   then AlphaToken -      when /\A#{BetaToken::PATTERN}\z/o    then BetaToken -      when /\A#{RCToken::PATTERN}\z/o      then RCToken -      when /\A#{PreToken::PATTERN}\z/o     then PreToken -      when /\A#{PatchToken::PATTERN}\z/o   then PatchToken -      when /\A#{NumericToken::PATTERN}\z/o then NumericToken -      when /\A#{StringToken::PATTERN}\z/o  then StringToken -      end.new(token) -    end -  end -    def self.parse(spec)      version = _parse(spec)      version.nil? ? NULL : new(version) @@ -461,6 +357,112 @@ class Version      m = /[-.vV]?((?:\d+\.)+\d+(?:[-_.]?(?i:alpha|beta|pre|rc)\.?\d{,2})?)/.match(spec_s)      return m.captures.first unless m.nil?    end + +  private_class_method :_parse + +  def initialize(val) +    unless val.respond_to?(:to_str) +      raise TypeError, "Version value must be a string; got a #{val.class} (#{val})" +    end +    @version = val.to_str +  end + +  def detected_from_url? +    false +  end + +  def head? +    false +  end + +  def null? +    false +  end + +  def <=>(other) +    # Needed to retain API compatibility with older string comparisons +    # for compiler versions, etc. +    other = Version.new(other) if other.is_a? String +    # Used by the *_build_version comparisons, which formerly returned Fixnum +    other = Version.new(other.to_s) if other.is_a? Integer +    return 1 if other.nil? + +    return unless other.is_a?(Version) +    return 0 if version == other.version +    return 1 if head? && !other.head? +    return -1 if !head? && other.head? +    return 0 if head? && other.head? + +    ltokens = tokens +    rtokens = other.tokens +    max = max(ltokens.length, rtokens.length) +    l = r = 0 + +    while l < max +      a = ltokens[l] || NULL_TOKEN +      b = rtokens[r] || NULL_TOKEN + +      if a == b +        l += 1 +        r += 1 +        next +      elsif a.numeric? && b.numeric? +        return a <=> b +      elsif a.numeric? +        return 1 if a > NULL_TOKEN +        l += 1 +      elsif b.numeric? +        return -1 if b > NULL_TOKEN +        r += 1 +      else +        return a <=> b +      end +    end + +    0 +  end +  alias eql? == + +  def hash +    version.hash +  end + +  def to_f +    version.to_f +  end + +  def to_s +    version.dup +  end +  alias to_str to_s + +  protected + +  attr_reader :version + +  def tokens +    @tokens ||= tokenize +  end + +  private + +  def max(a, b) +    (a > b) ? a : b +  end + +  def tokenize +    version.scan(SCAN_PATTERN).map! do |token| +      case token +      when /\A#{AlphaToken::PATTERN}\z/o   then AlphaToken +      when /\A#{BetaToken::PATTERN}\z/o    then BetaToken +      when /\A#{RCToken::PATTERN}\z/o      then RCToken +      when /\A#{PreToken::PATTERN}\z/o     then PreToken +      when /\A#{PatchToken::PATTERN}\z/o   then PatchToken +      when /\A#{NumericToken::PATTERN}\z/o then NumericToken +      when /\A#{StringToken::PATTERN}\z/o  then StringToken +      end.new(token) +    end +  end  end  class HeadVersion < Version | 
