Skip to content

Instantly share code, notes, and snippets.

@founddrama
Last active April 20, 2023 12:55
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save founddrama/971284 to your computer and use it in GitHub Desktop.
Save founddrama/971284 to your computer and use it in GitHub Desktop.
a version comparator (e.g., "1.0.2" < "1.0.10")
fixme
1.0.2
1.2.2.3
0.1
0.1.0.2
0.2
1.0
1.0.1.2
1.2.3
0.1.0.23
0.1.0.10
0.2-beta
0.1.0.2
2.0
0.2.0.4
0.2.0.3.1
1.5.2_05
1.5.2_04
1.5.2_10
1.6.0_01
2.0.0_02
1.0RC2
1.0RC1
3.1
#!/usr/bin/env ruby
args = $*.to_a
if args.index("-c")
ct = [args[args.index("-c") + 1].to_i, 1].max
end
tags = $stdin.to_a
tags.sort! {|a,b|
a = a.split(/[\._]/)
b = b.split(/[\._]/)
def is_i(str)
return str =~ /^\d+$/
end
c = 0
for i in 0..([a.size, b.size].max)
if i == a.size
c = is_i(b[i]) ? -1 : 1
elsif i == b.size
c = is_i(a[i]) ? 1 : -1
end
if is_i(a[i]) && is_i(b[i])
c = a[i].to_i <=> b[i].to_i
elsif is_i(a[i])
c = 1
elsif is_i(b[i])
c = -1
elsif !a[i].nil? && !b[i].nil?
c = a[i] <=> b[i]
end
break if c != 0
end
c
}
if ct
ct = [ct, tags.size].min
tag_range = tags[-ct..-1]
puts "LAST #{ct} VERSIONS:"
tag_range.each {|i| puts "#{i}" }
else
puts "LATEST VERSION: #{tags[-1]}"
end
def versions = []
def f = new File('mock-version-tags.txt')
f.eachLine { versions << it }
def versionComparator = { a, b ->
def VALID_TOKENS = /._/
a = a.tokenize(VALID_TOKENS)
b = b.tokenize(VALID_TOKENS)
for (i in 0..<Math.max(a.size(), b.size())) {
if (i == a.size()) {
return b[i].isInteger() ? -1 : 1
} else if (i == b.size()) {
return a[i].isInteger() ? 1 : -1
}
if (a[i].isInteger() && b[i].isInteger()) {
int c = (a[i] as int) <=> (b[i] as int)
if (c != 0) {
return c
}
} else if (a[i].isInteger()) {
return 1
} else if (b[i].isInteger()) {
return -1
} else {
int c = a[i] <=> b[i]
if (c != 0) {
return c
}
}
}
return 0
}
versions.sort(versionComparator)
// for the Node.js crew:
function versionComparator(a, b){
a = a.split(/[._]/);
b = b.split(/[._]/);
var mx = Math.max(a.length, b.length),
isInt(n){
return (n || '').match(/^\d+$/) !== null;
},
c = 0,
ai, bi;
for (var i = 0; i < mx; i++) {
ai = a[i],
bi = b[i];
if(c !== 0) break;
switch(i){
case a.length:
return isInt(ai) ? -1 : 1;
case b.length:
return isInt(bi) ? 1 : -1;
default:
var aiInt = isInt(ai),
biInt = isInt(bi);
if (aiInt && biInt) {
ai = parseInt(ai);
bi = parseInt(bi);
c = ai === bi ? 0 : ai > bi ? 1 : -1;
if (c !== 0) break;
} else if (aiInt) {
return 1;
} else if (biInt) {
return -1;
} else {
c = ai === bi ? 0 : ai > bi ? 1 : -1;
break;
}
}
}
return c;
}
@founddrama
Copy link
Author

Notes:

[fixme, 0.2-beta, 0.1, 0.1.0.2, 0.1.0.2,
0.1.0.10, 0.1.0.23, 0.2 0.2.0.3.1, 0.2.0.4,
1.0RC1, 1.0RC2, 1.0, 1.0.1.2, 1.0.2, 1.2.2.3,
1.2.3, 1.5.2_04, 1.5.2_05, 1.5.2_10, 1.6.0_01,
2.0, 2.0.0_02, 3.1]
  • Groovy implementation: result:
[fixme, 0.2-beta, 0.1, 0.1.0.2, 0.1.0.2,
0.1.0.10, 0.1.0.23, 0.2 0.2.0.3.1, 0.2.0.4,
1.0RC1, 1.0RC2, 1.0, 1.0.1.2, 1.0.2, 1.2.2.3,
1.2.3, 1.5.2_04, 1.5.2_05, 1.5.2_10, 1.6.0_01,
2.0, 2.0.0_02, 3.1]

@prineshaz
Copy link

Thank you!

@MalKeshar
Copy link

Why 0.2-beta is lower version than 0.1?

@ocafebabe
Copy link

Thanks mate!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment