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