diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2022-01-10 17:09:39 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-01-21 20:03:21 +0000 |
commit | 3ec97d1a4368fdd3212d524aacfc73403ed709ce (patch) | |
tree | 19e45c7af2353bbedf2823cf0d9b0c9e8a3bb6b6 /sonar-scanner-engine/src | |
parent | 77f20a5c300a8f1576c20185de265119ef2fc8a9 (diff) | |
download | sonarqube-3ec97d1a4368fdd3212d524aacfc73403ed709ce.tar.gz sonarqube-3ec97d1a4368fdd3212d524aacfc73403ed709ce.zip |
SONAR-14929 New Code using a 'reference branch' doesn't detect changed code with git merge workflow
Diffstat (limited to 'sonar-scanner-engine/src')
14 files changed, 65 insertions, 511 deletions
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ChangedLinesPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ChangedLinesPublisher.java index 396dacbf759..16267c27e55 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ChangedLinesPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ChangedLinesPublisher.java @@ -22,6 +22,7 @@ package org.sonar.scanner.report; import java.nio.file.Path; import java.util.Collections; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.StreamSupport; @@ -34,10 +35,13 @@ import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReportWriter; +import org.sonar.scanner.repository.ReferenceBranchSupplier; import org.sonar.scanner.scan.branch.BranchConfiguration; import org.sonar.scanner.scan.filesystem.InputComponentStore; import org.sonar.scanner.scm.ScmConfiguration; +import static java.util.Optional.empty; + public class ChangedLinesPublisher implements ReportPublisherStep { private static final Logger LOG = Loggers.get(ChangedLinesPublisher.class); private static final String LOG_MSG = "SCM writing changed lines"; @@ -46,31 +50,38 @@ public class ChangedLinesPublisher implements ReportPublisherStep { private final DefaultInputProject project; private final InputComponentStore inputComponentStore; private final BranchConfiguration branchConfiguration; + private final ReferenceBranchSupplier referenceBranchSupplier; public ChangedLinesPublisher(ScmConfiguration scmConfiguration, DefaultInputProject project, InputComponentStore inputComponentStore, - BranchConfiguration branchConfiguration) { + BranchConfiguration branchConfiguration, ReferenceBranchSupplier referenceBranchSupplier) { this.scmConfiguration = scmConfiguration; this.project = project; this.inputComponentStore = inputComponentStore; this.branchConfiguration = branchConfiguration; + this.referenceBranchSupplier = referenceBranchSupplier; } @Override public void publish(ScannerReportWriter writer) { - String targetBranchName = branchConfiguration.targetBranchName(); - if (scmConfiguration.isDisabled() || !branchConfiguration.isPullRequest() || targetBranchName == null) { - return; + Optional<String> targetBranch = getTargetBranch(); + if (targetBranch.isPresent()) { + Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); + int count = writeChangedLines(scmConfiguration.provider(), writer, targetBranch.get()); + LOG.debug("SCM reported changed lines for {} {} in the branch", count, ScannerUtils.pluralize("file", count)); + profiler.stopInfo(); } + } - ScmProvider provider = scmConfiguration.provider(); - if (provider == null) { - return; + private Optional<String> getTargetBranch() { + if (scmConfiguration.isDisabled() || scmConfiguration.provider() == null) { + return empty(); } - Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); - int count = writeChangedLines(provider, writer, targetBranchName); - LOG.debug("SCM reported changed lines for {} {} in the branch", count, ScannerUtils.pluralize("file", count)); - profiler.stopInfo(); + String targetBranchName = branchConfiguration.targetBranchName(); + if (branchConfiguration.isPullRequest() && targetBranchName != null) { + return Optional.of(targetBranchName); + } + return Optional.ofNullable(referenceBranchSupplier.get()); } private int writeChangedLines(ScmProvider provider, ScannerReportWriter writer, String targetScmBranch) { @@ -92,7 +103,9 @@ public class ChangedLinesPublisher implements ReportPublisherStep { Set<Integer> changedLines = pathSetMap.get(e.getKey()); if (changedLines == null) { - LOG.warn("File '{}' was detected as changed but without having changed lines", e.getKey().toAbsolutePath()); + if (branchConfiguration.isPullRequest()) { + LOG.warn("File '{}' was detected as changed but without having changed lines", e.getKey().toAbsolutePath()); + } // assume that no line was changed writeChangedLines(writer, e.getValue().scannerId(), Collections.emptySet()); } else { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java index 53efb72218b..4b5e46b2862 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java @@ -21,7 +21,6 @@ package org.sonar.scanner.report; import java.io.File; import java.nio.file.Path; -import java.time.Instant; import java.util.LinkedList; import java.util.Map.Entry; import java.util.regex.Pattern; @@ -38,7 +37,6 @@ import org.sonar.scanner.fs.InputModuleHierarchy; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReport.Metadata.BranchType; import org.sonar.scanner.protocol.output.ScannerReportWriter; -import org.sonar.scanner.repository.ForkDateSupplier; import org.sonar.scanner.rule.QProfile; import org.sonar.scanner.rule.QualityProfiles; import org.sonar.scanner.scan.branch.BranchConfiguration; @@ -57,13 +55,12 @@ public class MetadataPublisher implements ReportPublisherStep { private final ScannerPluginRepository pluginRepository; private final BranchConfiguration branchConfiguration; private final ScmRevision scmRevision; - private final ForkDateSupplier forkDateSupplier; private final InputComponentStore componentStore; private final ScmConfiguration scmConfiguration; public MetadataPublisher(ProjectInfo projectInfo, InputModuleHierarchy moduleHierarchy, QualityProfiles qProfiles, CpdSettings cpdSettings, ScannerPluginRepository pluginRepository, BranchConfiguration branchConfiguration, - ScmRevision scmRevision, ForkDateSupplier forkDateSupplier, InputComponentStore componentStore, ScmConfiguration scmConfiguration) { + ScmRevision scmRevision, InputComponentStore componentStore, ScmConfiguration scmConfiguration) { this.projectInfo = projectInfo; this.moduleHierarchy = moduleHierarchy; this.qProfiles = qProfiles; @@ -71,7 +68,6 @@ public class MetadataPublisher implements ReportPublisherStep { this.pluginRepository = pluginRepository; this.branchConfiguration = branchConfiguration; this.scmRevision = scmRevision; - this.forkDateSupplier = forkDateSupplier; this.componentStore = componentStore; this.scmConfiguration = scmConfiguration; } @@ -93,7 +89,6 @@ public class MetadataPublisher implements ReportPublisherStep { } addScmInformation(builder); - addForkPoint(builder); addNotAnalyzedFileCountsByLanguage(builder); for (QProfile qp : qProfiles.findAll()) { @@ -114,13 +109,6 @@ public class MetadataPublisher implements ReportPublisherStep { writer.writeMetadata(builder.build()); } - private void addForkPoint(ScannerReport.Metadata.Builder builder) { - Instant date = forkDateSupplier.get(); - if (date != null) { - builder.setForkDate(date.toEpochMilli()); - } - } - private void addModulesRelativePaths(ScannerReport.Metadata.Builder builder) { LinkedList<DefaultInputModule> queue = new LinkedList<>(); queue.add(moduleHierarchy.root()); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/ForkDateSupplier.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/ReferenceBranchSupplier.java index 18180ab0f53..48c526c1e01 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/ForkDateSupplier.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/ReferenceBranchSupplier.java @@ -19,41 +19,33 @@ */ package org.sonar.scanner.repository; -import java.time.Instant; import javax.annotation.CheckForNull; import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; import org.sonar.scanner.scan.branch.BranchConfiguration; import org.sonar.scanner.scan.branch.ProjectBranches; -import org.sonar.scanner.scm.ScmConfiguration; import org.sonarqube.ws.NewCodePeriods; -public class ForkDateSupplier { - private static final Logger LOG = Loggers.get(ForkDateSupplier.class); +public class ReferenceBranchSupplier { + private static final Logger LOG = Loggers.get(ReferenceBranchSupplier.class); private static final String LOG_MSG_WS = "Load New Code definition"; private final NewCodePeriodLoader newCodePeriodLoader; private final BranchConfiguration branchConfiguration; private final DefaultInputProject project; - private final ScmConfiguration scmConfiguration; private final ProjectBranches branches; - private final AnalysisWarnings analysisWarnings; - public ForkDateSupplier(NewCodePeriodLoader newCodePeriodLoader, BranchConfiguration branchConfiguration, - DefaultInputProject project, ScmConfiguration scmConfiguration, ProjectBranches branches, AnalysisWarnings analysisWarnings) { + public ReferenceBranchSupplier(NewCodePeriodLoader newCodePeriodLoader, BranchConfiguration branchConfiguration, DefaultInputProject project, ProjectBranches branches) { this.newCodePeriodLoader = newCodePeriodLoader; this.branchConfiguration = branchConfiguration; this.project = project; - this.scmConfiguration = scmConfiguration; this.branches = branches; - this.analysisWarnings = analysisWarnings; } @CheckForNull - public Instant get() { + public String get() { // branches will be empty in CE if (branchConfiguration.isPullRequest() || branches.isEmpty()) { return null; @@ -73,20 +65,6 @@ public class ForkDateSupplier { return null; } - LOG.info("Computing New Code since fork with '{}'", referenceBranchName); - if (scmConfiguration.isDisabled() || scmConfiguration.provider() == null) { - LOG.warn("SCM provider is disabled. No New Code will be computed."); - analysisWarnings.addUnique("The scanner failed to compute New Code because no SCM provider was found. Please check your scanner logs."); - return null; - } - - Instant forkdate = scmConfiguration.provider().forkDate(referenceBranchName, project.getBaseDir()); - if (forkdate != null) { - LOG.debug("Fork detected at '{}'", referenceBranchName, forkdate); - } else { - analysisWarnings.addUnique("The scanner failed to compute New Code. Please check your scanner logs."); - LOG.warn("Failed to detect fork date. No New Code will be computed.", referenceBranchName); - } - return forkdate; + return referenceBranchName; } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java index 94c44b23a73..4df53478096 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java @@ -89,7 +89,7 @@ import org.sonar.scanner.report.TestExecutionPublisher; import org.sonar.scanner.repository.ContextPropertiesCache; import org.sonar.scanner.repository.DefaultProjectRepositoriesLoader; import org.sonar.scanner.repository.DefaultQualityProfileLoader; -import org.sonar.scanner.repository.ForkDateSupplier; +import org.sonar.scanner.repository.ReferenceBranchSupplier; import org.sonar.scanner.repository.ProjectRepositoriesLoader; import org.sonar.scanner.repository.ProjectRepositoriesSupplier; import org.sonar.scanner.repository.QualityProfileLoader; @@ -230,7 +230,7 @@ public class ProjectScanContainer extends ComponentContainer { ProjectCoverageAndDuplicationExclusions.class, // Report - ForkDateSupplier.class, + ReferenceBranchSupplier.class, ScannerMetrics.class, ReportPublisher.class, AnalysisContextReportPublisher.class, 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 1fb9d8eda24..d9157b5a3ce 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 @@ -214,30 +214,6 @@ public class GitScmProvider extends ScmProvider { @Override @CheckForNull public Instant forkDate(String referenceBranchName, Path projectBaseDir) { - try (Repository repo = buildRepo(projectBaseDir)) { - Ref targetRef = resolveTargetRef(referenceBranchName, repo); - if (targetRef == null) { - LOG.warn("Branch '{}' not found in git", referenceBranchName); - return null; - } - - if (isDiffAlgoInvalid(repo.getConfig())) { - LOG.warn("The diff algorithm configured in git is not supported. " - + "No information regarding changes in the branch will be collected, which can lead to unexpected results."); - return null; - } - - Optional<RevCommit> mergeBaseCommit = findMergeBase(repo, targetRef); - if (!mergeBaseCommit.isPresent()) { - LOG.warn("No fork point found between HEAD and " + targetRef.getName()); - return null; - } - - return Instant.ofEpochSecond(mergeBaseCommit.get().getCommitTime()); - } catch (Exception e) { - LOG.warn("Failed to find fork point with git", e); - } - return null; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scm/svn/FindFork.java b/sonar-scanner-engine/src/main/java/org/sonar/scm/svn/FindFork.java deleted file mode 100644 index 5a2ea83ad3b..00000000000 --- a/sonar-scanner-engine/src/main/java/org/sonar/scm/svn/FindFork.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2021 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.scm.svn; - -import java.io.File; -import java.nio.file.Path; -import java.time.Instant; -import java.util.Optional; -import javax.annotation.CheckForNull; -import org.sonar.api.scanner.ScannerSide; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; -import org.tmatesoft.svn.core.ISVNLogEntryHandler; -import org.tmatesoft.svn.core.SVNException; -import org.tmatesoft.svn.core.SVNLogEntry; -import org.tmatesoft.svn.core.SVNLogEntryPath; -import org.tmatesoft.svn.core.wc.SVNClientManager; -import org.tmatesoft.svn.core.wc.SVNRevision; -import org.tmatesoft.svn.core.wc.SVNStatus; - -import static org.sonar.scm.svn.SvnScmSupport.newSvnClientManager; - -@ScannerSide -public class FindFork { - private static final Logger LOG = Loggers.get(FindFork.class); - - private final SvnConfiguration configuration; - - public FindFork(SvnConfiguration configuration) { - this.configuration = configuration; - } - - @CheckForNull - public Instant findDate(Path location, String referenceBranch) throws SVNException { - ForkPoint forkPoint = find(location, referenceBranch); - if (forkPoint != null) { - return forkPoint.date(); - } - return null; - } - - @CheckForNull - public ForkPoint find(Path location, String referenceBranch) throws SVNException { - SVNClientManager clientManager = newSvnClientManager(configuration); - SVNRevision revision = getSvnRevision(location, clientManager); - LOG.debug("latest revision is " + revision); - String svnRefBranch = "/" + referenceBranch; - - SVNLogEntryHolder handler = new SVNLogEntryHolder(); - SVNRevision endRevision = SVNRevision.create(1); - SVNRevision startRevision = SVNRevision.create(revision.getNumber()); - - do { - clientManager.getLogClient().doLog(new File[] {location.toFile()}, startRevision, endRevision, true, true, -1, handler); - SVNLogEntry lastEntry = handler.getLastEntry(); - Optional<SVNLogEntryPath> copyFromReference = lastEntry.getChangedPaths().values().stream() - .filter(e -> e.getCopyPath() != null && e.getCopyPath().equals(svnRefBranch)) - .findFirst(); - - if (copyFromReference.isPresent()) { - return new ForkPoint(String.valueOf(copyFromReference.get().getCopyRevision()), Instant.ofEpochMilli(lastEntry.getDate().getTime())); - } - - if (lastEntry.getChangedPaths().isEmpty()) { - // shouldn't happen since it should only stop in revisions with changed paths - return null; - } - - SVNLogEntryPath firstChangedPath = lastEntry.getChangedPaths().values().iterator().next(); - if (firstChangedPath.getCopyPath() == null) { - // we walked the history to the root, and the last commit found had no copy reference. Must be the trunk, there is no fork point - return null; - } - - // TODO Looks like a revision can have multiple changed paths. Should we iterate through all of them? - startRevision = SVNRevision.create(firstChangedPath.getCopyRevision()); - } while (true); - - } - - private static SVNRevision getSvnRevision(Path location, SVNClientManager clientManager) throws SVNException { - SVNStatus svnStatus = clientManager.getStatusClient().doStatus(location.toFile(), false); - return svnStatus.getRevision(); - } - - /** - * Handler keeping only the last entry, and count how many entries have been seen. - */ - private static class SVNLogEntryHolder implements ISVNLogEntryHandler { - SVNLogEntry value; - - public SVNLogEntry getLastEntry() { - return value; - } - - @Override - public void handleLogEntry(SVNLogEntry svnLogEntry) { - this.value = svnLogEntry; - } - } -} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scm/svn/SvnScmProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scm/svn/SvnScmProvider.java index 535ee8b2993..57bdbd4edd3 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scm/svn/SvnScmProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scm/svn/SvnScmProvider.java @@ -54,12 +54,10 @@ public class SvnScmProvider extends ScmProvider { private final SvnConfiguration configuration; private final SvnBlameCommand blameCommand; - private final FindFork findFork; - public SvnScmProvider(SvnConfiguration configuration, SvnBlameCommand blameCommand, FindFork findFork) { + public SvnScmProvider(SvnConfiguration configuration, SvnBlameCommand blameCommand) { this.configuration = configuration; this.blameCommand = blameCommand; - this.findFork = findFork; } @Override @@ -202,12 +200,7 @@ public class SvnScmProvider extends ScmProvider { @CheckForNull @Override public Instant forkDate(String referenceBranch, Path rootBaseDir) { - try { - return findFork.findDate(rootBaseDir, referenceBranch); - } catch (SVNException e) { - LOG.warn("Unable to find fork date with '" + referenceBranch + "'", e); - return null; - } + return null; } ChangedLinesComputer newChangedLinesComputer(Path rootBaseDir, Set<Path> changedFiles) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scm/svn/SvnScmSupport.java b/sonar-scanner-engine/src/main/java/org/sonar/scm/svn/SvnScmSupport.java index 8a664d1f0ef..9ee3f8fb4c6 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scm/svn/SvnScmSupport.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scm/svn/SvnScmSupport.java @@ -55,8 +55,7 @@ public class SvnScmSupport { public static List<Object> getObjects() { return Arrays.asList(SvnScmProvider.class, SvnBlameCommand.class, - SvnConfiguration.class, - FindFork.class + SvnConfiguration.class ); } } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java index f19917876e4..e13e116c0d2 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java @@ -39,6 +39,7 @@ import org.sonar.api.utils.log.LogTester; import org.sonar.scanner.fs.InputModuleHierarchy; import org.sonar.scanner.protocol.output.ScannerReportReader; import org.sonar.scanner.protocol.output.ScannerReportWriter; +import org.sonar.scanner.repository.ReferenceBranchSupplier; import org.sonar.scanner.scan.branch.BranchConfiguration; import org.sonar.scanner.scan.filesystem.InputComponentStore; import org.sonar.scanner.scm.ScmConfiguration; @@ -57,6 +58,7 @@ public class ChangedLinesPublisherTest { private InputModuleHierarchy inputModuleHierarchy = mock(InputModuleHierarchy.class); private InputComponentStore inputComponentStore = mock(InputComponentStore.class); private BranchConfiguration branchConfiguration = mock(BranchConfiguration.class); + private ReferenceBranchSupplier referenceBranchSupplier = mock(ReferenceBranchSupplier.class); private ScannerReportWriter writer; private ScmProvider provider = mock(ScmProvider.class); private DefaultInputProject project = mock(DefaultInputProject.class); @@ -67,7 +69,7 @@ public class ChangedLinesPublisherTest { @Rule public LogTester logTester = new LogTester(); - private ChangedLinesPublisher publisher = new ChangedLinesPublisher(scmConfiguration, project, inputComponentStore, branchConfiguration); + private ChangedLinesPublisher publisher = new ChangedLinesPublisher(scmConfiguration, project, inputComponentStore, branchConfiguration, referenceBranchSupplier); @Before public void setUp() { diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java index a7bda1c9992..b7f8356ac46 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java @@ -50,7 +50,7 @@ import org.sonar.scanner.fs.InputModuleHierarchy; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReportReader; import org.sonar.scanner.protocol.output.ScannerReportWriter; -import org.sonar.scanner.repository.ForkDateSupplier; +import org.sonar.scanner.repository.ReferenceBranchSupplier; import org.sonar.scanner.rule.QProfile; import org.sonar.scanner.rule.QualityProfiles; import org.sonar.scanner.scan.branch.BranchConfiguration; @@ -77,7 +77,7 @@ public class MetadataPublisherTest { private final QualityProfiles qProfiles = mock(QualityProfiles.class); private final ProjectInfo projectInfo = mock(ProjectInfo.class); private final CpdSettings cpdSettings = mock(CpdSettings.class); - private final ForkDateSupplier forkDateSupplier = mock(ForkDateSupplier.class); + private final ReferenceBranchSupplier referenceBranchSupplier = mock(ReferenceBranchSupplier.class); private final ScannerPluginRepository pluginRepository = mock(ScannerPluginRepository.class); private BranchConfiguration branches; private ScmConfiguration scmConfiguration; @@ -116,13 +116,12 @@ public class MetadataPublisherTest { scmConfiguration = mock(ScmConfiguration.class); when(scmConfiguration.provider()).thenReturn(scmProvider); underTest = new MetadataPublisher(projectInfo, inputModuleHierarchy, qProfiles, cpdSettings, - pluginRepository, branches, scmRevision, forkDateSupplier, componentStore, scmConfiguration); + pluginRepository, branches, scmRevision, componentStore, scmConfiguration); } @Test public void write_metadata() throws Exception { Date date = new Date(); - when(forkDateSupplier.get()).thenReturn(Instant.ofEpochMilli(123456789L)); when(qProfiles.findAll()).thenReturn(Collections.singletonList(new QProfile("q1", "Q1", "java", date))); when(pluginRepository.getPluginsByKey()).thenReturn(ImmutableMap.of( "java", new ScannerPlugin("java", 12345L, null), @@ -134,7 +133,6 @@ public class MetadataPublisherTest { ScannerReportReader reader = new ScannerReportReader(outputDir); ScannerReport.Metadata metadata = reader.readMetadata(); - assertThat(metadata.getForkDate()).isEqualTo(123456789L); assertThat(metadata.getAnalysisDate()).isEqualTo(1234567L); assertThat(metadata.getProjectKey()).isEqualTo("root"); assertThat(metadata.getModulesProjectRelativePathByKeyMap()).containsOnly(entry("module", "modulePath"), entry("root", "")); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ForkDateSupplierTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ReferenceBranchSupplierTest.java index 3ad2ebc69b4..4804d62e01c 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ForkDateSupplierTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ReferenceBranchSupplierTest.java @@ -42,82 +42,53 @@ import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; -public class ForkDateSupplierTest { +public class ReferenceBranchSupplierTest { private final static String PROJECT_KEY = "project"; private final static String BRANCH_KEY = "branch"; private final static Path BASE_DIR = Paths.get("root"); - private NewCodePeriodLoader newCodePeriodLoader = mock(NewCodePeriodLoader.class); - private BranchConfiguration branchConfiguration = mock(BranchConfiguration.class); - private DefaultInputProject project = mock(DefaultInputProject.class); - private ScmConfiguration scmConfiguration = mock(ScmConfiguration.class); - private ScmProvider scmProvider = mock(ScmProvider.class); - private ProjectBranches projectBranches = mock(ProjectBranches.class); - private AnalysisWarnings analysisWarnings = mock(AnalysisWarnings.class); - private ForkDateSupplier forkDateSupplier = new ForkDateSupplier(newCodePeriodLoader, branchConfiguration, project, scmConfiguration, projectBranches, analysisWarnings); + private final NewCodePeriodLoader newCodePeriodLoader = mock(NewCodePeriodLoader.class); + private final BranchConfiguration branchConfiguration = mock(BranchConfiguration.class); + private final DefaultInputProject project = mock(DefaultInputProject.class); + private final ProjectBranches projectBranches = mock(ProjectBranches.class); + private final ReferenceBranchSupplier referenceBranchSupplier = new ReferenceBranchSupplier(newCodePeriodLoader, branchConfiguration, project, projectBranches); @Before public void setUp() { when(projectBranches.isEmpty()).thenReturn(false); when(project.key()).thenReturn(PROJECT_KEY); when(project.getBaseDir()).thenReturn(BASE_DIR); - when(scmConfiguration.isDisabled()).thenReturn(false); - when(scmConfiguration.provider()).thenReturn(scmProvider); } @Test - public void returns_forkDate_for_branches_with_ref() { - Instant date = Instant.now(); + public void returns_reference_branch_when_set() { when(branchConfiguration.branchType()).thenReturn(BranchType.BRANCH); when(branchConfiguration.branchName()).thenReturn(BRANCH_KEY); - when(scmProvider.forkDate("master", BASE_DIR)).thenReturn(date); when(newCodePeriodLoader.load(PROJECT_KEY, BRANCH_KEY)).thenReturn(createResponse(NewCodePeriods.NewCodePeriodType.REFERENCE_BRANCH, "master")); - assertThat(forkDateSupplier.get()).isEqualTo(date); + assertThat(referenceBranchSupplier.get()).isEqualTo("master"); } @Test public void uses_default_branch_if_no_branch_specified() { - Instant date = Instant.now(); when(branchConfiguration.branchType()).thenReturn(BranchType.BRANCH); when(branchConfiguration.branchName()).thenReturn(null); when(projectBranches.defaultBranchName()).thenReturn("default"); when(newCodePeriodLoader.load(PROJECT_KEY, "default")).thenReturn(createResponse(NewCodePeriods.NewCodePeriodType.REFERENCE_BRANCH, "master")); - when(scmProvider.forkDate("master", BASE_DIR)).thenReturn(date); - assertThat(forkDateSupplier.get()).isEqualTo(date); - - verifyNoInteractions(analysisWarnings); + assertThat(referenceBranchSupplier.get()).isEqualTo("master"); } @Test public void returns_null_if_no_branches() { when(projectBranches.isEmpty()).thenReturn(true); - assertThat(forkDateSupplier.get()).isNull(); + assertThat(referenceBranchSupplier.get()).isNull(); verify(branchConfiguration).isPullRequest(); verify(projectBranches).isEmpty(); verifyNoMoreInteractions(branchConfiguration); - verifyNoInteractions(scmConfiguration, scmProvider, analysisWarnings, newCodePeriodLoader); - } - - @Test - public void returns_null_if_scm_disabled() { - when(branchConfiguration.branchType()).thenReturn(BranchType.BRANCH); - when(branchConfiguration.branchName()).thenReturn(BRANCH_KEY); - when(scmConfiguration.isDisabled()).thenReturn(true); - when(newCodePeriodLoader.load(PROJECT_KEY, BRANCH_KEY)).thenReturn(createResponse(NewCodePeriods.NewCodePeriodType.REFERENCE_BRANCH, "master")); - - assertThat(forkDateSupplier.get()).isNull(); - - verify(scmConfiguration).isDisabled(); - verify(branchConfiguration, times(2)).branchName(); - verify(branchConfiguration).isPullRequest(); - verify(analysisWarnings).addUnique(anyString()); - - verifyNoInteractions(scmProvider); - verifyNoMoreInteractions(branchConfiguration); + verifyNoInteractions(newCodePeriodLoader); } @Test @@ -126,24 +97,23 @@ public class ForkDateSupplierTest { when(branchConfiguration.branchName()).thenReturn(BRANCH_KEY); when(newCodePeriodLoader.load(PROJECT_KEY, BRANCH_KEY)).thenReturn(createResponse(NewCodePeriods.NewCodePeriodType.REFERENCE_BRANCH, BRANCH_KEY)); - assertThat(forkDateSupplier.get()).isNull(); + assertThat(referenceBranchSupplier.get()).isNull(); verify(branchConfiguration, times(2)).branchName(); verify(branchConfiguration).isPullRequest(); verify(newCodePeriodLoader).load(PROJECT_KEY, BRANCH_KEY); - verifyNoInteractions(scmProvider, analysisWarnings, scmConfiguration); verifyNoMoreInteractions(branchConfiguration); } @Test public void returns_null_if_pull_request() { when(branchConfiguration.isPullRequest()).thenReturn(true); - assertThat(forkDateSupplier.get()).isNull(); + assertThat(referenceBranchSupplier.get()).isNull(); verify(branchConfiguration).isPullRequest(); - verifyNoInteractions(newCodePeriodLoader, analysisWarnings, scmProvider, scmConfiguration); + verifyNoInteractions(newCodePeriodLoader); verifyNoMoreInteractions(branchConfiguration); } @@ -153,9 +123,7 @@ public class ForkDateSupplierTest { when(branchConfiguration.branchName()).thenReturn(BRANCH_KEY); when(newCodePeriodLoader.load(PROJECT_KEY, BRANCH_KEY)).thenReturn(createResponse(NewCodePeriods.NewCodePeriodType.NUMBER_OF_DAYS, "2")); - assertThat(forkDateSupplier.get()).isNull(); - - verifyNoInteractions(scmProvider, analysisWarnings, scmConfiguration); + assertThat(referenceBranchSupplier.get()).isNull(); } private NewCodePeriods.ShowWSResponse createResponse(NewCodePeriods.NewCodePeriodType type, String value) { 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 a3c9f88a0e0..daac3162570 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 @@ -316,84 +316,7 @@ public class GitScmProviderTest { } @Test - public void forkDate_from_diverged() throws IOException, GitAPIException { - createAndCommitFile("file-m1.xoo", Instant.now().minus(8, ChronoUnit.DAYS)); - createAndCommitFile("file-m2.xoo", Instant.now().minus(7, ChronoUnit.DAYS)); - Instant expectedForkDate = Instant.now().minus(6, ChronoUnit.DAYS); - createAndCommitFile("file-m3.xoo", expectedForkDate); - ObjectId forkPoint = git.getRepository().exactRef("HEAD").getObjectId(); - - appendToAndCommitFile("file-m3.xoo"); - createAndCommitFile("file-m4.xoo"); - - git.branchCreate().setName("b1").setStartPoint(forkPoint.getName()).call(); - git.checkout().setName("b1").call(); - createAndCommitFile("file-b1.xoo"); - appendToAndCommitFile("file-m1.xoo"); - deleteAndCommitFile("file-m2.xoo"); - - assertThat(newScmProvider().forkDate("master", worktree)) - .isEqualTo(expectedForkDate.truncatedTo(ChronoUnit.SECONDS)); - } - - @Test - public void forkDate_should_not_fail_if_reference_is_the_same_branch() throws IOException, GitAPIException { - createAndCommitFile("file-m1.xoo", Instant.now().minus(8, ChronoUnit.DAYS)); - createAndCommitFile("file-m2.xoo", Instant.now().minus(7, ChronoUnit.DAYS)); - - ObjectId forkPoint = git.getRepository().exactRef("HEAD").getObjectId(); - git.branchCreate().setName("b1").setStartPoint(forkPoint.getName()).call(); - git.checkout().setName("b1").call(); - - Instant expectedForkDate = Instant.now().minus(6, ChronoUnit.DAYS); - createAndCommitFile("file-m3.xoo", expectedForkDate); - - assertThat(newScmProvider().forkDate("b1", worktree)) - .isEqualTo(expectedForkDate.truncatedTo(ChronoUnit.SECONDS)); - } - - @Test - public void forkDate_should_not_fail_with_patience_diff_algo() throws IOException { - Path gitConfig = worktree.resolve(".git").resolve("config"); - Files.write(gitConfig, "[diff]\nalgorithm = patience\n".getBytes(StandardCharsets.UTF_8)); - Repository repo = FileRepositoryBuilder.create(worktree.resolve(".git").toFile()); - git = new Git(repo); - - assertThat(newScmProvider().forkDate("master", worktree)).isNull(); - } - - @Test - public void forkDate_should_not_fail_with_invalid_basedir() throws IOException { - assertThat(newScmProvider().forkDate("master", temp.newFolder().toPath())).isNull(); - } - - @Test - public void forkDate_should_not_fail_when_no_merge_base_is_found() throws IOException, GitAPIException { - createAndCommitFile("file-m1.xoo", Instant.now().minus(8, ChronoUnit.DAYS)); - - git.checkout().setOrphan(true).setName("b1").call(); - createAndCommitFile("file-b1.xoo"); - - assertThat(newScmProvider().forkDate("master", worktree)).isNull(); - } - - @Test - public void forkDate_without_target_branch() throws IOException, GitAPIException { - createAndCommitFile("file-m1.xoo", Instant.now().minus(8, ChronoUnit.DAYS)); - createAndCommitFile("file-m2.xoo", Instant.now().minus(7, ChronoUnit.DAYS)); - Instant expectedForkDate = Instant.now().minus(6, ChronoUnit.DAYS); - createAndCommitFile("file-m3.xoo", expectedForkDate); - ObjectId forkPoint = git.getRepository().exactRef("HEAD").getObjectId(); - - appendToAndCommitFile("file-m3.xoo"); - createAndCommitFile("file-m4.xoo"); - - git.branchCreate().setName("b1").setStartPoint(forkPoint.getName()).call(); - git.checkout().setName("b1").call(); - createAndCommitFile("file-b1.xoo"); - appendToAndCommitFile("file-m1.xoo"); - deleteAndCommitFile("file-m2.xoo"); - + public void forkDate_returns_null() { assertThat(newScmProvider().forkDate("unknown", worktree)).isNull(); } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/FindForkTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/FindForkTest.java deleted file mode 100644 index 7f7ae16ee1a..00000000000 --- a/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/FindForkTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2021 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.scm.svn; - -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.tmatesoft.svn.core.SVNException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -public class FindForkTest { - - @ClassRule - public static TemporaryFolder temp = new TemporaryFolder(); - - private static SvnTester svnTester; - - private static Path trunk; - private static Path b1; - private static Path b2; - - private FindFork findFork; - - @BeforeClass - public static void before() throws IOException, SVNException { - svnTester = new SvnTester(temp.newFolder().toPath()); - - trunk = temp.newFolder("trunk").toPath(); - svnTester.checkout(trunk, "trunk"); - createAndCommitFile(trunk, "file-1-commit-in-trunk.xoo"); - createAndCommitFile(trunk, "file-2-commit-in-trunk.xoo"); - createAndCommitFile(trunk, "file-3-commit-in-trunk.xoo"); - svnTester.checkout(trunk, "trunk"); - - svnTester.createBranch("b1"); - b1 = temp.newFolder("branches", "b1").toPath(); - svnTester.checkout(b1, "branches/b1"); - createAndCommitFile(b1, "file-1-commit-in-b1.xoo"); - createAndCommitFile(b1, "file-2-commit-in-b1.xoo"); - createAndCommitFile(b1, "file-3-commit-in-b1.xoo"); - svnTester.checkout(b1, "branches/b1"); - - svnTester.createBranch("branches/b1", "b2"); - b2 = temp.newFolder("branches", "b2").toPath(); - svnTester.checkout(b2, "branches/b2"); - - createAndCommitFile(b2, "file-1-commit-in-b2.xoo"); - createAndCommitFile(b2, "file-2-commit-in-b2.xoo"); - createAndCommitFile(b2, "file-3-commit-in-b2.xoo"); - svnTester.checkout(b2, "branches/b2"); - } - - @Before - public void setUp() { - SvnConfiguration configurationMock = mock(SvnConfiguration.class); - findFork = new FindFork(configurationMock); - } - - @Test - public void testEmptyBranch() throws SVNException, IOException { - svnTester.createBranch("empty"); - Path empty = temp.newFolder("branches", "empty").toPath(); - - svnTester.checkout(empty, "branches/empty"); - ForkPoint forkPoint = findFork.find(empty, "unknown"); - assertThat(forkPoint).isNull(); - } - - @Test - public void returnNoDate() throws SVNException { - FindFork findFork = new FindFork(mock(SvnConfiguration.class)) { - @Override - public ForkPoint find(Path location, String referenceBranch) { - return null; - } - }; - - assertThat(findFork.findDate(Paths.get(""), "branch")).isNull(); - } - - @Test - public void testTrunk() throws SVNException { - ForkPoint forkPoint = findFork.find(trunk, "unknown"); - assertThat(forkPoint).isNull(); - } - - @Test - public void testB1() throws SVNException { - ForkPoint forkPoint = findFork.find(b1, "trunk"); - assertThat(forkPoint.commit()).isEqualTo("5"); - } - - @Test - public void testB2() throws SVNException { - ForkPoint forkPoint = findFork.find(b2, "branches/b1"); - assertThat(forkPoint.commit()).isEqualTo("9"); - } - - @Test - public void testB2Date() throws SVNException { - assertThat(findFork.findDate(b2, "branches/b1")).isNotNull(); - } - - @Test - public void testB2FromTrunk() throws SVNException { - ForkPoint forkPoint = findFork.find(b2, "trunk"); - assertThat(forkPoint.commit()).isEqualTo("5"); - } - - private static void createAndCommitFile(Path worktree, String filename, String content) throws IOException, SVNException { - svnTester.createFile(worktree, filename, content); - svnTester.add(worktree, filename); - svnTester.commit(worktree); - } - - private static void createAndCommitFile(Path worktree, String filename) throws IOException, SVNException { - createAndCommitFile(worktree, filename, filename + "\n"); - } -} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/SvnScmProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/SvnScmProviderTest.java index ae10963a47d..0a5c3c6ce19 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/SvnScmProviderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/svn/SvnScmProviderTest.java @@ -24,7 +24,6 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.time.Instant; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -36,7 +35,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.scm.ScmProvider; -import org.tmatesoft.svn.core.SVNCancelException; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.wc.SVNClientManager; @@ -82,7 +80,6 @@ public class SvnScmProviderTest { @Rule public TemporaryFolder temp = new TemporaryFolder(); - private FindFork findFork = mock(FindFork.class); private SvnConfiguration config = mock(SvnConfiguration.class); private SvnTester svnTester; @@ -98,7 +95,7 @@ public class SvnScmProviderTest { @Test public void sanityCheck() { SvnBlameCommand blameCommand = new SvnBlameCommand(config); - SvnScmProvider svnScmProvider = new SvnScmProvider(config, blameCommand, findFork); + SvnScmProvider svnScmProvider = new SvnScmProvider(config, blameCommand); assertThat(svnScmProvider.key()).isEqualTo("svn"); assertThat(svnScmProvider.blameCommand()).isEqualTo(blameCommand); } @@ -231,7 +228,7 @@ public class SvnScmProviderTest { svnTester.createBranch("b1"); svnTester.checkout(b1, "branches/b1"); - SvnScmProvider scmProvider = new SvnScmProvider(config, new SvnBlameCommand(config), findFork) { + SvnScmProvider scmProvider = new SvnScmProvider(config, new SvnBlameCommand(config)) { @Override ChangedLinesComputer newChangedLinesComputer(Path rootBaseDir, Set<Path> changedFiles) { throw new IllegalStateException("crash"); @@ -241,29 +238,9 @@ public class SvnScmProviderTest { } @Test - public void forkDate_returns_null_if_no_fork_found() { - assertThat(new SvnScmProvider(config, new SvnBlameCommand(config), findFork).forkDate("branch", Paths.get(""))).isNull(); - } - - @Test - public void forkDate_returns_instant_if_fork_found() throws SVNException { - Path rootBaseDir = Paths.get(""); - String referenceBranch = "branch"; - Instant forkDate = Instant.ofEpochMilli(123456789L); - SvnScmProvider provider = new SvnScmProvider(config, new SvnBlameCommand(config), findFork); - when(findFork.findDate(rootBaseDir, referenceBranch)).thenReturn(forkDate); - - assertThat(provider.forkDate(referenceBranch, rootBaseDir)).isEqualTo(forkDate); - } - - @Test - public void forkDate_returns_null_if_exception_occurs() throws SVNException { - Path rootBaseDir = Paths.get(""); - String referenceBranch = "branch"; - SvnScmProvider provider = new SvnScmProvider(config, new SvnBlameCommand(config), findFork); - when(findFork.findDate(rootBaseDir, referenceBranch)).thenThrow(new SVNCancelException()); - - assertThat(provider.forkDate(referenceBranch, rootBaseDir)).isNull(); + public void forkDate_returns_null() throws SVNException { + SvnScmProvider provider = new SvnScmProvider(config, new SvnBlameCommand(config)); + assertThat(provider.forkDate("", Paths.get(""))).isNull(); } @Test @@ -305,7 +282,7 @@ public class SvnScmProviderTest { svnTester.commit(worktree); } - private void deleteAndCommitFile(Path worktree, String filename) throws IOException, SVNException { + private void deleteAndCommitFile(Path worktree, String filename) throws SVNException { svnTester.deleteFile(worktree, filename); svnTester.commit(worktree); } @@ -316,6 +293,6 @@ public class SvnScmProviderTest { } private SvnScmProvider newScmProvider() { - return new SvnScmProvider(config, new SvnBlameCommand(config), findFork); + return new SvnScmProvider(config, new SvnBlameCommand(config)); } } |