diff --git a/pom.xml b/pom.xml index d43989d..5052036 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.jvnet.hudson.plugins plugin - 1.351 + 1.382 ../pom.xml diff --git a/src/main/java/hudson/plugins/bazaar/BazaarAffectedFile.java b/src/main/java/hudson/plugins/bazaar/BazaarAffectedFile.java new file mode 100644 index 0000000..dbd646c --- /dev/null +++ b/src/main/java/hudson/plugins/bazaar/BazaarAffectedFile.java @@ -0,0 +1,49 @@ +package hudson.plugins.bazaar; + +import hudson.scm.ChangeLogSet; +import hudson.scm.EditType; + +/** + * {@link ChangeLogSet.AffectedFile} for Bazaar. + * + * @author Alexandre Garnier + */ +public class BazaarAffectedFile implements ChangeLogSet.AffectedFile { + + private BazaarChangeSet changeSet; + private EditType editType; + private String oldPath; + private String path; + private String fileId; + + public BazaarAffectedFile(EditType editType, String oldPath, String path, String fileId) { + this.editType = editType; + this.oldPath = oldPath; + this.path = path; + this.fileId = fileId; + } + + public void setChangeSet(BazaarChangeSet changeSet) { + this.changeSet = changeSet; + } + + public BazaarChangeSet getChangeSet() { + return this.changeSet; + } + + public EditType getEditType() { + return this.editType; + } + + public String getOldPath() { + return this.oldPath; + } + + public String getPath() { + return this.path; + } + + public String getFileId() { + return this.fileId; + } +} diff --git a/src/main/java/hudson/plugins/bazaar/BazaarChangeLogParser.java b/src/main/java/hudson/plugins/bazaar/BazaarChangeLogParser.java index 4c21163..95fd9ed 100644 --- a/src/main/java/hudson/plugins/bazaar/BazaarChangeLogParser.java +++ b/src/main/java/hudson/plugins/bazaar/BazaarChangeLogParser.java @@ -2,8 +2,9 @@ package hudson.plugins.bazaar; import hudson.model.AbstractBuild; import hudson.scm.ChangeLogParser; -import java.io.BufferedReader; +import hudson.scm.EditType; +import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; @@ -97,8 +98,10 @@ public class BazaarChangeLogParser extends ChangeLogParser { entry.setMsg(message.toString()); message.setLength(0); } else { + if (message.length() != 0) { + message.append("\n"); + } message.append(s); - message.append("\n"); } } break; @@ -112,7 +115,7 @@ public class BazaarChangeLogParser extends ChangeLogParser { } else if (s.startsWith("renamed:")){ state = 8; } else { - entry.getModifiedPaths().add(s); + entry.addAffectedFile(createAffectedFile(EditType.EDIT, s)); } @@ -127,7 +130,7 @@ public class BazaarChangeLogParser extends ChangeLogParser { } else if (s.startsWith("renamed:")){ state = 8; } else { - entry.getAddedPaths().add(s); + entry.addAffectedFile(createAffectedFile(EditType.ADD, s)); } break; @@ -141,7 +144,7 @@ public class BazaarChangeLogParser extends ChangeLogParser { } else if (s.startsWith("renamed:")){ state = 8; } else { - entry.getDeletedPaths().add(s); + entry.addAffectedFile(createAffectedFile(EditType.DELETE, s)); } break; @@ -155,7 +158,7 @@ public class BazaarChangeLogParser extends ChangeLogParser { } else if (s.startsWith("renamed:")){ state = 8; } else { - entry.getModifiedPaths().add(s); + entry.addAffectedFile(createAffectedFile(EditType.EDIT, s)); } break; @@ -179,4 +182,21 @@ public class BazaarChangeLogParser extends ChangeLogParser { return new BazaarChangeSetList(build, entries); } + + private BazaarAffectedFile createAffectedFile(EditType editType, String changelogLine) { + String oldPath = null; + String path = changelogLine.trim(); + String fileId = ""; + int index = changelogLine.lastIndexOf(' '); + if (index >= 0) { + path = changelogLine.substring(0, index).trim(); + fileId = changelogLine.substring(index, changelogLine.length()).trim(); + } + if (path.contains("=>")) { + String[] paths = path.split("=>"); + oldPath = paths[0].trim(); + path = paths[1].trim(); + } + return new BazaarAffectedFile(editType, oldPath, path, fileId); + } } diff --git a/src/main/java/hudson/plugins/bazaar/BazaarChangeSet.java b/src/main/java/hudson/plugins/bazaar/BazaarChangeSet.java index 0d1b915..9039fce 100644 --- a/src/main/java/hudson/plugins/bazaar/BazaarChangeSet.java +++ b/src/main/java/hudson/plugins/bazaar/BazaarChangeSet.java @@ -2,11 +2,12 @@ package hudson.plugins.bazaar; import hudson.model.User; import hudson.scm.ChangeLogSet; -import hudson.scm.EditType; + +import java.util.AbstractList; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.List; + import org.kohsuke.stapler.export.Exported; /** @@ -26,14 +27,8 @@ public class BazaarChangeSet extends ChangeLogSet.Entry { private String date; private String msg; - private List added = new ArrayList(); - private List deleted = new ArrayList(); - private List modified = new ArrayList(); - /** - * Lazily computed. - */ - private volatile List affectedPaths; + private List affectedFiles = new ArrayList(); /** * Commit message. @@ -60,6 +55,11 @@ public class BazaarChangeSet extends ChangeLogSet.Entry { } @Exported + public String getRevision() { + return this.getRevno(); + } + + @Exported public String getRevid() { return revid; } @@ -71,60 +71,19 @@ public class BazaarChangeSet extends ChangeLogSet.Entry { @Override public Collection getAffectedPaths() { - if (affectedPaths == null) { - List r = new ArrayList(added.size() + modified.size() + deleted.size()); - r.addAll(added); - r.addAll(modified); - r.addAll(deleted); - affectedPaths = r; - } - return affectedPaths; + return new AbstractList() { + public String get(int index) { + return affectedFiles.get(index).getPath(); + } + public int size() { + return affectedFiles.size(); + } + }; } - /** - * Gets all the files that were added. - */ - @Exported - public List getAddedPaths() { - return added; - } - - /** - * Gets all the files that were deleted. - */ - @Exported - public List getDeletedPaths() { - return deleted; - } - - /** - * Gets all the files that were modified. - */ - @Exported - public List getModifiedPaths() { - return modified; - } - - public List getPaths(EditType kind) { - if (kind == EditType.ADD) { - return getAddedPaths(); - } - if (kind == EditType.EDIT) { - return getModifiedPaths(); - } - if (kind == EditType.DELETE) { - return getDeletedPaths(); - } - return null; - } - - /** - * Returns all three variations of {@link EditType}. - * Placed here to simplify access from views. - */ - public List getEditTypes() { - // return EditType.ALL; - return Arrays.asList(EditType.ADD, EditType.EDIT, EditType.DELETE); + @Override + public Collection getAffectedFiles() { + return affectedFiles; } @Override @@ -159,4 +118,9 @@ public class BazaarChangeSet extends ChangeLogSet.Entry { public void setDate(String date) { this.date = date; } + + public void addAffectedFile(BazaarAffectedFile affectedFile) { + affectedFile.setChangeSet(this); + this.affectedFiles.add(affectedFile); + } } diff --git a/src/main/java/hudson/plugins/bazaar/BazaarRepositoryBrowser.java b/src/main/java/hudson/plugins/bazaar/BazaarRepositoryBrowser.java new file mode 100644 index 0000000..78e1e34 --- /dev/null +++ b/src/main/java/hudson/plugins/bazaar/BazaarRepositoryBrowser.java @@ -0,0 +1,33 @@ +package hudson.plugins.bazaar; + +import hudson.scm.RepositoryBrowser; + +import java.io.IOException; +import java.net.URL; + +/** + * {@link RepositoryBrowser} for Bazaar. + * + * @author Alexandre Garnier + */ +public abstract class BazaarRepositoryBrowser extends RepositoryBrowser { + + /** + * Determines the link to the diff between the version + * in the specified revision of {@link BazaarAffectedFile} to its previous version. + * + * @return + * null if the browser doesn't have any URL for diff. + */ + public abstract URL getDiffLink(BazaarAffectedFile affectedFile) throws IOException; + + /** + * Determines the link to a single file under Bazaar. + * This page should display all the past revisions of this file, etc. + * + * @return + * null if the browser doesn't have any suitable URL. + */ + public abstract URL getFileLink(BazaarAffectedFile affectedFile) throws IOException; + +} diff --git a/src/main/java/hudson/plugins/bazaar/BazaarSCM.java b/src/main/java/hudson/plugins/bazaar/BazaarSCM.java index 6bdb862..bd242dd 100644 --- a/src/main/java/hudson/plugins/bazaar/BazaarSCM.java +++ b/src/main/java/hudson/plugins/bazaar/BazaarSCM.java @@ -2,25 +2,26 @@ package hudson.plugins.bazaar; import hudson.EnvVars; import hudson.Extension; -import hudson.FilePath.FileCallable; import hudson.FilePath; +import hudson.FilePath.FileCallable; import hudson.Launcher; import hudson.Launcher.LocalLauncher; import hudson.Launcher.ProcStarter; +import hudson.model.BuildListener; +import hudson.model.TaskListener; import hudson.model.AbstractBuild; import hudson.model.AbstractProject; -import hudson.model.BuildListener; import hudson.model.Hudson; -import hudson.model.TaskListener; import hudson.remoting.VirtualChannel; import hudson.scm.ChangeLogParser; import hudson.scm.PollingResult; import hudson.scm.PollingResult.Change; -import hudson.scm.SCM; import hudson.scm.SCMDescriptor; import hudson.scm.SCMRevisionState; +import hudson.scm.SCM; import hudson.util.ArgumentListBuilder; import hudson.util.FormValidation; + import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; @@ -33,11 +34,15 @@ import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; + import javax.servlet.ServletException; + import net.sf.json.JSONObject; + import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.framework.io.ByteBuffer; /** @@ -52,11 +57,13 @@ public class BazaarSCM extends SCM implements Serializable { */ private final String source; private final boolean clean; + private final BazaarRepositoryBrowser browser; @DataBoundConstructor - public BazaarSCM(String source, boolean clean) { + public BazaarSCM(String source, boolean clean, BazaarRepositoryBrowser browser) { this.source = source; this.clean = clean; + this.browser = browser; } /** @@ -76,6 +83,12 @@ public class BazaarSCM extends SCM implements Serializable { return clean; } + @Override + @Exported + public BazaarRepositoryBrowser getBrowser() { + return browser; + } + private String getRevid(Launcher launcher, TaskListener listener, String root) throws InterruptedException { String rev = null; @@ -270,7 +283,7 @@ public class BazaarSCM extends SCM implements Serializable { } @Override - public void buildEnvVars(AbstractBuild build, Map env) { + public void buildEnvVars(AbstractBuild build, Map env) { } @Override @@ -290,7 +303,7 @@ public class BazaarSCM extends SCM implements Serializable { private transient String version; private DescriptorImpl() { - super(BazaarSCM.class, null); + super(BazaarSCM.class, BazaarRepositoryBrowser.class); load(); } diff --git a/src/main/java/hudson/plugins/bazaar/browsers/Loggerhead.java b/src/main/java/hudson/plugins/bazaar/browsers/Loggerhead.java new file mode 100644 index 0000000..b5f436c --- /dev/null +++ b/src/main/java/hudson/plugins/bazaar/browsers/Loggerhead.java @@ -0,0 +1,92 @@ +package hudson.plugins.bazaar.browsers; + +import hudson.model.Descriptor; +import hudson.plugins.bazaar.BazaarAffectedFile; +import hudson.plugins.bazaar.BazaarChangeSet; +import hudson.plugins.bazaar.BazaarRepositoryBrowser; +import hudson.scm.RepositoryBrowser; + +import java.io.IOException; +import java.net.URL; + +import org.kohsuke.stapler.DataBoundConstructor; + +/** + * {@link RepositoryBrowser} for Loggerhead. + * + * @author Alexandre Garnier + */ +public class Loggerhead extends BazaarRepositoryBrowser { + + /** + * The URL of the Loggerhead repository. + * + * This is normally like http://bazaar.launchpad.net/~myteam/myproject/ + * Normalized to have '/' at the tail. + */ + public final URL url; + + @DataBoundConstructor + public Loggerhead(URL url) { + this.url = normalizeToEndWithSlash(url); + } + + @Override + public URL getChangeSetLink(BazaarChangeSet changeSet) throws IOException { + return new URL(this.url, "./revision/" + changeSet.getRevno()); + } + + @Override + public URL getDiffLink(BazaarAffectedFile affectedFile) throws IOException { + URL url = null; + String path = affectedFile.getPath().trim(); + if (! isFolderPath(path) && ! isRenaming(affectedFile)) { + return new URL(this.url, String.format("./revision/%s/%s", affectedFile.getChangeSet().getRevno(), + trimHeadSlash(path))); + } + return url; + } + + private static boolean isRenaming(BazaarAffectedFile affectedFile) { + return affectedFile.getOldPath() != null; + } + + @Override + public URL getFileLink(BazaarAffectedFile affectedFile) throws IOException { + String path = affectedFile.getPath().trim(); + return new URL(this.url, String.format("./%s/%s/%s?file_id=%s", getBrowsingType(path), + affectedFile.getChangeSet().getRevno(), + trimHeadSlash(path), + affectedFile.getFileId())); + } + + private static String getBrowsingType(String path) { + String browsingType = "annotate"; + if (isFolderPath(path)) { + browsingType = "files"; + } + return browsingType; + } + + private static boolean isFolderPath(String path) { + return path.endsWith("/"); + } + + + public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl(); + + public Descriptor> getDescriptor() { + return DESCRIPTOR; + } + + public static class DescriptorImpl extends Descriptor> { + public DescriptorImpl() { + super(Loggerhead.class); + } + + @Override + public String getDisplayName() { + return "Loggerhead"; + } + } +} diff --git a/src/main/resources/hudson/plugins/bazaar/BazaarChangeSetList/digest.jelly b/src/main/resources/hudson/plugins/bazaar/BazaarChangeSetList/digest.jelly index a13856f..570a182 100644 --- a/src/main/resources/hudson/plugins/bazaar/BazaarChangeSetList/digest.jelly +++ b/src/main/resources/hudson/plugins/bazaar/BazaarChangeSetList/digest.jelly @@ -8,15 +8,15 @@ - No changes. + ${%No changes.} - Changes + ${%Changes}
    -
  1. Revno: ${cs.revno} +
  2. ${cs.msgAnnotated} - (detail + (${%detail} )
  3. diff --git a/src/main/resources/hudson/plugins/bazaar/BazaarChangeSetList/digest_fr.properties b/src/main/resources/hudson/plugins/bazaar/BazaarChangeSetList/digest_fr.properties new file mode 100644 index 0000000..f6bf6f1 --- /dev/null +++ b/src/main/resources/hudson/plugins/bazaar/BazaarChangeSetList/digest_fr.properties @@ -0,0 +1,3 @@ +No\ changes.=Aucun changement. +Changes=Changements +detail=détails diff --git a/src/main/resources/hudson/plugins/bazaar/BazaarChangeSetList/index.jelly b/src/main/resources/hudson/plugins/bazaar/BazaarChangeSetList/index.jelly index 569a2e1..badcc14 100644 --- a/src/main/resources/hudson/plugins/bazaar/BazaarChangeSetList/index.jelly +++ b/src/main/resources/hudson/plugins/bazaar/BazaarChangeSetList/index.jelly @@ -2,7 +2,9 @@ Displays Bazaar change log. --> -

    Summary

    + + +

    ${%Summary}

    1. @@ -14,21 +16,31 @@
      - - Changeset revno ${cs.revno} by ${cs.author} (Revision id: ${cs.revid}): + + ${%Revision} + ${cs.revision} ${%by} ${cs.author}
      ${cs.msgAnnotated}
      - - - - - ${p} - - + + + + + + + ${oldPath}=> + + ${af.path} + + + + (diff) + + + diff --git a/src/main/resources/hudson/plugins/bazaar/BazaarChangeSetList/index_fr.properties b/src/main/resources/hudson/plugins/bazaar/BazaarChangeSetList/index_fr.properties new file mode 100644 index 0000000..5890268 --- /dev/null +++ b/src/main/resources/hudson/plugins/bazaar/BazaarChangeSetList/index_fr.properties @@ -0,0 +1,3 @@ +Summary=Résumé +Revision=Modification +by=par diff --git a/src/main/resources/hudson/plugins/bazaar/BazaarSCM/config.jelly b/src/main/resources/hudson/plugins/bazaar/BazaarSCM/config.jelly index 29ec1f1..c15aed4 100644 --- a/src/main/resources/hudson/plugins/bazaar/BazaarSCM/config.jelly +++ b/src/main/resources/hudson/plugins/bazaar/BazaarSCM/config.jelly @@ -2,6 +2,7 @@ + diff --git a/src/main/resources/hudson/plugins/bazaar/browsers/Loggerhead/config.jelly b/src/main/resources/hudson/plugins/bazaar/browsers/Loggerhead/config.jelly new file mode 100644 index 0000000..72681fa --- /dev/null +++ b/src/main/resources/hudson/plugins/bazaar/browsers/Loggerhead/config.jelly @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/resources/hudson/plugins/bazaar/browsers/Loggerhead/help-url.html b/src/main/resources/hudson/plugins/bazaar/browsers/Loggerhead/help-url.html new file mode 100644 index 0000000..2ebdb11 --- /dev/null +++ b/src/main/resources/hudson/plugins/bazaar/browsers/Loggerhead/help-url.html @@ -0,0 +1,5 @@ +
      + The repository browser URL for the root of the project. + For example, a Launchpad project called myproject would use + http://bazaar.launchpad.net/~myteam/myproject/. +
      diff --git a/src/main/resources/hudson/plugins/bazaar/browsers/Loggerhead/help-url_fr.html b/src/main/resources/hudson/plugins/bazaar/browsers/Loggerhead/help-url_fr.html new file mode 100644 index 0000000..0491d12 --- /dev/null +++ b/src/main/resources/hudson/plugins/bazaar/browsers/Loggerhead/help-url_fr.html @@ -0,0 +1,5 @@ +
      + L'URL racine du projet pour le navigateur de l'outil de gestion de configuration du code. + Par exemple, pour un projet Launchpad appelĂ© monprojet : + http://bazaar.launchpad.net/~monequipe/monprojet. +