From: Julien HENRY Date: Mon, 13 Jun 2016 15:12:39 +0000 (+0200) Subject: SONAR-7755 deploy/plugins/index.txt should expose SonarLint compatibility X-Git-Tag: 6.0-RC1~135 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=e5818438a289fe522c87245d5bd18d71406f0e39;p=sonarqube.git SONAR-7755 deploy/plugins/index.txt should expose SonarLint compatibility --- diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java index 138ba56fb5b..6257dea6f92 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java @@ -21,21 +21,23 @@ package org.sonar.xoo; import org.junit.Test; import org.sonar.api.Plugin; +import org.sonar.api.SonarProduct; +import org.sonar.api.SonarQubeSide; +import org.sonar.api.SonarRuntime; import org.sonar.api.utils.Version; import org.sonar.xoo.lang.CpdTokenizerSensor; import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.RuntimeApiVersion.V5_5; public class XooPluginTest { @Test public void provide_extensions_for_5_5() { - Plugin.Context context = new Plugin.Context(V5_5, false); + Plugin.Context context = new Plugin.Context(new SonarRuntime(Version.parse("5.5"), SonarProduct.SONARQUBE, SonarQubeSide.SCANNER)); new XooPlugin().define(context); assertThat(context.getExtensions()).hasSize(40).contains(CpdTokenizerSensor.class); - context = new Plugin.Context(Version.parse("5.4"), false); + context = new Plugin.Context(new SonarRuntime(Version.parse("5.4"), SonarProduct.SONARLINT, null)); new XooPlugin().define(context); assertThat(context.getExtensions()).hasSize(39).doesNotContain(CpdTokenizerSensor.class); } diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java index 091c20b42f3..e709e31831f 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java @@ -23,6 +23,8 @@ import java.io.IOException; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.sonar.api.SonarProduct; +import org.sonar.api.SonarQubeSide; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; @@ -104,7 +106,7 @@ public class OneIssuePerLineSensorTest { SensorContextTester context = SensorContextTester.create(temp.newFolder()); context.fileSystem().add(inputFile); context.settings().setProperty(OneIssuePerLineSensor.EFFORT_TO_FIX_PROPERTY, "1.2"); - context.setRuntime(Version.parse("5.4"), false); + context.setRuntime(Version.parse("5.4"), SonarProduct.SONARQUBE, SonarQubeSide.SCANNER); sensor.execute(context); diff --git a/pom.xml b/pom.xml index 1e36a6bcb44..5d85db456fd 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ - 1.13 + 1.16-build309 3.13.1 2.11 5.0 @@ -465,7 +465,7 @@ ${project.version} - org.codehaus.sonar + org.sonarsource.update-center sonar-update-center-common ${sonarUpdateCenter.version} diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java index fe1e41c5c6c..ed1873c396b 100644 --- a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java +++ b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java @@ -22,8 +22,10 @@ package org.sonar.ce.container; import com.google.common.annotations.VisibleForTesting; import java.util.List; import javax.annotation.CheckForNull; +import org.sonar.api.SonarProduct; +import org.sonar.api.SonarQubeSide; import org.sonar.api.config.EmailSettings; -import org.sonar.api.internal.RuntimeApiVersionFactory; +import org.sonar.api.internal.SonarRuntimeFactory; import org.sonar.api.profiles.AnnotationProfileParser; import org.sonar.api.profiles.XMLProfileParser; import org.sonar.api.profiles.XMLProfileSerializer; @@ -135,7 +137,7 @@ import org.sonarqube.ws.Rules; public class ComputeEngineContainerImpl implements ComputeEngineContainer { private static final Object[] LEVEL_1_COMPONENTS = new Object[] { ComputeEngineSettings.class, - RuntimeApiVersionFactory.create(System2.INSTANCE, false), + SonarRuntimeFactory.create(System2.INSTANCE, SonarProduct.SONARQUBE, SonarQubeSide.COMPUTE_ENGINE), ServerImpl.class, UuidFactoryImpl.INSTANCE, // no EmbeddedDatabaseFactory.class, creating H2 DB if responsibility of WebServer diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/platform/ComputeEngineExtensionInstaller.java b/server/sonar-ce/src/main/java/org/sonar/ce/platform/ComputeEngineExtensionInstaller.java index 7a8b85536ce..d54a8fe488b 100644 --- a/server/sonar-ce/src/main/java/org/sonar/ce/platform/ComputeEngineExtensionInstaller.java +++ b/server/sonar-ce/src/main/java/org/sonar/ce/platform/ComputeEngineExtensionInstaller.java @@ -19,14 +19,14 @@ */ package org.sonar.ce.platform; -import org.sonar.api.RuntimeApiVersion; +import org.sonar.api.SonarRuntime; import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.server.ServerSide; import org.sonar.core.platform.PluginRepository; import org.sonar.server.plugins.ServerExtensionInstaller; public class ComputeEngineExtensionInstaller extends ServerExtensionInstaller { - public ComputeEngineExtensionInstaller(RuntimeApiVersion runtimeApiVersion, PluginRepository pluginRepository) { - super(runtimeApiVersion, pluginRepository, ServerSide.class, ComputeEngineSide.class); + public ComputeEngineExtensionInstaller(SonarRuntime sonarRuntime, PluginRepository pluginRepository) { + super(sonarRuntime, pluginRepository, ServerSide.class, ComputeEngineSide.class); } } diff --git a/server/sonar-server/pom.xml b/server/sonar-server/pom.xml index 8fdd868fec4..579e4f8d88b 100644 --- a/server/sonar-server/pom.xml +++ b/server/sonar-server/pom.xml @@ -88,7 +88,7 @@ ${project.version} - org.codehaus.sonar + org.sonarsource.update-center sonar-update-center-common diff --git a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityAction.java b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityAction.java index 038ff9fb24a..7625e39e169 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ActivityAction.java @@ -20,21 +20,6 @@ package org.sonar.server.ce.ws; -import static java.lang.String.format; -import static java.util.Collections.singletonList; -import static org.apache.commons.lang.StringUtils.defaultString; -import static org.sonar.api.utils.DateUtils.parseDateQuietly; -import static org.sonar.api.utils.DateUtils.parseDateTimeQuietly; -import static org.sonar.server.ws.WsUtils.checkRequest; -import static org.sonar.server.ws.WsUtils.writeProtobuf; -import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_ID; -import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_QUERY; -import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_MAX_EXECUTED_AT; -import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_MIN_SUBMITTED_AT; -import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_ONLY_CURRENTS; -import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_STATUS; -import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_TYPE; - import com.google.common.base.Joiner; import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; @@ -71,6 +56,21 @@ import org.sonarqube.ws.WsCe; import org.sonarqube.ws.WsCe.ActivityResponse; import org.sonarqube.ws.client.ce.ActivityWsRequest; +import static java.lang.String.format; +import static java.util.Collections.singletonList; +import static org.apache.commons.lang.StringUtils.defaultString; +import static org.sonar.api.utils.DateUtils.parseDateQuietly; +import static org.sonar.api.utils.DateUtils.parseDateTimeQuietly; +import static org.sonar.server.ws.WsUtils.checkRequest; +import static org.sonar.server.ws.WsUtils.writeProtobuf; +import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_ID; +import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_QUERY; +import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_MAX_EXECUTED_AT; +import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_MIN_SUBMITTED_AT; +import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_ONLY_CURRENTS; +import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_STATUS; +import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_TYPE; + public class ActivityAction implements CeWsAction { private static final int OFFSET = 0; private static final int MAX_PAGE_SIZE = 1000; diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java index 861f6375b39..a248ffef263 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java @@ -21,7 +21,9 @@ package org.sonar.server.platform.platformlevel; import java.util.Properties; import javax.annotation.Nullable; -import org.sonar.api.internal.RuntimeApiVersionFactory; +import org.sonar.api.SonarProduct; +import org.sonar.api.SonarQubeSide; +import org.sonar.api.internal.SonarRuntimeFactory; import org.sonar.api.utils.System2; import org.sonar.api.utils.internal.TempFolderCleaner; import org.sonar.ce.property.CePropertyDefinitions; @@ -68,7 +70,7 @@ public class PlatformLevel1 extends PlatformLevel { add(platform, properties); addExtraRootComponents(); add( - RuntimeApiVersionFactory.create(System2.INSTANCE, false), + SonarRuntimeFactory.create(System2.INSTANCE, SonarProduct.SONARQUBE, SonarQubeSide.SERVER), ProcessCommandWrapperImpl.class, RestartFlagHolderImpl.class, WebServerSettings.class, diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ServerExtensionInstaller.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ServerExtensionInstaller.java index e481935ee65..6dba5e491aa 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ServerExtensionInstaller.java +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ServerExtensionInstaller.java @@ -25,7 +25,7 @@ import java.lang.annotation.Annotation; import java.util.Map; import org.sonar.api.ExtensionProvider; import org.sonar.api.Plugin; -import org.sonar.api.RuntimeApiVersion; +import org.sonar.api.SonarRuntime; import org.sonar.api.utils.AnnotationUtils; import org.sonar.core.platform.ComponentContainer; import org.sonar.core.platform.PluginInfo; @@ -38,14 +38,14 @@ import static java.util.Objects.requireNonNull; */ public abstract class ServerExtensionInstaller { - private final RuntimeApiVersion runtimeApiVersion; + private final SonarRuntime sonarRuntime; private final PluginRepository pluginRepository; private final Class[] supportedAnnotationTypes; - protected ServerExtensionInstaller(RuntimeApiVersion runtimeApiVersion, PluginRepository pluginRepository, + protected ServerExtensionInstaller(SonarRuntime sonarRuntime, PluginRepository pluginRepository, Class... supportedAnnotationTypes) { requireNonNull(supportedAnnotationTypes, "At least one supported annotation type must be specified"); - this.runtimeApiVersion = runtimeApiVersion; + this.sonarRuntime = sonarRuntime; this.pluginRepository = pluginRepository; this.supportedAnnotationTypes = supportedAnnotationTypes; } @@ -59,7 +59,7 @@ public abstract class ServerExtensionInstaller { Plugin plugin = pluginRepository.getPluginInstance(pluginKey); container.addExtension(pluginInfo, plugin); - Plugin.Context context = new Plugin.Context(runtimeApiVersion.get(), runtimeApiVersion.isSonarlintRuntime()); + Plugin.Context context = new Plugin.Context(sonarRuntime); plugin.define(context); for (Object extension : context.getExtensions()) { if (installExtension(container, pluginInfo, extension, true) != null) { diff --git a/sonar-core/pom.xml b/sonar-core/pom.xml index e447767a2e6..db4949d70fb 100644 --- a/sonar-core/pom.xml +++ b/sonar-core/pom.xml @@ -44,7 +44,7 @@ sonar-plugin-api - org.codehaus.sonar + org.sonarsource.update-center sonar-update-center-common diff --git a/sonar-core/src/main/java/org/sonar/core/platform/PluginInfo.java b/sonar-core/src/main/java/org/sonar/core/platform/PluginInfo.java index 2c0ae9a413f..a7b68c7558c 100644 --- a/sonar-core/src/main/java/org/sonar/core/platform/PluginInfo.java +++ b/sonar-core/src/main/java/org/sonar/core/platform/PluginInfo.java @@ -136,6 +136,9 @@ public class PluginInfo implements Comparable { @CheckForNull private String implementationBuild; + @CheckForNull + private boolean sonarLintSupported; + private final Set requiredPlugins = new HashSet<>(); public PluginInfo(String key) { @@ -216,6 +219,11 @@ public class PluginInfo implements Comparable { return useChildFirstClassLoader; } + @CheckForNull + public boolean isSonarLintSupported() { + return sonarLintSupported; + } + @CheckForNull public String getBasePlugin() { return basePlugin; @@ -288,6 +296,11 @@ public class PluginInfo implements Comparable { return this; } + public PluginInfo setSonarLintSupported(boolean sonarLintPlugin) { + this.sonarLintSupported = sonarLintPlugin; + return this; + } + public PluginInfo setBasePlugin(@Nullable String s) { if ("l10nen".equals(s)) { Loggers.get(PluginInfo.class).info("Plugin [{}] defines 'l10nen' as base plugin. " + @@ -395,6 +408,7 @@ public class PluginInfo implements Comparable { info.setHomepageUrl(manifest.getHomepage()); info.setIssueTrackerUrl(manifest.getIssueTrackerUrl()); info.setUseChildFirstClassLoader(manifest.isUseChildFirstClassLoader()); + info.setSonarLintSupported(manifest.isSonarLintSupported()); info.setBasePlugin(manifest.getBasePlugin()); info.setImplementationBuild(manifest.getImplementationBuild()); String[] requiredPlugins = manifest.getRequirePlugins(); diff --git a/sonar-core/src/main/java/org/sonar/core/platform/RemotePlugin.java b/sonar-core/src/main/java/org/sonar/core/platform/RemotePlugin.java index d7e24418de4..13f97be6abd 100644 --- a/sonar-core/src/main/java/org/sonar/core/platform/RemotePlugin.java +++ b/sonar-core/src/main/java/org/sonar/core/platform/RemotePlugin.java @@ -27,6 +27,7 @@ import org.apache.commons.lang.StringUtils; public class RemotePlugin { private String pluginKey; + private boolean sonarLintSupported; private RemotePluginFile file = null; public RemotePlugin(String pluginKey) { @@ -36,14 +37,16 @@ public class RemotePlugin { public static RemotePlugin create(PluginInfo pluginInfo) { RemotePlugin result = new RemotePlugin(pluginInfo.getKey()); result.setFile(pluginInfo.getNonNullJarFile()); + result.setSonarLintSupported(pluginInfo.isSonarLintSupported()); return result; } public static RemotePlugin unmarshal(String row) { String[] fields = StringUtils.split(row, ","); RemotePlugin result = new RemotePlugin(fields[0]); - if (fields.length >= 2) { - String[] nameAndHash = StringUtils.split(fields[1], "|"); + if (fields.length >= 3) { + result.setSonarLintSupported(StringUtils.equals("true", fields[1])); + String[] nameAndHash = StringUtils.split(fields[2], "|"); result.setFile(nameAndHash[0], nameAndHash[1]); } return result; @@ -51,8 +54,13 @@ public class RemotePlugin { public String marshal() { StringBuilder sb = new StringBuilder(); - sb.append(pluginKey); - sb.append(",").append(file.getFilename()).append("|").append(file.getHash()); + sb.append(pluginKey) + .append(",") + .append(sonarLintSupported) + .append(",") + .append(file.getFilename()) + .append("|") + .append(file.getHash()); return sb.toString(); } @@ -65,6 +73,11 @@ public class RemotePlugin { return this; } + public RemotePlugin setSonarLintSupported(boolean sonarLintPlugin) { + this.sonarLintSupported = sonarLintPlugin; + return this; + } + public RemotePlugin setFile(File f) { try (FileInputStream fis = new FileInputStream(f)) { return this.setFile(f.getName(), DigestUtils.md5Hex(fis)); @@ -77,6 +90,10 @@ public class RemotePlugin { return file; } + public boolean isSonarLintSupported() { + return sonarLintSupported; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/sonar-core/src/test/java/org/sonar/core/platform/PluginInfoTest.java b/sonar-core/src/test/java/org/sonar/core/platform/PluginInfoTest.java index 35eec26eb91..a433bb905cb 100644 --- a/sonar-core/src/test/java/org/sonar/core/platform/PluginInfoTest.java +++ b/sonar-core/src/test/java/org/sonar/core/platform/PluginInfoTest.java @@ -157,6 +157,7 @@ public class PluginInfoTest { assertThat(pluginInfo.getOrganizationUrl()).isNull(); assertThat(pluginInfo.getMinimalSqVersion()).isNull(); assertThat(pluginInfo.getRequiredPlugins()).isEmpty(); + assertThat(pluginInfo.isSonarLintSupported()).isFalse(); } @Test @@ -176,6 +177,7 @@ public class PluginInfoTest { manifest.setOrganizationUrl("http://sonarsource.com"); manifest.setIssueTrackerUrl("http://jira.com"); manifest.setRequirePlugins(new String[] {"java:2.0", "pmd:1.3"}); + manifest.setSonarLintSupported(true); File jarFile = temp.newFile(); PluginInfo pluginInfo = PluginInfo.create(jarFile, manifest); @@ -190,6 +192,7 @@ public class PluginInfoTest { assertThat(pluginInfo.getOrganizationUrl()).isEqualTo("http://sonarsource.com"); assertThat(pluginInfo.getMinimalSqVersion().getName()).isEqualTo("4.5.1"); assertThat(pluginInfo.getRequiredPlugins()).extracting("key").containsOnly("java", "pmd"); + assertThat(pluginInfo.isSonarLintSupported()).isTrue(); } @Test diff --git a/sonar-core/src/test/java/org/sonar/core/platform/RemotePluginTest.java b/sonar-core/src/test/java/org/sonar/core/platform/RemotePluginTest.java index fbe8f21f5e4..b1e609bdb68 100644 --- a/sonar-core/src/test/java/org/sonar/core/platform/RemotePluginTest.java +++ b/sonar-core/src/test/java/org/sonar/core/platform/RemotePluginTest.java @@ -21,8 +21,7 @@ package org.sonar.core.platform; import org.junit.Test; -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; public class RemotePluginTest { @Test @@ -30,23 +29,31 @@ public class RemotePluginTest { RemotePlugin clirr1 = new RemotePlugin("clirr"); RemotePlugin clirr2 = new RemotePlugin("clirr"); RemotePlugin checkstyle = new RemotePlugin("checkstyle"); - assertThat(clirr1.equals(clirr2), is(true)); - assertThat(clirr1.equals(clirr1), is(true)); - assertThat(clirr1.equals(checkstyle), is(false)); + assertThat(clirr1).isEqualTo(clirr2); + assertThat(clirr1).isEqualTo(clirr1); + assertThat(clirr1).isNotEqualTo(checkstyle); } @Test - public void shouldMarshal() { + public void shouldMarshalNotSonarLintByDefault() { RemotePlugin clirr = new RemotePlugin("clirr").setFile("clirr-1.1.jar", "fakemd5"); String text = clirr.marshal(); - assertThat(text, is("clirr,clirr-1.1.jar|fakemd5")); + assertThat(text).isEqualTo("clirr,false,clirr-1.1.jar|fakemd5"); + } + + @Test + public void shouldMarshalSonarLint() { + RemotePlugin clirr = new RemotePlugin("clirr").setFile("clirr-1.1.jar", "fakemd5").setSonarLintSupported(true); + String text = clirr.marshal(); + assertThat(text).isEqualTo("clirr,true,clirr-1.1.jar|fakemd5"); } @Test public void shouldUnmarshal() { - RemotePlugin clirr = RemotePlugin.unmarshal("clirr,clirr-1.1.jar|fakemd5"); - assertThat(clirr.getKey(), is("clirr")); - assertThat(clirr.file().getFilename(), is("clirr-1.1.jar")); - assertThat(clirr.file().getHash(), is("fakemd5")); + RemotePlugin clirr = RemotePlugin.unmarshal("clirr,true,clirr-1.1.jar|fakemd5"); + assertThat(clirr.getKey()).isEqualTo("clirr"); + assertThat(clirr.isSonarLintSupported()).isTrue(); + assertThat(clirr.file().getFilename()).isEqualTo("clirr-1.1.jar"); + assertThat(clirr.file().getHash()).isEqualTo("fakemd5"); } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/Plugin.java b/sonar-plugin-api/src/main/java/org/sonar/api/Plugin.java index aa1a6f9511a..8fb50a0b14c 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/Plugin.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/Plugin.java @@ -85,21 +85,19 @@ import static java.util.Objects.requireNonNull; public interface Plugin { class Context { - private final Version runtimeApiVersion; + private final SonarRuntime sonarRuntime; private final List extensions = new ArrayList(); - private final boolean sonarlintRuntime; - public Context(Version runtimeApiVersion, boolean sonarlintRuntime) { - this.runtimeApiVersion = runtimeApiVersion; - this.sonarlintRuntime = sonarlintRuntime; + public Context(SonarRuntime sonarRuntime) { + this.sonarRuntime = sonarRuntime; } /** - * @deprecated since 6.0 + * @deprecated since 6.0 use {@link #getRuntimeApiVersion()} */ @Deprecated public Version getSonarQubeVersion() { - return runtimeApiVersion; + return sonarRuntime.getApiVersion(); } /** @@ -107,7 +105,7 @@ public interface Plugin { * @since 6.0 */ public Version getRuntimeApiVersion() { - return runtimeApiVersion; + return sonarRuntime.getApiVersion(); } /** @@ -154,11 +152,11 @@ public interface Plugin { } /** - * Test if plugin is currently executed in SonarLint. Can be use to conditionnaly add some extensions. + * Test the product the plugin is currently executed in. This can allow to implement a different behavior. * @since 6.0 */ - public boolean isSonarlintRuntime() { - return sonarlintRuntime; + public SonarProduct getRuntimeProduct() { + return sonarRuntime.getProduct(); } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/RuntimeApiVersion.java b/sonar-plugin-api/src/main/java/org/sonar/api/RuntimeApiVersion.java deleted file mode 100644 index e221f6f9f8e..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/RuntimeApiVersion.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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.batch.sensor.Sensor; -import org.sonar.api.ce.ComputeEngineSide; -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 1: a {@link Sensor} wants to use an API introduced in version 5.5 and still requires to support older versions - * at runtime. - *
- * public class MySensor implements Sensor {
- *
- *   public void execute(SensorContext context) {
- *     if (context.getRuntimeApiVersion().isGreaterThanOrEqual(RuntimeApiVersion.V5_5)) {
- *       context.newMethodIntroducedIn5_5();
- *     }
- *   }
- * }
- * 
- * - * Example 2: 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. - *
- *
- * // 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 RuntimeApiVersion runtimeApiVersion;
- *   private final AnApi api;
- *
- *   public MyExtension(RuntimeApiVersion runtimeApiVersion, AnApi api) {
- *     this.runtimeApiVersion = runtimeApiVersion;
- *     this.api = api;
- *   }
- *
- *   public void doSomething() {
- *     // assume that runtime is 5.5+
- *     api.foo();
- *
- *     if (runtimeApiVersion.isGreaterThanOrEqual(SonarQubeVersion.V5_6)) {
- *       api.bar();
- *     }
- *   }
- * }
- * 
- *

- * The minimal supported version of plugin API 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+: - *

- *

- * <packaging>sonar-plugin</packaging>
- *
- * <dependencies>
- *   <dependency>
- *     <groupId>org.sonarsource.sonarqube</groupId>
- *     <artifactId>sonar-plugin-api</artifactId>
- *     <version>5.6</version>
- *     <scope>provided</scope>
- *   </dependency>
- * </dependencies>
- *
- * <build>
- *  <plugins>
- *    <plugin>
- *      <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
- *      <artifactId>sonar-packaging-maven-plugin</artifactId>
- *      <version>1.16</version>
- *      <extensions>true</extensions>
- *      <configuration>
- *        <!-- Override the default value 5.6 which is guessed from sonar-plugin-api dependency -->
- *        <sonarQubeMinVersion>5.5</sonarQubeMinVersion>
- *      </configuration>
- *    </plugin>
- *  </plugins>
- * </build>
- * 
- * - * - * @since 6.0 - */ -@BatchSide -@ServerSide -@ComputeEngineSide -@Immutable -public class RuntimeApiVersion { - - /** - * 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; - private final boolean sonarlint; - - public RuntimeApiVersion(Version version, boolean sonarlint) { - requireNonNull(version); - this.version = version; - this.sonarlint = sonarlint; - } - - public Version get() { - return this.version; - } - - public boolean isGreaterThanOrEqual(Version than) { - return this.version.isGreaterThanOrEqual(than); - } - - /** - * @since 6.0 Test if current runtime is SonarLint. Can be used to implement a different behavior. - */ - public boolean isSonarlintRuntime() { - return sonarlint; - } - -} 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 new file mode 100644 index 00000000000..97a5dba1e37 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/SonarProduct.java @@ -0,0 +1,31 @@ +/* + * 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; + +/** + * List of different products/runtimes. + * @since 6.0 + */ +public enum SonarProduct { + + SONARQUBE, + SONARLINT; + +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/SonarQubeSide.java b/sonar-plugin-api/src/main/java/org/sonar/api/SonarQubeSide.java new file mode 100644 index 00000000000..5e02c2eae61 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/SonarQubeSide.java @@ -0,0 +1,32 @@ +/* + * 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; + +/** + * Differentiate runtime context in SonarQube product. + * @since 6.0 + */ +public enum SonarQubeSide { + + SCANNER, + SERVER, + COMPUTE_ENGINE; + +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/SonarQubeVersion.java b/sonar-plugin-api/src/main/java/org/sonar/api/SonarQubeVersion.java index 6b8a1e5cdbd..044df52a450 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/SonarQubeVersion.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/SonarQubeVersion.java @@ -19,6 +19,7 @@ */ package org.sonar.api; +import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; import org.sonar.api.batch.ScannerSide; import org.sonar.api.batch.sensor.Sensor; @@ -115,17 +116,21 @@ import org.sonar.api.utils.Version; * * * @since 5.5 - * @deprecated since 6.0 replaced by {@link RuntimeApiVersion} + * @deprecated since 6.0 replaced by {@link SonarRuntime} */ @ScannerSide @ServerSide @ComputeEngineSide @Immutable @Deprecated -public class SonarQubeVersion extends RuntimeApiVersion { +public class SonarQubeVersion extends SonarRuntime { - public SonarQubeVersion(Version version, boolean sonarlint) { - super(version, sonarlint); + public SonarQubeVersion(Version version, SonarProduct product, @Nullable SonarQubeSide sonarQubeSide) { + super(version, product, sonarQubeSide); + } + + public Version get() { + return super.getApiVersion(); } } 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 new file mode 100644 index 00000000000..0760fb77244 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/SonarRuntime.java @@ -0,0 +1,190 @@ +/* + * 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 com.google.common.base.Preconditions; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; +import org.sonar.api.batch.BatchSide; +import org.sonar.api.batch.sensor.Sensor; +import org.sonar.api.ce.ComputeEngineSide; +import org.sonar.api.server.ServerSide; +import org.sonar.api.utils.Version; +import org.sonarsource.api.sonarlint.SonarLintSide; + +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 1: a {@link Sensor} wants to use an API introduced in version 5.5 and still requires to support older versions + * at runtime. + *
+ * public class MySensor implements Sensor {
+ *
+ *   public void execute(SensorContext context) {
+ *     if (context.getRuntimeApiVersion().isGreaterThanOrEqual(RuntimeApiVersion.V5_5)) {
+ *       context.newMethodIntroducedIn5_5();
+ *     }
+ *   }
+ * }
+ * 
+ * + * Example 2: 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. + *
+ *
+ * // 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 RuntimeApiVersion runtimeApiVersion;
+ *   private final AnApi api;
+ *
+ *   public MyExtension(RuntimeApiVersion runtimeApiVersion, AnApi api) {
+ *     this.runtimeApiVersion = runtimeApiVersion;
+ *     this.api = api;
+ *   }
+ *
+ *   public void doSomething() {
+ *     // assume that runtime is 5.5+
+ *     api.foo();
+ *
+ *     if (runtimeApiVersion.isGreaterThanOrEqual(SonarQubeVersion.V5_6)) {
+ *       api.bar();
+ *     }
+ *   }
+ * }
+ * 
+ *

+ * The minimal supported version of plugin API 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+: + *

+ *

+ * <packaging>sonar-plugin</packaging>
+ *
+ * <dependencies>
+ *   <dependency>
+ *     <groupId>org.sonarsource.sonarqube</groupId>
+ *     <artifactId>sonar-plugin-api</artifactId>
+ *     <version>5.6</version>
+ *     <scope>provided</scope>
+ *   </dependency>
+ * </dependencies>
+ *
+ * <build>
+ *  <plugins>
+ *    <plugin>
+ *      <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
+ *      <artifactId>sonar-packaging-maven-plugin</artifactId>
+ *      <version>1.16</version>
+ *      <extensions>true</extensions>
+ *      <configuration>
+ *        <!-- Override the default value 5.6 which is guessed from sonar-plugin-api dependency -->
+ *        <sonarQubeMinVersion>5.5</sonarQubeMinVersion>
+ *      </configuration>
+ *    </plugin>
+ *  </plugins>
+ * </build>
+ * 
+ * + * + * @since 6.0 + */ +@BatchSide +@ServerSide +@ComputeEngineSide +@SonarLintSide +@Immutable +public class SonarRuntime { + + /** + * 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); + + /** + * Constant for version 6.0 + */ + public static final Version V6_0 = Version.create(6, 0); + + private final Version version; + private final SonarProduct product; + private final SonarQubeSide sonarQubeSide; + + public SonarRuntime(Version version, SonarProduct product, @Nullable SonarQubeSide sonarQubeSide) { + requireNonNull(version); + requireNonNull(product); + Preconditions.checkArgument((product == SonarProduct.SONARQUBE) == (sonarQubeSide != null), "sonarQubeSide should be provided only for SonarQube product"); + this.version = version; + this.product = product; + this.sonarQubeSide = sonarQubeSide; + } + + /** + * Runtime version of sonar-plugin-api. This could be used to test if a new feature can be used or not without using reflection. + */ + public Version getApiVersion() { + return this.version; + } + + public boolean isGreaterThanOrEqual(Version than) { + return this.version.isGreaterThanOrEqual(than); + } + + /** + * Allow to know what is current runtime product. Can be used to implement different behavior depending on runtime (SonarQube, SonarLint, ...). + * @since 6.0 + */ + public SonarProduct getProduct() { + return product; + } + + /** + * Allow to know the precise runtime context in SonarQube product. Only valid when {@link #getProduct()} returns {@link SonarProduct#SONARQUBE} + * @since 6.0 + * @throws UnsupportedOperationException if called and {@link #getProduct()} is not equal to {@link SonarProduct#SONARQUBE} + */ + public SonarQubeSide getSonarQubeSide() { + if (sonarQubeSide == null) { + throw new UnsupportedOperationException("Can only be called in SonarQube"); + } + return sonarQubeSide; + } + +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java index 4970132e71a..22319fb4613 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java @@ -20,6 +20,7 @@ package org.sonar.api.batch.sensor; import java.io.Serializable; +import org.sonar.api.SonarProduct; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputModule; import org.sonar.api.batch.rule.ActiveRules; @@ -75,10 +76,10 @@ public interface SensorContext { Version getRuntimeApiVersion(); /** - * Test if plugin is currently executed in SonarLint. This can allow to implement a different behavior. + * Test the product the plugin is currently executed in. This can allow to implement a different behavior. * @since 6.0 */ - boolean isSonarLintRuntime(); + SonarProduct getRuntimeProduct(); // ----------- MEASURES -------------- 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 9c3c8476028..53a66952c17 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 @@ -30,6 +30,8 @@ import java.util.List; import java.util.Map; import java.util.Set; import javax.annotation.CheckForNull; +import org.sonar.api.SonarProduct; +import org.sonar.api.SonarQubeSide; import org.sonar.api.SonarQubeVersion; import org.sonar.api.batch.fs.InputModule; import org.sonar.api.batch.fs.TextRange; @@ -58,7 +60,7 @@ import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; import org.sonar.api.batch.sensor.symbol.NewSymbolTable; import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; import org.sonar.api.config.Settings; -import org.sonar.api.internal.RuntimeApiVersionFactory; +import org.sonar.api.internal.SonarRuntimeFactory; import org.sonar.api.measures.Metric; import org.sonar.api.utils.System2; import org.sonar.api.utils.Version; @@ -95,7 +97,7 @@ public class SensorContextTester implements SensorContext { this.activeRules = new ActiveRulesBuilder().build(); this.sensorStorage = new InMemorySensorStorage(); this.module = new DefaultInputModule("projectKey"); - this.sqVersion = RuntimeApiVersionFactory.create(System2.INSTANCE, false); + this.sqVersion = SonarRuntimeFactory.create(System2.INSTANCE, SonarProduct.SONARQUBE, SonarQubeSide.SCANNER); } public static SensorContextTester create(File moduleBaseDir) { @@ -142,21 +144,21 @@ public class SensorContextTester implements SensorContext { */ @Override public Version getSonarQubeVersion() { - return sqVersion.get(); + return sqVersion.getApiVersion(); } @Override public Version getRuntimeApiVersion() { - return sqVersion.get(); + return sqVersion.getApiVersion(); } @Override - public boolean isSonarLintRuntime() { - return sqVersion.isSonarlintRuntime(); + public SonarProduct getRuntimeProduct() { + return sqVersion.getProduct(); } - public SensorContextTester setRuntime(Version version, boolean isSonarLint) { - this.sqVersion = new SonarQubeVersion(version, isSonarLint); + public SensorContextTester setRuntime(Version version, SonarProduct product, SonarQubeSide sonarQubeSide) { + this.sqVersion = new SonarQubeVersion(version, product, sonarQubeSide); return this; } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/internal/RuntimeApiVersionFactory.java b/sonar-plugin-api/src/main/java/org/sonar/api/internal/RuntimeApiVersionFactory.java deleted file mode 100644 index fd098bd4a64..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/internal/RuntimeApiVersionFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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.internal; - -import com.google.common.io.Resources; -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import org.sonar.api.SonarQubeVersion; -import org.sonar.api.utils.System2; -import org.sonar.api.utils.Version; - -/** - * For internal use only. - */ -public class RuntimeApiVersionFactory { - - private static final String FILE_PATH = "/sq-version.txt"; - - private RuntimeApiVersionFactory() { - // prevents instantiation - } - - public static SonarQubeVersion create(System2 system, boolean isSonarLint) { - try { - URL url = system.getResource(FILE_PATH); - String versionInFile = Resources.toString(url, StandardCharsets.UTF_8); - return new SonarQubeVersion(Version.parse(versionInFile), isSonarLint); - } catch (IOException e) { - throw new IllegalStateException("Can not load " + FILE_PATH + " from classpath", e); - } - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeFactory.java b/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeFactory.java new file mode 100644 index 00000000000..b47189b58a8 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeFactory.java @@ -0,0 +1,53 @@ +/* + * 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.internal; + +import com.google.common.io.Resources; +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import javax.annotation.Nullable; +import org.sonar.api.SonarProduct; +import org.sonar.api.SonarQubeSide; +import org.sonar.api.SonarQubeVersion; +import org.sonar.api.utils.System2; +import org.sonar.api.utils.Version; + +/** + * For internal use only. + */ +public class SonarRuntimeFactory { + + private static final String FILE_PATH = "/sq-version.txt"; + + private SonarRuntimeFactory() { + // prevents instantiation + } + + public static SonarQubeVersion create(System2 system, SonarProduct product, @Nullable SonarQubeSide sonarQubeSide) { + try { + URL url = system.getResource(FILE_PATH); + String versionInFile = Resources.toString(url, StandardCharsets.UTF_8); + return new SonarQubeVersion(Version.parse(versionInFile), product, sonarQubeSide); + } catch (IOException e) { + throw new IllegalStateException("Can not load " + FILE_PATH + " from classpath", e); + } + } +} 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 853a48bd59c..caa022c0290 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 @@ -23,13 +23,13 @@ import java.util.Arrays; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.RuntimeApiVersion.V5_5; +import static org.sonar.api.SonarRuntime.V5_5; public class PluginTest { @Test public void test_context() { - Plugin.Context context = new Plugin.Context(V5_5, true); + Plugin.Context context = new Plugin.Context(new SonarRuntime(V5_5, SonarProduct.SONARQUBE, SonarQubeSide.SERVER)); assertThat(context.getSonarQubeVersion()).isEqualTo(V5_5); assertThat(context.getExtensions()).isEmpty(); diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/RuntimeApiVersionTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/RuntimeApiVersionTest.java deleted file mode 100644 index e7fb658e2eb..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/RuntimeApiVersionTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.Version; - -import static org.assertj.core.api.Assertions.assertThat; - -public class RuntimeApiVersionTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void isGte() { - Version version = Version.parse("1.2.3"); - RuntimeApiVersion apiVersion = new RuntimeApiVersion(version, false); - assertThat(apiVersion.get()).isEqualTo(version); - assertThat(apiVersion.isSonarlintRuntime()).isFalse(); - assertThat(apiVersion.isGreaterThanOrEqual(version)).isTrue(); - assertThat(apiVersion.isGreaterThanOrEqual(Version.parse("1.1"))).isTrue(); - assertThat(apiVersion.isGreaterThanOrEqual(Version.parse("1.3"))).isFalse(); - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/SonarQubeVersionTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/SonarQubeVersionTest.java index e5ef829db69..8ee63aa98fd 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/SonarQubeVersionTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/SonarQubeVersionTest.java @@ -34,9 +34,8 @@ public class SonarQubeVersionTest { @Test public void isGte() { Version version = Version.parse("1.2.3"); - SonarQubeVersion qubeVersion = new SonarQubeVersion(version, true); + SonarQubeVersion qubeVersion = new SonarQubeVersion(version, SonarProduct.SONARLINT, null); assertThat(qubeVersion.get()).isEqualTo(version); - assertThat(qubeVersion.isSonarlintRuntime()).isTrue(); assertThat(qubeVersion.isGreaterThanOrEqual(version)).isTrue(); assertThat(qubeVersion.isGreaterThanOrEqual(Version.parse("1.1"))).isTrue(); assertThat(qubeVersion.isGreaterThanOrEqual(Version.parse("1.3"))).isFalse(); diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/SonarRuntimeTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/SonarRuntimeTest.java new file mode 100644 index 00000000000..6d26a5678ce --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/SonarRuntimeTest.java @@ -0,0 +1,73 @@ +/* + * 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.assertj.core.api.Assertions; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.utils.Version; + +import static org.assertj.core.api.Assertions.assertThat; + +public class SonarRuntimeTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void isGteInSQ() { + Version version = Version.parse("1.2.3"); + SonarRuntime apiVersion = new SonarRuntime(version, SonarProduct.SONARQUBE, SonarQubeSide.SCANNER); + assertThat(apiVersion.getApiVersion()).isEqualTo(version); + assertThat(apiVersion.getProduct()).isEqualTo(SonarProduct.SONARQUBE); + assertThat(apiVersion.getSonarQubeSide()).isEqualTo(SonarQubeSide.SCANNER); + assertThat(apiVersion.isGreaterThanOrEqual(version)).isTrue(); + assertThat(apiVersion.isGreaterThanOrEqual(Version.parse("1.1"))).isTrue(); + assertThat(apiVersion.isGreaterThanOrEqual(Version.parse("1.3"))).isFalse(); + } + + @Test + public void inSL() { + Version version = Version.parse("1.2.3"); + SonarRuntime apiVersion = new SonarRuntime(version, SonarProduct.SONARLINT, null); + assertThat(apiVersion.getApiVersion()).isEqualTo(version); + assertThat(apiVersion.getProduct()).isEqualTo(SonarProduct.SONARLINT); + assertThat(apiVersion.isGreaterThanOrEqual(version)).isTrue(); + assertThat(apiVersion.isGreaterThanOrEqual(Version.parse("1.1"))).isTrue(); + assertThat(apiVersion.isGreaterThanOrEqual(Version.parse("1.3"))).isFalse(); + try { + apiVersion.getSonarQubeSide(); + Assertions.fail("Expected exception"); + } catch (Exception e) { + assertThat(e).isInstanceOf(UnsupportedOperationException.class); + } + } + + @Test(expected = IllegalArgumentException.class) + public void testConstructorMissSide() throws Exception { + new SonarRuntime(Version.parse("1.2.3"), SonarProduct.SONARQUBE, null); + } + + @Test(expected = IllegalArgumentException.class) + public void testConstructorNoSideOnSonarLint() throws Exception { + new SonarRuntime(Version.parse("1.2.3"), SonarProduct.SONARLINT, SonarQubeSide.COMPUTE_ENGINE); + } +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/internal/RuntimeApiVersionFactoryTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/internal/RuntimeApiVersionFactoryTest.java deleted file mode 100644 index 69b3cca8c54..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/internal/RuntimeApiVersionFactoryTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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.internal; - -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.spy; -import static org.mockito.Mockito.when; - -public class RuntimeApiVersionFactoryTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void create() { - SonarQubeVersion version = RuntimeApiVersionFactory.create(System2.INSTANCE, true); - assertThat(version).isNotNull(); - assertThat(version.get().major()).isGreaterThanOrEqualTo(5); - assertThat(version.isSonarlintRuntime()).isTrue(); - } - - @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 = spy(System2.class); - when(system.getResource(anyString())).thenReturn(new File("target/unknown").toURI().toURL()); - RuntimeApiVersionFactory.create(system, false); - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/internal/SonarRuntimeFactoryTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/internal/SonarRuntimeFactoryTest.java new file mode 100644 index 00000000000..4db26447ca5 --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/internal/SonarRuntimeFactoryTest.java @@ -0,0 +1,58 @@ +/* + * 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.internal; + +import java.io.File; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.SonarProduct; +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.spy; +import static org.mockito.Mockito.when; + +public class SonarRuntimeFactoryTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void create() { + SonarQubeVersion version = SonarRuntimeFactory.create(System2.INSTANCE, SonarProduct.SONARLINT, null); + assertThat(version).isNotNull(); + assertThat(version.getApiVersion().major()).isGreaterThanOrEqualTo(5); + assertThat(version.getProduct()).isEqualTo(SonarProduct.SONARLINT); + } + + @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 = spy(System2.class); + when(system.getResource(anyString())).thenReturn(new File("target/unknown").toURI().toURL()); + SonarRuntimeFactory.create(system, SonarProduct.SONARLINT, null); + } + +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ExtensionInstaller.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ExtensionInstaller.java index f3d60147662..2cc1e043a0e 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ExtensionInstaller.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ExtensionInstaller.java @@ -23,7 +23,7 @@ import java.util.List; import javax.annotation.Nullable; import org.sonar.api.ExtensionProvider; import org.sonar.api.Plugin; -import org.sonar.api.RuntimeApiVersion; +import org.sonar.api.SonarRuntime; import org.sonar.api.batch.AnalysisMode; import org.sonar.core.platform.ComponentContainer; import org.sonar.core.platform.PluginInfo; @@ -31,12 +31,12 @@ import org.sonar.core.platform.PluginRepository; public class ExtensionInstaller { - private final RuntimeApiVersion runtimeApiVersionVersion; + private final SonarRuntime sonarRuntime; private final PluginRepository pluginRepository; private final AnalysisMode analysisMode; - public ExtensionInstaller(RuntimeApiVersion sonarQubeVersion, PluginRepository pluginRepository, AnalysisMode analysisMode) { - this.runtimeApiVersionVersion = sonarQubeVersion; + public ExtensionInstaller(SonarRuntime sonarRuntime, PluginRepository pluginRepository, AnalysisMode analysisMode) { + this.sonarRuntime = sonarRuntime; this.pluginRepository = pluginRepository; this.analysisMode = analysisMode; } @@ -51,7 +51,7 @@ public class ExtensionInstaller { // plugin extensions for (PluginInfo pluginInfo : pluginRepository.getPluginInfos()) { Plugin plugin = pluginRepository.getPluginInstance(pluginInfo.getKey()); - Plugin.Context context = new Plugin.Context(runtimeApiVersionVersion.get(), runtimeApiVersionVersion.isSonarlintRuntime()); + Plugin.Context context = new Plugin.Context(sonarRuntime); plugin.define(context); for (Object extension : context.getExtensions()) { doInstall(container, matcher, pluginInfo, extension); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java index fcd089cee54..23d6208c881 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java @@ -23,7 +23,9 @@ import java.util.List; import java.util.Map; import org.sonar.api.Plugin; -import org.sonar.api.internal.RuntimeApiVersionFactory; +import org.sonar.api.SonarProduct; +import org.sonar.api.SonarQubeSide; +import org.sonar.api.internal.SonarRuntimeFactory; import org.sonar.api.utils.System2; import org.sonar.api.utils.UriReader; import org.sonar.api.utils.log.Logger; @@ -76,7 +78,7 @@ public class GlobalContainer extends ComponentContainer { BatchPluginPredicate.class, ExtensionInstaller.class, - RuntimeApiVersionFactory.create(System2.INSTANCE, false), + SonarRuntimeFactory.create(System2.INSTANCE, SonarProduct.SONARQUBE, SonarQubeSide.SCANNER), CachesManager.class, GlobalSettings.class, new BatchWsClientProvider(), diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/DeprecatedSensorContext.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/DeprecatedSensorContext.java index 876e3062d94..bd97a527353 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/DeprecatedSensorContext.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/deprecated/DeprecatedSensorContext.java @@ -21,7 +21,7 @@ package org.sonar.scanner.deprecated; import java.io.Serializable; import java.util.Collection; -import org.sonar.api.RuntimeApiVersion; +import org.sonar.api.SonarRuntime; import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.SensorContext; import org.sonar.api.batch.fs.FileSystem; @@ -51,8 +51,8 @@ public class DeprecatedSensorContext extends DefaultSensorContext implements Sen private final CoverageExclusions coverageFilter; public DeprecatedSensorContext(InputModule module, DefaultIndex index, Project project, Settings settings, FileSystem fs, ActiveRules activeRules, - AnalysisMode analysisMode, CoverageExclusions coverageFilter, SensorStorage sensorStorage, RuntimeApiVersion sqVersion) { - super(module, settings, fs, activeRules, analysisMode, sensorStorage, sqVersion); + AnalysisMode analysisMode, CoverageExclusions coverageFilter, SensorStorage sensorStorage, SonarRuntime sonarRuntime) { + super(module, settings, fs, activeRules, analysisMode, sensorStorage, sonarRuntime); this.index = index; this.project = project; this.coverageFilter = coverageFilter; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorContext.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorContext.java index 55ac8d2161b..2155392dd71 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorContext.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorContext.java @@ -20,7 +20,8 @@ package org.sonar.scanner.sensor; import java.io.Serializable; -import org.sonar.api.RuntimeApiVersion; +import org.sonar.api.SonarProduct; +import org.sonar.api.SonarRuntime; import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputModule; @@ -57,17 +58,17 @@ public class DefaultSensorContext implements SensorContext { private final SensorStorage sensorStorage; private final AnalysisMode analysisMode; private final InputModule module; - private final RuntimeApiVersion sqVersion; + private final SonarRuntime sonarRuntime; public DefaultSensorContext(InputModule module, Settings settings, FileSystem fs, ActiveRules activeRules, AnalysisMode analysisMode, SensorStorage sensorStorage, - RuntimeApiVersion sqVersion) { + SonarRuntime sonarRuntime) { this.module = module; this.settings = settings; this.fs = fs; this.activeRules = activeRules; this.analysisMode = analysisMode; this.sensorStorage = sensorStorage; - this.sqVersion = sqVersion; + this.sonarRuntime = sonarRuntime; } @Override @@ -92,17 +93,17 @@ public class DefaultSensorContext implements SensorContext { @Override public Version getSonarQubeVersion() { - return sqVersion.get(); + return sonarRuntime.getApiVersion(); } @Override public Version getRuntimeApiVersion() { - return sqVersion.get(); + return sonarRuntime.getApiVersion(); } @Override - public boolean isSonarLintRuntime() { - return sqVersion.isSonarlintRuntime(); + public SonarProduct getRuntimeProduct() { + return sonarRuntime.getProduct(); } @Override diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorContextTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorContextTest.java index caf7dd58f7a..a7c5e59efb5 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorContextTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorContextTest.java @@ -24,6 +24,8 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; +import org.sonar.api.SonarProduct; +import org.sonar.api.SonarQubeSide; import org.sonar.api.SonarQubeVersion; import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.fs.InputModule; @@ -67,7 +69,7 @@ public class DefaultSensorContextTest { settings = new Settings(); sensorStorage = mock(SensorStorage.class); analysisMode = mock(AnalysisMode.class); - sqVersion = new SonarQubeVersion(Version.parse("5.5"), false); + sqVersion = new SonarQubeVersion(Version.parse("5.5"), SonarProduct.SONARQUBE, SonarQubeSide.SCANNER); adaptor = new DefaultSensorContext(mock(InputModule.class), settings, fs, activeRules, analysisMode, sensorStorage, sqVersion); } @@ -77,7 +79,7 @@ public class DefaultSensorContextTest { assertThat(adaptor.fileSystem()).isEqualTo(fs); assertThat(adaptor.settings()).isEqualTo(settings); assertThat(adaptor.getSonarQubeVersion()).isEqualTo(Version.parse("5.5")); - assertThat(adaptor.isSonarLintRuntime()).isFalse(); + assertThat(adaptor.getRuntimeProduct()).isEqualTo(SonarProduct.SONARQUBE); assertThat(adaptor.newIssue()).isNotNull(); assertThat(adaptor.newMeasure()).isNotNull();