keg: update sorting by version logic
This updates logic to add a `#scheme_and_version` method to be used with `.sort_by` and `.max_by`. Using `Keg#version` by itself can be inaccurate when different version schemes are present. This also updates the behavior of `Formula#eligible_kegs_for_cleanup` to match the previous behavior. We were dropping the wrong keg based on the sort being reversed in a previous PR.
This commit is contained in:
		
							parent
							
								
									9ae51618b9
								
							
						
					
					
						commit
						db507be41a
					
				@ -381,7 +381,7 @@ module Homebrew
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        Keg.sort(stable_kegs).first
 | 
			
		||||
        stable_kegs.max_by(&:scheme_and_version)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def resolve_default_keg(name)
 | 
			
		||||
 | 
			
		||||
@ -296,7 +296,7 @@ module Homebrew
 | 
			
		||||
        heads, versioned = kegs.partition { |k| k.version.head? }
 | 
			
		||||
        kegs = [
 | 
			
		||||
          *heads.sort_by { |k| -Tab.for_keg(k).time.to_i },
 | 
			
		||||
          *Keg.sort(versioned),
 | 
			
		||||
          *versioned.sort_by(&:scheme_and_version),
 | 
			
		||||
        ]
 | 
			
		||||
        if kegs.empty?
 | 
			
		||||
          puts "Not installed"
 | 
			
		||||
 | 
			
		||||
@ -175,7 +175,7 @@ module Homebrew
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      not_outdated.each do |f|
 | 
			
		||||
        latest_keg = Keg.sort(f.installed_kegs).first
 | 
			
		||||
        latest_keg = f.installed_kegs.max_by(&:scheme_and_version)
 | 
			
		||||
        if latest_keg.nil?
 | 
			
		||||
          ofail "#{f.full_specified_name} not installed"
 | 
			
		||||
        else
 | 
			
		||||
 | 
			
		||||
@ -1508,7 +1508,7 @@ class Formula
 | 
			
		||||
        []
 | 
			
		||||
      else
 | 
			
		||||
        all_kegs += old_installed_formulae.flat_map(&:installed_kegs)
 | 
			
		||||
        Keg.sort(all_kegs)
 | 
			
		||||
        all_kegs.sort_by(&:scheme_and_version)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
@ -2268,7 +2268,7 @@ class Formula
 | 
			
		||||
 | 
			
		||||
    hsh.merge!(dependencies_hash)
 | 
			
		||||
 | 
			
		||||
    hsh["installed"] = Keg.sort(installed_kegs).map do |keg|
 | 
			
		||||
    hsh["installed"] = installed_kegs.sort_by(&:scheme_and_version).map do |keg|
 | 
			
		||||
      tab = Tab.for_keg keg
 | 
			
		||||
      {
 | 
			
		||||
        "version"                 => keg.version.to_s,
 | 
			
		||||
@ -2841,7 +2841,7 @@ class Formula
 | 
			
		||||
      eligible_kegs = if head? && (head_prefix = latest_head_prefix)
 | 
			
		||||
        head, stable = installed_kegs.partition { |k| k.version.head? }
 | 
			
		||||
        # Remove newest head and stable kegs
 | 
			
		||||
        head - [Keg.new(head_prefix)] + Keg.sort(stable).drop(1)
 | 
			
		||||
        head - [Keg.new(head_prefix)] + stable.sort_by(&:scheme_and_version).slice(0...-1)
 | 
			
		||||
      else
 | 
			
		||||
        installed_kegs.select do |keg|
 | 
			
		||||
          tab = Tab.for_keg(keg)
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,7 @@ class FormulaPin
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def pin
 | 
			
		||||
    latest_keg = Keg.sort(@formula.installed_kegs).first
 | 
			
		||||
    latest_keg = @formula.installed_kegs.max_by(&:scheme_and_version)
 | 
			
		||||
    return if latest_keg.nil?
 | 
			
		||||
 | 
			
		||||
    pin_at(latest_keg.version)
 | 
			
		||||
 | 
			
		||||
@ -994,7 +994,7 @@ module Formulary
 | 
			
		||||
    flags: T.unsafe(nil)
 | 
			
		||||
  )
 | 
			
		||||
    kegs = rack.directory? ? rack.subdirs.map { |d| Keg.new(d) } : []
 | 
			
		||||
    keg = kegs.find(&:linked?) || kegs.find(&:optlinked?) || Keg.sort(kegs).first
 | 
			
		||||
    keg = kegs.find(&:linked?) || kegs.find(&:optlinked?) || kegs.max_by(&:scheme_and_version)
 | 
			
		||||
 | 
			
		||||
    options = {
 | 
			
		||||
      alias_path:,
 | 
			
		||||
 | 
			
		||||
@ -56,7 +56,7 @@ module InstalledDependents
 | 
			
		||||
        f_kegs = kegs_by_source[[f.name, f.tap]]
 | 
			
		||||
        next unless f_kegs
 | 
			
		||||
 | 
			
		||||
        Keg.sort(f_kegs).first
 | 
			
		||||
        f_kegs.max_by(&:scheme_and_version)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      next if required_kegs.empty?
 | 
			
		||||
 | 
			
		||||
@ -148,11 +148,6 @@ class Keg
 | 
			
		||||
    Formula.racks.flat_map(&:subdirs).map { |d| new(d) }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  sig { params(kegs: T::Array[Keg]).returns(T::Array[Keg]) }
 | 
			
		||||
  def self.sort(kegs)
 | 
			
		||||
    kegs.sort_by { |keg| [keg.version_scheme, keg.version] }.reverse!
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  attr_reader :path, :name, :linked_keg_record, :opt_record
 | 
			
		||||
 | 
			
		||||
  protected :path
 | 
			
		||||
@ -396,6 +391,12 @@ class Keg
 | 
			
		||||
    @version_scheme ||= tab.version_scheme
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # For ordering kegs by version with `.sort_by`, `.max_by`, etc.
 | 
			
		||||
  # @see Formula.version_scheme
 | 
			
		||||
  def scheme_and_version
 | 
			
		||||
    [version_scheme, version]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def to_formula
 | 
			
		||||
    Formulary.from_keg(self)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user