kitaev@213: /* kitaev@213: * Copyright (c) 2011 TMate Software Ltd kitaev@213: * kitaev@213: * This program is free software; you can redistribute it and/or modify kitaev@213: * it under the terms of the GNU General Public License as published by kitaev@213: * the Free Software Foundation; version 2 of the License. kitaev@213: * kitaev@213: * This program is distributed in the hope that it will be useful, kitaev@213: * but WITHOUT ANY WARRANTY; without even the implied warranty of kitaev@213: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the kitaev@213: * GNU General Public License for more details. kitaev@213: * kitaev@213: * For information on how to redistribute this software under kitaev@213: * the terms of a license other than GNU General Public License kitaev@213: * contact TMate Software at support@hg4j.com kitaev@213: */ kitaev@213: package org.tmatesoft.hg.console; kitaev@213: kitaev@213: import java.util.Formatter; kitaev@213: import java.util.LinkedList; kitaev@213: import java.util.List; kitaev@213: kitaev@213: import org.tmatesoft.hg.core.HgChangeset; kitaev@213: import org.tmatesoft.hg.core.HgChangesetHandler; kitaev@213: import org.tmatesoft.hg.core.Nodeid; kitaev@213: import org.tmatesoft.hg.core.HgLogCommand.FileRevision; kitaev@213: import org.tmatesoft.hg.repo.HgRepository; kitaev@213: import org.tmatesoft.hg.util.Path; kitaev@213: kitaev@213: /** kitaev@213: * kitaev@213: * @author Artem Tikhomirov kitaev@213: * @author TMate Software Ltd. kitaev@213: */ kitaev@213: public class ChangesetDumpHandler implements HgChangesetHandler { kitaev@213: // params kitaev@213: private boolean complete = false; // roughly --debug kitaev@213: private boolean reverseOrder = false; kitaev@213: private boolean verbose = false; // roughly -v kitaev@213: // own kitaev@213: private LinkedList l = new LinkedList(); kitaev@213: private final HgRepository repo; kitaev@213: private final int tip; kitaev@213: kitaev@213: public ChangesetDumpHandler(HgRepository hgRepo) { kitaev@213: repo = hgRepo; kitaev@213: tip = hgRepo.getChangelog().getLastRevision(); kitaev@213: } kitaev@213: kitaev@213: public ChangesetDumpHandler complete(boolean b) { kitaev@213: complete = b; kitaev@213: return this; kitaev@213: } kitaev@213: kitaev@213: public ChangesetDumpHandler reversed(boolean b) { kitaev@213: reverseOrder = b; kitaev@213: return this; kitaev@213: } kitaev@213: kitaev@213: public ChangesetDumpHandler verbose(boolean b) { kitaev@213: verbose = b; kitaev@213: return this; kitaev@213: } kitaev@213: kitaev@213: public void next(HgChangeset changeset) { kitaev@213: final String s = print(changeset); kitaev@213: if (reverseOrder) { kitaev@213: // XXX in fact, need to insert s into l according to changeset.getRevision() kitaev@213: // because when file history is being followed, revisions of the original file (with smaller revNumber) kitaev@213: // are reported *after* revisions of present file and with addFirst appear above them kitaev@213: l.addFirst(s); kitaev@213: } else { kitaev@213: System.out.print(s); kitaev@213: } kitaev@213: } kitaev@213: kitaev@213: public void done() { kitaev@213: if (!reverseOrder) { kitaev@213: return; kitaev@213: } kitaev@213: for (String s : l) { kitaev@213: System.out.print(s); kitaev@213: } kitaev@213: l.clear(); kitaev@213: } kitaev@213: kitaev@213: private String print(HgChangeset cset) { kitaev@213: StringBuilder sb = new StringBuilder(); kitaev@213: Formatter f = new Formatter(sb); kitaev@213: final Nodeid csetNodeid = cset.getNodeid(); kitaev@213: f.format("changeset: %d:%s\n", cset.getRevision(), complete ? csetNodeid : csetNodeid.shortNotation()); kitaev@213: if (cset.getRevision() == tip || repo.getTags().isTagged(csetNodeid)) { kitaev@213: kitaev@213: sb.append("tag: "); kitaev@213: for (String t : repo.getTags().tags(csetNodeid)) { kitaev@213: sb.append(t); kitaev@213: sb.append(' '); kitaev@213: } kitaev@213: if (cset.getRevision() == tip) { kitaev@213: sb.append("tip"); kitaev@213: } kitaev@213: sb.append('\n'); kitaev@213: } kitaev@213: if (complete) { kitaev@213: Nodeid p1 = cset.getFirstParentRevision(); kitaev@213: Nodeid p2 = cset.getSecondParentRevision(); kitaev@213: int p1x = p1 == Nodeid.NULL ? -1 : repo.getChangelog().getLocalRevision(p1); kitaev@213: int p2x = p2 == Nodeid.NULL ? -1 : repo.getChangelog().getLocalRevision(p2); kitaev@213: int mx = repo.getManifest().getLocalRevision(cset.getManifestRevision()); kitaev@213: f.format("parent: %d:%s\nparent: %d:%s\nmanifest: %d:%s\n", p1x, p1, p2x, p2, mx, cset.getManifestRevision()); kitaev@213: } kitaev@213: f.format("user: %s\ndate: %s\n", cset.getUser(), cset.getDate().toString()); kitaev@213: if (!complete && verbose) { kitaev@213: final List files = cset.getAffectedFiles(); kitaev@213: sb.append("files: "); kitaev@213: for (Path s : files) { kitaev@213: sb.append(' '); kitaev@213: sb.append(s); kitaev@213: } kitaev@213: sb.append('\n'); kitaev@213: } kitaev@213: if (complete) { kitaev@213: if (!cset.getModifiedFiles().isEmpty()) { kitaev@213: sb.append("files: "); kitaev@213: for (FileRevision s : cset.getModifiedFiles()) { kitaev@213: sb.append(' '); kitaev@213: sb.append(s.getPath()); kitaev@213: } kitaev@213: sb.append('\n'); kitaev@213: } kitaev@213: if (!cset.getAddedFiles().isEmpty()) { kitaev@213: sb.append("files+: "); kitaev@213: for (FileRevision s : cset.getAddedFiles()) { kitaev@213: sb.append(' '); kitaev@213: sb.append(s.getPath()); kitaev@213: } kitaev@213: sb.append('\n'); kitaev@213: } kitaev@213: if (!cset.getRemovedFiles().isEmpty()) { kitaev@213: sb.append("files-: "); kitaev@213: for (Path s : cset.getRemovedFiles()) { kitaev@213: sb.append(' '); kitaev@213: sb.append(s); kitaev@213: } kitaev@213: sb.append('\n'); kitaev@213: } kitaev@213: // if (cset.extras() != null) { kitaev@213: // sb.append("extra: "); kitaev@213: // for (Map.Entry e : cset.extras().entrySet()) { kitaev@213: // sb.append(' '); kitaev@213: // sb.append(e.getKey()); kitaev@213: // sb.append('='); kitaev@213: // sb.append(e.getValue()); kitaev@213: // } kitaev@213: // sb.append('\n'); kitaev@213: // } kitaev@213: } kitaev@213: if (complete || verbose) { kitaev@213: f.format("description:\n%s\n\n", cset.getComment()); kitaev@213: } else { kitaev@213: f.format("summary: %s\n\n", cset.getComment()); kitaev@213: } kitaev@213: return sb.toString(); kitaev@213: } kitaev@213: }