diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2019-04-30 10:52:55 -0500 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2019-05-06 11:01:03 +0200 |
commit | a517a4c1b6afe3c3c202801249dcbea41cfdec4c (patch) | |
tree | b3ffb242da45497fb6f3583123f1f7b58d7eb46c /sonar-plugin-api/src | |
parent | 140aa8271a5af00a84154698b18dc254d5f7bae9 (diff) | |
download | sonarqube-a517a4c1b6afe3c3c202801249dcbea41cfdec4c.tar.gz sonarqube-a517a4c1b6afe3c3c202801249dcbea41cfdec4c.zip |
SONAR-11969 Make Edition available for analyzers in the Scanner API
Diffstat (limited to 'sonar-plugin-api/src')
-rw-r--r-- | sonar-plugin-api/src/main/java/org/sonar/api/SonarEdition.java (renamed from sonar-plugin-api/src/main/java/org/sonar/api/internal/ApiVersion.java) | 37 | ||||
-rw-r--r-- | sonar-plugin-api/src/main/java/org/sonar/api/SonarRuntime.java | 32 | ||||
-rw-r--r-- | sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java | 4 | ||||
-rw-r--r-- | sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java | 77 | ||||
-rw-r--r-- | sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java | 20 | ||||
-rw-r--r-- | sonar-plugin-api/src/test/java/org/sonar/api/PluginTest.java | 2 | ||||
-rw-r--r-- | sonar-plugin-api/src/test/java/org/sonar/api/internal/MetadataLoaderTest.java (renamed from sonar-plugin-api/src/test/java/org/sonar/api/internal/ApiVersionTest.java) | 33 | ||||
-rw-r--r-- | sonar-plugin-api/src/test/java/org/sonar/api/internal/SonarRuntimeImplTest.java | 10 |
8 files changed, 161 insertions, 54 deletions
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/SonarEdition.java index 5b68a5d7aa4..7cfa5b45ca7 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/internal/ApiVersion.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/SonarEdition.java @@ -17,35 +17,22 @@ * 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.internal; +package org.sonar.api; -import com.google.common.io.Resources; -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import org.sonar.api.utils.System2; -import org.sonar.api.utils.Version; +public enum SonarEdition { + COMMUNITY("Community"), + DEVELOPER("Developer"), + ENTERPRISE("Enterprise"), + DATACENTER("Data Center"), + SONARCLOUD("SonarCloud"); -/** - * For internal use - * - * @since 6.0 - */ -public class ApiVersion { - - private static final String FILE_PATH = "/sonar-api-version.txt"; + private final String label; - private ApiVersion() { - // only static methods + SonarEdition(String label) { + this.label = label; } - public static Version load(System2 system) { - try { - URL url = system.getResource(FILE_PATH); - String versionInFile = Resources.toString(url, StandardCharsets.UTF_8); - return Version.parse(versionInFile); - } catch (IOException e) { - throw new IllegalStateException("Can not load " + FILE_PATH + " from classpath", e); - } + public String getLabel() { + return label; } } 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 0eecfb6977e..2579288a396 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 @@ -20,11 +20,10 @@ package org.sonar.api; import javax.annotation.concurrent.Immutable; - -import org.sonar.api.scanner.ScannerSide; import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.ce.ComputeEngineSide; +import org.sonar.api.scanner.ScannerSide; import org.sonar.api.server.ServerSide; import org.sonar.api.utils.Version; import org.sonarsource.api.sonarlint.SonarLintSide; @@ -53,7 +52,7 @@ import org.sonarsource.api.sonarlint.SonarLintSide; * // @since 6.1 * public void bar(); * } - * + * * // Plugin extension * public class MyExtension { * private final SonarRuntime sonarRuntime; @@ -77,7 +76,7 @@ import org.sonarsource.api.sonarlint.SonarLintSide; * * * <p> - * Note that {@link Sensor} extensions can directly get {@link SonarRuntime} through + * Note that {@link Sensor} extensions can directly get {@link SonarRuntime} through * {@link SensorContext#runtime()}, without using constructor injection: * </p> * <pre> @@ -127,16 +126,17 @@ import org.sonarsource.api.sonarlint.SonarLintSide; * </pre> * * <p> - * As this component was introduced in version 6.0, the pattern described above can't be - * exactly applied when plugin must support version 5.6 Long Term Support. In this case plugin - * should use {@link SonarQubeVersion}, for example through {@link Plugin.Context#getSonarQubeVersion()} or - * {@link SensorContext#getSonarQubeVersion()}. + * As this component was introduced in version 6.0, the pattern described above can't be + * exactly applied when plugin must support version 5.6 Long Term Support. In this case plugin + * should use {@link SonarQubeVersion}, for example through {@link Plugin.Context#getSonarQubeVersion()} or + * {@link SensorContext#getSonarQubeVersion()}. * </p> * * <p> * Unit tests of plugin extensions can create instances of {@link SonarRuntime} * via {@link org.sonar.api.internal.SonarRuntimeImpl}. * </p> + * * @since 6.0 */ @ScannerSide @@ -153,19 +153,29 @@ public interface SonarRuntime { * <br/> * Since 6.3, the returned version includes the build number in the fourth field, for * example {@code "6.3.0.12345"}. - */ + */ Version getApiVersion(); /** * The product being executed at runtime. It targets analysers so that they can implement - * different behaviours in SonarQube and SonarLint. + * different behaviours in SonarQube/SonarCloud and SonarLint. */ SonarProduct getProduct(); /** - * The SonarQube stack being executed at runtime. + * The SonarQube/SonarCloud stack being executed at runtime. + * * @throws UnsupportedOperationException if {@link #getProduct()} is not equal to {@link SonarProduct#SONARQUBE} */ SonarQubeSide getSonarQubeSide(); + /** + * The SonarQube/SonarCloud edition being executed at runtime. + * Note that there is a specific edition for SonarCloud. + * + * @throws UnsupportedOperationException if {@link #getProduct()} is not equal to {@link SonarProduct#SONARQUBE} + * @since 7.8 + */ + SonarEdition getEdition(); + } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java index 0ee4c211f7b..edf595685d4 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java @@ -80,7 +80,7 @@ import org.sonar.api.config.Configuration; import org.sonar.api.config.Settings; import org.sonar.api.config.internal.ConfigurationBridge; import org.sonar.api.config.internal.MapSettings; -import org.sonar.api.internal.ApiVersion; +import org.sonar.api.internal.MetadataLoader; import org.sonar.api.internal.SonarRuntimeImpl; import org.sonar.api.measures.Metric; import org.sonar.api.scanner.fs.InputProject; @@ -121,7 +121,7 @@ public class SensorContextTester implements SensorContext { this.sensorStorage = new InMemorySensorStorage(); this.project = new DefaultInputProject(ProjectDefinition.create().setKey("projectKey").setBaseDir(moduleBaseDir.toFile()).setWorkDir(moduleBaseDir.resolve(".sonar").toFile())); this.module = new DefaultInputModule(ProjectDefinition.create().setKey("projectKey").setBaseDir(moduleBaseDir.toFile()).setWorkDir(moduleBaseDir.resolve(".sonar").toFile())); - this.runtime = SonarRuntimeImpl.forSonarQube(ApiVersion.load(System2.INSTANCE), SonarQubeSide.SCANNER); + this.runtime = SonarRuntimeImpl.forSonarQube(MetadataLoader.loadVersion(System2.INSTANCE), SonarQubeSide.SCANNER, MetadataLoader.loadEdition(System2.INSTANCE)); } public static SensorContextTester create(File moduleBaseDir) { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java b/sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java new file mode 100644 index 00000000000..d22a4ec2aa6 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java @@ -0,0 +1,77 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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.internal; + +import com.google.common.io.Resources; +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import org.sonar.api.SonarEdition; +import org.sonar.api.utils.System2; +import org.sonar.api.utils.Version; + +import static org.apache.commons.lang.StringUtils.trimToEmpty; + +/** + * For internal use + * + * @since 7.8 + */ +public class MetadataLoader { + + private static final String VERSION_FILE_PATH = "/sonar-api-version.txt"; + private static final String EDITION_FILE_PATH = "/sonar-edition.txt"; + + private MetadataLoader() { + // only static methods + } + + public static Version loadVersion(System2 system) { + try { + URL url = system.getResource(VERSION_FILE_PATH); + String versionInFile = Resources.toString(url, StandardCharsets.UTF_8); + return Version.parse(versionInFile); + } catch (IOException e) { + throw new IllegalStateException("Can not load " + VERSION_FILE_PATH + " from classpath", e); + } + } + + public static SonarEdition loadEdition(System2 system) { + try { + URL url = system.getResource(EDITION_FILE_PATH); + if (url == null) { + return SonarEdition.COMMUNITY; + } + String editionInFile = Resources.toString(url, StandardCharsets.UTF_8); + return parseEdition(editionInFile); + } catch (IOException e) { + throw new IllegalStateException("Can not load " + EDITION_FILE_PATH + " from classpath", e); + } + } + + static SonarEdition parseEdition(String edition) { + String str = trimToEmpty(edition.toUpperCase()); + try { + return SonarEdition.valueOf(str); + } catch (IllegalArgumentException e) { + throw new IllegalStateException(String.format("Invalid edition found in '%s': '%s'", EDITION_FILE_PATH, str)); + } + } +} 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 6601412ac28..6395546469f 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 @@ -21,6 +21,7 @@ package org.sonar.api.internal; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; +import org.sonar.api.SonarEdition; import org.sonar.api.SonarProduct; import org.sonar.api.SonarQubeSide; import org.sonar.api.SonarRuntime; @@ -38,10 +39,13 @@ public class SonarRuntimeImpl implements SonarRuntime { private final Version version; private final SonarProduct product; private final SonarQubeSide sonarQubeSide; + private final SonarEdition edition; - private SonarRuntimeImpl(Version version, SonarProduct product, @Nullable SonarQubeSide sonarQubeSide) { + private SonarRuntimeImpl(Version version, SonarProduct product, @Nullable SonarQubeSide sonarQubeSide, @Nullable SonarEdition edition) { + this.edition = edition; requireNonNull(product); checkArgument((product == SonarProduct.SONARQUBE) == (sonarQubeSide != null), "sonarQubeSide should be provided only for SonarQube product"); + checkArgument((product == SonarProduct.SONARQUBE) == (edition != null), "edition should be provided only for SonarQube product"); this.version = requireNonNull(version); this.product = product; this.sonarQubeSide = sonarQubeSide; @@ -65,18 +69,26 @@ public class SonarRuntimeImpl implements SonarRuntime { return sonarQubeSide; } + @Override + public SonarEdition getEdition() { + if (sonarQubeSide == null) { + throw new UnsupportedOperationException("Can only be called in SonarQube"); + } + return edition; + } + /** * Create an instance for SonarQube runtime environment. */ - public static SonarRuntime forSonarQube(Version version, SonarQubeSide side) { - return new SonarRuntimeImpl(version, SonarProduct.SONARQUBE, side); + public static SonarRuntime forSonarQube(Version version, SonarQubeSide side, SonarEdition edition) { + return new SonarRuntimeImpl(version, SonarProduct.SONARQUBE, side, edition); } /** * Create an instance for SonarLint runtime environment. */ public static SonarRuntime forSonarLint(Version version) { - return new SonarRuntimeImpl(version, SonarProduct.SONARLINT, null); + return new SonarRuntimeImpl(version, SonarProduct.SONARLINT, null, null); } } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/PluginTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/PluginTest.java index 70064a5b00c..53b84c86164 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/PluginTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/PluginTest.java @@ -34,7 +34,7 @@ public class PluginTest { @Test public void test_context() { - SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(VERSION_5_6, SonarQubeSide.SERVER); + SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(VERSION_5_6, SonarQubeSide.SERVER, SonarEdition.COMMUNITY); MapSettings settings = new MapSettings().setProperty("foo", "bar"); Plugin.Context context = new PluginContextImpl.Builder() .setSonarRuntime(runtime) 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/MetadataLoaderTest.java index 4013878e9dd..d62ebdcf762 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/MetadataLoaderTest.java @@ -20,6 +20,8 @@ package org.sonar.api.internal; import java.io.File; +import java.net.MalformedURLException; +import org.sonar.api.SonarEdition; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -28,29 +30,50 @@ import org.sonar.api.utils.Version; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -public class ApiVersionTest { +public class MetadataLoaderTest { + private System2 system = mock(System2.class); @Rule public ExpectedException expectedException = ExpectedException.none(); @Test public void load_version_from_file_in_classpath() { - Version version = ApiVersion.load(System2.INSTANCE); + Version version = MetadataLoader.loadVersion(System2.INSTANCE); assertThat(version).isNotNull(); assertThat(version.major()).isGreaterThanOrEqualTo(5); } @Test + public void load_edition_from_file_in_classpath() { + SonarEdition edition = MetadataLoader.loadEdition(System2.INSTANCE); + assertThat(edition).isNotNull(); + } + + @Test + public void load_edition_defaults_to_community_if_file_not_found() throws MalformedURLException { + when(system.getResource(anyString())).thenReturn(new File("target/unknown").toURI().toURL()); + SonarEdition edition = MetadataLoader.loadEdition(System2.INSTANCE); + assertThat(edition).isEqualTo(SonarEdition.COMMUNITY); + } + + @Test + public void throw_ISE_if_edition_is_invalid() { + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Invalid edition found in '/sonar-edition.txt': 'TRASH'"); + + MetadataLoader.parseEdition("trash"); + } + + @Test public void throw_ISE_if_fail_to_load_version() throws Exception { expectedException.expect(IllegalStateException.class); 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()); - ApiVersion.load(system); + MetadataLoader.loadVersion(system); } } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/internal/SonarRuntimeImplTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/internal/SonarRuntimeImplTest.java index 5179ef530d9..8e439af9339 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/internal/SonarRuntimeImplTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/internal/SonarRuntimeImplTest.java @@ -19,6 +19,7 @@ */ package org.sonar.api.internal; +import org.sonar.api.SonarEdition; import org.assertj.core.api.Assertions; import org.junit.Rule; import org.junit.Test; @@ -30,7 +31,6 @@ import org.sonar.api.utils.Version; import static org.assertj.core.api.Assertions.assertThat; - public class SonarRuntimeImplTest { private static final Version A_VERSION = Version.parse("6.0"); @@ -40,7 +40,7 @@ public class SonarRuntimeImplTest { @Test public void sonarQube_environment() { - SonarRuntime apiVersion = SonarRuntimeImpl.forSonarQube(A_VERSION, SonarQubeSide.SCANNER); + SonarRuntime apiVersion = SonarRuntimeImpl.forSonarQube(A_VERSION, SonarQubeSide.SCANNER, SonarEdition.COMMUNITY); assertThat(apiVersion.getApiVersion()).isEqualTo(A_VERSION); assertThat(apiVersion.getProduct()).isEqualTo(SonarProduct.SONARQUBE); assertThat(apiVersion.getSonarQubeSide()).isEqualTo(SonarQubeSide.SCANNER); @@ -60,10 +60,8 @@ public class SonarRuntimeImplTest { } @Test(expected = IllegalArgumentException.class) - public void sonarqube_requires_side() throws Exception { - SonarRuntimeImpl.forSonarQube(A_VERSION, null); + public void sonarqube_requires_side() { + SonarRuntimeImpl.forSonarQube(A_VERSION, null, null); } - - } |