diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageRecorder.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageRecorder.java index 1e36964b1..fc72fb9ff 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageRecorder.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageRecorder.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -10,10 +9,10 @@ import org.apache.commons.lang3.StringUtils; -import edu.hm.hafner.coverage.Metric; import edu.hm.hafner.coverage.ModuleNode; import edu.hm.hafner.coverage.Node; import edu.hm.hafner.util.FilteredLog; +import edu.hm.hafner.util.TreeStringBuilder; import edu.umd.cs.findbugs.annotations.NonNull; import org.kohsuke.stapler.AncestorInPath; @@ -63,7 +62,7 @@ * * @author Ullrich Hafner */ -@SuppressWarnings({"checkstyle:ClassFanOutComplexity", "PMD.GodClass"}) +@SuppressWarnings({"PMD.GodClass", "checkstyle:ClassFanOutComplexity", "checkstyle:ClassDataAbstractionCoupling"}) public class CoverageRecorder extends Recorder { static final String CHECKS_DEFAULT_NAME = "Code Coverage"; @@ -379,7 +378,7 @@ void perform(final Run run, final FilePath workspace, final TaskListener t "No tools defined that will record the coverage files"); } else { - perform(run, workspace, taskListener, resultHandler, log); + perform(run, workspace, taskListener, resultHandler, log, logHandler); } } @@ -389,23 +388,21 @@ void perform(final Run run, final FilePath workspace, final TaskListener t } private void perform(final Run run, final FilePath workspace, final TaskListener taskListener, - final StageResultHandler resultHandler, final FilteredLog log) throws InterruptedException { + final StageResultHandler resultHandler, final FilteredLog log, final LogHandler logHandler) throws InterruptedException { List results = recordCoverageResults(run, workspace, taskListener, resultHandler, log); if (!results.isEmpty()) { CoverageReporter reporter = new CoverageReporter(); var rootNode = Node.merge(results); - // TODO: move code to coverage model - var sources = rootNode.getAll(Metric.MODULE) - .stream() - .filter(ModuleNode.class::isInstance) - .map(ModuleNode.class::cast) - .map(ModuleNode::getSourceFolders) - .flatMap(Collection::stream) - .collect(Collectors.toSet()); + + var sources = rootNode.getSourceFolders(); sources.addAll(getSourceDirectoriesPaths()); + + resolveAbsolutePaths(rootNode, workspace, sources, log); + logHandler.log(log); + var action = reporter.publishAction(getActualId(), getName(), getIcon(), rootNode, run, - workspace, taskListener, getQualityGates(), getScm(), sources, + workspace, taskListener, getQualityGates(), getScm(), getSourceCodeEncoding(), getSourceCodeRetention(), resultHandler); if (!skipPublishingChecks) { var checksPublisher = new CoverageChecksPublisher(action, rootNode, getChecksName(), getChecksAnnotationScope()); @@ -414,6 +411,21 @@ workspace, taskListener, getQualityGates(), getScm(), sources, } } + private void resolveAbsolutePaths(final Node rootNode, final FilePath workspace, final Set sources, + final FilteredLog log) throws InterruptedException { + log.logInfo("Resolving source code files..."); + var pathMapping = new PathResolver().resolvePaths(rootNode.getFiles(), sources, workspace, log); + + if (!pathMapping.isEmpty()) { + log.logInfo("Making paths of " + pathMapping.size() + " source code files relative to workspace root..."); + var builder = new TreeStringBuilder(); + rootNode.getAllFileNodes().stream() + .filter(file -> pathMapping.containsKey(file.getRelativePath())) + .forEach(file -> file.setRelativePath(builder.intern(pathMapping.get(file.getRelativePath())))); + builder.dedup(); + } + } + private String getIcon() { var icons = tools.stream().map(CoverageTool::getParser).map(Parser::getIcon).collect(Collectors.toSet()); if (icons.size() == 1) { diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageReporter.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageReporter.java index 932718b06..04261ea98 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageReporter.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/steps/CoverageReporter.java @@ -6,7 +6,6 @@ import java.util.Optional; import java.util.Set; import java.util.TreeMap; -import java.util.stream.Collectors; import org.apache.commons.lang3.math.Fraction; @@ -15,7 +14,6 @@ import edu.hm.hafner.coverage.Node; import edu.hm.hafner.coverage.Value; import edu.hm.hafner.util.FilteredLog; -import edu.hm.hafner.util.TreeStringBuilder; import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.FilePath; @@ -42,9 +40,8 @@ public class CoverageReporter { @SuppressWarnings("checkstyle:ParameterNumber") CoverageBuildAction publishAction(final String id, final String optionalName, final String icon, final Node rootNode, - final Run build, - final FilePath workspace, final TaskListener listener, final List qualityGates, - final String scm, final Set sourceDirectories, final String sourceCodeEncoding, + final Run build, final FilePath workspace, final TaskListener listener, + final List qualityGates, final String scm, final String sourceCodeEncoding, final SourceCodeRetention sourceCodeRetention, final StageResultHandler resultHandler) throws InterruptedException { FilteredLog log = new FilteredLog("Errors while reporting code coverage results:"); @@ -98,8 +95,6 @@ CoverageBuildAction publishAction(final String id, final String optionalName, fi filesToStore = rootNode.getAllFileNodes(); } - resolveAbsolutePaths(rootNode, workspace, sourceDirectories, log, filesToStore); - action = new CoverageBuildAction(build, id, optionalName, icon, rootNode, qualityGateResult, log, referenceAction.getOwner().getExternalizableId(), coverageDelta, modifiedLinesCoverageRoot.aggregateValues(), modifiedLinesCoverageDelta, @@ -112,8 +107,6 @@ CoverageBuildAction publishAction(final String id, final String optionalName, fi filesToStore = rootNode.getAllFileNodes(); - resolveAbsolutePaths(rootNode, workspace, sourceDirectories, log, filesToStore); - action = new CoverageBuildAction(build, id, optionalName, icon, rootNode, qualityGateStatus, log); } @@ -131,22 +124,6 @@ CoverageBuildAction publishAction(final String id, final String optionalName, fi return action; } - private void resolveAbsolutePaths(final Node rootNode, final FilePath workspace, final Set sourceDirectories, - final FilteredLog log, final List filesToStore) throws InterruptedException { - log.logInfo("Resolving source code files..."); - var relativePaths = filesToStore.stream().map(FileNode::getRelativePath).collect(Collectors.toSet()); - var pathMapping = new PathResolver().resolvePaths(relativePaths, sourceDirectories, workspace, log); - - if (!pathMapping.isEmpty()) { - log.logInfo("Making paths of " + pathMapping.size() + " source code files relative to workspace root..."); - var builder = new TreeStringBuilder(); - rootNode.getAllFileNodes().stream() - .filter(file -> pathMapping.containsKey(file.getRelativePath())) - .forEach(file -> file.setRelativePath(builder.intern(pathMapping.get(file.getRelativePath())))); - builder.dedup(); - } - } - private void createDeltaReports(final Node rootNode, final FilteredLog log, final Node referenceRoot, final CodeDeltaCalculator codeDeltaCalculator, final Delta delta) { FileChangesProcessor fileChangesProcessor = new FileChangesProcessor();