diff --git a/jenkins-plugin/pom.xml b/jenkins-plugin/pom.xml index 94af52395..c31ae1621 100644 --- a/jenkins-plugin/pom.xml +++ b/jenkins-plugin/pom.xml @@ -63,7 +63,7 @@ workflow-step-api or workflow-api--> 1.26.1 5.2 - 2.22 + 3.2 @@ -119,7 +119,7 @@ org.jenkins-ci.plugins.workflow workflow-job - 2.29 + 2.32 org.jenkins-ci.plugins.workflow @@ -145,7 +145,7 @@ TODO when there is enough adoption of workflow-step-api with https://github.com/jenkinsci/workflow-step-api-plugin/pull/38 Replace org.jenkinsci.plugins.pipeline.maven.fix.jenkins49337.GeneralNonBlockingStepExecution by org.jenkinsci.plugins.workflow.steps.GeneralNonBlockingStepExecution; --> - 2.16 + 2.19 org.jenkins-ci.plugins.workflow @@ -175,7 +175,7 @@ org.jenkins-ci.plugins script-security - 1.54.1 + 1.58 org.jenkins-ci.plugins @@ -200,6 +200,22 @@ compile true + + io.jenkins.plugins + warnings-ng + 5.0.0 + true + + + org.ow2.asm + asm + + + org.antlr + antlr4-runtime + + + org.jenkins-ci.plugins htmlpublisher @@ -541,7 +557,7 @@ commons-io commons-io - 2.5 + 2.6 org.jvnet.localizer @@ -581,7 +597,7 @@ org.apache.commons commons-lang3 - 3.8.1 + 3.9 org.jenkins-ci diff --git a/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/WarningsNgPublisher.java b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/WarningsNgPublisher.java new file mode 100644 index 000000000..e35044a70 --- /dev/null +++ b/jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/publishers/WarningsNgPublisher.java @@ -0,0 +1,130 @@ +package org.jenkinsci.plugins.pipeline.maven.publishers; + +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.Run; +import hudson.model.TaskListener; +import io.jenkins.plugins.analysis.core.model.Tool; +import io.jenkins.plugins.analysis.core.steps.IssuesRecorder; +import io.jenkins.plugins.analysis.warnings.SpotBugs; +import org.jenkinsci.plugins.pipeline.maven.MavenArtifact; +import org.jenkinsci.plugins.pipeline.maven.MavenPublisher; +import org.jenkinsci.plugins.pipeline.maven.MavenSpyLogProcessor; +import org.jenkinsci.plugins.pipeline.maven.util.XmlUtils; +import org.jenkinsci.plugins.workflow.steps.StepContext; +import org.w3c.dom.Element; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +import javax.annotation.Nonnull; + +/** + * @author Cyrille Le Clerc + */ +public class WarningsNgPublisher extends MavenPublisher { + private static final Logger LOGGER = Logger.getLogger(SpotBugsAnalysisPublisher.class.getName()); + + private static final long serialVersionUID = 1L; + + @Override + public void process(@Nonnull StepContext context, @Nonnull Element mavenSpyLogsElt) throws IOException, InterruptedException { + + TaskListener listener = context.get(TaskListener.class); + FilePath workspace = context.get(FilePath.class); + Run run = context.get(Run.class); + Launcher launcher = context.get(Launcher.class); + + List spotbugsEvents = XmlUtils.getExecutionEventsByPlugin(mavenSpyLogsElt, "com.github.spotbugs", "spotbugs-maven-plugin", "spotbugs", "MojoSucceeded", "MojoFailed"); + + if (spotbugsEvents.isEmpty()) { + LOGGER.log(Level.FINE, "No com.github.spotbugs:spotbugs-maven-plugin:spotbugs execution found"); + return; + } + + List spotBugsReportDetails = new ArrayList<>(); + for (Element spotBugsTestEvent : spotbugsEvents) { + String spotBugsEventType = spotBugsTestEvent.getAttribute("type"); + if (!spotBugsEventType.equals("MojoSucceeded") && !spotBugsEventType.equals("MojoFailed")) { + continue; + } + + Element pluginElt = XmlUtils.getUniqueChildElement(spotBugsTestEvent, "plugin"); + Element xmlOutputDirectoryElt = XmlUtils.getUniqueChildElementOrNull(pluginElt, "xmlOutputDirectory"); + Element projectElt = XmlUtils.getUniqueChildElement(spotBugsTestEvent, "project"); + MavenArtifact mavenArtifact = XmlUtils.newMavenArtifact(projectElt); + MavenSpyLogProcessor.PluginInvocation pluginInvocation = XmlUtils.newPluginInvocation(pluginElt); + + if (xmlOutputDirectoryElt == null) { + listener.getLogger().println("[withMaven] No element found for in " + XmlUtils.toString(spotBugsTestEvent)); + continue; + } + String xmlOutputDirectory = xmlOutputDirectoryElt.getTextContent().trim(); + if (xmlOutputDirectory.contains("${project.build.directory}")) { + String projectBuildDirectory = XmlUtils.getProjectBuildDirectory(projectElt); + if (projectBuildDirectory == null || projectBuildDirectory.isEmpty()) { + listener.getLogger().println("[withMaven] '${project.build.directory}' found for in " + XmlUtils.toString(spotBugsTestEvent)); + continue; + } + + xmlOutputDirectory = xmlOutputDirectory.replace("${project.build.directory}", projectBuildDirectory); + + } else if (xmlOutputDirectory.contains("${basedir}")) { + String baseDir = projectElt.getAttribute("baseDir"); + if (baseDir.isEmpty()) { + listener.getLogger().println("[withMaven] '${basedir}' found for in " + XmlUtils.toString(spotBugsTestEvent)); + continue; + } + + xmlOutputDirectory = xmlOutputDirectory.replace("${basedir}", baseDir); + } + + xmlOutputDirectory = XmlUtils.getPathInWorkspace(xmlOutputDirectory, workspace); + + String spotBugsResultsFile = xmlOutputDirectory + "/spotbugsXml.xml"; + + SpotBugsReportDetails details = new SpotBugsReportDetails(mavenArtifact, pluginInvocation, spotBugsResultsFile); + spotBugsReportDetails.add(details); + } + + List tools = new ArrayList<>(); + tools.addAll(spotBugsReportDetails.stream().map(details -> details.toTool()).collect(Collectors.toList())); + + IssuesRecorder issuesRecorder = new IssuesRecorder(); + issuesRecorder.setTools(tools); + issuesRecorder.perform(run, workspace, launcher, listener); + + } + + public static class SpotBugsReportDetails { + final MavenArtifact mavenArtifact; + final MavenSpyLogProcessor.PluginInvocation pluginInvocation; + final String spotBugsReportFile; + + public SpotBugsReportDetails(MavenArtifact mavenArtifact, MavenSpyLogProcessor.PluginInvocation pluginInvocation, String spotBugsReportFile) { + this.mavenArtifact = mavenArtifact; + this.pluginInvocation = pluginInvocation; + this.spotBugsReportFile = spotBugsReportFile; + } + + @Override + public String toString() { + return "spotBugsReportDetails{" + + "mavenArtifact=" + mavenArtifact + + ", pluginInvocation='" + pluginInvocation + '\'' + + ", spotBugsReportFile='" + spotBugsReportFile + '\'' + + '}'; + } + public SpotBugs toTool() { + SpotBugs spotBugs = new SpotBugs(); + spotBugs.setId(spotBugs.getDescriptor().getId() + "_" + mavenArtifact.getId() + "_" + pluginInvocation.getId()); + spotBugs.setName(spotBugs.getDescriptor().getName() + " " + mavenArtifact.getId() + " " + pluginInvocation.getId()); + spotBugs.setPattern(spotBugsReportFile); + return spotBugs; + } + } +}