From ac7b10b23c9b730e7fe353882ebed804fa98640d Mon Sep 17 00:00:00 2001 From: kohsuke Date: Thu, 1 Feb 2007 06:13:07 +0000 Subject: [PATCH] adding fingerprint support for maven. git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@2008 71c3de6d-444a-0410-be80-ed276b4c234a --- .../java/hudson/maven/MavenReporters.java | 6 +- .../maven/reporters/MavenFingerprinter.java | 127 ++++++++++++++++++ .../main/java/hudson/tasks/Fingerprinter.java | 15 ++- 3 files changed, 141 insertions(+), 7 deletions(-) create mode 100644 core/src/main/java/hudson/maven/reporters/MavenFingerprinter.java diff --git a/core/src/main/java/hudson/maven/MavenReporters.java b/core/src/main/java/hudson/maven/MavenReporters.java index 11f199557e..e77ede19d9 100644 --- a/core/src/main/java/hudson/maven/MavenReporters.java +++ b/core/src/main/java/hudson/maven/MavenReporters.java @@ -2,6 +2,7 @@ package hudson.maven; import hudson.model.Descriptor; import hudson.maven.reporters.MavenArtifactArchiver; +import hudson.maven.reporters.MavenFingerprinter; import java.util.List; @@ -13,7 +14,8 @@ public final class MavenReporters { /** * List of all installed {@link MavenReporter}s. */ - public static final List LIST = Descriptor.toList( - MavenArtifactArchiver.DescriptorImpl.DESCRIPTOR + public static final List LIST = Descriptor.toList( + MavenArtifactArchiver.DescriptorImpl.DESCRIPTOR, + MavenFingerprinter.DescriptorImpl.DESCRIPTOR ); } diff --git a/core/src/main/java/hudson/maven/reporters/MavenFingerprinter.java b/core/src/main/java/hudson/maven/reporters/MavenFingerprinter.java new file mode 100644 index 0000000000..01f81f4aa2 --- /dev/null +++ b/core/src/main/java/hudson/maven/reporters/MavenFingerprinter.java @@ -0,0 +1,127 @@ +package hudson.maven.reporters; + +import hudson.maven.MavenReporter; +import hudson.maven.MavenBuildProxy; +import hudson.maven.MavenReporterDescriptor; +import hudson.maven.MavenModule; +import hudson.maven.MojoInfo; +import hudson.maven.MavenBuild; +import hudson.maven.MavenBuildProxy.BuildCallable; +import hudson.model.BuildListener; +import hudson.model.FingerprintMap; +import hudson.model.Hudson; +import hudson.FilePath; +import hudson.tasks.Fingerprinter.FingerprintAction; +import org.kohsuke.stapler.StaplerRequest; +import org.apache.maven.project.MavenProject; +import org.apache.maven.artifact.Artifact; + +import java.io.IOException; +import java.io.File; +import java.util.Set; +import java.util.HashSet; +import java.util.Collection; +import java.util.Map; +import java.util.HashMap; + +/** + * Records fingerprints of the builds to keep track of dependencies. + * + * @author Kohsuke Kawaguchi + */ +public class MavenFingerprinter extends MavenReporter { + + /** + * Files whose fingerprints were already recorded. + */ + private transient Set files; + /** + * Recorded fingerprints. + */ + private transient Map record; + + public boolean preBuild(MavenBuildProxy build, MavenProject pom, BuildListener listener) throws InterruptedException, IOException { + files = new HashSet(); + record = new HashMap(); + return true; + } + + public boolean postExecute(MavenBuildProxy build, MavenProject pom, MojoInfo mojo, BuildListener listener) throws InterruptedException, IOException { + // really nice if we can do this in preExecute, + // but dependency resolution only happens after preExecute. + record(build,false,pom.getArtifacts()); + + // try to pick up artifacts as soon as they are found. + record(build,true,pom.getArtifact()); + record(build,true,pom.getAttachedArtifacts()); + + return true; + } + + private void record(MavenBuildProxy build, boolean produced, Collection artifacts) throws IOException, InterruptedException { + for (Artifact a : artifacts) + record(build,produced,a); + } + + /** + * Records the fingerprint of the given {@link Artifact}. + * + *

+ * This method contains the logic to avoid doubly recording the fingerprint + * of the same file. + */ + private void record(MavenBuildProxy build, final boolean produced, Artifact a) throws IOException, InterruptedException { + File f = a.getFile(); + if(f==null || !files.add(f)) + return; + + // new file + final String digest = new FilePath(f).digest(); + final String name = a.getGroupId()+':'+f.getName(); + record.put(name,digest); + + build.execute(new BuildCallable() { + public Void call(MavenBuild build) throws IOException, InterruptedException { + FingerprintMap map = Hudson.getInstance().getFingerprintMap(); + map.getOrCreate(produced?build:null, name, digest); + return null; + } + }); + } + + public boolean postBuild(MavenBuildProxy build, MavenProject pom, BuildListener listener) throws InterruptedException, IOException { + if(!record.isEmpty()) { + build.execute(new BuildCallable() { + public Void call(MavenBuild build) throws IOException, InterruptedException { + build.getActions().add(new FingerprintAction(build,record)); + return null; + } + }); + } + return true; + } + + public DescriptorImpl getDescriptor() { + return DescriptorImpl.DESCRIPTOR; + } + + public static final class DescriptorImpl extends MavenReporterDescriptor { + public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl(); + + private DescriptorImpl() { + super(MavenFingerprinter.class); + } + + public String getDisplayName() { + return "Record fingerprints"; + } + + public MavenFingerprinter newInstance(StaplerRequest req) throws FormException { + return new MavenFingerprinter(); + } + + public MavenReporter newAutoInstance(MavenModule module) { + return new MavenFingerprinter(); + } + } +} diff --git a/core/src/main/java/hudson/tasks/Fingerprinter.java b/core/src/main/java/hudson/tasks/Fingerprinter.java index 0646654b43..d402757f5a 100644 --- a/core/src/main/java/hudson/tasks/Fingerprinter.java +++ b/core/src/main/java/hudson/tasks/Fingerprinter.java @@ -13,6 +13,8 @@ import hudson.model.FingerprintMap; import hudson.model.Hudson; import hudson.model.Project; import hudson.model.Result; +import hudson.model.AbstractBuild; +import hudson.model.AbstractProject; import hudson.remoting.VirtualChannel; import hudson.util.IOException2; import org.apache.tools.ant.DirectoryScanner; @@ -185,13 +187,16 @@ public class Fingerprinter extends Publisher implements Serializable { * Action for displaying fingerprints. */ public static final class FingerprintAction implements Action { - private final Build build; + private final AbstractBuild build; + /** + * From file name to the digest. + */ private final Map record; private transient WeakReference> ref; - public FingerprintAction(Build build, Map record) { + public FingerprintAction(AbstractBuild build, Map record) { this.build = build; this.record = record; } @@ -208,7 +213,7 @@ public class Fingerprinter extends Publisher implements Serializable { return "fingerprints"; } - public Build getBuild() { + public AbstractBuild getBuild() { return build; } @@ -242,8 +247,8 @@ public class Fingerprinter extends Publisher implements Serializable { * Gets the dependency to other builds in a map. * Returns build numbers instead of {@link Build}, since log records may be gone. */ - public Map getDependencies() { - Map r = new HashMap(); + public Map getDependencies() { + Map r = new HashMap(); for (Fingerprint fp : getFingerprints().values()) { BuildPtr bp = fp.getOriginal(); -- GitLab