package org.jvnet.hudson.plugins.purecoverage;
import hudson.FilePath;
import hudson.Launcher;
import hudson.Util;
import hudson.model.Action;
import hudson.model.Build;
import hudson.model.BuildListener;
import hudson.model.Descriptor;
import hudson.model.Project;
import hudson.model.Result;
import hudson.tasks.Publisher;
import java.io.File;
import java.io.IOException;
import net.sf.json.JSONObject;
import org.jvnet.hudson.plugins.purecoverage.domain.ProjectCoverage;
import org.jvnet.hudson.plugins.purecoverage.parser.PureCoverageParser;
import org.kohsuke.stapler.StaplerRequest;
@SuppressWarnings("unchecked")
public class CoveragePublisher extends Publisher {
private String coverageReportPattern;
/**
* @param coverageReportPattern - file name pattern that points to PureCoverage report
* @stapler-constructor
*/
public CoveragePublisher(String coverageReportPattern) {
this.coverageReportPattern = coverageReportPattern;
}
public void setCoverageReportPattern(String coverageReportPattern) {
this.coverageReportPattern = coverageReportPattern;
}
public String getCoverageReportPattern() {
return coverageReportPattern;
}
@Override
public Action getProjectAction(Project project) {
return new CoverageProjectAction(project);
}
/**
* {@inheritDoc}
*/
public boolean perform(Build<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
if (coverageReportPattern == null) {
listener.getLogger().println("Skipping coverage reports as coverageReportPattern is null");
return false;
}
if (!Result.SUCCESS.equals(build.getResult())) {
listener.getLogger().println("Skipping coverage reports as the build was not successful...");
return true;
}
listener.getLogger().println("Publishing PureCoverage reports...");
FilePath buildTarget = new FilePath(build.getRootDir());
FilePath[] reports = new FilePath[0];
final FilePath moduleRoot = build.getParent().getWorkspace();
try {
reports = moduleRoot.list(coverageReportPattern);
} catch (IOException e) {
Util.displayIOException(e, listener);
e.printStackTrace(listener.fatalError("Unable to find PureCoverage results"));
build.setResult(Result.FAILURE);
}
if (reports.length == 0) {
listener.getLogger().println("No coverage results were found using the pattern '" + coverageReportPattern
+ "'. Did you generate the report(s)?");
build.setResult(Result.FAILURE);
return true;
}
if (reports.length > 1) {
listener.getLogger().println("PureCoverage publisher found more than one report that match the pattern. "
+ "Currently, accumulating PureCoverage results is not implemented!");
build.setResult(Result.FAILURE);
return true;
}
FilePath singleReport = reports[0];
final FilePath targetPath = new FilePath(buildTarget, CoverageReportsFinder.COVERAGE_PREFIX);
try {
singleReport.copyTo(targetPath);
} catch (IOException e) {
Util.displayIOException(e, listener);
e.printStackTrace(listener.fatalError("Unable to copy coverage from " + singleReport + " to " + buildTarget));
build.setResult(Result.FAILURE);
}
listener.getLogger().println("Parsing PureCoverage results...");
ProjectCoverage projectCoverage = null;
CoverageReportsFinder finder = new CoverageReportsFinder();
for (File coverageResult : finder.findReports(build)) {
try {
CoverageParser coverageParser = new PureCoverageParser();
projectCoverage = coverageParser.parse(coverageResult);
} catch (IOException e) {
Util.displayIOException(e, listener);
e.printStackTrace(listener.fatalError("Unable to parse " + coverageResult));
build.setResult(Result.FAILURE);
return false;
}
}
CoverageResult coverageResult = new CoverageResult(build, projectCoverage);
build.getActions().add(new CoverageBuildAction(build, coverageResult));
return true;
}
/**
* {@inheritDoc}
*/
public Descriptor<Publisher> getDescriptor() {
// see Descriptor javadoc for more about what a descriptor is.
return DESCRIPTOR;
}
public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl();
/**
* Descriptor for {@link CoveragePublisher}. Used as a singleton. The class is marked as public so that it can be
* accessed from views.
* <p/>
* <p/>
* See <tt>views/hudson/plugins/coverage/CoveragePublisher/*.jelly</tt> for the actual HTML fragment for the
* configuration screen.
*/
public static final class DescriptorImpl extends Descriptor<Publisher> {
/**
* Constructs a new DescriptorImpl.
*/
DescriptorImpl() {
super(CoveragePublisher.class);
}
/**
* This human readable name is used in the configuration screen.
*/
public String getDisplayName() {
return "Publish PureCoverage Report";
}
/**
* {@inheritDoc}
*/
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
return configure(req);
}
/**
* {@inheritDoc}
*/
public boolean configure(StaplerRequest req) throws FormException {
req.bindParameters(this, "pureCoverage.");
save();
return super.configure(req);
}
/**
* Creates a new instance of {@link CoveragePublisher} from a submitted form.
*/
public CoveragePublisher newInstance(StaplerRequest req) throws FormException {
CoveragePublisher instance = req.bindParameters(CoveragePublisher.class, "pureCoverage.");
return instance;
}
}
}