package hudson.plugins.tfs;
import hudson.Extension;
import hudson.FilePath;
import hudson.Launcher;
import hudson.model.AbstractProject;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.plugins.tfs.model.TeamRequestedResult;
import hudson.plugins.tfs.model.TeamResultType;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.Publisher;
import hudson.tasks.Recorder;
import hudson.util.DirScanner;
import hudson.util.io.Archiver;
import hudson.util.io.ArchiverFactory;
import jenkins.tasks.SimpleBuildStep;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
import javax.annotation.Nonnull;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
public class TeamCollectResultsPostBuildAction extends Recorder implements SimpleBuildStep {
private static final String TEAM_RESULTS = "team-results";
static final String TEAM_RESULTS_ZIP = "team-results.zip";
private List<TeamRequestedResult> requestedResults = new ArrayList<TeamRequestedResult>();
@DataBoundConstructor
public TeamCollectResultsPostBuildAction() {
}
public List<TeamRequestedResult> getRequestedResults() {
return requestedResults;
}
@DataBoundSetter
public void setRequestedResults(final List<TeamRequestedResult> requestedResults) {
this.requestedResults = requestedResults;
}
@Override
public void perform(
@Nonnull final Run<?, ?> run,
@Nonnull final FilePath workspace,
@Nonnull final Launcher launcher,
@Nonnull final TaskListener listener) throws InterruptedException, IOException {
// TODO: do we want to emit an error or warning like the following?
/*
if (requestedResults == null || requestedResults.size() == 0) {
final String template = "No results were requested. Aborting the '%s' post-build action.";
final String message = String.format(template, displayName);
listener.error(message);
return;
}
*/
final PrintStream logger = listener.getLogger();
logger.print("Recording results...");
final File rootDir = run.getRootDir();
final File resultsRoot = new File(rootDir, TEAM_RESULTS);
for (final TeamRequestedResult requestedResult : requestedResults) {
final TeamResultType teamResultType = requestedResult.getTeamResultType();
final String folderName = teamResultType.getFolderName();
logger.print(" " + teamResultType.getDisplayName());
final File resultFolder = new File(resultsRoot, folderName);
//noinspection ResultOfMethodCallIgnored
resultFolder.mkdirs();
final String includes = requestedResult.getIncludes();
final FilePath resultPath = new FilePath(resultFolder);
final int numCopied = workspace.copyRecursiveTo(includes, resultPath);
logger.print(" (" + numCopied + " file" + ((numCopied == 1) ? "" : "s") + ")");
}
logger.print(". Compressing...");
final ArchiverFactory zip = ArchiverFactory.ZIP;
final File resultsZipFile = new File(rootDir, TEAM_RESULTS_ZIP);
final FileOutputStream outputStream = new FileOutputStream(resultsZipFile);
try {
final Archiver archiver = zip.create(outputStream);
try {
final DirScanner scanner = new DirScanner.Glob(TEAM_RESULTS + "/**", null, false);
scanner.scan(rootDir, archiver);
}
finally {
IOUtils.closeQuietly(archiver);
}
}
finally {
IOUtils.closeQuietly(outputStream);
}
FileUtils.deleteDirectory(resultsRoot);
TeamResultsAction.addToRun(run);
logger.println(" Done.");
}
@Override
public DescriptorImpl getDescriptor() {
return (DescriptorImpl) super.getDescriptor();
}
@Override
public BuildStepMonitor getRequiredMonitorService() {
return BuildStepMonitor.NONE;
}
@Extension
public static class DescriptorImpl extends BuildStepDescriptor<Publisher> {
@Override
public boolean isApplicable(final Class<? extends AbstractProject> jobType) {
return true;
}
@Override
public String getDisplayName() {
return "Collect results for TFS/Team Services";
}
}
}