Skip to content

Commit

Permalink
fix issue #5
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucas3oo committed Dec 26, 2023
1 parent 23387a9 commit b294c69
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 19 deletions.
24 changes: 14 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Apply the plugin to your project.

```groovy
plugins {
id 'se.solrike.sonarlint' version '1.0.0-beta.16'
id 'se.solrike.sonarlint' version '1.0.0-beta.17'
}
```

Expand Down Expand Up @@ -96,7 +96,7 @@ dependencies {
sonarlintPlugins 'org.sonarsource.slang:sonar-ruby-plugin:1.11.0.3905'
sonarlintPlugins 'org.sonarsource.slang:sonar-scala-plugin:1.11.0.3905'
sonarlintPlugins 'org.sonarsource.sonarlint.omnisharp:sonarlint-omnisharp-plugin:1.4.0.50839'
sonarlintPlugins 'org.sonarsource.text:sonar-text-plugin:2.0.1.611'
sonarlintPlugins 'org.sonarsource.text:sonar-text-plugin:1.2.0.510' // versions after this will not work with sonarlint
sonarlintPlugins 'org.sonarsource.xml:sonar-xml-plugin:2.6.1.3686'
// include a plugin not in Maven repo but can be grabbed from the IDEs
sonarlintPlugins files("${System.getProperty('user.home')}/.p2/pool/plugins/org.sonarlint.eclipse.core_7.2.1.42550/plugins/sonar-secrets-plugin-1.1.0.36766.jar")
Expand Down Expand Up @@ -166,7 +166,7 @@ This example has TypeScript code under `projects/` and `src/`
plugins {
id 'base'
id 'com.github.node-gradle.node' version '5.0.0'
id 'se.solrike.sonarlint' version '1.0.0-beta.16'
id 'se.solrike.sonarlint' version '1.0.0-beta.17'
}
repositories {
mavenCentral()
Expand Down Expand Up @@ -213,7 +213,7 @@ Typical `gradle.build.kts`:
plugins {
// Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin.
id("org.jetbrains.kotlin.jvm") version "1.7.21"
id("se.solrike.sonarlint") version "1.0.0-beta.16"
id("se.solrike.sonarlint") version "1.0.0-beta.17"
}

repositories {
Expand Down Expand Up @@ -255,7 +255,7 @@ and `org.sonarsource.slang:sonar-scala-plugin:1.11.0.3905` and any additionally
```groovy
plugins {
id 'scala'
id 'se.solrike.sonarlint' version '1.0.0-beta.16'
id 'se.solrike.sonarlint' version '1.0.0-beta.17'
}
repositories {
Expand Down Expand Up @@ -293,7 +293,7 @@ Instead it has to be defined explicitly in the `build.gradle`.
```groovy
plugins {
id 'base'
id 'se.solrike.sonarlint' version '1.0.0-beta.16'
id 'se.solrike.sonarlint' version '1.0.0-beta.17'
}
repositories {
mavenCentral()
Expand Down Expand Up @@ -335,7 +335,7 @@ To list all the rules in your configured plugins you will have to create the tas

```groovy
plugins {
id 'se.solrike.sonarlint' version '1.0.0-beta.16'
id 'se.solrike.sonarlint' version '1.0.0-beta.17'
id 'com.github.node-gradle.node' version '5.0.0'
}
repositories {
Expand Down Expand Up @@ -590,10 +590,14 @@ You must install "SARIF SAST Scans Tab" from the marketplace into the Azure DevO
## Release notes
### 1.0.0-beta.16
Support for Gradle configuration cache <https://docs.gradle.org/current/userguide/configuration_cache.html>.
Contributed by <https://github.com/lukasgraef>.
### 1.0.0-beta.17
If any problems with the sonarlint plugins are found, the build will break. For instance using a too new plugin version or
missing dependencies or runtime (like NodeJS). This address issue [issue 5](https://github.com/Lucas3oo/sonarlint-gradle-plugin/issues/5)
where Sonarlint silently continues even if some plugins fail to load.
### 1.0.0-beta.16
Support for [Gradle configuration cache](https://docs.gradle.org/current/userguide/configuration_cache.html).
Contributed by [Lukas Gräf](https://github.com/lukasgraef).
### 1.0.0-beta.15
Fix bug in detecting CPU architecture for selecting correct node binaries.
Expand Down
14 changes: 8 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ dependencies {
}

group = 'se.solrike.sonarlint'
version = '1.0.0-beta.16'
version = '1.0.0-beta.17'

sourceSets {
main {
Expand Down Expand Up @@ -79,11 +79,13 @@ gradlePlugin {
implementationClass = 'se.solrike.sonarlint.SonarlintPlugin'
displayName = 'Sonarlint plugin'
description = 'Sonarlint static code analysis using stand-alone Sonarlint engine, for ' +
'Java, Kotlin, Scala and Node.js projects. But other languages are also possible to lint like Ruby and Golang. ' +
'\nIt is possible to include and exclude rules and also list the rules in the Sonarlist plugins you depend on. ' +
'\nThe plugin can produce Spotbugs compatible XML reports and also SARIF which can be used by Github actions, Jenkins, ' +
'AWS CodeCatalyst and Azure DevOps.' +
'\nMin Gradle version 7.0.'
'Java, Kotlin, Scala and Node.js projects. But other languages are also possible to lint like Ruby and Golang.\n' +
'It is possible to include and exclude rules and also list the rules in the Sonarlist plugins you depend on.\n' +
'If the plugin is configured with an incopatible Sonarlint plugin the build will fail.\n' +
'The plugin supports Gradle configuration cache.\n' +
'The plugin can produce Spotbugs compatible XML reports and also SARIF which can be used by Github actions, Jenkins, ' +
'AWS CodeCatalyst and Azure DevOps.\n' +
'Min Gradle version 7.0.'
}
}
}
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/se/solrike/sonarlint/impl/SonarlintAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
Expand All @@ -11,19 +12,22 @@
import java.util.Set;
import java.util.stream.Collectors;

import org.gradle.api.GradleException;
import org.gradle.api.Project;
import org.gradle.api.file.ProjectLayout;
import org.gradle.api.logging.Logger;
import org.gradle.api.provider.SetProperty;
import org.sonarsource.sonarlint.core.StandaloneSonarLintEngineImpl;
import org.sonarsource.sonarlint.core.analysis.api.AnalysisResults;
import org.sonarsource.sonarlint.core.client.api.common.PluginDetails;
import org.sonarsource.sonarlint.core.client.api.common.RuleKey;
import org.sonarsource.sonarlint.core.client.api.standalone.StandaloneAnalysisConfiguration;
import org.sonarsource.sonarlint.core.client.api.standalone.StandaloneGlobalConfiguration;
import org.sonarsource.sonarlint.core.client.api.standalone.StandaloneGlobalConfiguration.Builder;
import org.sonarsource.sonarlint.core.client.api.standalone.StandaloneSonarLintEngine;
import org.sonarsource.sonarlint.core.commons.Language;
import org.sonarsource.sonarlint.core.commons.Version;
import org.sonarsource.sonarlint.core.plugin.commons.SkipReason;

import se.solrike.sonarlint.Sonarlint;
import se.solrike.sonarlint.impl.util.NodePluginUtil;
Expand Down Expand Up @@ -125,6 +129,22 @@ protected List<IssueEx> analyze(Sonarlint task, Logger logger, SetProperty<File>

StandaloneGlobalConfiguration globalConfiguration = builder.build();
StandaloneSonarLintEngine engine = new StandaloneSonarLintEngineImpl(globalConfiguration);
// check for skipped plugins
Collection<PluginDetails> pluginDetails = engine.getPluginDetails();
pluginDetails.forEach(details -> {
if (details.skipReason().isPresent()) {
String errorMessage = "Failed to load plugin '" + details.name() + "' version " + details.version() + ". ";
if (details.skipReason().get().equals(SkipReason.IncompatiblePluginApi.INSTANCE)) {
errorMessage += "Plugin version too new for Sonarlint.";
}
else {
errorMessage += details.skipReason().get().toString();
}
// break the build
throw new GradleException(errorMessage);
}
});

IssueCollector collector = new IssueCollector();
AnalysisResults results = engine.analyze(analysisConfiguration, collector, new GradleClientLogOutput(logger),
new GradleProgressMonitor(logger));
Expand Down
113 changes: 113 additions & 0 deletions src/test/java/se/solrike/sonarlint/IncompatiblePluginTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package se.solrike.sonarlint;

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

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.GradleRunner;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

class IncompatiblePluginTest {

@TempDir
Path mProjectDir;
Path mBuildFile;

@BeforeEach
void setup() throws IOException {
mBuildFile = Files.createFile(mProjectDir.resolve("build.gradle"));
try (BufferedWriter writer = new BufferedWriter(new FileWriter(mBuildFile.toFile()))) {
writer.write("plugins { id ('java-library') \n id('se.solrike.sonarlint') }\n");
// @formatter:off
writer.write(""
+ "repositories {\n"
+ " mavenCentral()\n"
+ "}\n");
writer.write(""
+ "sonarlint {\n"
+ " dependencies {\n"
+ " sonarlintPlugins 'org.sonarsource.java:sonar-java-plugin:7.20.0.31692'\n"
+ " sonarlintPlugins 'org.sonarsource.text:sonar-text-plugin:2.0.1.611'\n"
+ " //sonarlintPlugins 'org.sonarsource.javascript:sonar-javascript-plugin:10.0.1.20755'\n"
+ " }\n"
+ " includeRules = ['java:S1176']\n"
+ "}\n"
+ "task sonarlintListRules(type: se.solrike.sonarlint.SonarlintListRules) {\n"
+ "}\n"
+ "sonarlintMain {\n"
+ " reports {"
+ " xml.enabled = true\n"
+ " sarif.enabled = true\n"
+ " }\n"
+ "}\n"
);
// @formatter:on
}
catch (IOException e) {
throw new RuntimeException(e);
}

// setup for java project
Files.createDirectories(mProjectDir.resolve("src/main/java/"));

}

@Test
void testSonarlintMain() throws IOException {
// given a java class with
createJavaFile(Files.createFile(mProjectDir.resolve("src/main/java/Hello.java")));

// when sonarlintMain is run
BuildResult buildResult = runGradle(false, List.of("sonarlintMain"));

// then the gradle build shall fail
assertThat(buildResult.task(":sonarlintMain").getOutcome()).isEqualTo(TaskOutcome.FAILED);
// and
assertThat(buildResult.getOutput())
.contains("Failed to load plugin 'Text Code Quality and Security' version 2.0.1.611.");

// CHECKSTYLE:OFF
System.err.println(buildResult.getOutput());
// CHECKSTYLE:ON
}

BuildResult runGradle(List<String> args) {
return runGradle(true, args);
}

BuildResult runGradle(boolean isSuccessExpected, List<String> args) {
// to get plugin under test found by the runner
GradleRunner gradleRunner = GradleRunner.create()
.withDebug(true)
.withArguments(args)
.withProjectDir(mProjectDir.toFile())
.withPluginClasspath();
return isSuccessExpected ? gradleRunner.build() : gradleRunner.buildAndFail();
}

void createJavaFile(Path javaFile) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(javaFile.toFile()))) {
// @formatter:off
writer.write(""
+ "public class Hello {\n"
+ " public static void get() {\n"
+ " }\n"
+ "}\n");
// @formatter:on
}
catch (IOException e) {
throw new RuntimeException(e);
}

}

}
15 changes: 12 additions & 3 deletions src/test/java/se/solrike/sonarlint/IntegrationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,18 @@ void setup() throws IOException {
writer.write(""
+ "sonarlint {\n"
+ " dependencies {\n"
+ " sonarlintPlugins 'org.sonarsource.java:sonar-java-plugin:7.17.0.31219'\n"
+ " sonarlintPlugins 'org.sonarsource.slang:sonar-go-plugin:1.12.0.4259'\n"
+ " sonarlintPlugins 'org.sonarsource.text:sonar-text-plugin:2.0.1.611'\n"
+ " //sonarlintPlugins 'org.sonarsource.html:sonar-html-plugin:3.6.0.3106'\n"
+ " sonarlintPlugins 'org.sonarsource.java:sonar-java-plugin:7.20.0.31692'\n"
+ " //sonarlintPlugins 'org.sonarsource.javascript:sonar-javascript-plugin:10.0.1.20755'\n"
+ " //sonarlintPlugins 'org.sonarsource.kotlin:sonar-kotlin-plugin:2.13.0.2116'\n"
+ " //sonarlintPlugins 'org.sonarsource.php:sonar-php-plugin:3.25.0.9077'\n"
+ " //sonarlintPlugins 'org.sonarsource.python:sonar-python-plugin:3.17.0.10029'\n"
+ " //sonarlintPlugins 'org.sonarsource.slang:sonar-go-plugin:1.12.0.4259'\n"
+ " //sonarlintPlugins 'org.sonarsource.slang:sonar-ruby-plugin:1.11.0.3905'\n"
+ " //sonarlintPlugins 'org.sonarsource.slang:sonar-scala-plugin:1.11.0.3905'\n"
+ " //sonarlintPlugins 'org.sonarsource.sonarlint.omnisharp:sonarlint-omnisharp-plugin:1.4.0.50839'\n"
+ " sonarlintPlugins 'org.sonarsource.text:sonar-text-plugin:1.2.0.510'\n"
+ " //sonarlintPlugins 'org.sonarsource.xml:sonar-xml-plugin:2.6.1.3686'\n"
+ " }\n"
+ " includeRules = ['java:S1176']\n"
+ "}\n"
Expand Down

0 comments on commit b294c69

Please sign in to comment.