Browse Source

SONAR-7458 new component org.sonar.api.SonarQubeVersion

tags/5.5-M11
Simon Brandhof 8 years ago
parent
commit
824a1c63f8

+ 2
- 0
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java View File

@@ -24,6 +24,7 @@ import javax.annotation.Nullable;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.internal.TempFolderCleaner;
import org.sonar.core.config.CorePropertyDefinitions;
import org.sonar.core.platform.SonarQubeVersionProvider;
import org.sonar.core.util.UuidFactoryImpl;
import org.sonar.db.DaoModule;
import org.sonar.db.DatabaseChecker;
@@ -66,6 +67,7 @@ public class PlatformLevel1 extends PlatformLevel {
add(platform, properties);
addExtraRootComponents();
add(
new SonarQubeVersionProvider(),
ServerSettings.class,
ServerImpl.class,
UuidFactoryImpl.INSTANCE,

+ 2
- 0
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java View File

@@ -43,6 +43,7 @@ import org.sonar.batch.task.Tasks;
import org.sonar.core.component.DefaultResourceTypes;
import org.sonar.core.config.CorePropertyDefinitions;
import org.sonar.core.issue.tracking.Tracker;
import org.sonar.core.platform.SonarQubeVersionProvider;

public class BatchComponents {
private BatchComponents() {
@@ -51,6 +52,7 @@ public class BatchComponents {

public static Collection<Object> all(AnalysisMode analysisMode) {
List<Object> components = Lists.newArrayList(
new SonarQubeVersionProvider(),
DefaultResourceTypes.get(),

// Tasks

+ 49
- 0
sonar-core/src/main/java/org/sonar/core/platform/SonarQubeVersionProvider.java View File

@@ -0,0 +1,49 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.core.platform;

import com.google.common.io.Resources;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import org.picocontainer.injectors.ProviderAdapter;
import org.sonar.api.SonarQubeVersion;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.Version;

public class SonarQubeVersionProvider extends ProviderAdapter {

private static final String FILE_PATH = "/sq-version.txt";

private SonarQubeVersion version = null;

public SonarQubeVersion provide(System2 system) {
if (version == null) {
try {
URL url = system.getResource(FILE_PATH);
String versionInFile = Resources.toString(url, StandardCharsets.UTF_8);
version = new SonarQubeVersion(Version.parse(versionInFile));
} catch (IOException e) {
throw new IllegalStateException("Can not load " + FILE_PATH + " from classpath", e);
}
}
return version;
}
}

+ 64
- 0
sonar-core/src/test/java/org/sonar/core/platform/SonarQubeVersionProviderTest.java View File

@@ -0,0 +1,64 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.core.platform;

import java.io.File;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.SonarQubeVersion;
import org.sonar.api.utils.System2;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class SonarQubeVersionProviderTest {

@Rule
public ExpectedException expectedException = ExpectedException.none();

SonarQubeVersionProvider underTest = new SonarQubeVersionProvider();

@Test
public void create() {
SonarQubeVersion version = underTest.provide(System2.INSTANCE);
assertThat(version).isNotNull();
assertThat(version.get().major()).isGreaterThanOrEqualTo(5);
}

@Test
public void cache_version() {
SonarQubeVersion version1 = underTest.provide(System2.INSTANCE);
SonarQubeVersion version2 = underTest.provide(System2.INSTANCE);
assertThat(version1).isSameAs(version2);
}

@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");

System2 system = mock(System2.class);
when(system.getResource(anyString())).thenReturn(new File("target/unknown").toURL());
underTest.provide(system);
}
}

+ 134
- 0
sonar-plugin-api/src/main/java/org/sonar/api/SonarQubeVersion.java View File

@@ -0,0 +1,134 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.api;

import javax.annotation.concurrent.Immutable;
import org.sonar.api.batch.BatchSide;
import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.Version;

import static java.util.Objects.requireNonNull;

/**
* Version of SonarQube at runtime. This component can be injected as a dependency
* of plugin extensions. The main usage for a plugin is to benefit from new APIs
* while keeping backward-compatibility with previous versions of SonarQube.

* Example: a plugin needs to use an API introduced in version 5.6 ({@code AnApi} in the following
* snippet) and still requires to support version 5.5 at runtime.
* <p></p>
* <pre>
* // Component provided by sonar-plugin-api
* // @since 5.5
* public interface AnApi {
* // implicitly since 5.5
* public void foo();
*
* // @since 5.6
* public void bar();
* }
*
* // Component provided by plugin
* public class MyExtension {
* private final SonarQubeVersion sonarQubeVersion;
* private final AnApi api;
*
* public MyExtension(SonarQubeVersion sonarQubeVersion, AnApi api) {
* this.sonarQubeVersion = sonarQubeVersion;
* this.api = api;
* }
*
* public void doSomething() {
* // assume that runtime is 5.5+
* api.foo();
*
* if (sonarQubeVersion.isGreaterThanOrEqual(SonarQubeVersion.V5_6)) {
* api.bar();
* }
* }
* }
* </pre>
* <p></p>
* The minimal supported version of SonarQube is verified at runtime. As plugin is built
* with sonar-plugin-api 5.6, we assume that the plugin requires v5.6 or greater at runtime.
* For this reason the plugin must default which is the minimal supported version
* in the configuration of sonar-packaging-maven-plugin 1.16+:
* <p></p>
* <pre>
* &lt;packaging&gt;sonar-plugin&lt;/packaging&gt;
*
* &lt;dependencies&gt;
* &lt;dependency&gt;
* &lt;groupId&gt;org.sonarsource.sonarqube&lt;/groupId&gt;
* &lt;artifactId&gt;sonar-plugin-api&lt;/artifactId&gt;
* &lt;version&gt;5.6&lt;/version&gt;
* &lt;scope&gt;provided&lt;/scope&gt;
* &lt;/dependency&gt;
* &lt;/dependencies&gt;
*
* &lt;build&gt;
* &lt;plugins&gt;
* &lt;plugin&gt;
* &lt;groupId&gt;org.sonarsource.sonar-packaging-maven-plugin&lt;/groupId&gt;
* &lt;artifactId&gt;sonar-packaging-maven-plugin&lt;/artifactId&gt;
* &lt;version&gt;1.16&lt;/version&gt;
* &lt;extensions&gt;true&lt;/extensions&gt;
* &lt;configuration&gt;
* &lt;!-- Override the default value 5.6 which is guessed from sonar-plugin-api dependency --&gt;
* &lt;sonarQubeMinVersion&gt;5.5&lt;/sonarQubeMinVersion&gt;
* &lt;/configuration&gt;
* &lt;/plugin&gt;
* &lt;/plugins&gt;
* &lt;/build&gt;
* </pre>
*
*
* @since 5.5
*/
@BatchSide
@ServerSide
@Immutable
public class SonarQubeVersion {

/**
* Constant for version 5.5
*/
public static final Version V5_5 = Version.create(5, 5);

/**
* Constant for version 5.6
*/
public static final Version V5_6 = Version.create(5, 6);

private final Version version;

public SonarQubeVersion(Version version) {
requireNonNull(version);
this.version = version;
}

public Version get() {
return this.version;
}

public boolean isGreaterThanOrEqual(Version than) {
return this.version.compareTo(than) >= 0;
}
}

+ 31
- 2
sonar-plugin-api/src/main/java/org/sonar/api/utils/Version.java View File

@@ -24,12 +24,25 @@ import java.util.List;
import javax.annotation.concurrent.Immutable;

import static java.lang.Integer.parseInt;
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;

/**
* TODO document equals/comparison without qualifier
* Version composed of 3 integer-sequences (major, minor and patch fields) and optionally a qualifier.
* <p></p>
* Examples: 1.0, 1.0.0, 1.2.3, 1.2-beta1, 1.2.1-beta-1
* <p></p>
* <h3>IMPORTANT NOTE</h3>
* Qualifier is ignored when comparing objects (methods {@link #equals(Object)}, {@link #hashCode()}
* and {@link #compareTo(Version)}).
* <p></p>
* <pre>
* assertThat(Version.parse("1.2")).isEqualTo(Version.parse("1.2-beta1"));
* assertThat(Version.parse("1.2").compareTo(Version.parse("1.2-beta1"))).isZero();
* </pre>
*
* @since 5.5
*/
@Immutable
@@ -45,6 +58,7 @@ public class Version implements Comparable<Version> {
private final String qualifier;

private Version(int major, int minor, int patch, String qualifier) {
requireNonNull(qualifier, "Version qualifier must not be null");
this.major = major;
this.minor = minor;
this.patch = patch;
@@ -64,12 +78,27 @@ public class Version implements Comparable<Version> {
}

/**
* @return non-null suffix
* @return non-null suffix. Empty if absent, else the suffix without the first character "-"
*/
public String qualifier() {
return qualifier;
}

/**
* Convert a {@link String} to a Version. Supported formats:
* <ul>
* <li>1</li>
* <li>1.2</li>
* <li>1.2.3</li>
* <li>1-beta-1</li>
* <li>1.2-beta-1</li>
* <li>1.2.3-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.
*/
public static Version parse(String text) {
String s = trimToEmpty(text);
String qualifier = substringAfter(s, QUALIFIER_SEPARATOR);

+ 38
- 0
sonar-plugin-api/src/test/java/org/sonar/api/SonarQubeVersionTest.java View File

@@ -0,0 +1,38 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.api;

import org.junit.Test;
import org.sonar.api.utils.Version;

import static org.assertj.core.api.Assertions.assertThat;

public class SonarQubeVersionTest {

@Test
public void isGte() {
Version version = Version.parse("1.2.3");
SonarQubeVersion qubeVersion = new SonarQubeVersion(version);
assertThat(qubeVersion.get()).isEqualTo(version);
assertThat(qubeVersion.isGreaterThanOrEqual(version)).isTrue();
assertThat(qubeVersion.isGreaterThanOrEqual(Version.parse("1.1"))).isTrue();
assertThat(qubeVersion.isGreaterThanOrEqual(Version.parse("1.3"))).isFalse();
}
}

+ 12
- 1
sonar-plugin-api/src/test/java/org/sonar/api/utils/VersionTest.java View File

@@ -57,6 +57,7 @@ public class VersionTest {
assertThat(one).isEqualTo(parse("1.0"));
assertThat(one).isEqualTo(parse("1.0.0"));
assertThat(one).isNotEqualTo(parse("1.2.3"));
assertThat(one).isNotEqualTo("1");

assertThat(parse("1.2.3")).isEqualTo(parse("1.2.3"));
assertThat(parse("1.2.3")).isNotEqualTo(parse("1.2.4"));
@@ -98,8 +99,18 @@ public class VersionTest {
assertThat(parse("1.2.3-b1").toString()).isEqualTo("1.2.3-b1");
}

@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");
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, String expectedQualifier) {
assertThat(version.major()).isEqualTo(expectedMajor);
assertThat(version.minor()).isEqualTo(expectedMinor);
assertThat(version.patch()).isEqualTo(expectedPatch);

Loading…
Cancel
Save