changeset 565:78a9e26e670d

Refactor common code to initialize changelog revision for a command into standalone class
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 09 Apr 2013 17:15:30 +0200
parents e6407313bab7
children 32453f30de07
files src/org/tmatesoft/hg/core/HgCatCommand.java src/org/tmatesoft/hg/core/HgCheckoutCommand.java src/org/tmatesoft/hg/core/HgLogCommand.java src/org/tmatesoft/hg/core/HgManifestCommand.java src/org/tmatesoft/hg/core/HgRevertCommand.java src/org/tmatesoft/hg/internal/CsetParamKeeper.java test/org/tmatesoft/hg/test/TestCommit.java
diffstat 7 files changed, 126 insertions(+), 59 deletions(-) [+]
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/core/HgCatCommand.java	Wed Apr 03 21:28:06 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgCatCommand.java	Tue Apr 09 17:15:30 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 TMate Software Ltd
+ * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -125,6 +125,7 @@
 		revisionIndex = BAD_REVISION;
 		revision = null;
 		cset = nodeid;
+		// TODO [2.0 API break] shall use CsetParamKeeper instead, but Exception thrown would break the API
 		return this;
 	}
 
--- a/src/org/tmatesoft/hg/core/HgCheckoutCommand.java	Wed Apr 03 21:28:06 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgCheckoutCommand.java	Tue Apr 09 17:15:30 2013 +0200
@@ -25,6 +25,7 @@
 import java.io.OutputStreamWriter;
 import java.nio.channels.FileChannel;
 
+import org.tmatesoft.hg.internal.CsetParamKeeper;
 import org.tmatesoft.hg.internal.DirstateBuilder;
 import org.tmatesoft.hg.internal.EncodingHelper;
 import org.tmatesoft.hg.internal.Experimental;
@@ -32,11 +33,10 @@
 import org.tmatesoft.hg.internal.WorkingDirFileWriter;
 import org.tmatesoft.hg.repo.HgDataFile;
 import org.tmatesoft.hg.repo.HgDirstate;
-import org.tmatesoft.hg.repo.HgInternals;
-import org.tmatesoft.hg.repo.HgInvalidRevisionException;
-import org.tmatesoft.hg.repo.HgManifest;
 import org.tmatesoft.hg.repo.HgDirstate.EntryKind;
 import org.tmatesoft.hg.repo.HgDirstate.Record;
+import org.tmatesoft.hg.repo.HgInternals;
+import org.tmatesoft.hg.repo.HgManifest;
 import org.tmatesoft.hg.repo.HgManifest.Flags;
 import org.tmatesoft.hg.repo.HgRepository;
 import org.tmatesoft.hg.repo.HgRuntimeException;
@@ -57,11 +57,12 @@
 public class HgCheckoutCommand extends HgAbstractCommand<HgCheckoutCommand>{
 
 	private final HgRepository repo;
-	private int revisionToCheckout = HgRepository.BAD_REVISION;
+	private final CsetParamKeeper revisionToCheckout;
 	private boolean cleanCheckout;
 
 	public HgCheckoutCommand(HgRepository hgRepo) {
 		repo = hgRepo;
+		revisionToCheckout = new CsetParamKeeper(repo);
 	}
 	
 	/**
@@ -85,29 +86,19 @@
 	 * @throws HgBadArgumentException if failed to find supplied changeset 
 	 */
 	public HgCheckoutCommand changeset(Nodeid nodeid) throws HgBadArgumentException {
-		try {
-			return changeset(repo.getChangelog().getRevisionIndex(nodeid));
-		} catch (HgInvalidRevisionException ex) {
-			throw new HgBadArgumentException("Can't find revision", ex).setRevision(nodeid);
-		}
+		revisionToCheckout.set(nodeid);
+		return this;
 	}
 
 	/**
 	 * Select revision to check out using local revision index
 	 * 
-	 * @param changesetIndex local revision index, or {@link HgRepository#TIP}
+	 * @param changesetIndex local changelog revision index, or {@link HgRepository#TIP}
 	 * @return <code>this</code> for convenience
 	 * @throws HgBadArgumentException if failed to find supplied changeset 
 	 */
 	public HgCheckoutCommand changeset(int changesetIndex) throws HgBadArgumentException {
-		int lastCsetIndex = repo.getChangelog().getLastRevision();
-		if (changesetIndex == HgRepository.TIP) {
-			changesetIndex = lastCsetIndex;
-		}
-		if (changesetIndex < 0 || changesetIndex > lastCsetIndex) {
-			throw new HgBadArgumentException(String.format("Bad revision index %d, value from [0..%d] expected", changesetIndex, lastCsetIndex), null).setRevisionIndex(changesetIndex);
-		}
-		revisionToCheckout = changesetIndex;
+		revisionToCheckout.set(changesetIndex);
 		return this;
 	}
 
@@ -159,8 +150,10 @@
 					return true;
 				}
 			};
-			dirstateBuilder.parents(repo.getChangelog().getRevision(revisionToCheckout), null);
-			repo.getManifest().walk(revisionToCheckout, revisionToCheckout, insp);
+			// checkout tip if no revision set
+			final int coRevision = revisionToCheckout.get(HgRepository.TIP);
+			dirstateBuilder.parents(repo.getChangelog().getRevision(coRevision), null);
+			repo.getManifest().walk(coRevision, coRevision, insp);
 			worker.checkFailed();
 			File dirstateFile = internalRepo.getRepositoryFile(Dirstate);
 			try {
@@ -170,7 +163,7 @@
 			} catch (IOException ex) {
 				throw new HgIOException("Can't write down new directory state", ex, dirstateFile);
 			}
-			String branchName = repo.getChangelog().range(revisionToCheckout, revisionToCheckout).get(0).branch();
+			String branchName = repo.getChangelog().range(coRevision, coRevision).get(0).branch();
 			assert branchName != null;
 			if (!HgRepository.DEFAULT_BRANCH_NAME.equals(branchName)) {
 				File branchFile = internalRepo.getRepositoryFile(Branch);
--- a/src/org/tmatesoft/hg/core/HgLogCommand.java	Wed Apr 03 21:28:06 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgLogCommand.java	Tue Apr 09 17:15:30 2013 +0200
@@ -1,5 +1,5 @@
 /*
-s * Copyright (c) 2011-2012 TMate Software Ltd
+s * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,6 +36,7 @@
 
 import org.tmatesoft.hg.internal.AdapterPlug;
 import org.tmatesoft.hg.internal.BatchRangeHelper;
+import org.tmatesoft.hg.internal.CsetParamKeeper;
 import org.tmatesoft.hg.internal.IntMap;
 import org.tmatesoft.hg.internal.IntVector;
 import org.tmatesoft.hg.internal.Internals;
@@ -45,7 +46,6 @@
 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset;
 import org.tmatesoft.hg.repo.HgDataFile;
 import org.tmatesoft.hg.repo.HgInvalidControlFileException;
-import org.tmatesoft.hg.repo.HgInvalidRevisionException;
 import org.tmatesoft.hg.repo.HgInvalidStateException;
 import org.tmatesoft.hg.repo.HgParentChildMap;
 import org.tmatesoft.hg.repo.HgRepository;
@@ -176,6 +176,7 @@
 			startRev = rev1;
 			endRev = rev2;
 		}
+		// TODO [2.0 API break] shall throw HgBadArgumentException, like other commands do
 		return this;
 	}
 	
@@ -188,12 +189,8 @@
 	 */
 	public HgLogCommand changeset(Nodeid nid) throws HgBadArgumentException {
 		// XXX perhaps, shall support multiple (...) arguments and extend #execute to handle not only range, but also set of revisions.
-		try {
-			final int csetRevIndex = repo.getChangelog().getRevisionIndex(nid);
-			return range(csetRevIndex, csetRevIndex);
-		} catch (HgInvalidRevisionException ex) {
-			throw new HgBadArgumentException("Can't find revision", ex).setRevision(nid);
-		}
+		final int csetRevIndex = new CsetParamKeeper(repo).set(nid).get();
+		return range(csetRevIndex, csetRevIndex);
 	}
 	
 	/**
--- a/src/org/tmatesoft/hg/core/HgManifestCommand.java	Wed Apr 03 21:28:06 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgManifestCommand.java	Tue Apr 09 17:15:30 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012 TMate Software Ltd
+ * Copyright (c) 2011-2013 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -17,19 +17,17 @@
 package org.tmatesoft.hg.core;
 
 import static org.tmatesoft.hg.repo.HgRepository.*;
-import static org.tmatesoft.hg.repo.HgRepository.BAD_REVISION;
-import static org.tmatesoft.hg.repo.HgRepository.TIP;
 
 import java.util.ConcurrentModificationException;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
 
+import org.tmatesoft.hg.internal.CsetParamKeeper;
 import org.tmatesoft.hg.internal.PathPool;
-import org.tmatesoft.hg.repo.HgInvalidRevisionException;
 import org.tmatesoft.hg.repo.HgManifest;
+import org.tmatesoft.hg.repo.HgManifest.Flags;
 import org.tmatesoft.hg.repo.HgRepository;
-import org.tmatesoft.hg.repo.HgManifest.Flags;
 import org.tmatesoft.hg.repo.HgRuntimeException;
 import org.tmatesoft.hg.util.CancelSupport;
 import org.tmatesoft.hg.util.CancelledException;
@@ -70,6 +68,7 @@
 		badArgs |= rev2 != TIP && rev2 < rev1; // range(3, 1);
 		badArgs |= rev1 == TIP && rev2 != TIP; // range(TIP, 2), although this may be legitimate when TIP points to 2
 		if (badArgs) {
+			// TODO [2.0 API break] throw checked HgBadArgumentException instead
 			throw new IllegalArgumentException(String.format("Bad range: [%d, %d]", rev1, rev2));
 		}
 		startRev = rev1;
@@ -83,6 +82,7 @@
 	 * @return <code>this</code> for convenience.
 	 */
 	public HgManifestCommand changeset(int csetRevisionIndex) {
+		// TODO [2.0 API break] shall throw HgBadArgumentException, like other commands do
 		return range(csetRevisionIndex, csetRevisionIndex);
 	}
 	
@@ -95,12 +95,8 @@
 	 */
 	public HgManifestCommand changeset(Nodeid nid) throws HgBadArgumentException {
 		// XXX also see HgLogCommand#changeset(Nodeid)
-		try {
-			final int csetRevIndex = repo.getChangelog().getRevisionIndex(nid);
-			return range(csetRevIndex, csetRevIndex);
-		} catch (HgInvalidRevisionException ex) {
-			throw new HgBadArgumentException("Can't find revision", ex).setRevision(nid);
-		}
+		final int csetRevIndex = new CsetParamKeeper(repo).set(nid).get();
+		return range(csetRevIndex, csetRevIndex);
 	}
 
 	public HgManifestCommand dirs(boolean include) {
--- a/src/org/tmatesoft/hg/core/HgRevertCommand.java	Wed Apr 03 21:28:06 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgRevertCommand.java	Tue Apr 09 17:15:30 2013 +0200
@@ -21,15 +21,15 @@
 import java.util.LinkedHashSet;
 import java.util.Set;
 
+import org.tmatesoft.hg.internal.CsetParamKeeper;
 import org.tmatesoft.hg.internal.DirstateBuilder;
 import org.tmatesoft.hg.internal.DirstateReader;
 import org.tmatesoft.hg.internal.Experimental;
 import org.tmatesoft.hg.internal.Internals;
-import org.tmatesoft.hg.repo.HgInvalidRevisionException;
 import org.tmatesoft.hg.repo.HgManifest;
+import org.tmatesoft.hg.repo.HgManifest.Flags;
 import org.tmatesoft.hg.repo.HgRepository;
 import org.tmatesoft.hg.repo.HgRuntimeException;
-import org.tmatesoft.hg.repo.HgManifest.Flags;
 import org.tmatesoft.hg.util.CancelledException;
 import org.tmatesoft.hg.util.Path;
 
@@ -46,11 +46,13 @@
 
 	private final HgRepository repo;
 	private final Set<Path> files = new LinkedHashSet<Path>();
-	private int changesetToCheckout = HgRepository.WORKING_COPY; // XXX WORKING_COPY_PARENT, in fact
+	private CsetParamKeeper changesetToCheckout;
 	private boolean keepOriginal = true;
 
 	public HgRevertCommand(HgRepository hgRepo) {
 		repo = hgRepo;
+		changesetToCheckout = new CsetParamKeeper(hgRepo);
+		changesetToCheckout.doSet(HgRepository.WORKING_COPY); // XXX WORKING_COPY_PARENT, in fact
 	}
 
 	/**
@@ -72,11 +74,7 @@
 	 * @throws HgBadArgumentException
 	 */
 	public HgRevertCommand changeset(int changesetRevIndex) throws HgBadArgumentException {
-		int lastCsetIndex = repo.getChangelog().getLastRevision();
-		if (changesetRevIndex < 0 || changesetRevIndex > lastCsetIndex) {
-			throw new HgBadArgumentException(String.format("Bad revision index %d, value from [0..%d] expected", changesetRevIndex, lastCsetIndex), null).setRevisionIndex(changesetRevIndex);
-		}
-		changesetToCheckout = changesetRevIndex;
+		changesetToCheckout.set(changesetRevIndex);
 		return this;
 	}
 	
@@ -88,14 +86,11 @@
 	 * @throws HgBadArgumentException
 	 */
 	public HgRevertCommand changeset(Nodeid revision) throws HgBadArgumentException {
-		try {
-			return changeset(repo.getChangelog().getRevisionIndex(revision));
-		} catch (HgInvalidRevisionException ex) {
-			throw new HgBadArgumentException("Can't find revision", ex).setRevision(revision);
-		}
+		changesetToCheckout.set(revision);
+		return this;
 	}
 	
-	// TODO keepOriginal() to save .orig
+	// TODO keepOriginal() to save .orig (with tests!)
 
 	/**
 	 * Perform the back out for the given files
@@ -107,10 +102,10 @@
 	public void execute() throws HgException, CancelledException {
 		try {
 			final int csetRevision;
-			if (changesetToCheckout == HgRepository.WORKING_COPY) {
+			if (changesetToCheckout.get() == HgRepository.WORKING_COPY) {
 				csetRevision = repo.getChangelog().getRevisionIndex(repo.getWorkingCopyParents().first());
 			} else {
-				csetRevision = changesetToCheckout;
+				csetRevision = changesetToCheckout.get();
 			}
 			Internals implRepo = Internals.getInstance(repo);
 			final DirstateBuilder dirstateBuilder = new DirstateBuilder(implRepo);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/tmatesoft/hg/internal/CsetParamKeeper.java	Tue Apr 09 17:15:30 2013 +0200
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2013 TMate Software Ltd
+ *  
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * For information on how to redistribute this software under
+ * the terms of a license other than GNU General Public License
+ * contact TMate Software at support@hg4j.com
+ */
+package org.tmatesoft.hg.internal;
+
+import static org.tmatesoft.hg.repo.HgRepository.BAD_REVISION;
+import static org.tmatesoft.hg.repo.HgRepository.TIP;
+
+import org.tmatesoft.hg.core.HgBadArgumentException;
+import org.tmatesoft.hg.core.Nodeid;
+import org.tmatesoft.hg.repo.HgInvalidRevisionException;
+import org.tmatesoft.hg.repo.HgRepository;
+
+/**
+ * Common code to keep changelog revision and to perform boundary check.
+ *
+ * @author Artem Tikhomirov
+ * @author TMate Software Ltd.
+ */
+public class CsetParamKeeper {
+	private final HgRepository repo;
+	private int changelogRevisionIndex = HgRepository.BAD_REVISION;
+	
+	public CsetParamKeeper(HgRepository hgRepo) {
+		repo = hgRepo;
+	}
+	
+	public CsetParamKeeper set(Nodeid changeset) throws HgBadArgumentException {
+		try {
+			set(repo.getChangelog().getRevisionIndex(changeset));
+		} catch (HgInvalidRevisionException ex) {
+			throw new HgBadArgumentException("Can't find revision", ex).setRevision(changeset);
+		}
+		return this;
+	}
+	
+	public CsetParamKeeper set(int changelogRevIndex) throws HgBadArgumentException {
+		int lastCsetIndex = repo.getChangelog().getLastRevision();
+		if (changelogRevIndex == HgRepository.TIP) {
+			changelogRevIndex = lastCsetIndex;
+		}
+		if (changelogRevIndex < 0 || changelogRevIndex > lastCsetIndex) {
+			throw new HgBadArgumentException(String.format("Bad revision index %d, value from [0..%d] expected", changelogRevIndex, lastCsetIndex), null).setRevisionIndex(changelogRevIndex);
+		}
+		doSet(changelogRevIndex);
+		return this;
+	}
+	
+	public void doSet(int changelogRevIndex) {
+		changelogRevisionIndex = changelogRevIndex;
+	}
+
+	/**
+	 * @return the value set, or {@link HgRepository#BAD_REVISION} otherwise
+	 */
+	public int get() {
+		return changelogRevisionIndex;
+	}
+
+	/**
+	 * @param defaultRevisionIndex value to return when no revision was set, may be {@link HgRepository#TIP} which gets translated to real index if used
+	 * @return changelog revision index if set, or defaultRevisionIndex value otherwise
+	 */
+	public int get(int defaultRevisionIndex) {
+		// XXX perhaps, shall translate other predefined constants (like WORKING COPY) here, too (e.g. for HgRevertCommand)
+		if (changelogRevisionIndex != BAD_REVISION || changelogRevisionIndex != TIP) {
+			return changelogRevisionIndex;
+		}
+		if (changelogRevisionIndex == TIP || defaultRevisionIndex == TIP) {
+			return repo.getChangelog().getLastRevision();
+		}
+		return defaultRevisionIndex;
+	}
+}
--- a/test/org/tmatesoft/hg/test/TestCommit.java	Wed Apr 03 21:28:06 2013 +0200
+++ b/test/org/tmatesoft/hg/test/TestCommit.java	Tue Apr 09 17:15:30 2013 +0200
@@ -23,13 +23,11 @@
 
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileWriter;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.util.List;
 
-import org.hamcrest.CoreMatchers;
 import org.junit.Test;
 import org.tmatesoft.hg.core.HgAddRemoveCommand;
 import org.tmatesoft.hg.core.HgCatCommand;