github.com/bshelton229/agent@v3.5.4+incompatible/scripts/latest_version.rb (about)

     1  #!/usr/bin/env ruby
     2  
     3  # Reads a list of versions from STDIN and prints the highest one:
     4  #
     5  # echo -e "latest\n1.0.1\n1.2.1\n2.3.2-beta.2\n2.3.2-alpha.2\n3.1\n3.1-beta.1\n3.0" | ruby latest_version.rb
     6  # => 3.1
     7  
     8  def parse(version_string)
     9    pattern = %r{
    10      # Major is required
    11      (?<major>\d+)
    12      # All these numbers are optional
    13      (\.(?<minor>\d+))?
    14      (\.(?<patch>\d+))?
    15      (\.(?<tiny>\d+))?
    16      # Pre is a string like alpha, beta, etc
    17      (\-(?<prerelease>[a-z]+))?
    18      # The rest are numbers, and we dont care if its dashes or dots
    19      ([\-\.](?<prerelease_major>\d+))?
    20      ([\-\.](?<prerelease_minor>\d+))?
    21      ([\-\.](?<prerelease_patch>\d+))?
    22      ([\-\.](?<prerelease_tiny>\d+))?
    23    }x
    24  
    25    if m = pattern.match(version_string)
    26      {
    27        # Parse all the integer strings. If it's nil, make it 0
    28        # (i.e. "2" becomes "2,0,0,0,nil,0,0,0,0")
    29        major:            m[:major].to_i,
    30        minor:            m[:minor].to_i,
    31        patch:            m[:patch].to_i,
    32        tiny:             m[:tiny].to_i,
    33        prerelease:       m[:prerelease],
    34        prerelease_major: m[:prerelease_major].to_i,
    35        prerelease_minor: m[:prerelease_minor].to_i,
    36        prerelease_patch: m[:prerelease_patch].to_i,
    37        prerelease_tiny:  m[:prerelease_tiny].to_i
    38      }
    39    end
    40  end
    41  
    42  def sort(v1, v2)
    43    # Stable release get preferred over pre-releases, but if we just let Ruby
    44    # sort v1.values <=> v2.values:
    45    #
    46    # [2, 3, 2, 1, nil,     0, 0, 0, 0]
    47    # [2, 3, 2, 1, 'beta',  1, 1, 0, 0]
    48    #
    49    # then 2.3.2.1-beta.1 would be greater than 2.3.2.1
    50    #
    51    # So we special case 2.3.2.1 <=> 2.3.2.1-beta.1 (or vice versa) and preference the
    52    # version that isn't the prerelease
    53    if v1.values.first(4) == v2.values.first(4) && (v1[:prerelease].nil? || v2[:prerelease].nil?)
    54      # 2.3.2.1 <=> 2.3.2.1
    55      if v1[:prerelease].nil? && v2[:prerelease].nil?
    56        0
    57      # 2.3.2.1 <=> 2.3.2.1-beta.1
    58      elsif v1[:prerelease].nil? && v2[:prerelease]
    59        1
    60      # 2.3.2.1-beta.1 <=> 2.3.2.1
    61      elsif v1[:prerelease] && v2[:prerelease].nil?
    62        -1
    63      end
    64    # For all other cases we can just let Ruby sort all the things
    65    #
    66    # [2, 0, 0, 0, nil,     0, 0, 0, 0]
    67    # [2, 3, 0, 0, nil,     0, 0, 0, 0]
    68    # [2, 3, 0, 0, nil,     0, 0, 0, 0]
    69    # [2, 3, 2, 1, 'alpha', 0, 0, 0, 0]
    70    # [2, 3, 2, 1, 'beta',  0, 0, 0, 0]
    71    # [2, 3, 2, 1, 'beta',  1, 0, 0, 0]
    72    # [2, 3, 2, 1, 'beta',  1, 1, 0, 0]
    73    # [2, 3, 2, 2, nil,     0, 0, 0, 0]
    74    else
    75      v1.values <=> v2.values
    76    end
    77  end
    78  
    79  parsed_version_lines = STDIN.readlines.map(&:strip).map {|line|
    80    if version = parse(line)
    81      [line, version]
    82    end
    83  }.compact
    84  
    85  puts parsed_version_lines.sort {|(l1, v1), (l2, v2)|
    86    sort(v1, v2)
    87  }.last[0]