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]