@Override public boolean checkout( @SuppressWarnings("rawtypes") final AbstractBuild build, final Launcher launcher, final FilePath workspace, final BuildListener listener, final File changelogFile) throws IOException, InterruptedException { FilePath repoDir; if (destinationDir != null) { repoDir = workspace.child(destinationDir); if (!repoDir.isDirectory()) { repoDir.mkdirs(); } } else { repoDir = workspace; } if (!checkoutCode(launcher, repoDir, listener.getLogger())) { return false; } final String manifest = getStaticManifest(launcher, repoDir, listener.getLogger()); final RevisionState currentState = new RevisionState(manifest, manifestBranch, listener.getLogger()); build.addAction(currentState); final RevisionState previousState = getLastState(build.getPreviousBuild()); ChangeLog.saveChangeLog(currentState, previousState, changelogFile, launcher, repoDir); build.addAction(new TagAction(build)); return true; }
private boolean createTag( String tagName, TaskListener listener, File destdir, String moduleLocalDir, String module, boolean isFlatten) throws IOException, InterruptedException { FilePath path = (isFlatten ? new FilePath(destdir).child(module) : new FilePath(destdir).child(moduleLocalDir).child(module)); boolean isDir = path.isDirectory(); ArgumentListBuilder cmd = new ArgumentListBuilder(); cmd.add(scmInstance.getDescriptor().getCvsExeOrDefault(), "tag"); if (isDir) { cmd.add("-R"); } cmd.add(tagName); if (!isDir) { cmd.add(path.getName()); path = path.getParent(); } if (!scmInstance.run(new Launcher.LocalLauncher(listener), cmd, listener, path)) { listener.getLogger().println(Messages.CVSSCM_TaggingFailed()); return false; } return true; }
protected static FilePath[] getEmmaReports(File file) throws IOException, InterruptedException { FilePath path = new FilePath(file); if (path.isDirectory()) { return path.list("*xml"); } else { // Read old builds (before 1.11) FilePath report = new FilePath(new File(path.getName() + ".xml")); return report.exists() ? new FilePath[] {report} : new FilePath[0]; } }
@Override protected PollingResult compareRemoteRevisionWith( final AbstractProject<?, ?> project, final Launcher launcher, final FilePath workspace, final TaskListener listener, final SCMRevisionState baseline) throws IOException, InterruptedException { SCMRevisionState myBaseline = baseline; if (myBaseline == null) { // Probably the first build, or possibly an aborted build. myBaseline = getLastState(project.getLastBuild()); if (myBaseline == null) { return PollingResult.BUILD_NOW; } } FilePath repoDir; if (destinationDir != null) { repoDir = workspace.child(destinationDir); if (!repoDir.isDirectory()) { repoDir.mkdirs(); } } else { repoDir = workspace; } if (!checkoutCode(launcher, repoDir, listener.getLogger())) { // Some error occurred, try a build now so it gets logged. return new PollingResult(myBaseline, myBaseline, Change.INCOMPARABLE); } final RevisionState currentState = new RevisionState( getStaticManifest(launcher, repoDir, listener.getLogger()), manifestBranch, listener.getLogger()); final Change change; if (currentState.equals(myBaseline)) { change = Change.NONE; } else { change = Change.SIGNIFICANT; } return new PollingResult(myBaseline, currentState, change); }
/** Checks for progress or completion of the external task. */ CheckResult check() { try { Computer c = Jenkins.getInstance().getComputer(node); if (c == null) { LOGGER.log(Level.FINE, "no such computer {0}", node); return CheckResult.NO_CHANGE; } if (c.isOffline()) { LOGGER.log(Level.FINE, "{0} is offline", node); return CheckResult.NO_CHANGE; } FilePath ws = new FilePath(c.getChannel(), remote); if (!ws.isDirectory()) { error = new AbortException("missing workspace " + remote + " on " + node); return CheckResult.DONE; } TaskListener listener = context.get(TaskListener.class); boolean wrote = controller.writeLog(ws, listener.getLogger()); Integer exitCode = controller.exitStatus(ws); if (exitCode == null) { LOGGER.log(Level.FINE, "still running in {0} on {1}", new Object[] {remote, node}); return wrote ? CheckResult.UPDATED : CheckResult.NO_CHANGE; } else if (exitCode == 0) { result = exitCode; // TODO could add an option to have this be text output from command } else { error = new AbortException("script returned exit code " + exitCode); } controller.cleanup(ws); return CheckResult.DONE; } catch (IOException x) { error = x; } catch (InterruptedException x) { error = x; } return CheckResult.DONE; }
/** * Serves a file from the file system (Maps the URL to a directory in a file system.) * * @param icon The icon file name, like "folder-open.gif" * @param serveDirIndex True to generate the directory index. False to serve "index.html" * @deprecated as of 1.297 Instead of calling this method explicitly, just return the {@link * DirectoryBrowserSupport} object from the {@code doXYZ} method and let Stapler generate a * response for you. */ public void serveFile( StaplerRequest req, StaplerResponse rsp, FilePath root, String icon, boolean serveDirIndex) throws IOException, ServletException, InterruptedException { // handle form submission String pattern = req.getParameter("pattern"); if (pattern == null) pattern = req.getParameter("path"); // compatibility with Hudson<1.129 if (pattern != null) { rsp.sendRedirect2(pattern); return; } String path = getPath(req); if (path.replace('\\', '/').indexOf("/../") != -1) { // don't serve anything other than files in the artifacts dir rsp.sendError(HttpServletResponse.SC_BAD_REQUEST); return; } // split the path to the base directory portion "abc/def/ghi" which doesn't include any // wildcard, // and the GLOB portion "**/*.xml" (the rest) StringBuilder _base = new StringBuilder(); StringBuilder _rest = new StringBuilder(); int restSize = -1; // number of ".." needed to go back to the 'base' level. boolean zip = false; // if we are asked to serve a zip file bundle boolean plain = false; // if asked to serve a plain text directory listing { boolean inBase = true; StringTokenizer pathTokens = new StringTokenizer(path, "/"); while (pathTokens.hasMoreTokens()) { String pathElement = pathTokens.nextToken(); // Treat * and ? as wildcard unless they match a literal filename if ((pathElement.contains("?") || pathElement.contains("*")) && inBase && !(new FilePath(root, (_base.length() > 0 ? _base + "/" : "") + pathElement) .exists())) inBase = false; if (pathElement.equals("*zip*")) { // the expected syntax is foo/bar/*zip*/bar.zip // the last 'bar.zip' portion is to causes browses to set a good default file name. // so the 'rest' portion ends here. zip = true; break; } if (pathElement.equals("*plain*")) { plain = true; break; } StringBuilder sb = inBase ? _base : _rest; if (sb.length() > 0) sb.append('/'); sb.append(pathElement); if (!inBase) restSize++; } } restSize = Math.max(restSize, 0); String base = _base.toString(); String rest = _rest.toString(); // this is the base file/directory FilePath baseFile = new FilePath(root, base); if (baseFile.isDirectory()) { if (zip) { rsp.setContentType("application/zip"); baseFile.zip(rsp.getOutputStream(), rest); return; } if (plain) { rsp.setContentType("text/plain;charset=UTF-8"); OutputStream os = rsp.getOutputStream(); try { for (String kid : baseFile.act(new SimpleChildList())) { os.write(kid.getBytes("UTF-8")); os.write('\n'); } os.flush(); } finally { os.close(); } return; } if (rest.length() == 0) { // if the target page to be displayed is a directory and the path doesn't end with '/', // redirect StringBuffer reqUrl = req.getRequestURL(); if (reqUrl.charAt(reqUrl.length() - 1) != '/') { rsp.sendRedirect2(reqUrl.append('/').toString()); return; } } FileCallable<List<List<Path>>> glob = null; if (rest.length() > 0) { // the rest is Ant glob pattern glob = new PatternScanner(rest, createBackRef(restSize)); } else if (serveDirIndex) { // serve directory index glob = new ChildPathBuilder(); } if (glob != null) { // serve glob req.setAttribute("it", this); List<Path> parentPaths = buildParentPath(base, restSize); req.setAttribute("parentPath", parentPaths); req.setAttribute("backPath", createBackRef(restSize)); req.setAttribute("topPath", createBackRef(parentPaths.size() + restSize)); req.setAttribute("files", baseFile.act(glob)); req.setAttribute("icon", icon); req.setAttribute("path", path); req.setAttribute("pattern", rest); req.setAttribute("dir", baseFile); req.getView(this, "dir.jelly").forward(req, rsp); return; } // convert a directory service request to a single file service request by serving // 'index.html' baseFile = baseFile.child(indexFileName); } // serve a single file if (!baseFile.exists()) { rsp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } boolean view = rest.equals("*view*"); if (rest.equals("*fingerprint*")) { rsp.forward(Hudson.getInstance().getFingerprint(baseFile.digest()), "/", req); return; } ContentInfo ci = baseFile.act(new ContentInfo()); if (LOGGER.isLoggable(Level.FINE)) LOGGER.fine( "Serving " + baseFile + " with lastModified=" + ci.lastModified + ", contentLength=" + ci.contentLength); InputStream in = baseFile.read(); if (view) { // for binary files, provide the file name for download rsp.setHeader("Content-Disposition", "inline; filename=" + baseFile.getName()); // pseudo file name to let the Stapler set text/plain rsp.serveFile(req, in, ci.lastModified, -1, ci.contentLength, "plain.txt"); } else { rsp.serveFile(req, in, ci.lastModified, -1, ci.contentLength, baseFile.getName()); } }
/** {@inheritDoc} */ @Override public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { Result threshold = onlyStable ? Result.SUCCESS : Result.UNSTABLE; if (build.getResult().isWorseThan(threshold)) { listener .getLogger() .println( "Skipping Cobertura coverage report as build was not " + threshold.toString() + " or better ..."); return true; } listener.getLogger().println("[Cobertura] Publishing Cobertura coverage report..."); final FilePath[] moduleRoots = build.getModuleRoots(); final boolean multipleModuleRoots = moduleRoots != null && moduleRoots.length > 1; final FilePath moduleRoot = multipleModuleRoots ? build.getWorkspace() : build.getModuleRoot(); final File buildCoberturaDir = build.getRootDir(); FilePath buildTarget = new FilePath(buildCoberturaDir); FilePath[] reports = new FilePath[0]; try { reports = moduleRoot.act(new ParseReportCallable(coberturaReportFile)); // if the build has failed, then there's not // much point in reporting an error if (build.getResult().isWorseOrEqualTo(Result.FAILURE) && reports.length == 0) { return true; } } catch (IOException e) { Util.displayIOException(e, listener); e.printStackTrace(listener.fatalError("Unable to find coverage results")); build.setResult(Result.FAILURE); } if (reports.length == 0) { String msg = "[Cobertura] No coverage results were found using the pattern '" + coberturaReportFile + "' relative to '" + moduleRoot.getRemote() + "'." + " Did you enter a pattern relative to the correct directory?" + " Did you generate the XML report(s) for Cobertura?"; listener.getLogger().println(msg); if (failNoReports) { build.setResult(Result.FAILURE); } else { listener.getLogger().println("[Cobertura] Skipped cobertura reports."); } return true; } for (int i = 0; i < reports.length; i++) { final FilePath targetPath = new FilePath(buildTarget, "coverage" + (i == 0 ? "" : i) + ".xml"); try { reports[i].copyTo(targetPath); } catch (IOException e) { Util.displayIOException(e, listener); e.printStackTrace( listener.fatalError( "Unable to copy coverage from " + reports[i] + " to " + buildTarget)); build.setResult(Result.FAILURE); } } listener.getLogger().println("Publishing Cobertura coverage results..."); Set<String> sourcePaths = new HashSet<String>(); CoverageResult result = null; for (File coberturaXmlReport : getCoberturaReports(build)) { try { result = CoberturaCoverageParser.parse(coberturaXmlReport, result, sourcePaths); } catch (IOException e) { Util.displayIOException(e, listener); e.printStackTrace(listener.fatalError("Unable to parse " + coberturaXmlReport)); build.setResult(Result.FAILURE); } } if (result != null) { listener.getLogger().println("Cobertura coverage report found."); result.setOwner(build); final FilePath paintedSourcesPath = new FilePath(new File(build.getProject().getRootDir(), "cobertura")); paintedSourcesPath.mkdirs(); if (sourcePaths.contains(".")) { sourcePaths.remove("."); for (FilePath f : reports) { FilePath p = f.getParent(); if (p != null && p.isDirectory()) { sourcePaths.add(p.getRemote()); } } } SourceCodePainter painter = new SourceCodePainter( paintedSourcesPath, sourcePaths, result.getPaintedSources(), listener, getSourceEncoding()); moduleRoot.act(painter); final CoberturaBuildAction action = CoberturaBuildAction.load( build, result, healthyTarget, unhealthyTarget, getOnlyStable(), getFailUnhealthy(), getFailUnstable(), getAutoUpdateHealth(), getAutoUpdateStability()); build.getActions().add(action); Set<CoverageMetric> failingMetrics = failingTarget.getFailingMetrics(result); if (!failingMetrics.isEmpty()) { listener.getLogger().println("Code coverage enforcement failed for the following metrics:"); float oldStabilityPercent; float setStabilityPercent; for (CoverageMetric metric : failingMetrics) { oldStabilityPercent = failingTarget.getObservedPercent(result, metric); setStabilityPercent = failingTarget.getSetPercent(result, metric); listener .getLogger() .println( " " + metric.getName() + "'s stability is " + roundDecimalFloat(oldStabilityPercent * 100f) + " and set mininum stability is " + roundDecimalFloat(setStabilityPercent * 100f) + "."); } if (!getFailUnstable()) { listener.getLogger().println("Setting Build to unstable."); build.setResult(Result.UNSTABLE); } else { listener.getLogger().println("Failing build due to unstability."); build.setResult(Result.FAILURE); } } if (getFailUnhealthy()) { Set<CoverageMetric> unhealthyMetrics = unhealthyTarget.getFailingMetrics(result); if (!unhealthyMetrics.isEmpty()) { listener.getLogger().println("Unhealthy for the following metrics:"); float oldHealthyPercent; float setHealthyPercent; for (CoverageMetric metric : unhealthyMetrics) { oldHealthyPercent = unhealthyTarget.getObservedPercent(result, metric); setHealthyPercent = unhealthyTarget.getSetPercent(result, metric); listener .getLogger() .println( " " + metric.getName() + "'s health is " + roundDecimalFloat(oldHealthyPercent * 100f) + " and set minimum health is " + roundDecimalFloat(setHealthyPercent * 100f) + "."); } listener.getLogger().println("Failing build because it is unhealthy."); build.setResult(Result.FAILURE); } } if (build.getResult() == Result.SUCCESS) { if (getAutoUpdateHealth()) { setNewPercentages(result, true, listener); } if (getAutoUpdateStability()) { setNewPercentages(result, false, listener); } } } else { listener .getLogger() .println( "No coverage results were successfully parsed. Did you generate " + "the XML report(s) for Cobertura?"); build.setResult(Result.FAILURE); } return true; }