aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-plugin-api
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2017-01-05 17:59:05 +0100
committerSimon Brandhof <simon.brandhof@sonarsource.com>2017-01-11 11:20:36 +0100
commite1eaa719e95a20438dda7516797d155db1c3b56c (patch)
treecb9935064763eb6b05aaad6fde3ac3a9d417afb7 /sonar-plugin-api
parentf3020783d4aecd24160171f13c3cfa93bb46fe93 (diff)
downloadsonarqube-e1eaa719e95a20438dda7516797d155db1c3b56c.tar.gz
sonarqube-e1eaa719e95a20438dda7516797d155db1c3b56c.zip
SONAR-8458 add SonarQube buildNumber to plugin API
Diffstat (limited to 'sonar-plugin-api')
-rw-r--r--sonar-plugin-api/pom.xml2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/SonarProduct.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/SonarRuntime.java9
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/internal/ApiVersion.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java5
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/Version.java96
-rw-r--r--sonar-plugin-api/src/main/resources/sonar-api-version.txt1
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/internal/ApiVersionTest.java2
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/VersionTest.java51
9 files changed, 121 insertions, 49 deletions
diff --git a/sonar-plugin-api/pom.xml b/sonar-plugin-api/pom.xml
index 306c9691c2d..cddd24b91af 100644
--- a/sonar-plugin-api/pom.xml
+++ b/sonar-plugin-api/pom.xml
@@ -217,7 +217,7 @@
<resources>
<resource>
- <!-- Used to set SonarQube version in sq-version.txt file -->
+ <!-- Used to resolve variables in files sq-version.txt and sonar-api-version.txt -->
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/SonarProduct.java b/sonar-plugin-api/src/main/java/org/sonar/api/SonarProduct.java
index 97a5dba1e37..42bd1f35343 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/SonarProduct.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/SonarProduct.java
@@ -26,6 +26,6 @@ package org.sonar.api;
public enum SonarProduct {
SONARQUBE,
- SONARLINT;
+ SONARLINT
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/SonarRuntime.java b/sonar-plugin-api/src/main/java/org/sonar/api/SonarRuntime.java
index fdae32f5f5f..df35e1a488c 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/SonarRuntime.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/SonarRuntime.java
@@ -144,9 +144,12 @@ import org.sonarsource.api.sonarlint.SonarLintSide;
public interface SonarRuntime {
/**
- * Version of API (sonar-plugin-api artifact) at runtime.
- * It can be helpful to call some API classes/methods without checking their availability at
- * runtime by using reflection.
+ * Version of API (sonar-plugin-api artifact) at runtime.
+ * It can be helpful to call some API classes/methods without checking their availability at
+ * runtime by using reflection.
+ * <br/>
+ * Since 6.3, the returned version includes the build number in the fourth field, for
+ * example {@code "6.3.0.12345"}.
*/
Version getApiVersion();
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/internal/ApiVersion.java b/sonar-plugin-api/src/main/java/org/sonar/api/internal/ApiVersion.java
index de57cf0761a..5b03cc75fc5 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/internal/ApiVersion.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/internal/ApiVersion.java
@@ -33,7 +33,7 @@ import org.sonar.api.utils.Version;
*/
public class ApiVersion {
- private static final String FILE_PATH = "/sq-version.txt";
+ private static final String FILE_PATH = "/sonar-api-version.txt";
private ApiVersion() {
// only static methods
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java b/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java
index 601c8d017c2..046190b15a5 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java
@@ -40,17 +40,16 @@ public class SonarRuntimeImpl implements SonarRuntime {
private final SonarQubeSide sonarQubeSide;
private SonarRuntimeImpl(Version version, SonarProduct product, @Nullable SonarQubeSide sonarQubeSide) {
- requireNonNull(version);
requireNonNull(product);
checkArgument((product == SonarProduct.SONARQUBE) == (sonarQubeSide != null), "sonarQubeSide should be provided only for SonarQube product");
- this.version = version;
+ this.version = requireNonNull(version);
this.product = product;
this.sonarQubeSide = sonarQubeSide;
}
@Override
public Version getApiVersion() {
- return this.version;
+ return version;
}
@Override
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/Version.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/Version.java
index 23f7a2b738f..1ba2065f8b5 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/Version.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/Version.java
@@ -24,15 +24,16 @@ import java.util.List;
import javax.annotation.concurrent.Immutable;
import static java.lang.Integer.parseInt;
+import static java.lang.Long.parseLong;
import static java.util.Objects.requireNonNull;
import static org.apache.commons.lang.StringUtils.substringAfter;
import static org.apache.commons.lang.StringUtils.substringBefore;
import static org.apache.commons.lang.StringUtils.trimToEmpty;
/**
- * Version composed of 3 integer-sequences (major, minor and patch fields) and optionally a qualifier.
+ * Version composed of maximum four fields (major, minor, patch and build ID numbers) and optionally a qualifier.
* <p>
- * Examples: 1.0, 1.0.0, 1.2.3, 1.2-beta1, 1.2.1-beta-1
+ * Examples: 1.0, 1.0.0, 1.2.3, 1.2-beta1, 1.2.1-beta-1, 1.2.3.4567
* <p>
* <h3>IMPORTANT NOTE</h3>
* Qualifier is ignored when comparing objects (methods {@link #equals(Object)}, {@link #hashCode()}
@@ -48,6 +49,9 @@ import static org.apache.commons.lang.StringUtils.trimToEmpty;
@Immutable
public class Version implements Comparable<Version> {
+ private static final long DEFAULT_BUILD_NUMBER = 0L;
+ private static final int DEFAULT_PATCH = 0;
+ private static final String DEFAULT_QUALIFIER = "";
private static final String QUALIFIER_SEPARATOR = "-";
private static final char SEQUENCE_SEPARATOR = '.';
private static final Splitter SEQUENCE_SPLITTER = Splitter.on(SEQUENCE_SEPARATOR);
@@ -55,14 +59,15 @@ public class Version implements Comparable<Version> {
private final int major;
private final int minor;
private final int patch;
+ private final long buildNumber;
private final String qualifier;
- private Version(int major, int minor, int patch, String qualifier) {
- requireNonNull(qualifier, "Version qualifier must not be null");
+ private Version(int major, int minor, int patch, long buildNumber, String qualifier) {
this.major = major;
this.minor = minor;
this.patch = patch;
- this.qualifier = qualifier;
+ this.buildNumber = buildNumber;
+ this.qualifier = requireNonNull(qualifier, "Version qualifier must not be null");
}
public int major() {
@@ -78,6 +83,15 @@ public class Version implements Comparable<Version> {
}
/**
+ * Build number if the fourth field, for example {@code 12345} for "6.3.0.12345".
+ * If absent, then value is zero.
+ * @since 6.3
+ */
+ public long buildNumber() {
+ return buildNumber;
+ }
+
+ /**
* @return non-null suffix. Empty if absent, else the suffix without the first character "-"
*/
public String qualifier() {
@@ -93,11 +107,13 @@ public class Version implements Comparable<Version> {
* <li>1-beta-1</li>
* <li>1.2-beta-1</li>
* <li>1.2.3-beta-1</li>
+ * <li>1.2.3.4567</li>
+ * <li>1.2.3.4567-beta-1</li>
* </ul>
* Note that the optional qualifier is the part after the first "-".
*
* @throws IllegalArgumentException if parameter is badly formatted, for example
- * if it defines 4 integer-sequences.
+ * if it defines 5 integer-sequences.
*/
public static Version parse(String text) {
String s = trimToEmpty(text);
@@ -105,43 +121,58 @@ public class Version implements Comparable<Version> {
if (!qualifier.isEmpty()) {
s = substringBefore(s, QUALIFIER_SEPARATOR);
}
- List<String> split = SEQUENCE_SPLITTER.splitToList(s);
+ List<String> fields = SEQUENCE_SPLITTER.splitToList(s);
int major = 0;
int minor = 0;
- int patch = 0;
- int size = split.size();
+ int patch = DEFAULT_PATCH;
+ long buildNumber = DEFAULT_BUILD_NUMBER;
+ int size = fields.size();
if (size > 0) {
- major = parseSequence(split.get(0));
+ major = parseFieldAsInt(fields.get(0));
if (size > 1) {
- minor = parseSequence(split.get(1));
+ minor = parseFieldAsInt(fields.get(1));
if (size > 2) {
- patch = parseSequence(split.get(2));
+ patch = parseFieldAsInt(fields.get(2));
if (size > 3) {
- throw new IllegalArgumentException("Only 3 sequences are accepted");
+ buildNumber = parseFieldAsLong(fields.get(3));
+ if (size > 4) {
+ throw new IllegalArgumentException("Maximum 4 fields are accepted: " + text);
+ }
}
}
}
}
- return new Version(major, minor, patch, qualifier);
+ return new Version(major, minor, patch, buildNumber, qualifier);
}
public static Version create(int major, int minor) {
- return new Version(major, minor, 0, "");
+ return new Version(major, minor, DEFAULT_PATCH, DEFAULT_BUILD_NUMBER, DEFAULT_QUALIFIER);
}
public static Version create(int major, int minor, int patch) {
- return new Version(major, minor, patch, "");
+ return new Version(major, minor, patch, DEFAULT_BUILD_NUMBER, DEFAULT_QUALIFIER);
}
+ /**
+ * @deprecated in 6.3 to avoid ambiguity with build number (see {@link #buildNumber()}
+ */
+ @Deprecated
public static Version create(int major, int minor, int patch, String qualifier) {
- return new Version(major, minor, patch, qualifier);
+ return new Version(major, minor, patch, DEFAULT_BUILD_NUMBER, qualifier);
}
- private static int parseSequence(String sequence) {
- if (sequence.isEmpty()) {
+ private static int parseFieldAsInt(String field) {
+ if (field.isEmpty()) {
return 0;
}
- return parseInt(sequence);
+ return parseInt(field);
+ }
+
+ private static long parseFieldAsLong(String field) {
+ if (field.isEmpty()) {
+ return 0L;
+ }
+ return parseLong(field);
}
public boolean isGreaterThanOrEqual(Version than) {
@@ -153,11 +184,20 @@ public class Version implements Comparable<Version> {
if (this == o) {
return true;
}
- if (!(o instanceof Version)) {
+ if (o == null || getClass() != o.getClass()) {
return false;
}
- Version other = (Version) o;
- return major == other.major && minor == other.minor && patch == other.patch;
+ Version version = (Version) o;
+ if (major != version.major) {
+ return false;
+ }
+ if (minor != version.minor) {
+ return false;
+ }
+ if (patch != version.patch) {
+ return false;
+ }
+ return buildNumber == version.buildNumber;
}
@Override
@@ -165,6 +205,7 @@ public class Version implements Comparable<Version> {
int result = major;
result = 31 * result + minor;
result = 31 * result + patch;
+ result = 31 * result + (int) (buildNumber ^ (buildNumber >>> 32));
return result;
}
@@ -175,6 +216,10 @@ public class Version implements Comparable<Version> {
c = minor - other.minor;
if (c == 0) {
c = patch - other.patch;
+ if (c == 0) {
+ long diff = buildNumber - other.buildNumber;
+ c = diff > 0 ? 1 : (diff < 0 ? -1 : 0);
+ }
}
}
return c;
@@ -184,8 +229,11 @@ public class Version implements Comparable<Version> {
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(major).append(SEQUENCE_SEPARATOR).append(minor);
- if (patch > 0) {
+ if (patch > 0 || buildNumber > 0) {
sb.append(SEQUENCE_SEPARATOR).append(patch);
+ if (buildNumber > 0) {
+ sb.append(SEQUENCE_SEPARATOR).append(buildNumber);
+ }
}
if (!qualifier.isEmpty()) {
sb.append(QUALIFIER_SEPARATOR).append(qualifier);
diff --git a/sonar-plugin-api/src/main/resources/sonar-api-version.txt b/sonar-plugin-api/src/main/resources/sonar-api-version.txt
new file mode 100644
index 00000000000..ad96e7cf933
--- /dev/null
+++ b/sonar-plugin-api/src/main/resources/sonar-api-version.txt
@@ -0,0 +1 @@
+${project.version}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/internal/ApiVersionTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/internal/ApiVersionTest.java
index 996b0648ddf..bed7ac47508 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/internal/ApiVersionTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/internal/ApiVersionTest.java
@@ -46,7 +46,7 @@ public class ApiVersionTest {
@Test
public void throw_ISE_if_fail_to_load_version() throws Exception {
expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("Can not load /sq-version.txt from classpath");
+ expectedException.expectMessage("Can not load /sonar-api-version.txt from classpath");
System2 system = spy(System2.class);
when(system.getResource(anyString())).thenReturn(new File("target/unknown").toURI().toURL());
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/VersionTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/VersionTest.java
index a702c852fd5..ef777d243b5 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/VersionTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/VersionTest.java
@@ -33,20 +33,23 @@ public class VersionTest {
@Test
public void test_parse() {
- assertVersion(parse(""), 0, 0, 0, "");
- assertVersion(parse("1"), 1, 0, 0, "");
- assertVersion(parse("1.2"), 1, 2, 0, "");
- assertVersion(parse("1.2.3"), 1, 2, 3, "");
- assertVersion(parse("1.2-beta-1"), 1, 2, 0, "beta-1");
- assertVersion(parse("1.2.3-beta1"), 1, 2, 3, "beta1");
- assertVersion(parse("1.2.3-beta-1"), 1, 2, 3, "beta-1");
+ assertVersion(parse(""), 0, 0, 0, 0, "");
+ assertVersion(parse("1"), 1, 0, 0, 0, "");
+ assertVersion(parse("1.2"), 1, 2, 0, 0,"");
+ assertVersion(parse("1.2.3"), 1, 2, 3, 0,"");
+ assertVersion(parse("1.2-beta-1"), 1, 2, 0, 0,"beta-1");
+ assertVersion(parse("1.2.3-beta1"), 1, 2, 3, 0,"beta1");
+ assertVersion(parse("1.2.3-beta-1"), 1, 2, 3, 0,"beta-1");
+ assertVersion(parse("1.2.3.4567"), 1, 2, 3, 4567,"");
+ assertVersion(parse("1.2.3.4567-alpha"), 1, 2, 3, 4567,"alpha");
}
@Test
- public void parse_throws_IAE_if_more_than_3_sequences() {
+ public void parse_throws_IAE_if_more_than_4_fields() {
expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Only 3 sequences are accepted");
- parse("1.2.3.4");
+ expectedException.expectMessage("Maximum 4 fields are accepted: 1.2.3.456.7");
+
+ parse("1.2.3.456.7");
}
@Test
@@ -84,6 +87,15 @@ public class VersionTest {
}
@Test
+ public void compareTo_handles_build_number() {
+ assertThat(parse("1.2").compareTo(parse("1.2.0.0"))).isEqualTo(0);
+ assertThat(parse("1.2.3.1234").compareTo(parse("1.2.3.4567"))).isLessThan(0);
+ assertThat(parse("1.2.3.1234").compareTo(parse("1.2.3"))).isGreaterThan(0);
+ assertThat(parse("1.2.3.1234").compareTo(parse("1.2.4"))).isLessThan(0);
+ assertThat(parse("1.2.3.9999").compareTo(parse("1.2.4.1111"))).isLessThan(0);
+ }
+
+ @Test
public void qualifier_is_ignored_from_comparison() {
assertThat(parse("1.2.3")).isEqualTo(parse("1.2.3-build1"));
assertThat(parse("1.2.3")).isEqualTo(parse("1.2.3-build1"));
@@ -97,23 +109,32 @@ public class VersionTest {
assertThat(parse("1.2.3").toString()).isEqualTo("1.2.3");
assertThat(parse("1.2-b1").toString()).isEqualTo("1.2-b1");
assertThat(parse("1.2.3-b1").toString()).isEqualTo("1.2.3-b1");
+ assertThat(parse("1.2.3.4567").toString()).isEqualTo("1.2.3.4567");
+ assertThat(parse("1.2.3.4567-beta1").toString()).isEqualTo("1.2.3.4567-beta1");
+
+ // do not display zero numbers when possible
+ assertThat(parse("1.2.0.0").toString()).isEqualTo("1.2");
+ assertThat(parse("1.2.0.1").toString()).isEqualTo("1.2.0.1");
+ assertThat(parse("1.2.1.0").toString()).isEqualTo("1.2.1");
+ assertThat(parse("1.2.1.0-beta").toString()).isEqualTo("1.2.1-beta");
}
@Test
public void test_create() {
- assertVersion(Version.create(1, 2), 1, 2, 0, "");
- assertVersion(Version.create(1, 2, 3), 1, 2, 3, "");
- assertVersion(Version.create(1, 2, 0, ""), 1, 2, 0, "");
- assertVersion(Version.create(1, 2, 3, "build1"), 1, 2, 3, "build1");
+ assertVersion(Version.create(1, 2), 1, 2, 0, 0, "");
+ assertVersion(Version.create(1, 2, 3), 1, 2, 3, 0, "");
+ assertVersion(Version.create(1, 2, 0, ""), 1, 2, 0, 0, "");
+ assertVersion(Version.create(1, 2, 3, "build1"), 1, 2, 3, 0, "build1");
assertThat(Version.create(1, 2, 3, "build1").toString()).isEqualTo("1.2.3-build1");
}
private static void assertVersion(Version version,
- int expectedMajor, int expectedMinor, int expectedPatch, String expectedQualifier) {
+ int expectedMajor, int expectedMinor, int expectedPatch, long expectedBuildNumber, String expectedQualifier) {
assertThat(version.major()).isEqualTo(expectedMajor);
assertThat(version.minor()).isEqualTo(expectedMinor);
assertThat(version.patch()).isEqualTo(expectedPatch);
+ assertThat(version.buildNumber()).isEqualTo(expectedBuildNumber);
assertThat(version.qualifier()).isEqualTo(expectedQualifier);
}
}