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;
QualityGateFinder.class,
QualityGateEvaluatorImpl.class,
- new AnalysisCacheCleaningModule()
+ new AnalysisCacheCleaningModule(),
+
+ DefaultDocumentationLinkGenerator.class
);
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;
WebAnalyticsLoaderImpl.class,
new MonitoringWsModule(),
DefaultBranchNameResolver.class,
+ DefaultDocumentationLinkGenerator.class,
// batch
new BatchWsModule(),
--- /dev/null
+/*
+ * 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("");
+ }
+}
--- /dev/null
+/*
+ * 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);
+
+}
--- /dev/null
+/*
+ * 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");
+ }
+}
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;
new GlobalConfigurationProvider(),
new ScannerWsClientProvider(),
DefaultServer.class,
+ DefaultDocumentationLinkGenerator.class,
new GlobalTempFolderProvider(),
analysisWarnings,
UriReader.class,
*/
package org.sonar.scanner.scm;
+import com.google.common.annotations.VisibleForTesting;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
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();
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));
}
}
return filesCount == 1 ? "source file" : "source files";
}
}
+
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;
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;
this.branchConfiguration = branchConfiguration;
this.writer = reportPublisher.getWriter();
this.analysisWarnings = analysisWarnings;
+ this.documentationLinkGenerator = documentationLinkGenerator;
}
public void publish() {
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) {
*/
package org.sonar.scm.git;
+import com.google.common.annotations.VisibleForTesting;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
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;
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
}
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) {
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))
@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))
@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))
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;
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;
+ "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();
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");
}
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);
}
}
@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";
@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();
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;
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);
}
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;
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) {
@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();
}
private GitScmProvider newGitScmProvider() {
- return new GitScmProvider(mock(CompositeBlameCommand.class), analysisWarnings, gitIgnoreCommand, system2);
+ return new GitScmProvider(mock(CompositeBlameCommand.class), analysisWarnings, gitIgnoreCommand, system2, documentationLinkGenerator);
}
@Test
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);
}
}
private GitScmProvider newScmProvider() {
- return new GitScmProvider(mockCommand(), analysisWarnings, gitIgnoreCommand, system2);
+ return new GitScmProvider(mockCommand(), analysisWarnings, gitIgnoreCommand, system2, documentationLinkGenerator);
}
}