-
-
Save akomakom/fd8bad8f4d80d973c2146b4903d2b989 to your computer and use it in GitHub Desktop.
Semantic Versioning class for Groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This evolved from pure SemVer to any-length version with optional -suffix | |
* accepts any of: | |
* 1 | |
* 1.2 | |
* 1.2.3 | |
* 1.2.3.4 (etc, no limit) | |
* 1.2.3-SNAPSHOT | |
* | |
* bump() also accepts index values, eg -1 (last component), -2 (second from end), etc: | |
* -1 (or 'MINOR') : | |
* 1.1-SNAPSHOT to 1.2-SNAPSHOT | |
* 1.1 to 1.2 | |
* 1.2.3 to 1.3.0 | |
* -1 (or 'PATCH') : 1.2.3-SNAPSHOT to 1.2.4-SNAPSHOT | |
* -2 (or 'MINOR') : 1.2.3-SNAPSHOT to 1.3.0-SNAPSHOT | |
* -3 : 1.2.3.4.5.6.7 to 1.2.3.4.6.0.0 | |
* 'PATCH' : 1.2.3.4.5.6.7 to 1.2.4.0.0.0.0 | |
*/ | |
class SemVer implements Serializable { | |
enum PatchLevel { | |
MAJOR, MINOR, PATCH | |
} | |
private int[] components | |
private String suffix = '' | |
SemVer(String version) { | |
if (version.contains('-')) { | |
suffix = version.substring(version.indexOf('-')) | |
version = version - suffix | |
} | |
components = version.tokenize('.').collect{it.toInteger()} | |
} | |
SemVer(int major, int minor, int patch) { | |
this.components = [major, minor, patch] | |
} | |
SemVer bump(int componentIndex) { | |
// from the end or front? | |
def index = (componentIndex < 0) ? components.size() + componentIndex : componentIndex | |
if (components.size() <= index) { | |
throw new IllegalArgumentException("Can't bump index ${componentIndex} of version ${toString()} because we don't have enough components") | |
} | |
components[index]++ | |
// reset all following digits to 0 | |
for (int i = index + 1 ; i < components.size() ; i++) { | |
components[i] = 0 | |
} | |
return this | |
} | |
SemVer bump(PatchLevel patchLevel) { | |
// convert to index | |
bump(PatchLevel.findIndexOf {it == patchLevel}) | |
} | |
/** | |
* One-line convenience static method. | |
* @param version - a string version with optional -suffix. | |
* @param patchLevel - which version component to increment. | |
* One of: | |
* * string name for the enum constant, | |
* * relative array index (eg -1 or "-1" for last component) | |
* @return string version after bumping: | |
*/ | |
static String bump(String version, def patchLevel = -1) { | |
def semVer = new SemVer(version) | |
PatchLevel level | |
if (!PatchLevel.any{it.name() == patchLevel}) { | |
// Not a valid enum element name, | |
// this must be an integer index in the provided version. | |
semVer.bump(patchLevel.toInteger()).toString() | |
} else { | |
semVer.bump(PatchLevel.valueOf(patchLevel)).toString() | |
} | |
} | |
/** | |
* @return the number of version numeric components | |
*/ | |
int size() { | |
return components.size() | |
} | |
String toString() { | |
return "${components.join('.')}${suffix}" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class UnitTests extends GroovyTestCase { | |
void test_semver() { | |
assertEquals '1.2.4', SemVer.bump('1.2.3') | |
assertEquals '1.2.4', SemVer.bump('1.2.3', 'PATCH') | |
assertEquals '1.3.0', SemVer.bump('1.2.3', 'MINOR') | |
assertEquals '1.3', SemVer.bump('1.2', 'MINOR') | |
assertEquals '2.0.0', SemVer.bump('1.2.3', 'MAJOR') | |
assertEquals '2.0', SemVer.bump('1.2', 'MAJOR') | |
assertEquals '1.3.0.0', SemVer.bump('1.2.3.4', 'MINOR') | |
assertEquals '1.3.0-SNAPSHOT', SemVer.bump('1.2.3-SNAPSHOT', 'MINOR') | |
assertEquals '1.3-SNAPSHOT', SemVer.bump('1.2-SNAPSHOT', 'MINOR') | |
// also by index | |
assertEquals '1.2.4', SemVer.bump('1.2.3', '-1') | |
assertEquals '1.3.0', SemVer.bump('1.2.3', '-2') | |
assertEquals '1.3.0.0', SemVer.bump('1.2.3.4', '-3') | |
//from the front | |
assertEquals '1.2.4', SemVer.bump('1.2.3', '2') | |
assertEquals '1.3.0.0', SemVer.bump('1.2.3.4', '1') | |
assertEquals '2.0.0.0', SemVer.bump('1.2.3.4', '0') | |
// bump PATCH that doesn't exist | |
expect_exception{ SemVer.bump('1.2', 'PATCH') } | |
} | |
/** | |
* Groovy's Junit doesn't seem to support @Test(expect) | |
*/ | |
private void expect_exception(def closure) { | |
try { | |
with closure | |
fail "Exception was never thrown" | |
} catch (Exception x) {} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Noice!