package hudson.plugins.collabnet; import hudson.FilePath; import hudson.Launcher; import hudson.model.AbstractBuild; import hudson.model.BuildListener; import hudson.model.User; import hudson.scm.ChangeLogParser; import hudson.scm.ChangeLogSet; import hudson.scm.ChangeLogSet.Entry; import hudson.scm.NullSCM; import hudson.scm.SCM; import hudson.util.AdaptedIterator; import hudson.util.IOException2; import org.xml.sax.SAXException; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import static java.util.Arrays.asList; /** * {@link SCM} for test that enables the caller to fake changelog entries programatically. * This {@link SCM} doesn't really touch any files. * * TODO: to be moved to Hudson's test harness. * * @author Kohsuke Kawaguchi */ public class FakeChangeLogSCM extends NullSCM { private List<Commit> commits = new ArrayList<Commit>(); public static final class Commit implements Serializable { private String message = "a commit"; private String user="someone"; private List<String> paths = new ArrayList<String>(); public Commit by(String user) { this.user = user; return this; } public Commit says(String message) { this.message = message; return this; } private static final long serialVersionUID = 1L; } /** * Fakes a new commit, to be made available to Hudson in the next build. * The contents of the commit should be filled with the fluent API pattern. * * @param paths * The paths that are touched by a commit. */ public Commit commit(String... paths) { Commit c = new Commit(); c.paths.addAll(asList(paths)); commits.add(c); return c; } @Override public boolean checkout(AbstractBuild<?, ?> build, Launcher launcher, FilePath remoteDir, BuildListener listener, File changeLogFile) throws IOException, InterruptedException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(changeLogFile)); oos.writeObject(commits); oos.close(); commits.clear(); return true; } @Override public ChangeLogParser createChangeLogParser() { return new ChangeLogParser() { @Override public ChangeLogSet<? extends Entry> parse(AbstractBuild build, File changelogFile) throws IOException, SAXException { try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(changelogFile)); final List<Commit> commits = (List<Commit>)ois.readObject(); ois.close(); return new ChangeLogSet<Entry>(build) { private final ChangeLogSet THIS = this; public boolean isEmptySet() { return commits.isEmpty(); } public Iterator<Entry> iterator() { return new AdaptedIterator<Commit,Entry>(commits.iterator()) { @Override protected Entry adapt(final Commit item) { return new Entry() { { setParent(THIS); } @Override public String getMsg() { return item.message; } @Override public User getAuthor() { return User.get(item.user); } @Override public Collection<String> getAffectedPaths() { return item.paths; } }; } }; } }; } catch (ClassNotFoundException e) { throw new IOException2(e); } } }; } }