Skip to content

Instantly share code, notes, and snippets.

@jpf91
Created June 20, 2011 08:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jpf91/1035294 to your computer and use it in GitHub Desktop.
Save jpf91/1035294 to your computer and use it in GitHub Desktop.
import std.datetime;
import std.array;
import std.conv;
import std.string;
import std.algorithm;
struct PackageVersion
{
enum VersionType
{
release,
prerelease,
snapshot
}
VersionType type;
uint[] baseVersion;
uint pre;
DateTime date;
this(uint[] ver)
{
this.type = VersionType.release;
this.baseVersion = ver;
}
this(uint[] ver, uint preRel)
{
this.type = VersionType.prerelease;
this.baseVersion = ver;
this.pre = preRel;
}
this(uint[] ver, DateTime snap, uint preRel = 0)
{
this.type = VersionType.snapshot;
this.baseVersion = ver;
this.pre = preRel;
this.date = snap;
}
int opCmp(PackageVersion rhs)
{
return compareVersion(this, rhs);
}
string toString()
{
static string baseVerToString(uint[] basever)
{
string result;
foreach(i, number; basever)
{
result ~= to!string(number);
if(i != basever.length -1)
result ~= ".";
}
return result;
}
final switch(this.type)
{
case VersionType.release:
return format("%s", baseVerToString(this.baseVersion));
break;
case VersionType.prerelease:
return format("%s-pre%s", baseVerToString(this.baseVersion), this.pre);
break;
case VersionType.snapshot:
if(this.pre != 0)
return format("%s-pre%s snapshot-%s", baseVerToString(this.baseVersion),
this.pre, this.date.toSimpleString);
else
return format("%s snapshot-%s", baseVerToString(this.baseVersion),
this.date.toSimpleString);
break;
}
}
}
int compareBaseVer(const(uint[]) lhs, const(uint[]) rhs)
{
foreach(i, number; lhs[0 .. min(lhs.length, rhs.length)])
{
if(number > rhs[i])
return 1;
if(number < rhs[i])
return -1;
}
if(lhs.length == rhs.length)
return 0;
if(lhs.length > rhs.length)
{
foreach(number; lhs[rhs.length .. $])
{
if(number != 0)
return 1;
}
return 0;
}
if(lhs.length < rhs.length)
{
foreach(number; rhs[lhs.length .. $])
{
if(number != 0)
return -1;
}
return 0;
}
assert(0);
}
unittest
{
assert(compareBaseVer([1], [1]) == 0);
assert(compareBaseVer([0], [1]) == -1);
assert(compareBaseVer([1], [0]) == 1);
assert(compareBaseVer([1], [1, 0, 0, 0]) == 0);
assert(compareBaseVer([1, 0, 0, 1], [1]) == 1);
assert(compareBaseVer([1], [1, 0, 0, 0]) == 0);
assert(compareBaseVer([1], [1, 0, 0, 1]) == -1);
assert(compareBaseVer([1, 0, 0, 1], [1, 0, 0, 2]) == -1);
assert(compareBaseVer([1, 0, 0, 2], [1, 0, 0,1 ]) == 1);
assert(compareBaseVer([1, 1, 0, 1], [1, 0, 0, 2]) == 1);
assert(compareBaseVer([1, 0, 0, 2], [1, 1, 0,1 ]) == -1);
}
int coparePreRelease(uint[] lhs, uint lhsPre, uint[] rhs, uint rhsPre)
{
int res = compareBaseVer(lhs, rhs);
if(res != 0)
return res;
if(lhsPre == rhsPre)
return 0;
if(lhsPre == 0)
return 1;
if(rhsPre == 0)
return -1;
if(lhsPre > rhsPre)
return 1;
if(lhsPre < rhsPre)
return -1;
return 0;
}
int compareSnapshot(uint[] lhs, uint lhsPre, DateTime lhsDate, uint[] rhs,
uint rhsPre, DateTime rhsDate)
{
int res = coparePreRelease(lhs, lhsPre, rhs, rhsPre);
if(res != 0)
return res;
if(lhsDate > rhsDate)
return 1;
if(lhsDate < rhsDate)
return -1;
return 0;
}
int compareVersion(PackageVersion lhs, PackageVersion rhs)
{
final switch(lhs.type)
{
case PackageVersion.VersionType.release:
final switch(rhs.type)
{
case PackageVersion.VersionType.release:
return compareBaseVer(lhs.baseVersion, rhs.baseVersion);
break;
case PackageVersion.VersionType.prerelease:
return coparePreRelease(lhs.baseVersion, 0, rhs.baseVersion, rhs.pre);
break;
case PackageVersion.VersionType.snapshot:
return compareSnapshot(lhs.baseVersion, 0, DateTime.min,
rhs.baseVersion, rhs.pre, rhs.date);
break;
}
break;
case PackageVersion.VersionType.prerelease:
final switch(rhs.type)
{
case PackageVersion.VersionType.release:
return coparePreRelease(lhs.baseVersion, lhs.pre, rhs.baseVersion, 0);
break;
case PackageVersion.VersionType.prerelease:
return coparePreRelease(lhs.baseVersion, lhs.pre, rhs.baseVersion, rhs.pre);
break;
case PackageVersion.VersionType.snapshot:
return compareSnapshot(lhs.baseVersion, lhs.pre, DateTime.min,
rhs.baseVersion, rhs.pre, rhs.date);
break;
}
break;
case PackageVersion.VersionType.snapshot:
final switch(rhs.type)
{
case PackageVersion.VersionType.release:
return compareSnapshot(lhs.baseVersion, lhs.pre, lhs.date,
rhs.baseVersion, 0, DateTime.min);
break;
case PackageVersion.VersionType.prerelease:
return compareSnapshot(lhs.baseVersion, lhs.pre, lhs.date,
rhs.baseVersion, rhs.pre, DateTime.min);
break;
case PackageVersion.VersionType.snapshot:
return compareSnapshot(lhs.baseVersion, lhs.pre, lhs.date,
rhs.baseVersion, rhs.pre, rhs.date);
break;
}
break;
}
}
import std.random;
import std.stdio;
void main()
{
PackageVersion[] versions;
versions ~= PackageVersion([0,0,0,1]);
versions ~= PackageVersion([0,0,1,1], DateTime(2011, 06, 20, 0, 0, 0)); //snapshot
versions ~= PackageVersion([0,0,1,1], DateTime(2011, 06, 20, 1, 0, 0)); //snapshot
versions ~= PackageVersion([0,0,1,1], 1); //alpha1
versions ~= PackageVersion([0,0,1,1], DateTime(2011, 06, 20, 1, 0, 0), 1); //snapshot based on alpha1
versions ~= PackageVersion([0,0,1,1], 2); //alpha2
versions ~= PackageVersion([0,0,1,1], 3); //beta1
versions ~= PackageVersion([0,0,1,1], DateTime(2011, 06, 20, 1, 0, 1), 3); //snapshot
versions ~= PackageVersion([0,0,1,1], DateTime(2011, 06, 20, 1, 0, 2), 3); //snapshot
versions ~= PackageVersion([0,0,1,1], DateTime(2011, 06, 20, 1, 0, 3), 3); //snapshot
versions ~= PackageVersion([0,0,2,0], 1); //alpha1
versions ~= PackageVersion([0,0,2,0], 2); //alpha2
versions ~= PackageVersion([0,0,2,0], DateTime(2011, 06, 20, 1, 0, 10), 2); //snapshot
versions ~= PackageVersion([0,0,2,0], DateTime(2011, 06, 20, 1, 0, 11), 2); //snapshot
versions ~= PackageVersion([0,0,1,1], 4); //rc1
versions ~= PackageVersion([0,0,1,1], DateTime(2011, 06, 20, 1, 0, 20), 4); //snapshot
versions ~= PackageVersion([0,0,1,1], DateTime(2011, 06, 20, 1, 0, 21), 4); //snapshot
versions ~= PackageVersion([0,0,1,1]); //final
randomShuffle(versions);
sort!("a < b")(versions);
foreach(ver; versions)
writeln(ver);
}
@jpf91
Copy link
Author

jpf91 commented Jun 20, 2011

Output:

0.0.1.1-pre1
0.0.1.1-pre1 snapshot-2011-Jun-20 01:00:00
0.0.1.1-pre2
0.0.1.1-pre3
0.0.1.1-pre3 snapshot-2011-Jun-20 01:00:01
0.0.1.1-pre3 snapshot-2011-Jun-20 01:00:02
0.0.1.1-pre3 snapshot-2011-Jun-20 01:00:03
0.0.1.1-pre4
0.0.1.1-pre4 snapshot-2011-Jun-20 01:00:20
0.0.1.1-pre4 snapshot-2011-Jun-20 01:00:21
0.0.1.1
0.0.1.1 snapshot-2011-Jun-20 00:00:00
0.0.1.1 snapshot-2011-Jun-20 01:00:00
0.0.2.0-pre1
0.0.2.0-pre2
0.0.2.0-pre2 snapshot-2011-Jun-20 01:00:10
0.0.2.0-pre2 snapshot-2011-Jun-20 01:00:11```

@jpf91
Copy link
Author

jpf91 commented Jun 20, 2011

Damn, just noted it sorts in the wrong direction :fp I guess I should have looked up the opCmp documentation...

EDIT: fixed

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