diff --git a/its/org.sonarlint.eclipse.its.connected.sq/res/azurepipelines-sonarlint.xml b/its/org.sonarlint.eclipse.its.connected.sq/res/azurepipelines-sonarlint.xml
new file mode 100644
index 0000000000..bb4afbd0a0
--- /dev/null
+++ b/its/org.sonarlint.eclipse.its.connected.sq/res/azurepipelines-sonarlint.xml
@@ -0,0 +1,13 @@
+
+
+ SonarLint IT Azure Pipelines
+ azurepipelines
+
+
+
+ azurepipelines
+ S1135
+ MAJOR
+
+
+
diff --git a/its/org.sonarlint.eclipse.its.connected.sq/res/shell-sonarlint.xml b/its/org.sonarlint.eclipse.its.connected.sq/res/shell-sonarlint.xml
new file mode 100644
index 0000000000..0291ec5a8f
--- /dev/null
+++ b/its/org.sonarlint.eclipse.its.connected.sq/res/shell-sonarlint.xml
@@ -0,0 +1,13 @@
+
+
+ SonarLint IT Shell
+ shell
+
+
+
+ shell
+ S6505
+ MAJOR
+
+
+
diff --git a/its/org.sonarlint.eclipse.its.connected.sq/src/org/sonarlint/eclipse/its/connected/sq/AbstractSonarQubeConnectedModeTest.java b/its/org.sonarlint.eclipse.its.connected.sq/src/org/sonarlint/eclipse/its/connected/sq/AbstractSonarQubeConnectedModeTest.java
index d787c4a6e3..03baebb1ee 100644
--- a/its/org.sonarlint.eclipse.its.connected.sq/src/org/sonarlint/eclipse/its/connected/sq/AbstractSonarQubeConnectedModeTest.java
+++ b/its/org.sonarlint.eclipse.its.connected.sq/src/org/sonarlint/eclipse/its/connected/sq/AbstractSonarQubeConnectedModeTest.java
@@ -19,6 +19,7 @@
*/
package org.sonarlint.eclipse.its.connected.sq;
+import com.google.gson.JsonParser;
import com.sonar.orchestrator.build.MavenBuild;
import com.sonar.orchestrator.container.Server;
import com.sonar.orchestrator.junit4.OrchestratorRule;
@@ -49,6 +50,7 @@
import org.sonarqube.ws.client.HttpConnector;
import org.sonarqube.ws.client.WsClient;
import org.sonarqube.ws.client.WsClientFactories;
+import org.sonarqube.ws.client.languages.ListRequest;
import org.sonarqube.ws.client.projects.CreateRequest;
import org.sonarqube.ws.client.settings.SetRequest;
import org.sonarqube.ws.client.usertokens.GenerateRequest;
@@ -74,21 +76,24 @@ public static void prepare(OrchestratorRule orchestrator) {
adminWsClient.settings().set(new SetRequest().setKey("sonar.forceAuthentication").setValue("true"));
try {
- orchestrator.getServer().restoreProfile(
- URLLocation.create(FileLocator.toFileURL(FileLocator.find(FrameworkUtil.getBundle(SonarQubeConnectedModeTest.class), new Path("res/java-sonarlint.xml"), null))));
- orchestrator.getServer().restoreProfile(
- URLLocation.create(FileLocator.toFileURL(FileLocator.find(FrameworkUtil.getBundle(SonarQubeConnectedModeTest.class), new Path("res/java-sonarlint-new-code.xml"), null))));
+ restoreQualityProfile(orchestrator, "res/java-sonarlint.xml");
+ restoreQualityProfile(orchestrator, "res/java-sonarlint-new-code.xml");
if (orchestrator.getServer().version().isGreaterThanOrEquals(10, 4)) {
- orchestrator.getServer().restoreProfile(
- URLLocation.create(FileLocator.toFileURL(FileLocator.find(FrameworkUtil.getBundle(SonarQubeConnectedModeTest.class), new Path("res/custom-secrets.xml"), null))));
+ restoreQualityProfile(orchestrator, "res/custom-secrets.xml");
}
if (orchestrator.getServer().version().isGreaterThanOrEquals(10, 6)) {
- orchestrator.getServer().restoreProfile(
- URLLocation.create(FileLocator.toFileURL(FileLocator.find(FrameworkUtil.getBundle(SonarQubeConnectedModeTest.class), new Path("res/java-sonarlint-dbd.xml"), null))));
- orchestrator.getServer().restoreProfile(
- URLLocation.create(FileLocator.toFileURL(FileLocator.find(FrameworkUtil.getBundle(SonarQubeConnectedModeTest.class), new Path("res/python-sonarlint-dbd.xml"), null))));
+ restoreQualityProfile(orchestrator, "res/java-sonarlint-dbd.xml");
+ restoreQualityProfile(orchestrator, "res/python-sonarlint-dbd.xml");
+ }
+
+ if (isLanguageSupported("azurepipelines")) {
+ restoreQualityProfile(orchestrator, "res/azurepipelines-sonarlint.xml");
+ }
+
+ if (isLanguageSupported("shell")) {
+ restoreQualityProfile(orchestrator, "res/shell-sonarlint.xml");
}
} catch (IOException e) {
fail("Unable to load quality profile", e);
@@ -109,6 +114,22 @@ protected static WsClient newAdminWsClient(Server server) {
.build());
}
+ protected static boolean isLanguageSupported(String languageKey) {
+ var response = JsonParser.parseString(adminWsClient.languages().list(new ListRequest().setQ(languageKey))).getAsJsonObject();
+ var languages = response.getAsJsonArray("languages");
+ if (languages == null) {
+ return false;
+ }
+
+ for (var language : languages) {
+ var key = language.getAsJsonObject().get("key");
+ if (key != null && languageKey.equals(key.getAsString())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/** Create a project on SonarQube via Web API with corresponding quality profile assigned */
public static void createProjectOnSonarQube(OrchestratorRule orchestrator, String projectKey, String qualityProfile) {
adminWsClient.projects()
@@ -207,6 +228,11 @@ protected static void createConnectionAndBindProject(OrchestratorRule orchestrat
projectBindingWizard.finish();
}
+ private static void restoreQualityProfile(OrchestratorRule orchestrator, String resourcePath) throws IOException {
+ orchestrator.getServer().restoreProfile(
+ URLLocation.create(FileLocator.toFileURL(FileLocator.find(FrameworkUtil.getBundle(SonarQubeConnectedModeTest.class), new Path(resourcePath), null))));
+ }
+
protected static void bindProjectFromContextMenu(Project project, String projectKey) {
new ContextMenu(project.getTreeItem()).getItem("SonarQube", "Bind to SonarQube (Server, Cloud)...").select();
diff --git a/its/org.sonarlint.eclipse.its.connected.sq/src/org/sonarlint/eclipse/its/connected/sq/SonarQubeConnectedModeTest.java b/its/org.sonarlint.eclipse.its.connected.sq/src/org/sonarlint/eclipse/its/connected/sq/SonarQubeConnectedModeTest.java
index c572f29e43..f877ef01c3 100644
--- a/its/org.sonarlint.eclipse.its.connected.sq/src/org/sonarlint/eclipse/its/connected/sq/SonarQubeConnectedModeTest.java
+++ b/its/org.sonarlint.eclipse.its.connected.sq/src/org/sonarlint/eclipse/its/connected/sq/SonarQubeConnectedModeTest.java
@@ -90,6 +90,12 @@ public class SonarQubeConnectedModeTest extends AbstractSonarQubeConnectedModeTe
private static final String MAVEN2_PROJECT_KEY = "maven2";
private static final String MAVEN_TAINT_PROJECT_KEY = "maven-taint";
private static final String DBD_PROJECT_KEY = "dbd";
+ private static final String AZUREPIPELINES_PROJECT_KEY = "azurepipelines-simple";
+ private static final String AZUREPIPELINES_QUALITY_PROFILE = "SonarLint IT Azure Pipelines";
+ private static final String AZUREPIPELINES_LANGUAGE_KEY = "azurepipelines";
+ private static final String SHELL_PROJECT_KEY = "shell-simple";
+ private static final String SHELL_QUALITY_PROFILE = "SonarLint IT Shell";
+ private static final String SHELL_LANGUAGE_KEY = "shell";
private static final String CUSTOM_SECRETS_PROJECT_KEY = "secrets-custom";
private static final String INSUFFICIENT_PERMISSION_USER = "iHaveNoRights";
private static final MarkerDescriptionMatcher ISSUE_MATCHER = new MarkerDescriptionMatcher(
@@ -612,6 +618,68 @@ public void test_Java_Python_DBD() {
new DefaultEditor().close();
}
+ @Test
+ public void test_AzurePipelines() {
+ Assume.assumeTrue(isLanguageSupported(AZUREPIPELINES_LANGUAGE_KEY));
+
+ adminWsClient.projects()
+ .create(new CreateRequest()
+ .setName(AZUREPIPELINES_PROJECT_KEY)
+ .setProject(AZUREPIPELINES_PROJECT_KEY));
+ orchestrator.getServer().associateProjectToQualityProfile(AZUREPIPELINES_PROJECT_KEY, AZUREPIPELINES_LANGUAGE_KEY, AZUREPIPELINES_QUALITY_PROFILE);
+
+ new JavaPerspective().open();
+ var rootProject = importExistingProjectIntoWorkspace("azurepipelines/azurepipelines-simple", AZUREPIPELINES_PROJECT_KEY);
+ closeUnsupportedLanguageNotifications();
+
+ var onTheFlyView = new OnTheFlyView();
+ onTheFlyView.open();
+
+ openFileAndWaitForAnalysisCompletion(rootProject.getResource("azure-pipelines.yml"));
+ closeUnsupportedLanguageNotifications();
+ waitForNoSonarLintMarkers(onTheFlyView);
+ new DefaultEditor().close();
+
+ createConnectionAndBindProject(orchestrator, AZUREPIPELINES_PROJECT_KEY);
+ shellByName("SonarQube - Binding Suggestion").ifPresent(shell -> new DefaultLink(shell, "Don't ask again").click());
+ waitForAnalysisReady(AZUREPIPELINES_PROJECT_KEY);
+
+ openFileAndWaitForAnalysisCompletion(rootProject.getResource("azure-pipelines.yml"));
+ waitForSingleIssueOnResource(onTheFlyView, "azure-pipelines.yml");
+ new DefaultEditor().close();
+ }
+
+ @Test
+ public void test_Shell() {
+ Assume.assumeTrue(isLanguageSupported(SHELL_LANGUAGE_KEY));
+
+ adminWsClient.projects()
+ .create(new CreateRequest()
+ .setName(SHELL_PROJECT_KEY)
+ .setProject(SHELL_PROJECT_KEY));
+ orchestrator.getServer().associateProjectToQualityProfile(SHELL_PROJECT_KEY, SHELL_LANGUAGE_KEY, SHELL_QUALITY_PROFILE);
+
+ new JavaPerspective().open();
+ var rootProject = importExistingProjectIntoWorkspace("shell/shell-simple", SHELL_PROJECT_KEY);
+ closeUnsupportedLanguageNotifications();
+
+ var onTheFlyView = new OnTheFlyView();
+ onTheFlyView.open();
+
+ openFileAndWaitForAnalysisCompletion(rootProject.getResource("install.sh"));
+ closeUnsupportedLanguageNotifications();
+ waitForNoSonarLintMarkers(onTheFlyView);
+ new DefaultEditor().close();
+
+ createConnectionAndBindProject(orchestrator, SHELL_PROJECT_KEY);
+ shellByName("SonarQube - Binding Suggestion").ifPresent(shell -> new DefaultLink(shell, "Don't ask again").click());
+ waitForAnalysisReady(SHELL_PROJECT_KEY);
+
+ openFileAndWaitForAnalysisCompletion(rootProject.getResource("install.sh"));
+ waitForSingleIssueOnResource(onTheFlyView, "install.sh");
+ new DefaultEditor().close();
+ }
+
@Test
public void test_custom_secrets() {
// INFO: Since 10.4 this is supported for SonarLint for Eclipse!
@@ -687,4 +755,20 @@ private static void setNewCodePeriodToPreviousVersion(String projectKey) {
.setParam("type", "PREVIOUS_VERSION")
.execute();
}
+
+ private static void closeUnsupportedLanguageNotifications() {
+ shellByName("SonarQube for Eclipse - Language could not be analyzed").ifPresent(DefaultShell::close);
+ shellByName("SonarQube for Eclipse - Languages could not be analyzed").ifPresent(DefaultShell::close);
+ }
+
+ private static void waitForSingleIssueOnResource(OnTheFlyView onTheFlyView, String resourceName) {
+ await().atMost(20, TimeUnit.SECONDS).untilAsserted(() -> {
+ var issues = onTheFlyView.getIssues();
+ assertThat(issues).hasSize(1);
+ assertThat(issues)
+ .extracting(SonarLintIssueMarker::getResource)
+ .containsOnly(resourceName);
+ assertThat(issues.get(0).getDescription()).isNotBlank();
+ });
+ }
}
diff --git a/its/projects/azurepipelines/azurepipelines-simple/azure-pipelines.yml b/its/projects/azurepipelines/azurepipelines-simple/azure-pipelines.yml
new file mode 100644
index 0000000000..464e55da6a
--- /dev/null
+++ b/its/projects/azurepipelines/azurepipelines-simple/azure-pipelines.yml
@@ -0,0 +1,7 @@
+trigger:
+ - main
+
+steps:
+ - script: echo "Build started"
+ displayName: "Run initial script"
+ # TODO: Add deployment step
diff --git a/its/projects/shell/shell-simple/install.sh b/its/projects/shell/shell-simple/install.sh
new file mode 100644
index 0000000000..05e5a27eae
--- /dev/null
+++ b/its/projects/shell/shell-simple/install.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+npm install
diff --git a/org.sonarlint.eclipse.core/META-INF/MANIFEST.MF b/org.sonarlint.eclipse.core/META-INF/MANIFEST.MF
index f9fe87eb0c..94770eb038 100644
--- a/org.sonarlint.eclipse.core/META-INF/MANIFEST.MF
+++ b/org.sonarlint.eclipse.core/META-INF/MANIFEST.MF
@@ -43,6 +43,6 @@ Require-Bundle: org.eclipse.equinox.security;resolution:=optional,
org.eclipse.jdt.annotation;resolution:=optional,
org.eclipse.text,
org.eclipse.wildwebdeveloper.embedder.node;resolution:=optional,
- org.sonarsource.sonarlint.core.sonarlint-java-client-osgi;bundle-version="[11.5.0,11.6.0)"
+ org.sonarsource.sonarlint.core.sonarlint-java-client-osgi;bundle-version="[11.6.0,11.7.0)"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-11
diff --git a/org.sonarlint.eclipse.core/src/org/sonarlint/eclipse/core/analysis/SonarLintLanguage.java b/org.sonarlint.eclipse.core/src/org/sonarlint/eclipse/core/analysis/SonarLintLanguage.java
index 705e9f61dd..0185f7f26c 100644
--- a/org.sonarlint.eclipse.core/src/org/sonarlint/eclipse/core/analysis/SonarLintLanguage.java
+++ b/org.sonarlint.eclipse.core/src/org/sonarlint/eclipse/core/analysis/SonarLintLanguage.java
@@ -27,6 +27,7 @@ public enum SonarLintLanguage {
ABAP,
APEX,
+ AZUREPIPELINES,
C,
CPP,
CSS,
@@ -45,6 +46,7 @@ public enum SonarLintLanguage {
RUBY,
SCALA,
SECRETS,
+ SHELL,
TSQL,
TS,
XML;
diff --git a/org.sonarlint.eclipse.core/src/org/sonarlint/eclipse/core/internal/utils/SonarLintUtils.java b/org.sonarlint.eclipse.core/src/org/sonarlint/eclipse/core/internal/utils/SonarLintUtils.java
index 1d690c98fa..b87eda9640 100644
--- a/org.sonarlint.eclipse.core/src/org/sonarlint/eclipse/core/internal/utils/SonarLintUtils.java
+++ b/org.sonarlint.eclipse.core/src/org/sonarlint/eclipse/core/internal/utils/SonarLintUtils.java
@@ -69,9 +69,9 @@ public class SonarLintUtils {
private static final Set OPTIONAL_LANGUAGES = EnumSet.of(SonarLintLanguage.JAVA,
SonarLintLanguage.JSP, SonarLintLanguage.C, SonarLintLanguage.CPP);
private static final Set DEFAULT_CONNECTED_LANGUAGES = EnumSet.of(SonarLintLanguage.ABAP,
- SonarLintLanguage.APEX, SonarLintLanguage.COBOL, SonarLintLanguage.JCL, SonarLintLanguage.KOTLIN,
- SonarLintLanguage.PLI, SonarLintLanguage.PLSQL, SonarLintLanguage.RPG, SonarLintLanguage.RUBY,
- SonarLintLanguage.SCALA, SonarLintLanguage.TSQL);
+ SonarLintLanguage.APEX, SonarLintLanguage.AZUREPIPELINES, SonarLintLanguage.COBOL, SonarLintLanguage.JCL,
+ SonarLintLanguage.KOTLIN, SonarLintLanguage.PLI, SonarLintLanguage.PLSQL, SonarLintLanguage.RPG,
+ SonarLintLanguage.RUBY, SonarLintLanguage.SCALA, SonarLintLanguage.SHELL, SonarLintLanguage.TSQL);
private SonarLintUtils() {
// utility class, forbidden constructor
diff --git a/org.sonarlint.eclipse.ui/META-INF/MANIFEST.MF b/org.sonarlint.eclipse.ui/META-INF/MANIFEST.MF
index 4d79f57339..93d35ed7e1 100644
--- a/org.sonarlint.eclipse.ui/META-INF/MANIFEST.MF
+++ b/org.sonarlint.eclipse.ui/META-INF/MANIFEST.MF
@@ -27,7 +27,7 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.text,
org.eclipse.compare,
org.eclipse.core.expressions,
- org.sonarsource.sonarlint.core.sonarlint-java-client-osgi;bundle-version="[11.5.0,11.6.0)"
+ org.sonarsource.sonarlint.core.sonarlint-java-client-osgi;bundle-version="[11.6.0,11.7.0)"
Export-Package: org.sonarlint.eclipse.ui.internal;x-friends:="org.sonarlint.eclipse.core.tests",
org.sonarlint.eclipse.ui.internal.backend;x-friends:="org.sonarlint.eclipse.core.tests",
org.sonarlint.eclipse.ui.internal.notifications;x-friends:="org.sonarlint.eclipse.core.tests",
diff --git a/pom.xml b/pom.xml
index b41bd8a182..ab668983e6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -77,7 +77,7 @@
4.0.12
- 11.5.0.85871
+ 11.6.0.85933
11
diff --git a/target-platforms/commons-build.target b/target-platforms/commons-build.target
index 506c2b8857..c3439911ab 100644
--- a/target-platforms/commons-build.target
+++ b/target-platforms/commons-build.target
@@ -12,7 +12,7 @@
org.sonarsource.sonarlint.core
sonarlint-java-client-osgi
- 11.5.0.85871
+ 11.6.0.85933
jar