Permalink
Browse files

Merge pull request #1 from samskivert/master

Added support for maven-metadata.xml so that snapshots work with Maven 3.
  • Loading branch information...
2 parents ab5001a + 88e30c2 commit 90a61beb2b2b9d284e9a11879704e83b56d06236 @magnayn committed Oct 8, 2011
@@ -41,17 +41,23 @@
public class ArtifactRepositoryItem implements RepositoryContent {
private MavenArtifact artifact;
- private RepositoryDirectory directory;
private MavenBuild build;
+ private boolean timestampedSnapshot;
+ private RepositoryDirectory directory;
- public ArtifactRepositoryItem(MavenBuild build, MavenArtifact mavenArtifact)
- {
+ public ArtifactRepositoryItem(MavenBuild build, MavenArtifact mavenArtifact, boolean timestampedSnapshot) {
this.artifact = mavenArtifact;
- this.build = build;
+ this.build = build;
+ this.timestampedSnapshot = timestampedSnapshot;
}
public String getName() {
- return artifact.canonicalName;
+ if (timestampedSnapshot && artifact.version.endsWith("-SNAPSHOT")) {
+ String vers = MetadataRepositoryItem.formatDateVersion(getLastModified(), build.getNumber());
+ return artifact.canonicalName.replaceAll("SNAPSHOT", vers);
+ } else {
+ return artifact.canonicalName;
+ }
}
public RepositoryDirectory getParent() {
@@ -83,8 +89,16 @@ public String getDescription() {
return "From Build #" + build.getNumber() + " of " + build.getParentBuild().getParent().getName();
}
- public File getFile()
- {
+ public boolean fileExists() {
+ try {
+ getFile();
+ return true;
+ } catch (IllegalStateException ise) {
+ return false;
+ }
+ }
+
+ public File getFile() {
File fPath = new File(new File(new File(build.getArtifactsDir(), artifact.groupId), artifact.artifactId), artifact.version);
File fArtifact;
@@ -104,13 +118,11 @@ public File getFile()
* The path that the artifact believes it belongs to.
* @return
*/
- public String getArtifactPath()
- {
- return artifact.groupId.replace('.','/') + "/" + artifact.artifactId + '/' + artifact.version + "/" + artifact.canonicalName;
+ public String getArtifactPath() {
+ return artifact.groupId.replace('.','/') + "/" + artifact.artifactId + '/' + artifact.version + "/" + getName();
}
- public String getContentType()
- {
+ public String getContentType() {
return null;
}
}
@@ -0,0 +1,69 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2011, Nigel Magnay / NiRiMa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.nirima.jenkins.repo.build;
+
+import hudson.maven.MavenBuild;
+import hudson.maven.reporters.MavenArtifact;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Date;
+
+/**
+ * Represent a {@code maven-metadata.xml} file.
+ */
+public class MetadataChecksumRepositoryItem extends TextRepositoryItem {
+
+ private String algorithm;
+ private MetadataRepositoryItem item;
+
+ public MetadataChecksumRepositoryItem(String algorithm, MetadataRepositoryItem item) {
+ this.algorithm = algorithm;
+ this.item = item;
+ }
+
+ public String getName() {
+ return "maven-metadata.xml." + algorithm.toLowerCase();
+ }
+
+ public Date getLastModified() {
+ return item.getLastModified();
+ }
+
+ public String getDescription() {
+ return item.getDescription();
+ }
+
+ protected String generateContent() {
+ try {
+ MessageDigest md = MessageDigest.getInstance(algorithm.toUpperCase());
+ byte[] digest = md.digest(item.generateContent().getBytes());
+ String hex = new BigInteger(1, digest).toString(16);
+ return (hex.length() % 2 == 0) ? hex : ("0" + hex);
+ } catch (NoSuchAlgorithmException nsae) {
+ return "";
+ }
+ }
+}
@@ -0,0 +1,106 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2011, Nigel Magnay / NiRiMa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.nirima.jenkins.repo.build;
+
+import hudson.maven.MavenBuild;
+import hudson.maven.reporters.MavenArtifact;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Represents a {@code maven-metadata.xml} file.
+ */
+public class MetadataRepositoryItem extends TextRepositoryItem {
+
+ private MavenBuild build;
+ private String groupId, artifactId, version;
+ private Map<String,ArtifactRepositoryItem> items = new HashMap<String,ArtifactRepositoryItem>();
+
+ public static String formatDateVersion(Date date, int buildNo) {
+ return _vfmt.format(date) + "-" + buildNo;
+ }
+
+ public MetadataRepositoryItem(MavenBuild build, MavenArtifact artifact) {
+ this.build = build;
+ this.groupId = artifact.groupId;
+ this.artifactId = artifact.artifactId;
+ this.version = artifact.version;
+ }
+
+ public String getPath() {
+ return groupId.replace('.','/') + "/" + artifactId + "/" + version + "/" + getName();
+ }
+
+ public void addArtifact(MavenArtifact artifact, ArtifactRepositoryItem item) {
+ this.items.put(artifact.type, item);
+ }
+
+ public String getName() {
+ return "maven-metadata.xml";
+ }
+
+ public Date getLastModified() {
+ long lastModified = 0L;
+ for (ArtifactRepositoryItem item : items.values()) {
+ lastModified = Math.max(lastModified, item.getLastModified().getTime());
+ }
+ return new Date(lastModified);
+ }
+
+ public String getDescription() {
+ return "From Build #" + build.getNumber() + " of " + build.getParentBuild().getParent().getName();
+ }
+
+ @Override
+ protected String generateContent() {
+ StringBuilder buf = new StringBuilder();
+ buf.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ buf.append("<metadata modelVersion=\"1.1.0\">\n");
+ buf.append(" <groupId>" + groupId + "</groupId>\n");
+ buf.append(" <artifactId>" + artifactId + "</artifactId>\n");
+ buf.append(" <version>" + version + "</version>\n");
+ buf.append(" <versioning>\n");
+ buf.append(" <snapshotVersions>\n");
+ for (Map.Entry<String,ArtifactRepositoryItem> entry : items.entrySet()) {
+ String dateVers = formatDateVersion(entry.getValue().getLastModified(), build.getNumber());
+ String itemVersion = version.replaceAll("SNAPSHOT", dateVers);
+ String lastMod = _ufmt.format(entry.getValue().getLastModified());
+ buf.append(" <snapshotVersion>\n");
+ buf.append(" <extension>").append(entry.getKey()).append("</extension>\n");
+ buf.append(" <value>").append(itemVersion).append("</value>\n");
+ buf.append(" <updated>").append(lastMod).append("</updated>\n");
+ buf.append(" </snapshotVersion>\n");
+ }
+ buf.append(" </snapshotVersions>\n");
+ buf.append(" </versioning>\n");
+ buf.append("</metadata>\n");
+ return buf.toString();
+ }
+
+ protected static SimpleDateFormat _ufmt = new SimpleDateFormat("yyyyMMddHHmmss");
+ protected static SimpleDateFormat _vfmt = new SimpleDateFormat("yyyyMMdd.HHmmss");
+}
@@ -0,0 +1,66 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2011, Nigel Magnay / NiRiMa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.nirima.jenkins.repo.build;
+
+import com.nirima.jenkins.repo.RepositoryContent;
+import com.nirima.jenkins.repo.RepositoryDirectory;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+/**
+ * A repository item that generates text on the fly.
+ */
+public abstract class TextRepositoryItem implements RepositoryContent {
+
+ private RepositoryDirectory directory;
+
+ public RepositoryDirectory getParent() {
+ return directory;
+ }
+
+ public void setParent(RepositoryDirectory parent)
+ {
+ this.directory = parent;
+ }
+
+ public String getPath() {
+ return directory.getPath() + "/" + getName();
+ }
+
+ public InputStream getContent() throws Exception {
+ return new ByteArrayInputStream(generateContent().getBytes());
+ }
+
+ public Long getSize() {
+ return (long)generateContent().length();
+ }
+
+ public String getContentType()
+ {
+ return "text/plain";
+ }
+
+ protected abstract String generateContent();
+}
@@ -23,17 +23,18 @@
*/
package com.nirima.jenkins.repo.util;
-import com.nirima.jenkins.repo.RepositoryDirectory;
import com.nirima.jenkins.repo.build.ArtifactRepositoryItem;
import com.nirima.jenkins.repo.build.DirectoryRepositoryItem;
+import com.nirima.jenkins.repo.build.MetadataChecksumRepositoryItem;
+import com.nirima.jenkins.repo.build.MetadataRepositoryItem;
import hudson.maven.MavenBuild;
import hudson.maven.MavenModule;
import hudson.maven.MavenModuleSetBuild;
import hudson.maven.reporters.MavenArtifact;
import hudson.maven.reporters.MavenArtifactRecord;
import hudson.model.Run;
-import java.util.List;
+import java.util.HashMap;
import java.util.Map;
/**
@@ -50,9 +51,36 @@ public DirectoryPopulatorVisitor(DirectoryRepositoryItem root, boolean allowOver
this.allowOverwrite = allowOverwrite;
}
- public @Override void visitArtifact(MavenBuild build, MavenArtifact mavenArtifact)
+ public @Override void visitArtifact(MavenBuild build, MavenArtifact artifact)
{
- ArtifactRepositoryItem repositoryItem = new ArtifactRepositoryItem(build, mavenArtifact);
+ // add a Maven 2 compatible artifact entry
+ ArtifactRepositoryItem repositoryItem = new ArtifactRepositoryItem(build, artifact, false);
+ if (!repositoryItem.fileExists()) {
+ return; // skip this artifact, its file was purged
+ }
root.insert(repositoryItem, repositoryItem.getArtifactPath(), allowOverwrite);
+
+ // if this is a snapshot, also add a Maven 3 compatible artifact entry
+ if (artifact.version.endsWith("-SNAPSHOT")) {
+ ArtifactRepositoryItem item = new ArtifactRepositoryItem(build, artifact, true);
+ root.insert(item, item.getArtifactPath(), allowOverwrite);
+
+ // add metadata for this artifact version
+ String key = artifact.groupId + ":" + artifact.artifactId + ":" + artifact.version;
+ MetadataRepositoryItem meta = metadata.get(key);
+ if (meta == null) {
+ metadata.put(key, meta = new MetadataRepositoryItem(build, artifact));
+ root.insert(meta, meta.getPath(), allowOverwrite);
+ // add checksums for the item as well
+ root.insert(new MetadataChecksumRepositoryItem("md5", meta),
+ meta.getPath() + ".md5", allowOverwrite);
+ root.insert(new MetadataChecksumRepositoryItem("sha1", meta),
+ meta.getPath() + ".sha1", allowOverwrite);
+ }
+ meta.addArtifact(artifact, item);
+ }
}
+
+ private Map<String,MetadataRepositoryItem> metadata =
+ new HashMap<String,MetadataRepositoryItem>();
}

0 comments on commit 90a61be

Please sign in to comment.