示例#1
0
  @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;
  }
示例#2
0
  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];
   }
 }
示例#4
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;
 }
示例#6
0
  /**
   * 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;
  }