aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Campomenosi <benjamin.campomenosi@sonarsource.com>2022-12-20 17:33:54 +0100
committersonartech <sonartech@sonarsource.com>2022-12-28 20:02:48 +0000
commit1eb320deeb1981d572f50645163795f3786f2845 (patch)
tree5de723b74364a898100093d3d360e0004e6046f0
parentd023db004a914ab40a9d7caaaa40d901433a018b (diff)
downloadsonarqube-1eb320deeb1981d572f50645163795f3786f2845.tar.gz
sonarqube-1eb320deeb1981d572f50645163795f3786f2845.zip
SONAR-17610 Backend documentation links targets https://docs.sonarqube.org/ instead of embedded doc
-rw-r--r--server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java5
-rw-r--r--server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java2
-rw-r--r--sonar-core/src/main/java/org/sonar/core/documentation/DefaultDocumentationLinkGenerator.java41
-rw-r--r--sonar-core/src/main/java/org/sonar/core/documentation/DocumentationLinkGenerator.java34
-rw-r--r--sonar-core/src/test/java/org/sonar/core/documentation/DefaultDocumentationLinkGeneratorTest.java62
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java2
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java19
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java9
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scm/git/GitScmProvider.java15
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java31
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmProviderTest.java32
11 files changed, 217 insertions, 35 deletions
diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java
index 847bc10c2dc..1dd7307f102 100644
--- a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java
+++ b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java
@@ -66,6 +66,7 @@ import org.sonar.ce.taskprocessor.CeProcessingScheduler;
import org.sonar.ce.taskprocessor.CeTaskProcessorModule;
import org.sonar.core.component.DefaultResourceTypes;
import org.sonar.core.config.CorePropertyDefinitions;
+import org.sonar.core.documentation.DefaultDocumentationLinkGenerator;
import org.sonar.core.extension.CoreExtensionRepositoryImpl;
import org.sonar.core.extension.CoreExtensionsLoader;
import org.sonar.core.language.LanguagesProvider;
@@ -451,7 +452,9 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer {
QualityGateFinder.class,
QualityGateEvaluatorImpl.class,
- new AnalysisCacheCleaningModule()
+ new AnalysisCacheCleaningModule(),
+
+ DefaultDocumentationLinkGenerator.class
);
diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
index a57f28666b7..587d180255a 100644
--- a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
+++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
@@ -49,6 +49,7 @@ import org.sonar.ce.task.projectanalysis.taskprocessor.IssueSyncTaskProcessor;
import org.sonar.ce.task.projectanalysis.taskprocessor.ReportTaskProcessor;
import org.sonar.ce.task.projectexport.taskprocessor.ProjectExportTaskProcessor;
import org.sonar.core.component.DefaultResourceTypes;
+import org.sonar.core.documentation.DefaultDocumentationLinkGenerator;
import org.sonar.core.extension.CoreExtensionsInstaller;
import org.sonar.core.language.LanguagesProvider;
import org.sonar.core.platform.PlatformEditionProvider;
@@ -300,6 +301,7 @@ public class PlatformLevel4 extends PlatformLevel {
WebAnalyticsLoaderImpl.class,
new MonitoringWsModule(),
DefaultBranchNameResolver.class,
+ DefaultDocumentationLinkGenerator.class,
// batch
new BatchWsModule(),
diff --git a/sonar-core/src/main/java/org/sonar/core/documentation/DefaultDocumentationLinkGenerator.java b/sonar-core/src/main/java/org/sonar/core/documentation/DefaultDocumentationLinkGenerator.java
new file mode 100644
index 00000000000..148ef8353d1
--- /dev/null
+++ b/sonar-core/src/main/java/org/sonar/core/documentation/DefaultDocumentationLinkGenerator.java
@@ -0,0 +1,41 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info 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.core.documentation;
+
+import java.util.Optional;
+import javax.annotation.Nullable;
+import org.sonar.api.utils.Version;
+import org.sonar.core.platform.SonarQubeVersion;
+
+public class DefaultDocumentationLinkGenerator implements DocumentationLinkGenerator {
+ private static final String DOCUMENTATION_PUBLIC_URL = "https://docs.sonarqube.org/";
+
+ private final String documentationBaseUrl;
+
+ public DefaultDocumentationLinkGenerator(SonarQubeVersion sonarQubeVersion) {
+ Version version = sonarQubeVersion.get();
+ this.documentationBaseUrl = DOCUMENTATION_PUBLIC_URL + version.major() + "." + version.minor();
+ }
+
+ @Override
+ public String getDocumentationLink(@Nullable String suffix) {
+ return documentationBaseUrl + Optional.ofNullable(suffix).orElse("");
+ }
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/documentation/DocumentationLinkGenerator.java b/sonar-core/src/main/java/org/sonar/core/documentation/DocumentationLinkGenerator.java
new file mode 100644
index 00000000000..fb262e2404c
--- /dev/null
+++ b/sonar-core/src/main/java/org/sonar/core/documentation/DocumentationLinkGenerator.java
@@ -0,0 +1,34 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info 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.core.documentation;
+
+import javax.annotation.Nullable;
+import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.api.scanner.ScannerSide;
+import org.sonar.api.server.ServerSide;
+
+@ServerSide
+@ComputeEngineSide
+@ScannerSide
+public interface DocumentationLinkGenerator {
+
+ String getDocumentationLink(@Nullable String suffix);
+
+}
diff --git a/sonar-core/src/test/java/org/sonar/core/documentation/DefaultDocumentationLinkGeneratorTest.java b/sonar-core/src/test/java/org/sonar/core/documentation/DefaultDocumentationLinkGeneratorTest.java
new file mode 100644
index 00000000000..9926bb2abce
--- /dev/null
+++ b/sonar-core/src/test/java/org/sonar/core/documentation/DefaultDocumentationLinkGeneratorTest.java
@@ -0,0 +1,62 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info 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.core.documentation;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.sonar.core.platform.SonarQubeVersion;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class DefaultDocumentationLinkGeneratorTest {
+ private static final String TEST_SUFFIX = "/documentation/analyzing-source-code/scm-integration/";
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private SonarQubeVersion sonarQubeVersion;
+
+ private DefaultDocumentationLinkGenerator documentationLinkGenerator;
+
+ @Before
+ public void setUp() {
+ when(sonarQubeVersion.get().major()).thenReturn(100);
+ when(sonarQubeVersion.get().minor()).thenReturn(1000);
+ documentationLinkGenerator = new DefaultDocumentationLinkGenerator(sonarQubeVersion);
+ }
+
+ @Test
+ public void getDocumentationLink_whenSuffixProvided_concatenatesIt() {
+ String generatedLink = documentationLinkGenerator.getDocumentationLink(TEST_SUFFIX);
+
+ assertThat(generatedLink).isEqualTo("https://docs.sonarqube.org/100.1000/documentation/analyzing-source-code/scm-integration/");
+ }
+
+ @Test
+ public void getDocumentationLink_whenSuffixNotProvided_returnsBaseUrl() {
+ String generatedLink = documentationLinkGenerator.getDocumentationLink(null);
+
+ assertThat(generatedLink).isEqualTo("https://docs.sonarqube.org/100.1000");
+ }
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java
index 78be7024302..02ec64c891c 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java
@@ -36,6 +36,7 @@ import org.sonar.api.utils.UriReader;
import org.sonar.api.utils.Version;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
+import org.sonar.core.documentation.DefaultDocumentationLinkGenerator;
import org.sonar.core.extension.CoreExtensionRepositoryImpl;
import org.sonar.core.extension.CoreExtensionsLoader;
import org.sonar.core.platform.PluginClassLoader;
@@ -96,6 +97,7 @@ public class SpringGlobalContainer extends SpringComponentContainer {
new GlobalConfigurationProvider(),
new ScannerWsClientProvider(),
DefaultServer.class,
+ DefaultDocumentationLinkGenerator.class,
new GlobalTempFolderProvider(),
analysisWarnings,
UriReader.class,
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java
index d7d512da5b1..d821f809047 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java
@@ -19,6 +19,7 @@
*/
package org.sonar.scanner.scm;
+import com.google.common.annotations.VisibleForTesting;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
@@ -35,27 +36,34 @@ import org.sonar.api.batch.scm.BlameLine;
import org.sonar.api.notifications.AnalysisWarnings;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
+import org.sonar.core.documentation.DocumentationLinkGenerator;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.Changesets.Builder;
import org.sonar.scanner.protocol.output.ScannerReportWriter;
import org.sonar.scanner.util.ProgressReport;
+import static java.lang.String.format;
import static org.sonar.api.utils.Preconditions.checkArgument;
class DefaultBlameOutput implements BlameOutput {
private static final Logger LOG = Loggers.get(DefaultBlameOutput.class);
+ @VisibleForTesting
+ static final String SCM_INTEGRATION_DOCUMENTATION_SUFFIX = "/analyzing-source-code/scm-integration/";
private final ScannerReportWriter writer;
private AnalysisWarnings analysisWarnings;
+ private final DocumentationLinkGenerator documentationLinkGenerator;
private final Set<InputFile> allFilesToBlame = new LinkedHashSet<>();
private ProgressReport progressReport;
private int count;
private int total;
- DefaultBlameOutput(ScannerReportWriter writer, AnalysisWarnings analysisWarnings, List<InputFile> filesToBlame) {
+ DefaultBlameOutput(ScannerReportWriter writer, AnalysisWarnings analysisWarnings, List<InputFile> filesToBlame,
+ DocumentationLinkGenerator documentationLinkGenerator) {
this.writer = writer;
this.analysisWarnings = analysisWarnings;
+ this.documentationLinkGenerator = documentationLinkGenerator;
this.allFilesToBlame.addAll(filesToBlame);
count = 0;
total = filesToBlame.size();
@@ -134,12 +142,12 @@ class DefaultBlameOutput implements BlameOutput {
LOG.warn(" * " + f);
}
LOG.warn("This may lead to missing/broken features in SonarQube");
- String link = "/documentation/analyzing-source-code/scm-integration/";
- analysisWarnings.addUnique(String.format("Missing blame information for %d %s. This may lead to some features not working correctly. " +
- "Please check the analysis logs and refer to <a href=\"%s\" target=\"_blank\">the documentation</a>.",
+ String docUrl = documentationLinkGenerator.getDocumentationLink(SCM_INTEGRATION_DOCUMENTATION_SUFFIX);
+ analysisWarnings.addUnique(format("Missing blame information for %d %s. This may lead to some features not working correctly. " +
+ "Please check the analysis logs and refer to <a href=\"%s\" rel=\"noopener noreferrer\" target=\"_blank\">the documentation</a>.",
allFilesToBlame.size(),
allFilesToBlame.size() > 1 ? "files" : "file",
- link));
+ docUrl));
}
}
@@ -147,3 +155,4 @@ class DefaultBlameOutput implements BlameOutput {
return filesCount == 1 ? "source file" : "source files";
}
}
+
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java
index e773c0d3bcf..fd24e4b4052 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java
@@ -31,6 +31,7 @@ import org.sonar.api.batch.scm.ScmProvider;
import org.sonar.api.notifications.AnalysisWarnings;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
+import org.sonar.core.documentation.DocumentationLinkGenerator;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.Changesets.Builder;
import org.sonar.scanner.protocol.output.ScannerReportWriter;
@@ -49,11 +50,12 @@ public final class ScmPublisher {
private final InputComponentStore componentStore;
private final FileSystem fs;
private final ScannerReportWriter writer;
- private AnalysisWarnings analysisWarnings;
+ private final AnalysisWarnings analysisWarnings;
private final BranchConfiguration branchConfiguration;
+ private final DocumentationLinkGenerator documentationLinkGenerator;
public ScmPublisher(ScmConfiguration configuration, ProjectRepositories projectRepositories, InputComponentStore componentStore, FileSystem fs,
- ReportPublisher reportPublisher, BranchConfiguration branchConfiguration, AnalysisWarnings analysisWarnings) {
+ ReportPublisher reportPublisher, BranchConfiguration branchConfiguration, AnalysisWarnings analysisWarnings, DocumentationLinkGenerator documentationLinkGenerator) {
this.configuration = configuration;
this.projectRepositories = projectRepositories;
this.componentStore = componentStore;
@@ -61,6 +63,7 @@ public final class ScmPublisher {
this.branchConfiguration = branchConfiguration;
this.writer = reportPublisher.getWriter();
this.analysisWarnings = analysisWarnings;
+ this.documentationLinkGenerator = documentationLinkGenerator;
}
public void publish() {
@@ -79,7 +82,7 @@ public final class ScmPublisher {
if (!filesToBlame.isEmpty()) {
String key = provider.key();
LOG.info("SCM Publisher SCM provider for this project is: " + key);
- DefaultBlameOutput output = new DefaultBlameOutput(writer, analysisWarnings, filesToBlame);
+ DefaultBlameOutput output = new DefaultBlameOutput(writer, analysisWarnings, filesToBlame, documentationLinkGenerator);
try {
provider.blameCommand().blame(new DefaultBlameInput(fs, filesToBlame), output);
} catch (Exception e) {
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scm/git/GitScmProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scm/git/GitScmProvider.java
index aec033458e7..817f2370d04 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scm/git/GitScmProvider.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scm/git/GitScmProvider.java
@@ -19,6 +19,7 @@
*/
package org.sonar.scm.git;
+import com.google.common.annotations.VisibleForTesting;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
@@ -69,6 +70,7 @@ import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
+import org.sonar.core.documentation.DocumentationLinkGenerator;
import static java.lang.String.format;
import static java.util.function.Function.identity;
@@ -84,18 +86,22 @@ public class GitScmProvider extends ScmProvider {
private static final Logger LOG = Loggers.get(GitScmProvider.class);
private static final String COULD_NOT_FIND_REF = "Could not find ref '%s' in refs/heads, refs/remotes, refs/remotes/upstream or refs/remotes/origin";
private static final String NO_MERGE_BASE_FOUND_MESSAGE = "No merge base found between HEAD and %s";
+ @VisibleForTesting
+ static final String SCM_INTEGRATION_DOCUMENTATION_SUFFIX = "/analyzing-source-code/scm-integration/";
private final BlameCommand blameCommand;
private final AnalysisWarnings analysisWarnings;
private final GitIgnoreCommand gitIgnoreCommand;
private final System2 system2;
- private final String documentationLink;
+ private final DocumentationLinkGenerator documentationLinkGenerator;
+
+ public GitScmProvider(CompositeBlameCommand blameCommand, AnalysisWarnings analysisWarnings, GitIgnoreCommand gitIgnoreCommand, System2 system2,
+ DocumentationLinkGenerator documentationLinkGenerator) {
- public GitScmProvider(CompositeBlameCommand blameCommand, AnalysisWarnings analysisWarnings, GitIgnoreCommand gitIgnoreCommand, System2 system2) {
this.blameCommand = blameCommand;
this.analysisWarnings = analysisWarnings;
this.gitIgnoreCommand = gitIgnoreCommand;
this.system2 = system2;
- this.documentationLink = "/documentation/analyzing-source-code/scm-integration/";
+ this.documentationLinkGenerator = documentationLinkGenerator;
}
@Override
@@ -257,10 +263,11 @@ public class GitScmProvider extends ScmProvider {
}
private void addWarningTargetNotFound(String targetBranchName) {
+ String url = documentationLinkGenerator.getDocumentationLink(SCM_INTEGRATION_DOCUMENTATION_SUFFIX);
analysisWarnings.addUnique(format(COULD_NOT_FIND_REF
+ ". You may see unexpected issues and changes. "
+ "Please make sure to fetch this ref before pull request analysis and refer to"
- + " <a href=\"%s\" target=\"_blank\">the documentation</a>.", targetBranchName, documentationLink));
+ + " <a href=\"%s\" rel=\"noopener noreferrer\" target=\"_blank\">the documentation</a>.", targetBranchName, url));
}
private void collectChangedLines(Repository repo, RevCommit mergeBaseCommit, Map<Path, Set<Integer>> changedLines, Path changedFilePath, ChangedFile changedFile) {
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java
index 5e1972b4b80..9fc3d7104f5 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java
@@ -25,39 +25,58 @@ import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.api.batch.scm.BlameLine;
import org.sonar.api.utils.System2;
+import org.sonar.core.documentation.DocumentationLinkGenerator;
import org.sonar.scanner.notifications.DefaultAnalysisWarnings;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.sonar.scanner.scm.DefaultBlameOutput.SCM_INTEGRATION_DOCUMENTATION_SUFFIX;
public class DefaultBlameOutputTest {
+ private static final String DOC_LINK = "https://link.to.documentation/new/page";
private System2 system2 = mock(System2.class);
private DefaultAnalysisWarnings analysisWarnings = new DefaultAnalysisWarnings(system2);
+ private DocumentationLinkGenerator documentationLinkGenerator = mock(DocumentationLinkGenerator.class);
@Test
public void shouldNotFailIfNotSameNumberOfLines() {
InputFile file = new TestInputFileBuilder("foo", "src/main/java/Foo.java").setLines(10).build();
- new DefaultBlameOutput(null, analysisWarnings, singletonList(file)).blameResult(file, singletonList(new BlameLine().revision("1").author("guy")));
+ new DefaultBlameOutput(null, analysisWarnings, singletonList(file), mock(DocumentationLinkGenerator.class)).blameResult(file,
+ singletonList(new BlameLine().revision("1").author("guy")));
}
@Test
public void addWarningIfFilesMissing() {
+ when(documentationLinkGenerator.getDocumentationLink(SCM_INTEGRATION_DOCUMENTATION_SUFFIX)).thenReturn(DOC_LINK);
InputFile file = new TestInputFileBuilder("foo", "src/main/java/Foo.java").setLines(10).build();
- new DefaultBlameOutput(null, analysisWarnings, singletonList(file)).finish(true);
+ new DefaultBlameOutput(null, analysisWarnings, singletonList(file), documentationLinkGenerator).finish(true);
assertThat(analysisWarnings.warnings()).extracting(DefaultAnalysisWarnings.Message::getText)
.containsOnly("Missing blame information for 1 file. This may lead to some features not working correctly. " +
- "Please check the analysis logs and refer to <a href=\"/documentation/analyzing-source-code/scm-integration/\" target=\"_blank\">the documentation</a>.");
+ "Please check the analysis logs and refer to <a href=\"" + DOC_LINK + "\" rel=\"noopener noreferrer\" target=\"_blank\">the documentation</a>.");
+ }
+
+ @Test
+ public void addWarningWithContextIfFiles() {
+ when(documentationLinkGenerator.getDocumentationLink(SCM_INTEGRATION_DOCUMENTATION_SUFFIX)).thenReturn(DOC_LINK);
+ InputFile file = new TestInputFileBuilder("foo", "src/main/java/Foo.java").setLines(10).build();
+ when(documentationLinkGenerator.getDocumentationLink("suffix")).thenReturn("blababl");
+ new DefaultBlameOutput(null, analysisWarnings, singletonList(file), documentationLinkGenerator).finish(true);
+ assertThat(analysisWarnings.warnings()).extracting(DefaultAnalysisWarnings.Message::getText)
+ .containsOnly("Missing blame information for 1 file. This may lead to some features not working correctly. " +
+ "Please check the analysis logs and refer to <a href=\"" + DOC_LINK + "\" rel=\"noopener noreferrer\" target=\"_blank\">the documentation</a>.");
}
@Test
public void shouldFailIfNotExpectedFile() {
InputFile file = new TestInputFileBuilder("foo", "src/main/java/Foo.java").build();
var blameOutput = new DefaultBlameOutput(null, analysisWarnings,
- singletonList(new TestInputFileBuilder("foo", "src/main/java/Foo2.java").build()));
+ singletonList(new TestInputFileBuilder("foo", "src/main/java/Foo2.java").build()),
+ mock(DocumentationLinkGenerator.class));
var lines = singletonList(new BlameLine().revision("1").author("guy"));
assertThatThrownBy(() -> blameOutput.blameResult(file, lines))
@@ -68,7 +87,7 @@ public class DefaultBlameOutputTest {
@Test
public void shouldFailIfNullDate() {
InputFile file = new TestInputFileBuilder("foo", "src/main/java/Foo.java").setLines(1).build();
- var blameOutput = new DefaultBlameOutput(null, analysisWarnings, singletonList(file));
+ var blameOutput = new DefaultBlameOutput(null, analysisWarnings, singletonList(file), mock(DocumentationLinkGenerator.class));
var lines = singletonList(new BlameLine().revision("1").author("guy"));
assertThatThrownBy(() -> blameOutput.blameResult(file, lines))
@@ -79,7 +98,7 @@ public class DefaultBlameOutputTest {
@Test
public void shouldFailIfNullRevision() {
InputFile file = new TestInputFileBuilder("foo", "src/main/java/Foo.java").setLines(1).build();
- var blameOUtput = new DefaultBlameOutput(null, analysisWarnings, singletonList(file));
+ var blameOUtput = new DefaultBlameOutput(null, analysisWarnings, singletonList(file), mock(DocumentationLinkGenerator.class));
var lines = singletonList(new BlameLine().date(new Date()).author("guy"));
assertThatThrownBy(() -> blameOUtput.blameResult(file, lines))
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmProviderTest.java
index e8e2d7bcebe..186677e7df4 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmProviderTest.java
@@ -60,6 +60,7 @@ import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.log.LogAndArguments;
import org.sonar.api.utils.log.LogTester;
+import org.sonar.core.documentation.DocumentationLinkGenerator;
import static java.lang.String.format;
import static java.util.Collections.emptySet;
@@ -74,6 +75,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
import static org.sonar.api.utils.log.LoggerLevel.WARN;
+import static org.sonar.scm.git.GitScmProvider.SCM_INTEGRATION_DOCUMENTATION_SUFFIX;
import static org.sonar.scm.git.GitUtils.createFile;
import static org.sonar.scm.git.GitUtils.createRepository;
import static org.sonar.scm.git.Utils.javaUnzip;
@@ -109,6 +111,7 @@ public class GitScmProviderTest {
+ "The door of all subtleties!";
private static final String BRANCH_NAME = "branch";
+ private static final String TEST_DOC_LINK = "documentation link";
@Rule
public TemporaryFolder temp = new TemporaryFolder();
@@ -123,11 +126,13 @@ public class GitScmProviderTest {
private Path worktree;
private Git git;
private final AnalysisWarnings analysisWarnings = mock(AnalysisWarnings.class);
+ private final DocumentationLinkGenerator documentationLinkGenerator = mock(DocumentationLinkGenerator.class);
@Before
public void before() throws IOException, GitAPIException {
worktree = temp.newFolder().toPath();
git = createRepository(worktree);
+ when(documentationLinkGenerator.getDocumentationLink(SCM_INTEGRATION_DOCUMENTATION_SUFFIX)).thenReturn(TEST_DOC_LINK);
createAndCommitFile("file-in-first-commit.xoo");
}
@@ -142,7 +147,7 @@ public class GitScmProviderTest {
JGitBlameCommand jblameCommand = new JGitBlameCommand();
GitBlameCommand nativeBlameCommand = new GitBlameCommand(System2.INSTANCE, new ProcessWrapperFactory());
CompositeBlameCommand compositeBlameCommand = new CompositeBlameCommand(analysisWarnings, new PathResolver(), jblameCommand, nativeBlameCommand);
- GitScmProvider gitScmProvider = new GitScmProvider(compositeBlameCommand, analysisWarnings, gitIgnoreCommand, system2);
+ GitScmProvider gitScmProvider = new GitScmProvider(compositeBlameCommand, analysisWarnings, gitIgnoreCommand, system2, documentationLinkGenerator);
assertThat(gitScmProvider.blameCommand()).isEqualTo(compositeBlameCommand);
}
@@ -419,7 +424,8 @@ public class GitScmProviderTest {
}
@Test
- public void branchChangedLinesWithFileMovementDetection_detects_modified_lines_on_renamed_pr_files_compared_to_original_files_on_target_branch() throws GitAPIException, IOException {
+ public void branchChangedLinesWithFileMovementDetection_detects_modified_lines_on_renamed_pr_files_compared_to_original_files_on_target_branch()
+ throws GitAPIException, IOException {
String fileM1 = "file-m1.xoo";
String newFileM1 = "new-file-m1.xoo";
String fileM2 = "file-m2.xoo";
@@ -616,7 +622,7 @@ public class GitScmProviderTest {
@Test
public void branchChangedFiles_should_return_null_on_io_errors_of_repo_builder() {
- GitScmProvider provider = new GitScmProvider(mockCommand(), analysisWarnings, gitIgnoreCommand, system2) {
+ GitScmProvider provider = new GitScmProvider(mockCommand(), analysisWarnings, gitIgnoreCommand, system2, documentationLinkGenerator) {
@Override
Repository buildRepo(Path basedir) throws IOException {
throw new IOException();
@@ -633,7 +639,7 @@ public class GitScmProviderTest {
when(repository.getRefDatabase()).thenReturn(refDatabase);
when(refDatabase.findRef(BRANCH_NAME)).thenReturn(null);
- GitScmProvider provider = new GitScmProvider(mockCommand(), analysisWarnings, gitIgnoreCommand, system2) {
+ GitScmProvider provider = new GitScmProvider(mockCommand(), analysisWarnings, gitIgnoreCommand, system2, documentationLinkGenerator) {
@Override
Repository buildRepo(Path basedir) {
return repository;
@@ -648,7 +654,7 @@ public class GitScmProviderTest {
String warning = refNotFound
+ ". You may see unexpected issues and changes. Please make sure to fetch this ref before pull request analysis"
- + " and refer to <a href=\"/documentation/analyzing-source-code/scm-integration/\" target=\"_blank\">the documentation</a>.";
+ + " and refer to <a href=\"" + TEST_DOC_LINK + "\" rel=\"noopener noreferrer\" target=\"_blank\">the documentation</a>.";
verify(analysisWarnings).addUnique(warning);
}
@@ -663,7 +669,7 @@ public class GitScmProviderTest {
Git git = mock(Git.class);
when(git.diff()).thenReturn(diffCommand);
- GitScmProvider provider = new GitScmProvider(mockCommand(), analysisWarnings, gitIgnoreCommand, system2) {
+ GitScmProvider provider = new GitScmProvider(mockCommand(), analysisWarnings, gitIgnoreCommand, system2, documentationLinkGenerator) {
@Override
Git newGit(Repository repo) {
return git;
@@ -700,7 +706,7 @@ public class GitScmProviderTest {
commit(f3);
AtomicInteger callCount = new AtomicInteger(0);
- GitScmProvider provider = new GitScmProvider(mockCommand(), analysisWarnings, gitIgnoreCommand, system2) {
+ GitScmProvider provider = new GitScmProvider(mockCommand(), analysisWarnings, gitIgnoreCommand, system2, documentationLinkGenerator) {
@Override
AbstractTreeIterator prepareTreeParser(Repository repo, RevCommit commit) throws IOException {
if (callCount.getAndIncrement() == 2) {
@@ -721,7 +727,7 @@ public class GitScmProviderTest {
@Test
public void branchChangedLines_returns_null_on_io_errors_of_repo_builder() {
- GitScmProvider provider = new GitScmProvider(mockCommand(), analysisWarnings, gitIgnoreCommand, system2) {
+ GitScmProvider provider = new GitScmProvider(mockCommand(), analysisWarnings, gitIgnoreCommand, system2, documentationLinkGenerator) {
@Override
Repository buildRepo(Path basedir) throws IOException {
throw new IOException();
@@ -736,7 +742,7 @@ public class GitScmProviderTest {
}
private GitScmProvider newGitScmProvider() {
- return new GitScmProvider(mock(CompositeBlameCommand.class), analysisWarnings, gitIgnoreCommand, system2);
+ return new GitScmProvider(mock(CompositeBlameCommand.class), analysisWarnings, gitIgnoreCommand, system2, documentationLinkGenerator);
}
@Test
@@ -814,12 +820,6 @@ public class GitScmProviderTest {
createAndCommitFile(relativePath, randomizedContent(relativePath, 3), git, this.worktree);
}
- private void createAndCommitFile(String relativePath, Instant commitDate) throws IOException, GitAPIException {
- createFile(relativePath, randomizedContent(relativePath, 3), this.worktree);
- commit(relativePath, commitDate);
- }
-
-
private void createAndCommitFile(String fileName, Git git, Path worktree) throws IOException, GitAPIException {
createAndCommitFile(fileName, randomizedContent(fileName, 3), git, worktree);
}
@@ -896,6 +896,6 @@ public class GitScmProviderTest {
}
private GitScmProvider newScmProvider() {
- return new GitScmProvider(mockCommand(), analysisWarnings, gitIgnoreCommand, system2);
+ return new GitScmProvider(mockCommand(), analysisWarnings, gitIgnoreCommand, system2, documentationLinkGenerator);
}
}