Skip to content

Commit

Permalink
refactor: robust version parsing
Browse files Browse the repository at this point in the history
Tries to parse given version in `ComparableVersion` disregarding
non-numeric characters. This allows parsing Docker CLI versions like
`18.06.0-dev`.
  • Loading branch information
zregvart committed Feb 26, 2019
1 parent c58a6f1 commit 39456f5
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
package org.testcontainers.utility;

import java.util.ArrayList;
import java.util.List;

import com.google.common.annotations.VisibleForTesting;

import org.jetbrains.annotations.NotNull;

public class ComparableVersion implements Comparable<ComparableVersion> {
public final class ComparableVersion implements Comparable<ComparableVersion> {

private final String[] parts;
private final int[] parts;

public static final ComparableVersion OS_VERSION = new ComparableVersion(System.getProperty("os.version"));

public ComparableVersion(String version) {
this.parts = version.split("\\.");
this.parts = parseVersion(version);
}

@Override
public int compareTo(@NotNull ComparableVersion other) {
for (int i=0; i<Math.min(this.parts.length, other.parts.length); i++) {
Integer thisPart = Integer.valueOf(this.parts[i]);
Integer otherPart = Integer.valueOf(other.parts[i]);
int thisPart = this.parts[i];
int otherPart = other.parts[i];
if (thisPart > otherPart) {
return 1;
} else if (thisPart < otherPart) {
Expand All @@ -34,4 +39,33 @@ public boolean isLessThan(String other) {
public boolean isGreaterThanOrEqualTo(String other) {
return this.compareTo(new ComparableVersion(other)) >= 0;
}

@VisibleForTesting
static int[] parseVersion(final String version) {
final List<Integer> parts = new ArrayList<>(5);

int acc = 0;
for (final char c : version.toCharArray()) {
if (c == '.') {
parts.add(acc);
acc = 0;
}

if (Character.isDigit(c)) {
acc = 10 * acc + Character.digit(c, 10);
}
}

if (acc != 0) {
parts.add(acc);
}

final int[] ret = new int[parts.size()];
for (int i = 0; i < ret.length; i++) {
ret[i] = parts.get(i);
}

return ret;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.testcontainers.utility;

import java.util.Arrays;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import static org.junit.Assert.assertArrayEquals;

@RunWith(Parameterized.class)
public class ComparableVersionTest {

private final int[] expected;
private final String given;

public ComparableVersionTest(final String given, final int[] expected) {
this.given = given;
this.expected = expected;
}

@Test
public void shouldParseVersions() {
assertArrayEquals(expected, ComparableVersion.parseVersion(given));
}

@Parameters(name = "Parsed version: {0}={1}")
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][] {
{"1.2.3", new int[] {1, 2, 3}},
{"", new int[0]},
{"1", new int[] {1}},
{"1.2.3.4.5.6.7", new int[] {1, 2, 3, 4, 5, 6, 7}},
{"1.2-dev", new int[] {1, 2}},
{"18.06.0-dev", new int[] {18, 6}},
});
}

}

0 comments on commit 39456f5

Please sign in to comment.