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);
}
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;
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);
</distributionManagement>
<properties>
- <sonarUpdateCenter.version>1.13</sonarUpdateCenter.version>
+ <sonarUpdateCenter.version>1.16-build309</sonarUpdateCenter.version>
<sonarJava.version>3.13.1</sonarJava.version>
<sonarJavaScript.version>2.11</sonarJavaScript.version>
<sonarCSharp.version>5.0</sonarCSharp.version>
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.codehaus.sonar</groupId>
+ <groupId>org.sonarsource.update-center</groupId>
<artifactId>sonar-update-center-common</artifactId>
<version>${sonarUpdateCenter.version}</version>
</dependency>
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;
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
*/
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);
}
}
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.codehaus.sonar</groupId>
+ <groupId>org.sonarsource.update-center</groupId>
<artifactId>sonar-update-center-common</artifactId>
</dependency>
<dependency>
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;
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;
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;
add(platform, properties);
addExtraRootComponents();
add(
- RuntimeApiVersionFactory.create(System2.INSTANCE, false),
+ SonarRuntimeFactory.create(System2.INSTANCE, SonarProduct.SONARQUBE, SonarQubeSide.SERVER),
ProcessCommandWrapperImpl.class,
RestartFlagHolderImpl.class,
WebServerSettings.class,
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;
*/
public abstract class ServerExtensionInstaller {
- private final RuntimeApiVersion runtimeApiVersion;
+ private final SonarRuntime sonarRuntime;
private final PluginRepository pluginRepository;
private final Class<? extends Annotation>[] supportedAnnotationTypes;
- protected ServerExtensionInstaller(RuntimeApiVersion runtimeApiVersion, PluginRepository pluginRepository,
+ protected ServerExtensionInstaller(SonarRuntime sonarRuntime, PluginRepository pluginRepository,
Class<? extends Annotation>... supportedAnnotationTypes) {
requireNonNull(supportedAnnotationTypes, "At least one supported annotation type must be specified");
- this.runtimeApiVersion = runtimeApiVersion;
+ this.sonarRuntime = sonarRuntime;
this.pluginRepository = pluginRepository;
this.supportedAnnotationTypes = supportedAnnotationTypes;
}
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) {
<artifactId>sonar-plugin-api</artifactId>
</dependency>
<dependency>
- <groupId>org.codehaus.sonar</groupId>
+ <groupId>org.sonarsource.update-center</groupId>
<artifactId>sonar-update-center-common</artifactId>
</dependency>
@CheckForNull
private String implementationBuild;
+ @CheckForNull
+ private boolean sonarLintSupported;
+
private final Set<RequiredPlugin> requiredPlugins = new HashSet<>();
public PluginInfo(String key) {
return useChildFirstClassLoader;
}
+ @CheckForNull
+ public boolean isSonarLintSupported() {
+ return sonarLintSupported;
+ }
+
@CheckForNull
public String getBasePlugin() {
return basePlugin;
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. " +
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();
public class RemotePlugin {
private String pluginKey;
+ private boolean sonarLintSupported;
private RemotePluginFile file = null;
public RemotePlugin(String pluginKey) {
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;
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();
}
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));
return file;
}
+ public boolean isSonarLintSupported() {
+ return sonarLintSupported;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
assertThat(pluginInfo.getOrganizationUrl()).isNull();
assertThat(pluginInfo.getMinimalSqVersion()).isNull();
assertThat(pluginInfo.getRequiredPlugins()).isEmpty();
+ assertThat(pluginInfo.isSonarLintSupported()).isFalse();
}
@Test
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);
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
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
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");
}
}
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();
}
/**
* @since 6.0
*/
public Version getRuntimeApiVersion() {
- return runtimeApiVersion;
+ return sonarRuntime.getApiVersion();
}
/**
}
/**
- * 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();
}
}
+++ /dev/null
-/*
- * 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.
- * <br><br>
- *
- * Example 1: a {@link Sensor} wants to use an API introduced in version 5.5 and still requires to support older versions
- * at runtime.
- * <pre>
- * public class MySensor implements Sensor {
- *
- * public void execute(SensorContext context) {
- * if (context.getRuntimeApiVersion().isGreaterThanOrEqual(RuntimeApiVersion.V5_5)) {
- * context.newMethodIntroducedIn5_5();
- * }
- * }
- * }
- * </pre>
- *
- * 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.
- * <br>
- * <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 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();
- * }
- * }
- * }
- * </pre>
- * <p>
- * 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+:
- * <p>
- * <pre>
- * <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>
- * </pre>
- *
- *
- * @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;
- }
-
-}
--- /dev/null
+/*
+ * 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;
+
+}
--- /dev/null
+/*
+ * 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;
+
+}
*/
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;
*
*
* @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();
}
}
--- /dev/null
+/*
+ * 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.
+ * <br><br>
+ *
+ * Example 1: a {@link Sensor} wants to use an API introduced in version 5.5 and still requires to support older versions
+ * at runtime.
+ * <pre>
+ * public class MySensor implements Sensor {
+ *
+ * public void execute(SensorContext context) {
+ * if (context.getRuntimeApiVersion().isGreaterThanOrEqual(RuntimeApiVersion.V5_5)) {
+ * context.newMethodIntroducedIn5_5();
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * 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.
+ * <br>
+ * <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 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();
+ * }
+ * }
+ * }
+ * </pre>
+ * <p>
+ * 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+:
+ * <p>
+ * <pre>
+ * <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>
+ * </pre>
+ *
+ *
+ * @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;
+ }
+
+}
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;
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 --------------
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;
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;
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) {
*/
@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;
}
+++ /dev/null
-/*
- * 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);
- }
- }
-}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
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();
+++ /dev/null
-/*
- * 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();
- }
-
-}
@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();
--- /dev/null
+/*
+ * 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);
+ }
+}
+++ /dev/null
-/*
- * 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);
- }
-
-}
--- /dev/null
+/*
+ * 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);
+ }
+
+}
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;
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;
}
// 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);
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;
BatchPluginPredicate.class,
ExtensionInstaller.class,
- RuntimeApiVersionFactory.create(System2.INSTANCE, false),
+ SonarRuntimeFactory.create(System2.INSTANCE, SonarProduct.SONARQUBE, SonarQubeSide.SCANNER),
CachesManager.class,
GlobalSettings.class,
new BatchWsClientProvider(),
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;
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;
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;
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
@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
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;
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);
}
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();