@@ -25,17 +25,17 @@ 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.SonarQubeVersion.V5_5; | |||
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); | |||
Plugin.Context context = new Plugin.Context(V5_5, false); | |||
new XooPlugin().define(context); | |||
assertThat(context.getExtensions()).hasSize(40).contains(CpdTokenizerSensor.class); | |||
context = new Plugin.Context(Version.parse("5.4")); | |||
context = new Plugin.Context(Version.parse("5.4"), false); | |||
new XooPlugin().define(context); | |||
assertThat(context.getExtensions()).hasSize(39).doesNotContain(CpdTokenizerSensor.class); | |||
} |
@@ -104,7 +104,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.setSonarQubeVersion(Version.parse("5.4")); | |||
context.setRuntime(Version.parse("5.4"), false); | |||
sensor.execute(context); | |||
@@ -23,7 +23,7 @@ import com.google.common.annotations.VisibleForTesting; | |||
import java.util.List; | |||
import javax.annotation.CheckForNull; | |||
import org.sonar.api.config.EmailSettings; | |||
import org.sonar.api.internal.SonarQubeVersionFactory; | |||
import org.sonar.api.internal.RuntimeApiVersionFactory; | |||
import org.sonar.api.profiles.AnnotationProfileParser; | |||
import org.sonar.api.profiles.XMLProfileParser; | |||
import org.sonar.api.profiles.XMLProfileSerializer; | |||
@@ -135,7 +135,7 @@ import org.sonarqube.ws.Rules; | |||
public class ComputeEngineContainerImpl implements ComputeEngineContainer { | |||
private static final Object[] LEVEL_1_COMPONENTS = new Object[] { | |||
ComputeEngineSettings.class, | |||
SonarQubeVersionFactory.create(System2.INSTANCE), | |||
RuntimeApiVersionFactory.create(System2.INSTANCE, false), | |||
ServerImpl.class, | |||
UuidFactoryImpl.INSTANCE, | |||
// no EmbeddedDatabaseFactory.class, creating H2 DB if responsibility of WebServer |
@@ -19,14 +19,14 @@ | |||
*/ | |||
package org.sonar.ce.platform; | |||
import org.sonar.api.SonarQubeVersion; | |||
import org.sonar.api.RuntimeApiVersion; | |||
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(SonarQubeVersion sonarQubeVersion, PluginRepository pluginRepository) { | |||
super(sonarQubeVersion, pluginRepository, ServerSide.class, ComputeEngineSide.class); | |||
public ComputeEngineExtensionInstaller(RuntimeApiVersion runtimeApiVersion, PluginRepository pluginRepository) { | |||
super(runtimeApiVersion, pluginRepository, ServerSide.class, ComputeEngineSide.class); | |||
} | |||
} |
@@ -21,7 +21,7 @@ package org.sonar.server.platform.platformlevel; | |||
import java.util.Properties; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.internal.SonarQubeVersionFactory; | |||
import org.sonar.api.internal.RuntimeApiVersionFactory; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.api.utils.internal.TempFolderCleaner; | |||
import org.sonar.ce.property.CePropertyDefinitions; | |||
@@ -68,7 +68,7 @@ public class PlatformLevel1 extends PlatformLevel { | |||
add(platform, properties); | |||
addExtraRootComponents(); | |||
add( | |||
SonarQubeVersionFactory.create(System2.INSTANCE), | |||
RuntimeApiVersionFactory.create(System2.INSTANCE, false), | |||
ProcessCommandWrapperImpl.class, | |||
RestartFlagHolderImpl.class, | |||
WebServerSettings.class, |
@@ -23,10 +23,9 @@ import com.google.common.collect.ArrayListMultimap; | |||
import com.google.common.collect.ListMultimap; | |||
import java.lang.annotation.Annotation; | |||
import java.util.Map; | |||
import org.sonar.api.Extension; | |||
import org.sonar.api.ExtensionProvider; | |||
import org.sonar.api.Plugin; | |||
import org.sonar.api.SonarQubeVersion; | |||
import org.sonar.api.RuntimeApiVersion; | |||
import org.sonar.api.utils.AnnotationUtils; | |||
import org.sonar.core.platform.ComponentContainer; | |||
import org.sonar.core.platform.PluginInfo; | |||
@@ -39,14 +38,14 @@ import static java.util.Objects.requireNonNull; | |||
*/ | |||
public abstract class ServerExtensionInstaller { | |||
private final SonarQubeVersion sonarQubeVersion; | |||
private final RuntimeApiVersion runtimeApiVersion; | |||
private final PluginRepository pluginRepository; | |||
private final Class<? extends Annotation>[] supportedAnnotationTypes; | |||
protected ServerExtensionInstaller(SonarQubeVersion sonarQubeVersion, PluginRepository pluginRepository, | |||
protected ServerExtensionInstaller(RuntimeApiVersion runtimeApiVersion, PluginRepository pluginRepository, | |||
Class<? extends Annotation>... supportedAnnotationTypes) { | |||
requireNonNull(supportedAnnotationTypes, "At least one supported annotation type must be specified"); | |||
this.sonarQubeVersion = sonarQubeVersion; | |||
this.runtimeApiVersion = runtimeApiVersion; | |||
this.pluginRepository = pluginRepository; | |||
this.supportedAnnotationTypes = supportedAnnotationTypes; | |||
} | |||
@@ -60,7 +59,7 @@ public abstract class ServerExtensionInstaller { | |||
Plugin plugin = pluginRepository.getPluginInstance(pluginKey); | |||
container.addExtension(pluginInfo, plugin); | |||
Plugin.Context context = new Plugin.Context(sonarQubeVersion.get()); | |||
Plugin.Context context = new Plugin.Context(runtimeApiVersion.get(), runtimeApiVersion.isSonarlintRuntime()); | |||
plugin.define(context); | |||
for (Object extension : context.getExtensions()) { | |||
if (installExtension(container, pluginInfo, extension, true) != null) { | |||
@@ -119,7 +118,7 @@ public abstract class ServerExtensionInstaller { | |||
return isType(extension, ExtensionProvider.class) || extension instanceof ExtensionProvider; | |||
} | |||
static boolean isType(Object extension, Class<? extends Extension> extensionClass) { | |||
static boolean isType(Object extension, Class extensionClass) { | |||
Class clazz = extension instanceof Class ? (Class) extension : extension.getClass(); | |||
return extensionClass.isAssignableFrom(clazz); | |||
} |
@@ -19,16 +19,20 @@ | |||
*/ | |||
package org.sonar.api; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.ce.ComputeEngineSide; | |||
import org.sonar.api.server.ServerSide; | |||
/** | |||
* Factory of extensions. It allows to dynamically create extensions depending upon runtime context. A use-case is | |||
* Factory of extensions. It allows to dynamically create extensions depending upon runtime context. One use-case is | |||
* to create one rule repository by language. | |||
* | |||
* <p>Notes : | |||
* <ul> | |||
* <li>the provider is declared in Plugin.getExtensions()</li> | |||
* <li>the provider must also implement ServerExtension and/or BatchExtension</li> | |||
* <li>the provider must also add annotation {@link ServerSide}, {@link ComputeEngineSide} and/or {@link BatchSide}</li> | |||
* <li>the provider can accept dependencies (parameters) in its constructors.</li> | |||
* <li>the method provide() is executed once by sonar</li> | |||
* <li>the method provide() is executed once by the platform</li> | |||
* <li>the method provide() must return an object, a class or an Iterable of objects. <strong>Arrays are excluded</strong>.</li> | |||
* </ul> | |||
* | |||
@@ -36,7 +40,8 @@ package org.sonar.api; | |||
* <p>Example: | |||
* <pre> | |||
* {@code | |||
* public class RuleRepositoryProvider extends ExtensionProvider implements ServerExtension { | |||
* {@literal @}ServerSide | |||
* public class RuleRepositoryProvider extends ExtensionProvider { | |||
* private Language[] languages; | |||
* | |||
* public RuleRepositoryProvider(Language[] languages) { | |||
@@ -59,7 +64,8 @@ package org.sonar.api; | |||
* @deprecated since 6.0 should no more be used | |||
*/ | |||
@Deprecated | |||
public abstract class ExtensionProvider implements Extension { | |||
@ExtensionPoint | |||
public abstract class ExtensionProvider { | |||
public abstract Object provide(); | |||
} |
@@ -85,18 +85,29 @@ import static java.util.Objects.requireNonNull; | |||
public interface Plugin { | |||
class Context { | |||
private final Version version; | |||
private final Version runtimeApiVersion; | |||
private final List extensions = new ArrayList(); | |||
private final boolean sonarlintRuntime; | |||
public Context(Version version) { | |||
this.version = version; | |||
public Context(Version runtimeApiVersion, boolean sonarlintRuntime) { | |||
this.runtimeApiVersion = runtimeApiVersion; | |||
this.sonarlintRuntime = sonarlintRuntime; | |||
} | |||
/** | |||
* Runtime version of SonarQube | |||
* @deprecated since 6.0 | |||
*/ | |||
@Deprecated | |||
public Version getSonarQubeVersion() { | |||
return version; | |||
return runtimeApiVersion; | |||
} | |||
/** | |||
* Runtime API version. Can be use to conditionnaly add some extensions. | |||
* @since 6.0 | |||
*/ | |||
public Version getRuntimeApiVersion() { | |||
return runtimeApiVersion; | |||
} | |||
/** | |||
@@ -141,6 +152,14 @@ public interface Plugin { | |||
public List getExtensions() { | |||
return extensions; | |||
} | |||
/** | |||
* Test if plugin is currently executed in SonarLint. Can be use to conditionnaly add some extensions. | |||
* @since 6.0 | |||
*/ | |||
public boolean isSonarlintRuntime() { | |||
return sonarlintRuntime; | |||
} | |||
} | |||
/** |
@@ -0,0 +1,161 @@ | |||
/* | |||
* 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; | |||
} | |||
} |
@@ -26,8 +26,6 @@ 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 | |||
@@ -117,36 +115,17 @@ import static java.util.Objects.requireNonNull; | |||
* | |||
* | |||
* @since 5.5 | |||
* @deprecated since 6.0 replaced by {@link RuntimeApiVersion} | |||
*/ | |||
@ScannerSide | |||
@ServerSide | |||
@ComputeEngineSide | |||
@Immutable | |||
public class SonarQubeVersion { | |||
/** | |||
* Constant for version 5.5 | |||
*/ | |||
public static final Version V5_5 = Version.create(5, 5); | |||
/** | |||
* Constant for version 5.6 | |||
*/ | |||
public static final Version V5_6 = Version.create(5, 6); | |||
private final Version version; | |||
public SonarQubeVersion(Version version) { | |||
requireNonNull(version); | |||
this.version = version; | |||
} | |||
public Version get() { | |||
return this.version; | |||
} | |||
@Deprecated | |||
public class SonarQubeVersion extends RuntimeApiVersion { | |||
public boolean isGreaterThanOrEqual(Version than) { | |||
return this.version.isGreaterThanOrEqual(than); | |||
public SonarQubeVersion(Version version, boolean sonarlint) { | |||
super(version, sonarlint); | |||
} | |||
} |
@@ -22,6 +22,7 @@ package org.sonar.api.batch.sensor; | |||
import org.sonar.api.ExtensionPoint; | |||
import org.sonar.api.batch.ScannerSide; | |||
import org.sonar.api.batch.sensor.internal.SensorContextTester; | |||
import org.sonarsource.api.sonarlint.SonarLintSide; | |||
/** | |||
* <p> | |||
@@ -34,6 +35,7 @@ import org.sonar.api.batch.sensor.internal.SensorContextTester; | |||
* @since 5.1 | |||
*/ | |||
@ScannerSide | |||
@SonarLintSide | |||
@ExtensionPoint | |||
public interface Sensor { | |||
@@ -64,9 +64,22 @@ public interface SensorContext { | |||
/** | |||
* @since 5.5 | |||
* @deprecated since 6.0 replaced by {@link #getRuntimeApiVersion()} | |||
*/ | |||
@Deprecated | |||
Version getSonarQubeVersion(); | |||
/** | |||
* @since 6.0 | |||
*/ | |||
Version getRuntimeApiVersion(); | |||
/** | |||
* Test if plugin is currently executed in SonarLint. This can allow to implement a different behavior. | |||
* @since 6.0 | |||
*/ | |||
boolean isSonarLintRuntime(); | |||
// ----------- MEASURES -------------- | |||
/** |
@@ -58,7 +58,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.SonarQubeVersionFactory; | |||
import org.sonar.api.internal.RuntimeApiVersionFactory; | |||
import org.sonar.api.measures.Metric; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.api.utils.Version; | |||
@@ -95,7 +95,7 @@ public class SensorContextTester implements SensorContext { | |||
this.activeRules = new ActiveRulesBuilder().build(); | |||
this.sensorStorage = new InMemorySensorStorage(); | |||
this.module = new DefaultInputModule("projectKey"); | |||
this.sqVersion = SonarQubeVersionFactory.create(System2.INSTANCE); | |||
this.sqVersion = RuntimeApiVersionFactory.create(System2.INSTANCE, false); | |||
} | |||
public static SensorContextTester create(File moduleBaseDir) { | |||
@@ -145,8 +145,18 @@ public class SensorContextTester implements SensorContext { | |||
return sqVersion.get(); | |||
} | |||
public SensorContextTester setSonarQubeVersion(Version version) { | |||
this.sqVersion = new SonarQubeVersion(version); | |||
@Override | |||
public Version getRuntimeApiVersion() { | |||
return sqVersion.get(); | |||
} | |||
@Override | |||
public boolean isSonarLintRuntime() { | |||
return sqVersion.isSonarlintRuntime(); | |||
} | |||
public SensorContextTester setRuntime(Version version, boolean isSonarLint) { | |||
this.sqVersion = new SonarQubeVersion(version, isSonarLint); | |||
return this; | |||
} | |||
@@ -30,19 +30,19 @@ import org.sonar.api.utils.Version; | |||
/** | |||
* For internal use only. | |||
*/ | |||
public class SonarQubeVersionFactory { | |||
public class RuntimeApiVersionFactory { | |||
private static final String FILE_PATH = "/sq-version.txt"; | |||
private SonarQubeVersionFactory() { | |||
private RuntimeApiVersionFactory() { | |||
// prevents instantiation | |||
} | |||
public static SonarQubeVersion create(System2 system) { | |||
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)); | |||
return new SonarQubeVersion(Version.parse(versionInFile), isSonarLint); | |||
} catch (IOException e) { | |||
throw new IllegalStateException("Can not load " + FILE_PATH + " from classpath", e); | |||
} |
@@ -24,6 +24,7 @@ import org.sonar.api.batch.ScannerSide; | |||
import org.sonar.api.batch.InstantiationStrategy; | |||
import org.sonar.api.ce.ComputeEngineSide; | |||
import org.sonar.api.server.ServerSide; | |||
import org.sonarsource.api.sonarlint.SonarLintSide; | |||
/** | |||
* The extension point to define a new language | |||
@@ -35,6 +36,7 @@ import org.sonar.api.server.ServerSide; | |||
@ScannerSide | |||
@InstantiationStrategy(InstantiationStrategy.PER_BATCH) | |||
@ServerSide | |||
@SonarLintSide | |||
@ComputeEngineSide | |||
@ExtensionPoint | |||
public interface Language { |
@@ -40,13 +40,14 @@ import javax.annotation.concurrent.Immutable; | |||
import org.apache.commons.io.IOUtils; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.ExtensionPoint; | |||
import org.sonar.api.ce.ComputeEngineSide; | |||
import org.sonar.api.rule.RuleStatus; | |||
import org.sonar.api.rule.Severity; | |||
import org.sonar.api.rules.RuleType; | |||
import org.sonar.api.ce.ComputeEngineSide; | |||
import org.sonar.api.server.ServerSide; | |||
import org.sonar.api.server.debt.DebtRemediationFunction; | |||
import org.sonar.api.utils.log.Loggers; | |||
import org.sonarsource.api.sonarlint.SonarLintSide; | |||
import static com.google.common.base.Preconditions.checkArgument; | |||
import static com.google.common.base.Preconditions.checkState; | |||
@@ -149,6 +150,7 @@ import static org.apache.commons.lang.StringUtils.trimToNull; | |||
*/ | |||
@ServerSide | |||
@ComputeEngineSide | |||
@SonarLintSide | |||
@ExtensionPoint | |||
public interface RulesDefinition { | |||
@@ -672,6 +674,7 @@ public interface RulesDefinition { | |||
private final Set<String> tags = Sets.newTreeSet(); | |||
private final Map<String, NewParam> paramsByKey = Maps.newHashMap(); | |||
private final DebtRemediationFunctions functions; | |||
private boolean activatedByDefault; | |||
private NewRule(String repoKey, String key) { | |||
this.repoKey = repoKey; | |||
@@ -696,6 +699,15 @@ public interface RulesDefinition { | |||
return this; | |||
} | |||
/** | |||
* Should this rule be enabled by default. For example in SonarLint standalone. | |||
* @since 6.0 | |||
*/ | |||
public NewRule setActivatedByDefault(boolean activatedByDefault) { | |||
this.activatedByDefault = activatedByDefault; | |||
return this; | |||
} | |||
public NewRule setSeverity(String s) { | |||
checkArgument(Severity.ALL.contains(s), "Severity of rule %s is not correct: %s", this, s); | |||
this.severity = s; | |||
@@ -915,6 +927,7 @@ public interface RulesDefinition { | |||
private final Set<String> tags; | |||
private final Map<String, Param> params; | |||
private final RuleStatus status; | |||
private final boolean activatedByDefault; | |||
private Rule(Repository repository, NewRule newRule) { | |||
this.repository = repository; | |||
@@ -936,6 +949,7 @@ public interface RulesDefinition { | |||
paramsBuilder.put(newParam.key, new Param(newParam)); | |||
} | |||
this.params = paramsBuilder.build(); | |||
this.activatedByDefault = newRule.activatedByDefault; | |||
} | |||
public Repository repository() { | |||
@@ -976,6 +990,14 @@ public interface RulesDefinition { | |||
return template; | |||
} | |||
/** | |||
* Should this rule be enabled by default. For example in SonarLint standalone. | |||
* @since 6.0 | |||
*/ | |||
public boolean activatedByDefault() { | |||
return activatedByDefault; | |||
} | |||
public RuleStatus status() { | |||
return status; | |||
} |
@@ -54,8 +54,7 @@ public class RulesDefinitionAnnotationLoader { | |||
.put(Boolean.class, RuleParamType.BOOLEAN) | |||
.put(boolean.class, RuleParamType.BOOLEAN) | |||
.build(), | |||
RuleParamType.STRING | |||
); | |||
RuleParamType.STRING); | |||
public void load(RulesDefinition.NewExtendedRepository repo, Class... annotatedClasses) { | |||
for (Class annotatedClass : annotatedClasses) { |
@@ -21,8 +21,6 @@ package org.sonar.api.server.rule; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.i18n.RuleI18n; | |||
import org.sonar.api.ce.ComputeEngineSide; | |||
import org.sonar.api.server.ServerSide; | |||
/** | |||
* Loads the English bundles of rules (name, description and parameters) that are | |||
@@ -36,8 +34,6 @@ import org.sonar.api.server.ServerSide; | |||
* @see org.sonar.api.server.rule.RulesDefinition for an example | |||
* @since 4.3 | |||
*/ | |||
@ServerSide | |||
@ComputeEngineSide | |||
public class RulesDefinitionI18nLoader { | |||
private final RuleI18n i18n; |
@@ -32,13 +32,14 @@ import javax.xml.stream.XMLStreamException; | |||
import org.codehaus.staxmate.SMInputFactory; | |||
import org.codehaus.staxmate.in.SMHierarchicCursor; | |||
import org.codehaus.staxmate.in.SMInputCursor; | |||
import org.sonar.api.ce.ComputeEngineSide; | |||
import org.sonar.api.rule.RuleStatus; | |||
import org.sonar.api.rule.Severity; | |||
import org.sonar.api.rules.RuleType; | |||
import org.sonar.api.ce.ComputeEngineSide; | |||
import org.sonar.api.server.ServerSide; | |||
import org.sonar.api.server.debt.DebtRemediationFunction; | |||
import org.sonar.check.Cardinality; | |||
import org.sonarsource.api.sonarlint.SonarLintSide; | |||
import static java.lang.String.format; | |||
import static org.apache.commons.lang.StringUtils.equalsIgnoreCase; | |||
@@ -180,6 +181,7 @@ import static org.apache.commons.lang.StringUtils.trim; | |||
*/ | |||
@ServerSide | |||
@ComputeEngineSide | |||
@SonarLintSide | |||
public class RulesDefinitionXmlLoader { | |||
private enum DescriptionFormat { |
@@ -0,0 +1,52 @@ | |||
/* | |||
* 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.sonarsource.api.sonarlint; | |||
import java.lang.annotation.Documented; | |||
import java.lang.annotation.ElementType; | |||
import java.lang.annotation.Retention; | |||
import java.lang.annotation.RetentionPolicy; | |||
import java.lang.annotation.Target; | |||
/** | |||
* Marker annotation for all the components available in container of sonarlint. Note that | |||
* injection of dependencies by constructor is used : | |||
* <pre> | |||
* {@literal @}SonarLintSide | |||
* public class Foo { | |||
* | |||
* } | |||
* {@literal @}SonarLintSide | |||
* public class Bar { | |||
* private final Foo foo; | |||
* public Bar(Foo f) { | |||
* this.foo = f; | |||
* } | |||
* } | |||
* | |||
* </pre> | |||
* | |||
* @since 6.0 | |||
*/ | |||
@Documented | |||
@Retention(RetentionPolicy.RUNTIME) | |||
@Target(ElementType.TYPE) | |||
public @interface SonarLintSide { | |||
} |
@@ -0,0 +1,23 @@ | |||
/* | |||
* 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. | |||
*/ | |||
@ParametersAreNonnullByDefault | |||
package org.sonarsource.api.sonarlint; | |||
import javax.annotation.ParametersAreNonnullByDefault; |
@@ -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.SonarQubeVersion.V5_5; | |||
import static org.sonar.api.RuntimeApiVersion.V5_5; | |||
public class PluginTest { | |||
@Test | |||
public void test_context() { | |||
Plugin.Context context = new Plugin.Context(V5_5); | |||
Plugin.Context context = new Plugin.Context(V5_5, true); | |||
assertThat(context.getSonarQubeVersion()).isEqualTo(V5_5); | |||
assertThat(context.getExtensions()).isEmpty(); |
@@ -0,0 +1,45 @@ | |||
/* | |||
* 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(); | |||
} | |||
} |
@@ -34,8 +34,9 @@ public class SonarQubeVersionTest { | |||
@Test | |||
public void isGte() { | |||
Version version = Version.parse("1.2.3"); | |||
SonarQubeVersion qubeVersion = new SonarQubeVersion(version); | |||
SonarQubeVersion qubeVersion = new SonarQubeVersion(version, true); | |||
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(); |
@@ -31,16 +31,17 @@ import static org.mockito.Matchers.anyString; | |||
import static org.mockito.Mockito.spy; | |||
import static org.mockito.Mockito.when; | |||
public class SonarQubeVersionFactoryTest { | |||
public class RuntimeApiVersionFactoryTest { | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@Test | |||
public void create() { | |||
SonarQubeVersion version = SonarQubeVersionFactory.create(System2.INSTANCE); | |||
SonarQubeVersion version = RuntimeApiVersionFactory.create(System2.INSTANCE, true); | |||
assertThat(version).isNotNull(); | |||
assertThat(version.get().major()).isGreaterThanOrEqualTo(5); | |||
assertThat(version.isSonarlintRuntime()).isTrue(); | |||
} | |||
@Test | |||
@@ -50,7 +51,7 @@ public class SonarQubeVersionFactoryTest { | |||
System2 system = spy(System2.class); | |||
when(system.getResource(anyString())).thenReturn(new File("target/unknown").toURI().toURL()); | |||
SonarQubeVersionFactory.create(system); | |||
RuntimeApiVersionFactory.create(system, false); | |||
} | |||
} |
@@ -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.SonarQubeVersion; | |||
import org.sonar.api.RuntimeApiVersion; | |||
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 SonarQubeVersion sonarQubeVersion; | |||
private final RuntimeApiVersion runtimeApiVersionVersion; | |||
private final PluginRepository pluginRepository; | |||
private final AnalysisMode analysisMode; | |||
public ExtensionInstaller(SonarQubeVersion sonarQubeVersion, PluginRepository pluginRepository, AnalysisMode analysisMode) { | |||
this.sonarQubeVersion = sonarQubeVersion; | |||
public ExtensionInstaller(RuntimeApiVersion sonarQubeVersion, PluginRepository pluginRepository, AnalysisMode analysisMode) { | |||
this.runtimeApiVersionVersion = sonarQubeVersion; | |||
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(sonarQubeVersion.get()); | |||
Plugin.Context context = new Plugin.Context(runtimeApiVersionVersion.get(), runtimeApiVersionVersion.isSonarlintRuntime()); | |||
plugin.define(context); | |||
for (Object extension : context.getExtensions()) { | |||
doInstall(container, matcher, pluginInfo, extension); |
@@ -23,7 +23,7 @@ import java.util.List; | |||
import java.util.Map; | |||
import org.sonar.api.Plugin; | |||
import org.sonar.api.internal.SonarQubeVersionFactory; | |||
import org.sonar.api.internal.RuntimeApiVersionFactory; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.api.utils.UriReader; | |||
import org.sonar.api.utils.log.Logger; | |||
@@ -76,7 +76,7 @@ public class GlobalContainer extends ComponentContainer { | |||
BatchPluginPredicate.class, | |||
ExtensionInstaller.class, | |||
SonarQubeVersionFactory.create(System2.INSTANCE), | |||
RuntimeApiVersionFactory.create(System2.INSTANCE, false), | |||
CachesManager.class, | |||
GlobalSettings.class, | |||
new BatchWsClientProvider(), |
@@ -21,7 +21,7 @@ package org.sonar.scanner.deprecated; | |||
import java.io.Serializable; | |||
import java.util.Collection; | |||
import org.sonar.api.SonarQubeVersion; | |||
import org.sonar.api.RuntimeApiVersion; | |||
import org.sonar.api.batch.AnalysisMode; | |||
import org.sonar.api.batch.SensorContext; | |||
import org.sonar.api.batch.fs.FileSystem; | |||
@@ -51,7 +51,7 @@ 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, SonarQubeVersion sqVersion) { | |||
AnalysisMode analysisMode, CoverageExclusions coverageFilter, SensorStorage sensorStorage, RuntimeApiVersion sqVersion) { | |||
super(module, settings, fs, activeRules, analysisMode, sensorStorage, sqVersion); | |||
this.index = index; | |||
this.project = project; |
@@ -20,7 +20,7 @@ | |||
package org.sonar.scanner.sensor; | |||
import java.io.Serializable; | |||
import org.sonar.api.SonarQubeVersion; | |||
import org.sonar.api.RuntimeApiVersion; | |||
import org.sonar.api.batch.AnalysisMode; | |||
import org.sonar.api.batch.fs.FileSystem; | |||
import org.sonar.api.batch.fs.InputModule; | |||
@@ -57,10 +57,10 @@ public class DefaultSensorContext implements SensorContext { | |||
private final SensorStorage sensorStorage; | |||
private final AnalysisMode analysisMode; | |||
private final InputModule module; | |||
private final SonarQubeVersion sqVersion; | |||
private final RuntimeApiVersion sqVersion; | |||
public DefaultSensorContext(InputModule module, Settings settings, FileSystem fs, ActiveRules activeRules, AnalysisMode analysisMode, SensorStorage sensorStorage, | |||
SonarQubeVersion sqVersion) { | |||
RuntimeApiVersion sqVersion) { | |||
this.module = module; | |||
this.settings = settings; | |||
this.fs = fs; | |||
@@ -95,6 +95,16 @@ public class DefaultSensorContext implements SensorContext { | |||
return sqVersion.get(); | |||
} | |||
@Override | |||
public Version getRuntimeApiVersion() { | |||
return sqVersion.get(); | |||
} | |||
@Override | |||
public boolean isSonarLintRuntime() { | |||
return sqVersion.isSonarlintRuntime(); | |||
} | |||
@Override | |||
public <G extends Serializable> NewMeasure<G> newMeasure() { | |||
return new DefaultMeasure<>(sensorStorage); |
@@ -67,7 +67,7 @@ public class DefaultSensorContextTest { | |||
settings = new Settings(); | |||
sensorStorage = mock(SensorStorage.class); | |||
analysisMode = mock(AnalysisMode.class); | |||
sqVersion = new SonarQubeVersion(Version.parse("5.5")); | |||
sqVersion = new SonarQubeVersion(Version.parse("5.5"), false); | |||
adaptor = new DefaultSensorContext(mock(InputModule.class), settings, fs, activeRules, analysisMode, sensorStorage, sqVersion); | |||
} | |||
@@ -77,6 +77,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.newIssue()).isNotNull(); | |||
assertThat(adaptor.newMeasure()).isNotNull(); |