diff --git a/core/src/main/java/hudson/tasks/JavadocArchiver.java b/core/src/main/java/hudson/tasks/JavadocArchiver.java index 0d04efa75a..0c4e43d7f6 100644 --- a/core/src/main/java/hudson/tasks/JavadocArchiver.java +++ b/core/src/main/java/hudson/tasks/JavadocArchiver.java @@ -3,7 +3,6 @@ package hudson.tasks; import hudson.FilePath; import hudson.Launcher; import hudson.Util; -import hudson.maven.MavenModuleSet; import hudson.maven.AbstractMavenProject; import hudson.model.*; import hudson.util.FormFieldValidator; @@ -26,16 +25,25 @@ public class JavadocArchiver extends Publisher { * Path to the Javadoc directory in the workspace. */ private final String javadocDir; + /** + * If true, retain javadoc for all the successful builds. + */ + private final boolean keepAll; @DataBoundConstructor - public JavadocArchiver(String javadoc_dir) { + public JavadocArchiver(String javadoc_dir, boolean keep_all) { this.javadocDir = javadoc_dir; + this.keepAll = keep_all; } public String getJavadocDir() { return javadocDir; } + public boolean isKeepAll() { + return keepAll; + } + /** * Gets the directory where the Javadoc is stored for the given project. */ @@ -43,26 +51,40 @@ public class JavadocArchiver extends Publisher { return new File(project.getRootDir(),"javadoc"); } + /** + * Gets the directory where the Javadoc is stored for the given build. + */ + private static File getJavadocDir(Run run) { + return new File(run.getRootDir(),"javadoc"); + } + public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException { listener.getLogger().println(Messages.JavadocArchiver_Publishing()); FilePath javadoc = build.getParent().getWorkspace().child(javadocDir); - FilePath target = new FilePath(getJavadocDir(build.getParent())); + FilePath target = new FilePath(keepAll ? getJavadocDir(build) : getJavadocDir(build.getProject())); try { - // if the build has failed, then there's not much point in reporting an error - // saying javadoc directory doesn't exist. We want the user to focus on the real error, - // which is the build failure. - if(build.getResult().isWorseOrEqualTo(Result.FAILURE) && !javadoc.exists()) + if (javadoc.copyRecursiveTo("**/*",target)==0) { + if(build.getResult().isBetterOrEqualTo(Result.UNSTABLE)) { + // If the build failed, don't complain that there was no javadoc. + // The build probably didn't even get to the point where it produces javadoc. + listener.error(Messages.JavadocArchiver_NoMatchFound(javadoc)); + } + build.setResult(Result.FAILURE); return true; - - javadoc.copyRecursiveTo("**/*",target); + } } catch (IOException e) { Util.displayIOException(e,listener); e.printStackTrace(listener.fatalError(Messages.JavadocArchiver_UnableToCopy(javadoc,target))); build.setResult(Result.FAILURE); + return true; } - + + // add build action, if javadoc is recorded for each build + if(keepAll) + build.addAction(new JavadocBuildAction(build)); + return true; } @@ -74,29 +96,22 @@ public class JavadocArchiver extends Publisher { return DESCRIPTOR; } - public static final Descriptor DESCRIPTOR = new DescriptorImpl(); - public static class JavadocAction implements ProminentProjectAction { - private final AbstractItem project; - - public JavadocAction(AbstractItem project) { - this.project = project; - } - + protected static abstract class BaseJavadocAction implements Action { public String getUrlName() { return "javadoc"; } public String getDisplayName() { - if(new File(getJavadocDir(project),"help-doc.html").exists()) + if (new File(dir(), "help-doc.html").exists()) return Messages.JavadocArchiver_DisplayName_Javadoc(); else return Messages.JavadocArchiver_DisplayName_Generic(); } public String getIconFileName() { - if(getJavadocDir(project).exists()) + if(dir().exists()) return "help.gif"; else // hide it since we don't have javadoc yet. @@ -104,8 +119,58 @@ public class JavadocArchiver extends Publisher { } public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { - new DirectoryBrowserSupport(this,project.getDisplayName()+" javadoc") - .serveFile(req, rsp, new FilePath(getJavadocDir(project)), "help.gif", false); + new DirectoryBrowserSupport(this, getTitle()) + .serveFile(req, rsp, new FilePath(dir()), "help.gif", false); + } + + protected abstract String getTitle(); + + protected abstract File dir(); + } + + public static class JavadocAction extends BaseJavadocAction implements ProminentProjectAction { + private final AbstractItem project; + + public JavadocAction(AbstractItem project) { + this.project = project; + } + + protected File dir() { + // Would like to change AbstractItem to AbstractProject, but is + // that a backwards compatible change? + if (project instanceof AbstractProject) { + AbstractProject abstractProject = (AbstractProject) project; + + Run run = abstractProject.getLastSuccessfulBuild(); + if (run != null) { + File javadocDir = getJavadocDir(run); + + if (javadocDir.exists()) + return javadocDir; + } + } + + return getJavadocDir(project); + } + + protected String getTitle() { + return project.getDisplayName()+" javadoc"; + } + } + + public static class JavadocBuildAction extends BaseJavadocAction { + private final AbstractBuild build; + + public JavadocBuildAction(AbstractBuild build) { + this.build = build; + } + + protected String getTitle() { + return build.getDisplayName()+" javadoc"; + } + + protected File dir() { + return getJavadocDir(build); } } diff --git a/core/src/main/resources/hudson/tasks/JavadocArchiver/config.jelly b/core/src/main/resources/hudson/tasks/JavadocArchiver/config.jelly index e187dec39e..7dfbde14ed 100644 --- a/core/src/main/resources/hudson/tasks/JavadocArchiver/config.jelly +++ b/core/src/main/resources/hudson/tasks/JavadocArchiver/config.jelly @@ -4,4 +4,8 @@ + + + + \ No newline at end of file diff --git a/core/src/main/resources/hudson/tasks/JavadocArchiver/config.properties b/core/src/main/resources/hudson/tasks/JavadocArchiver/config.properties index 7cf08b4f3f..d4d1f65f3d 100644 --- a/core/src/main/resources/hudson/tasks/JavadocArchiver/config.properties +++ b/core/src/main/resources/hudson/tasks/JavadocArchiver/config.properties @@ -1 +1,2 @@ -description=Directory relative to the root of the workspace, such as 'myproject/build/javadoc' \ No newline at end of file +description=Directory relative to the root of the workspace, such as 'myproject/build/javadoc' +keepAll=Keep javadoc output for all successful builds \ No newline at end of file diff --git a/core/src/main/resources/hudson/tasks/Messages.properties b/core/src/main/resources/hudson/tasks/Messages.properties index d438ae5874..8e7a7243ae 100644 --- a/core/src/main/resources/hudson/tasks/Messages.properties +++ b/core/src/main/resources/hudson/tasks/Messages.properties @@ -40,6 +40,7 @@ Fingerprinter.Recording=Recording fingerprints JavadocArchiver.DisplayName=Publish Javadoc JavadocArchiver.DisplayName.Generic=Document JavadocArchiver.DisplayName.Javadoc=Javadoc +JavadocArchiver.NoMatchFound=No javadoc found in {0} JavadocArchiver.Publishing=Publishing Javadoc JavadocArchiver.UnableToCopy=Unable to copy Javadoc from {0} to {1} diff --git a/war/resources/help/project-config/javadoc-keep-all.html b/war/resources/help/project-config/javadoc-keep-all.html new file mode 100644 index 0000000000..f150c63628 --- /dev/null +++ b/war/resources/help/project-config/javadoc-keep-all.html @@ -0,0 +1,9 @@ +
+ If you check this option, Hudson will retain javadoc for each successful build. + This allows you to browser javadoc for older builds, at the expense of additional + disk space requirement. + +

+ If you leave this optoin unchecked, Hudson will only keep the latest javadoc, + so older javadoc will be overwritten as new builds succeed. +

\ No newline at end of file