Skip to content
Permalink
Browse files

[JENKINS-51366] Autodetect report type by default

  • Loading branch information
cizezsy committed May 17, 2018
1 parent bfb195f commit 52da47db9e16f5cc20bfb90905a3dc84561071e1
@@ -19,11 +19,26 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package io.jenkins.plugins.coverage;

import hudson.model.Run;

public class BuildUtils {

public final class BuildUtils {

/**
* BuildUtils cannot be instantiated.
*/
private BuildUtils() {
}

/**
* Get previous not failed completed build.
*
* @param b current build
* @return previous not failed completed build
*/
public static Run<?, ?> getPreviousNotFailedCompletedBuild(Run<?, ?> b) {
while (true) {
b = b.getPreviousNotFailedBuild();
@@ -7,22 +7,25 @@
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.remoting.VirtualChannel;
import io.jenkins.plugins.coverage.adapter.*;
import io.jenkins.plugins.coverage.adapter.CoverageReportAdapter;
import io.jenkins.plugins.coverage.adapter.CoverageReportAdapterDescriptor;
import io.jenkins.plugins.coverage.adapter.Detectable;
import io.jenkins.plugins.coverage.exception.ConversionException;
import io.jenkins.plugins.coverage.targets.CoverageElement;
import io.jenkins.plugins.coverage.targets.CoverageResult;
import io.jenkins.plugins.coverage.threshhold.ThreshHold;
import jenkins.MasterToSlaveFileCallable;
import org.apache.commons.collections.IteratorUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.ClassUtils;

import javax.annotation.Nonnull;
import java.io.*;
import java.lang.reflect.Constructor;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author Shenyu Zheng
*/
public class CoverageProcessor {

private static final String DEFAULT_REPORT_SAVE_NAME = "coverage-report.xml";
@@ -56,6 +59,12 @@ public CoverageResult processCoverageReport() throws IOException, InterruptedExc
return report;
}

/**
* Convert report specified by {@link CoverageReportAdapter} into coverage results.
*
* @param adapters {@link CoverageReportAdapter} for each report
* @return {@link CoverageResult} for each report
*/
private List<CoverageResult> convertToResults(List<CoverageReportAdapter> adapters)
throws IOException, InterruptedException {

@@ -91,6 +100,7 @@ public CoverageResult processCoverageReport() throws IOException, InterruptedExc
}
}

// If enable automatically detecting, it will try to find report and correspond adapter.
if (isEnableAutoDetect()) {
List<FilePath> detectedFilePaths = Arrays.stream(workspace.act(new FindReportCallable(autoDetectPath, null)))
.filter(filePath -> {
@@ -177,6 +187,7 @@ private CoverageResult aggregatedToReport(List<CoverageResult> results) {

/**
* Find all detectable {@link CoverageReportAdapterDescriptor}
*
* @return Detectable CoverageReportAdapterDescriptors
*/
@SuppressWarnings("unchecked")
@@ -188,7 +199,7 @@ private CoverageResult aggregatedToReport(List<CoverageResult> results) {
Iterator<CoverageReportAdapterDescriptor<?>> i = availableCoverageReportDescriptors.iterator();
while (i.hasNext()) {
CoverageReportAdapterDescriptor c = i.next();
if(c instanceof Detectable) {
if (c instanceof Detectable) {
results.add(c);
}
}
@@ -198,6 +209,7 @@ private CoverageResult aggregatedToReport(List<CoverageResult> results) {

/**
* Enable report auto-detect
*
* @param autoDetectPath Ant-Style path to specify coverage report
*/
public void enableAutoDetect(String autoDetectPath) {
@@ -236,14 +248,16 @@ public FindReportCallable(String reportFilePath, CoverageReportAdapter reportAda
public static void saveReport(Run<?, ?> run, CoverageResult report) throws IOException {
File reportFile = new File(run.getRootDir(), DEFAULT_REPORT_SAVE_NAME);

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(reportFile));
oos.writeObject(report);
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(reportFile))) {
oos.writeObject(report);
}
}

public static CoverageResult recoverReport(Run<?, ?> run) throws IOException, ClassNotFoundException {
File reportFile = new File(run.getRootDir(), DEFAULT_REPORT_SAVE_NAME);

ObjectInputStream ois = new ObjectInputStream(new FileInputStream(reportFile));
return (CoverageResult) ois.readObject();
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(reportFile))) {
return (CoverageResult) ois.readObject();
}
}
}
@@ -33,7 +33,7 @@
private List<CoverageReportAdapter> adapters;
private List<ThreshHold> globalThreshHolds;

private AutoDetectConfig autoDetectConfig = null;
private String autoDetectPath;

@DataBoundConstructor
public CoveragePublisher(List<CoverageReportAdapter> adapters, List<ThreshHold> globalThreshHolds) {
@@ -45,8 +45,8 @@ public CoveragePublisher(List<CoverageReportAdapter> adapters, List<ThreshHold>
public void perform(@Nonnull Run<?, ?> run, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull TaskListener listener) throws InterruptedException, IOException {
CoverageProcessor processor = new CoverageProcessor(run, workspace, listener, adapters, globalThreshHolds);

if (autoDetectConfig != null && !StringUtils.isEmpty(autoDetectConfig.getAutoDetectPath())) {
processor.enableAutoDetect(autoDetectConfig.getAutoDetectPath());
if (StringUtils.isEmpty(autoDetectPath)) {
processor.enableAutoDetect(autoDetectPath);
}

CoverageResult result = processor.processCoverageReport();
@@ -68,13 +68,14 @@ public BuildStepMonitor getRequiredMonitorService() {
return globalThreshHolds;
}

public AutoDetectConfig getAutoDetectConfig() {
return autoDetectConfig;

public String getAutoDetectPath() {
return autoDetectPath;
}

@DataBoundSetter
public void setAutoDetectConfig(AutoDetectConfig autoDetectConfig) {
this.autoDetectConfig = autoDetectConfig;
public void setAutoDetectPath(String autoDetectPath) {
this.autoDetectPath = autoDetectPath;
}

@Extension
@@ -119,22 +120,4 @@ public Publisher newInstance(@CheckForNull StaplerRequest req, @Nonnull JSONObje
return super.newInstance(req, formData);
}
}

public class AutoDetectConfig {
private String autoDetectPath;

@DataBoundConstructor
public AutoDetectConfig(String autoDetectPath) {
this.autoDetectPath = autoDetectPath;
}

public String getAutoDetectPath() {
return autoDetectPath;
}

@DataBoundSetter
public void setAutoDetectPath(String autoDetectPath) {
this.autoDetectPath = autoDetectPath;
}
}
}
@@ -9,10 +9,13 @@
import javax.xml.transform.TransformerException;
import java.io.File;

/**
* Coverage report adapter for Cobertura.
*/
public final class CoberturaReportAdapter extends JavaXMLCoverageReportAdapter {

@DataBoundConstructor
public CoberturaReportAdapter(String path) {
public CoberturaReportAdapter(final String path) {
super(path);
}

@@ -34,17 +37,19 @@ public String getXSD() {

@Extension
public static final class CoverturaReportAdapterDescriptor
extends CoverageReportAdapterDescriptor<CoberturaReportAdapter> implements Detectable {
extends CoverageReportAdapterDescriptor<CoberturaReportAdapter>
implements Detectable {

public CoverturaReportAdapterDescriptor() {
super(CoberturaReportAdapter.class, "Cobertura");
}


@Override
public boolean detect(File file) {
if (!file.exists())
public boolean detect(final File file) {
if (!file.exists()) {
return false;
}

Document d;
try {
@@ -54,8 +59,9 @@ public boolean detect(File file) {
}

Element e = d.getDocumentElement();
if (e == null)
if (e == null) {
return false;
}

return "coverage".equals(e.getLocalName());
}
@@ -15,7 +15,7 @@
public abstract class CoverageReportAdapter implements ExtensionPoint, Describable<CoverageReportAdapter> {

// path of report file
private String path;
private final String path;

public CoverageReportAdapter(String path) {
this.path = path;
@@ -48,8 +48,4 @@ public CoverageResult getResult(File source) throws ConversionException {
public String getPath() {
return path;
}

public void setPath(String path) {
this.path = path;
}
}
@@ -6,6 +6,7 @@

public abstract class JavaXMLCoverageReportAdapter extends XMLCoverageReportAdapter {


public JavaXMLCoverageReportAdapter(String path) {
super(path);
}
@@ -2,6 +2,7 @@

import io.jenkins.plugins.coverage.adapter.util.XMLUtils;
import io.jenkins.plugins.coverage.exception.ConversionException;
import org.apache.commons.lang.StringUtils;
import org.w3c.dom.Document;

import javax.annotation.CheckForNull;
@@ -12,6 +13,7 @@

public abstract class XMLCoverageReportAdapter extends CoverageReportAdapter {


public XMLCoverageReportAdapter(String path) {
super(path);
}
@@ -55,8 +57,13 @@ public Document convert(File source) throws ConversionException {
@SuppressWarnings("WeakerAccess")
protected File getRealXSL() throws ConversionException, FileNotFoundException {
try {
File realXSL = new File(getClass().getResource(getXSL()).toURI());
if (!realXSL.exists()) {
String xsl = getXSL();
if (StringUtils.isEmpty(xsl)) {
throw new FileNotFoundException("xsl path must be no-empty");
}

File realXSL = new File(getClass().getResource(xsl).toURI());
if (!realXSL.exists() || !realXSL.isFile()) {
throw new FileNotFoundException("Cannot found xsl file");
} else {
return realXSL;
@@ -5,7 +5,10 @@
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import javax.xml.transform.*;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
@@ -32,7 +35,8 @@ private XMLUtils() {
* @param source Source xml file
* @return Converted document
*/
public Document convertToDocumentWithXSL(File xsl, File source) throws FileNotFoundException, ConversionException {
public Document convertToDocumentWithXSL(File xsl, File source)
throws FileNotFoundException, ConversionException {
DOMResult result = convertToDOMResultWithXSL(xsl, source);

return getDocumentFromDomResult(result);
@@ -45,13 +49,14 @@ public Document convertToDocumentWithXSL(File xsl, File source) throws FileNotFo
* @param source Source file
* @param result Result that want to be written in
*/
private void convertWithXSL(File xsl, File source, Result result) throws FileNotFoundException, ConversionException {
private void convertWithXSL(File xsl, File source, Result result)
throws FileNotFoundException, ConversionException {
if (!xsl.exists()) {
throw new FileNotFoundException("XSL File not exist!");
throw new FileNotFoundException("XSL File does not exist!");
}

if (!source.exists()) {
throw new FileNotFoundException("source File not exist!");
throw new FileNotFoundException("source File does not exist!");
}


@@ -75,7 +80,8 @@ private void convertWithXSL(File xsl, File source, Result result) throws FileNot
* @param source Source xml file
* @return DOMResult
*/
public DOMResult convertToDOMResultWithXSL(File xsl, File source) throws FileNotFoundException, ConversionException {
public DOMResult convertToDOMResultWithXSL(File xsl, File source)
throws FileNotFoundException, ConversionException {
DOMResult result = new DOMResult();
convertWithXSL(xsl, source, result);
return result;
@@ -88,7 +94,8 @@ public DOMResult convertToDOMResultWithXSL(File xsl, File source) throws FileNot
* @param source Source xml file
* @return SAXResult
*/
public SAXResult convertToSAXResultWithXSL(File xsl, File source) throws FileNotFoundException, ConversionException {
public SAXResult convertToSAXResultWithXSL(File xsl, File source)
throws FileNotFoundException, ConversionException {
SAXResult result = new SAXResult();
convertWithXSL(xsl, source, result);
return result;
@@ -118,8 +125,10 @@ public Document readXMLtoDocument(File file) throws TransformerException {

private Document getDocumentFromDomResult(DOMResult domResult) {
Node node = domResult.getNode();
if (node == null)
if (node == null) {
return null;
}

return node.getNodeType() == Node.DOCUMENT_NODE ? ((Document) node) : node.getOwnerDocument();
}
}

0 comments on commit 52da47d

Please sign in to comment.
You can’t perform that action at this time.