Skip to content

Commit

Permalink
Make issues in modified code visible.
Browse files Browse the repository at this point in the history
  • Loading branch information
uhafner committed Jan 26, 2024
1 parent 7422834 commit 9320d92
Show file tree
Hide file tree
Showing 31 changed files with 550 additions and 179 deletions.
60 changes: 33 additions & 27 deletions plugin/pom.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.jvnet.hudson.plugins</groupId>
<artifactId>analysis-pom</artifactId>
<version>6.17.0</version>
<relativePath />
<version>7.0.0</version>
<relativePath/>
</parent>

<groupId>io.jenkins.plugins</groupId>
Expand All @@ -25,14 +26,12 @@
<changelist>-SNAPSHOT</changelist>
<module.name>${project.groupId}.warnings.ng</module.name>

<analysis-model-api.version>11.14.0</analysis-model-api.version>
<analysis-model-tests.version>${analysis-model-api.version}</analysis-model-tests.version>
<analysis-model-api.version>11.20.0-rc789.31c8340705ef</analysis-model-api.version>
<analysis-model-tests.version>11.6.0</analysis-model-tests.version>
<pull-request-monitoring.version>1.7.8</pull-request-monitoring.version>

<eclipse-collections.version>9.2.0</eclipse-collections.version>

<json.version>20231013</json.version>

<!-- Test Library Dependencies Versions -->
<xmlunit.version>2.9.1</xmlunit.version>
<jsoup.version>1.17.2</jsoup.version>
Expand All @@ -47,12 +46,15 @@
<flexible-publish.version>0.15.2</flexible-publish.version>
<form-element-path.version>1.11</form-element-path.version>

<!-- Maven Surefire ArgLine -->
<argLine>-Djava.awt.headless=true -Xmx1024m -Djenkins.test.timeout=1000 --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED</argLine>

<prism-api.version>1.29.0-8</prism-api.version>
<plugin-util-api.version>3.9.0-rc855.756b_f8df78a_1</plugin-util-api.version>
<plugin-util-api.version>3.9.0-rc856.7a_4b_8d226cb_2</plugin-util-api.version>
<forensics-api.version>2.4.0-rc1530.ccd6a_b_012b_c7</forensics-api.version>

<!-- Maven Surefire ArgLine -->
<argLine>-Djava.awt.headless=true -Xmx1024m -Djenkins.test.timeout=1000 --add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens
java.base/java.util.concurrent=ALL-UNNAMED
</argLine>
</properties>

<licenses>
Expand Down Expand Up @@ -87,6 +89,12 @@
<groupId>net.minidev</groupId>
<artifactId>json-smart</artifactId>
<version>${json-smart.version}</version>
<exclusions>
<exclusion>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
Expand Down Expand Up @@ -171,6 +179,11 @@
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>forensics-api</artifactId>
<version>${forensics-api.version}</version>
</dependency>
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>json-api</artifactId>
</dependency>

<!-- AxivionSuite Dependencies -->
Expand All @@ -183,9 +196,8 @@
<artifactId>apache-httpcomponents-client-4-api</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
<groupId>io.jenkins.plugins</groupId>
<artifactId>gson-api</artifactId>
</dependency>

<!-- Optional Jenkins Plug-in Dependencies -->
Expand Down Expand Up @@ -284,12 +296,6 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>${json.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>jenkins-test-harness-tools</artifactId>
Expand Down Expand Up @@ -614,13 +620,13 @@
</plugins>
</build>
</profile>
<profile>
<id>fast</id>
<properties>
<skipTests>true</skipTests>
<skipITs>true</skipITs>
</properties>
</profile>
<profile>
<id>fast</id>
<properties>
<skipTests>true</skipTests>
<skipITs>true</skipITs>
</properties>
</profile>
</profiles>

<scm>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,42 @@
package io.jenkins.plugins.analysis.core.charts;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import edu.hm.hafner.analysis.Severity;

import io.jenkins.plugins.analysis.core.util.AnalysisBuildResult;
import io.jenkins.plugins.analysis.core.util.IssuesStatistics;
import io.jenkins.plugins.analysis.core.util.IssuesStatisticsBuilder;

/**
* A build result that is composed of a series of other builds results simply by summing up the number of issues.
*
* @author Ullrich Hafner
*/
// FIXME: IssueStatistics?
public class CompositeBuildResult implements AnalysisBuildResult {
private final Map<String, Integer> sizesPerOrigin = new HashMap<>();
private final Map<Severity, Integer> sizesPerSeverity = new HashMap<>();
private final Map<Severity, Integer> newSizesPerSeverity = new HashMap<>();

private int fixedSize = 0;
private final Map<String, Integer> sizesPerOrigin;
private final IssuesStatistics totals;

/**
* Adds the specified results to this composition. Adds the new value of each property to the existing value of the
* Creates a composition of the specified results. Adds the new value of each property to the existing value of the
* same property.
*
* @param additionalResults
* the additional results to add
*
* @return returns this to simplify call chains
* @param results
* the results to add
*/
public CompositeBuildResult add(final AnalysisBuildResult... additionalResults) {
for (AnalysisBuildResult another : additionalResults) {
sizesPerOrigin.putAll(another.getSizePerOrigin());
for (Severity severity : Severity.getPredefinedValues()) {
sizesPerSeverity.merge(severity, another.getTotalSizeOf(severity), Integer::sum);
newSizesPerSeverity.merge(severity, another.getNewSizeOf(severity), Integer::sum);
}
fixedSize += another.getFixedSize();
}
return this;
public CompositeBuildResult(final Collection<? extends AnalysisBuildResult> results) {
totals = results.stream()
.map(AnalysisBuildResult::getTotals)
.map(Objects::requireNonNull)
.reduce(new IssuesStatisticsBuilder().build(), IssuesStatistics::aggregate);
sizesPerOrigin = results.stream().map(AnalysisBuildResult::getSizePerOrigin)
.reduce(new HashMap<>(), (first, second) -> {
second.forEach((key, value) -> first.merge(key, value, Integer::sum));
return first;
});
}

@Override
Expand All @@ -48,30 +46,31 @@ public Map<String, Integer> getSizePerOrigin() {

@Override
public int getFixedSize() {
return fixedSize;
return getTotals().getFixedSize();
}

@Override
public int getTotalSize() {
return sum(sizesPerSeverity);
return getTotals().getTotalSize();
}

@Override
public int getTotalSizeOf(final Severity severity) {
return sizesPerSeverity.getOrDefault(severity, 0);
return getTotals().getTotalSizeOf(severity);
}

@Override
public int getNewSize() {
return sum(newSizesPerSeverity);
return getTotals().getNewSize();
}

private Integer sum(final Map<Severity, Integer> map) {
return map.values().stream().reduce(0, Integer::sum);
@Override
public int getNewSizeOf(final Severity severity) {
return getTotals().getNewSizeOf(severity);
}

@Override
public int getNewSizeOf(final Severity severity) {
return newSizesPerSeverity.getOrDefault(severity, 0);
public IssuesStatistics getTotals() {
return totals;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.jenkins.plugins.analysis.core.charts;

import edu.hm.hafner.analysis.Report;
import edu.hm.hafner.echarts.PieChartModel;
import edu.hm.hafner.echarts.PieData;

import io.jenkins.plugins.echarts.JenkinsPalette;

/**
* Builds the model for a pie chart showing the number of issues in modified code.
*
* @author Ullrich Hafner
*/
public class ModifiedCodePieChart {
/**
* Creates the chart for the specified result.
*
* @param issues
* all issues
*
* @return the chart model
*/
public PieChartModel create(final Report issues) {
PieChartModel model = new PieChartModel(Messages.NewVersusFixed_Name());

var totals = issues.size();
model.add(new PieData(Messages.Modified_Code_Warnings_Short(), totals), JenkinsPalette.RED.normal());
model.add(new PieData(Messages.Unchanged_Code_Warnings_Short(), totals), JenkinsPalette.YELLOW.normal());

return model;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public boolean hasNext() {

@Override
public BuildResult<AnalysisBuildResult> next() {
if (!latestAction.isPresent()) {
if (latestAction.isEmpty()) {
throw new NoSuchElementException("No more build results available");
}
Run<?, ?> run = latestAction.get();
Expand All @@ -155,11 +155,7 @@ public BuildResult<AnalysisBuildResult> next() {
.stream()
.map(ResultAction::getResult)
.collect(Collectors.toSet());
CompositeBuildResult compositeBuildResult = new CompositeBuildResult();
for (AnalysisResult result : results) {
compositeBuildResult.add(result);
}
return new BuildResult<>(new JenkinsBuild(run), compositeBuildResult);
return new BuildResult<>(new JenkinsBuild(run), new CompositeBuildResult(results));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ public String toString() {
return new JenkinsFacade().getBuild(referenceBuildId);
}

@Override
@Whitelisted
public IssuesStatistics getTotals() {
return totals;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public DeltaReport(final Report report, final History history, final int current
else {
report.logInfo("No valid reference build found that meets the criteria (%s)", history);
report.logInfo("All reported issues will be considered outstanding");
report.forEach(issue -> issue.setReference(String.valueOf(currentBuildNumber)));
report.setReference(String.valueOf(currentBuildNumber));
outstandingIssues = report;
referenceIssues = EMPTY_REPORT;
newIssues = EMPTY_REPORT;
Expand Down Expand Up @@ -94,7 +94,7 @@ public Report getAllIssues() {
}

/**
* Returns all outstanding issues: i.e. all issues, that are part of the current and reference report.
* Returns all outstanding issues: i.e., all issues, that are part of the current and reference report.
*
* @return the outstanding issues
*/
Expand All @@ -103,7 +103,7 @@ public Report getOutstandingIssues() {
}

/**
* Returns all new issues: i.e. all issues, that are part of the current report but have not been shown up in the
* Returns all new issues: i.e., all issues, that are part of the current report but have not been shown up in the
* reference report.
*
* @return the new issues
Expand All @@ -113,7 +113,7 @@ public Report getNewIssues() {
}

/**
* Returns all fixed issues: i.e. all issues, that are part of the reference report but are not present in the
* Returns all fixed issues: i.e., all issues, that are part of the reference report but are not present in the
* current report anymore.
*
* @return the fixed issues
Expand All @@ -124,19 +124,21 @@ public Report getFixedIssues() {

/**
* Returns statistics for the number of issues (total, new, delta).
*
*
* @return the issues statistics
*/
public IssuesStatistics getStatistics() {
IssuesStatisticsBuilder builder = new IssuesStatisticsBuilder();
builder.setTotalErrorSize(allIssues.getSizeOf(ERROR))
.setTotalHighSize(allIssues.getSizeOf(WARNING_HIGH))
.setTotalNormalSize(allIssues.getSizeOf(WARNING_NORMAL))
.setTotalLowSize(allIssues.getSizeOf(WARNING_LOW));
.setTotalLowSize(allIssues.getSizeOf(WARNING_LOW))
.setTotalModifiedSize(allIssues.getInModifiedCode().size());
builder.setNewErrorSize(newIssues.getSizeOf(ERROR))
.setNewHighSize(newIssues.getSizeOf(WARNING_HIGH))
.setNewNormalSize(newIssues.getSizeOf(WARNING_NORMAL))
.setNewLowSize(newIssues.getSizeOf(WARNING_LOW));
.setNewLowSize(newIssues.getSizeOf(WARNING_LOW))
.setNewModifiedSize(newIssues.getInModifiedCode().size());
builder.setFixedSize(fixedIssues.size());
if (!referenceBuildId.isEmpty()) {
builder.setDeltaErrorSize(allIssues.getSizeOf(ERROR) - referenceIssues.getSizeOf(ERROR))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ private Marker asMarker(final Issue issue, final String description, final Strin
.withColumnEnd(issue.getColumnEnd()).build();
}

@SuppressWarnings("checkstyle:ParameterNumber")
@SuppressWarnings({"checkstyle:ParameterNumber", "PMD.CyclomaticComplexity"})
@SuppressFBWarnings("IMPROPER_UNICODE")
private Object createNewDetailView(final String link, final Run<?, ?> owner, final AnalysisResult result,
final Report allIssues, final Report newIssues, final Report outstandingIssues, final Report fixedIssues,
Expand All @@ -162,6 +162,11 @@ private Object createNewDetailView(final String link, final Run<?, ?> owner, fin
return new IssuesDetail(owner, result, allIssues, newIssues, outstandingIssues, fixedIssues,
labelProvider.getLinkName(), url, labelProvider, sourceEncoding);
}
if ("modified".equalsIgnoreCase(link)) {
return new IssuesDetail(owner, result, filterModified(allIssues), filterModified(newIssues),
filterModified(outstandingIssues), EMPTY,
Messages.Modified_Warnings_Header(), url, labelProvider, sourceEncoding);
}
if ("fixed".equalsIgnoreCase(link)) {
return new FixedWarningsDetail(owner, result, fixedIssues, url, labelProvider, sourceEncoding);
}
Expand Down Expand Up @@ -191,6 +196,10 @@ private Object createNewDetailView(final String link, final Run<?, ?> owner, fin
throw new NoSuchElementException(String.format("There is no URL mapping for %s and %s", parent.getUrl(), link));
}

private Report filterModified(final Report report) {
return report.filter(Issue::isPartOfModifiedCode);
}

private Predicate<Issue> createPropertyFilter(final String plainLink, final String property) {
return issue -> plainLink.equals(String.valueOf(
Issue.getPropertyValueAsString(issue, property).hashCode()));
Expand Down
Loading

0 comments on commit 9320d92

Please sign in to comment.