changeset 637:4a0bab2c6da1

HgInitCommand: expose repo init functionality
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Fri, 07 Jun 2013 12:32:15 +0200
parents ffce73efa2c2
children d07497128747
files src/org/tmatesoft/hg/core/HgCloneCommand.java src/org/tmatesoft/hg/core/HgInitCommand.java src/org/tmatesoft/hg/core/HgRepoFacade.java src/org/tmatesoft/hg/internal/RepoInitializer.java test/org/tmatesoft/hg/test/ComplexTest.java test/org/tmatesoft/hg/test/RepoUtils.java test/org/tmatesoft/hg/test/TestClone.java test/org/tmatesoft/hg/test/TestStorePath.java
diffstat 8 files changed, 177 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/core/HgCloneCommand.java	Thu Jun 06 19:39:06 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgCloneCommand.java	Fri Jun 07 12:32:15 2013 +0200
@@ -173,7 +173,7 @@
 			ctx = sessionCtx;
 			hgDir = new File(destDir, ".hg");
 			repoInit = new RepoInitializer();
-			repoInit.setRequires(STORE | FNCACHE | DOTENCODE);
+			repoInit.setRequires(REVLOGV1 | STORE | FNCACHE | DOTENCODE);
 			storagePathHelper = repoInit.buildDataFilesHelper(sessionCtx);
 			progressSupport = progress;
 			cancelSupport = cancel;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/tmatesoft/hg/core/HgInitCommand.java	Fri Jun 07 12:32:15 2013 +0200
@@ -0,0 +1,109 @@
+/*
+ * 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.core;
+
+import static org.tmatesoft.hg.internal.RequiresFile.*;
+
+import java.io.File;
+
+import org.tmatesoft.hg.internal.RepoInitializer;
+import org.tmatesoft.hg.repo.HgLookup;
+import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.util.CancelledException;
+
+/**
+ * Initialize empty local repository. 
+ * <p>
+ * Two predefined alternatives are available, {@link #revlogV0() old} and {@link #revlogV1() new} mercurial format respectively.
+ * <p>
+ * Specific requirements may be turned off/on as needed if you know what you're doing.
+ * 
+ * @see http://mercurial.selenic.com/wiki/RequiresFile
+ * @author Artem Tikhomirov
+ * @author TMate Software Ltd.
+ */
+public class HgInitCommand extends HgAbstractCommand<HgInitCommand> {
+	private static final int V1_DEFAULT = REVLOGV1 | STORE | FNCACHE | DOTENCODE;
+	
+	private final HgLookup hgLookup;
+	private File location;
+	private int requiresFlags;
+	
+	public HgInitCommand() {
+		this(null);
+	}
+
+	public HgInitCommand(HgLookup lookupEnv) {
+		hgLookup = lookupEnv;
+		requiresFlags = V1_DEFAULT;
+	}
+	
+	public HgInitCommand location(File repoLoc) {
+		location = repoLoc;
+		return this;
+	}
+	
+	public HgInitCommand revlogV0() {
+		requiresFlags = REVLOGV0;
+		return this;
+	}
+	
+	public HgInitCommand revlogV1() {
+		requiresFlags = V1_DEFAULT;
+		return this;
+	}
+	
+	public HgInitCommand store(boolean enable) {
+		return switchFlag(STORE, enable);
+	}
+	
+	public HgInitCommand fncache(boolean enable) {
+		return switchFlag(FNCACHE, enable);
+	}
+	
+	public HgInitCommand dotencode(boolean enable) {
+		return switchFlag(DOTENCODE, enable);
+	}
+
+	public HgRepository execute() throws HgRepositoryNotFoundException, HgException, CancelledException {
+		if (location == null) {
+			throw new IllegalArgumentException();
+		}
+		File repoDir;
+		if (".hg".equals(location.getName())) {
+			repoDir = location;
+		} else {
+			repoDir = new File(location, ".hg");
+		}
+		new RepoInitializer().setRequires(requiresFlags).initEmptyRepository(repoDir);
+		return getNewRepository();
+	}
+	
+	public HgRepository getNewRepository() throws HgRepositoryNotFoundException {
+		HgLookup l = hgLookup == null ? new HgLookup() : hgLookup;
+		return l.detect(location);
+	}
+	
+	private HgInitCommand switchFlag(int flag, boolean enable) {
+		if (enable) {
+			requiresFlags |= flag;
+		} else {
+			requiresFlags &= ~flag;
+		}
+		return this;
+	}
+}
--- a/src/org/tmatesoft/hg/core/HgRepoFacade.java	Thu Jun 06 19:39:06 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgRepoFacade.java	Fri Jun 07 12:32:15 2013 +0200
@@ -101,6 +101,14 @@
 	public SessionContext getSessionContext() {
 		return context;
 	}
+	
+	/**
+	 * This factory method doesn't need this facade to be initialized with a repository.
+	 * @return command instance, never <code>null</code>
+	 */
+	public HgInitCommand createInitCommand() {
+		return new HgInitCommand(new HgLookup(context));
+	}
 
 	public HgLogCommand createLogCommand() {
 		return new HgLogCommand(repo/*, getCommandContext()*/);
--- a/src/org/tmatesoft/hg/internal/RepoInitializer.java	Thu Jun 06 19:39:06 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/RepoInitializer.java	Fri Jun 07 12:32:15 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 TMate Software Ltd
+ * Copyright (c) 2012-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
@@ -32,6 +32,7 @@
  * Responsible of `requires` processing both on repo read and repo write
  * XXX needs better name, perhaps
  * 
+ * @see http://mercurial.selenic.com/wiki/RequiresFile
  * @author Artem Tikhomirov
  * @author TMate Software Ltd.
  */
@@ -66,7 +67,9 @@
 		try {
 			FileOutputStream requiresStream = new FileOutputStream(requiresFile);
 			StringBuilder sb = new StringBuilder(40);
-			sb.append("revlogv1\n");
+			if ((requiresFlags & REVLOGV1) != 0) {
+				sb.append("revlogv1\n");
+			}
 			if ((requiresFlags & STORE) != 0) {
 				sb.append("store\n");
 			}
@@ -81,7 +84,9 @@
 		} catch (IOException ex) {
 			throw new HgIOException("Failed to initialize empty repo", ex, requiresFile);
 		}
-		new File(repoDir, "store").mkdir(); // with that, hg verify says ok.
+		if ((requiresFlags & STORE) != 0) {
+			new File(repoDir, "store").mkdir(); // with that, hg verify says ok.
+		}
 	}
 
 	public PathRewrite buildDataFilesHelper(SessionContext ctx) {
--- a/test/org/tmatesoft/hg/test/ComplexTest.java	Thu Jun 06 19:39:06 2013 +0200
+++ b/test/org/tmatesoft/hg/test/ComplexTest.java	Fri Jun 07 12:32:15 2013 +0200
@@ -25,8 +25,8 @@
 import org.tmatesoft.hg.core.HgAddRemoveCommand;
 import org.tmatesoft.hg.core.HgCheckoutCommand;
 import org.tmatesoft.hg.core.HgCommitCommand;
+import org.tmatesoft.hg.core.HgInitCommand;
 import org.tmatesoft.hg.core.HgRevertCommand;
-import org.tmatesoft.hg.repo.HgLookup;
 import org.tmatesoft.hg.repo.HgManifest;
 import org.tmatesoft.hg.repo.HgRepository;
 import org.tmatesoft.hg.util.Path;
@@ -47,9 +47,7 @@
 	public void testLocalScenario1() throws Exception {
 		File repoLoc = RepoUtils.createEmptyDir("composite-scenario-1");
 		// init empty
-		// TODO HgInitCommand
-		RepoUtils.exec(repoLoc, 0, "hg", "init");
-		HgRepository hgRepo = new HgLookup().detect(repoLoc);
+		HgRepository hgRepo = new HgInitCommand().location(repoLoc).revlogV1().execute();
 		assertFalse("[sanity]", hgRepo.isInvalid());
 		assertEquals("[sanity]", 0, hgRepo.getChangelog().getRevisionCount());
 		// add 2 files
--- a/test/org/tmatesoft/hg/test/RepoUtils.java	Thu Jun 06 19:39:06 2013 +0200
+++ b/test/org/tmatesoft/hg/test/RepoUtils.java	Fri Jun 07 12:32:15 2013 +0200
@@ -18,7 +18,6 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
-import static org.tmatesoft.hg.internal.RequiresFile.*;
 import static org.tmatesoft.hg.util.LogFacility.Severity.Debug;
 
 import java.io.File;
@@ -29,15 +28,16 @@
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.LinkedList;
+import java.util.List;
 
 import junit.framework.Assert;
 
 import org.tmatesoft.hg.core.HgException;
-import org.tmatesoft.hg.core.HgIOException;
+import org.tmatesoft.hg.core.HgInitCommand;
 import org.tmatesoft.hg.internal.FileUtils;
-import org.tmatesoft.hg.internal.RepoInitializer;
 import org.tmatesoft.hg.internal.StreamLogFacility;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.util.CancelledException;
 
 /**
  * 
@@ -46,18 +46,20 @@
  */
 public class RepoUtils {
 
-	static File initEmptyTempRepo(String dirName) throws IOException, HgIOException {
+	static File initEmptyTempRepo(String dirName) throws IOException, HgException {
 		File dest = createEmptyDir(dirName);
-		RepoInitializer ri = new RepoInitializer();
-		ri.setRequires(STORE | FNCACHE | DOTENCODE);
-		ri.initEmptyRepository(new File(dest, ".hg"));
+		try {
+			new HgInitCommand().location(dest).revlogV1().execute();
+		} catch (CancelledException ex) {
+			Assert.fail(ex.toString());
+		}
 		return dest;
 	}
 
 	static File createEmptyDir(String dirName) throws IOException {
 		File dest = new File(Configuration.get().getTempDir(), dirName);
 		if (dest.exists()) {
-			TestClone.rmdir(dest);
+			rmdir(dest);
 		}
 		dest.mkdirs();
 		return dest;
@@ -170,4 +172,22 @@
 			throw ex;
 		}
 	}
+
+	static void rmdir(File dest) throws IOException {
+		LinkedList<File> queue = new LinkedList<File>();
+		queue.addAll(Arrays.asList(dest.listFiles()));
+		while (!queue.isEmpty()) {
+			File next = queue.removeFirst();
+			if (next.isDirectory()) {
+				List<File> files = Arrays.asList(next.listFiles());
+				if (!files.isEmpty()) {
+					queue.addAll(files);
+					queue.add(next);
+				}
+				// fall through
+			} 
+			next.delete();
+		}
+		dest.delete();
+	}
 }
--- a/test/org/tmatesoft/hg/test/TestClone.java	Thu Jun 06 19:39:06 2013 +0200
+++ b/test/org/tmatesoft/hg/test/TestClone.java	Fri Jun 07 12:32:15 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011 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
@@ -16,16 +16,16 @@
  */
 package org.tmatesoft.hg.test;
 
+import static org.tmatesoft.hg.internal.RequiresFile.*;
+
 import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
 
 import org.hamcrest.CoreMatchers;
 import org.junit.Rule;
 import org.junit.Test;
 import org.tmatesoft.hg.core.HgCloneCommand;
+import org.tmatesoft.hg.core.HgInitCommand;
+import org.tmatesoft.hg.internal.RepoInitializer;
 import org.tmatesoft.hg.repo.HgRemoteRepository;
 
 /**
@@ -56,13 +56,26 @@
 			cmd.source(hgRemote);
 			File dest = new File(tempDir, "test-clone-" + x++);
 			if (dest.exists()) {
-				rmdir(dest);
+				RepoUtils.rmdir(dest);
 			}
 			cmd.destination(dest);
 			cmd.execute();
 			verify(hgRemote, dest);
 		}
 	}
+	
+	@Test
+	public void testInitEmpty() throws Exception {
+		File repoLoc = RepoUtils.createEmptyDir("test-init");
+		new HgInitCommand().location(repoLoc).revlogV1().dotencode(false).fncache(false).execute();
+		
+		int requires = new RepoInitializer().initRequiresFromFile(new File(repoLoc, ".hg")).getRequires();
+		errorCollector.assertTrue(0 != (requires & REVLOGV1));
+		errorCollector.assertTrue(0 != (requires & STORE));
+		errorCollector.assertTrue(0 == (requires & DOTENCODE));
+		errorCollector.assertTrue(0 == (requires & FNCACHE));
+		errorCollector.assertTrue(0 == (requires & REVLOGV0));
+	}
 
 	private void verify(HgRemoteRepository hgRemote, File dest) throws Exception {
 		ExecHelper eh = new ExecHelper(new OutputParser.Stub(), dest);
@@ -73,22 +86,4 @@
 		eh.run("hg", "in", hgRemote.getLocation());
 		errorCollector.checkThat("Incoming", eh.getExitValue(), CoreMatchers.equalTo(1));
 	}
-
-	static void rmdir(File dest) throws IOException {
-		LinkedList<File> queue = new LinkedList<File>();
-		queue.addAll(Arrays.asList(dest.listFiles()));
-		while (!queue.isEmpty()) {
-			File next = queue.removeFirst();
-			if (next.isDirectory()) {
-				List<File> files = Arrays.asList(next.listFiles());
-				if (!files.isEmpty()) {
-					queue.addAll(files);
-					queue.add(next);
-				}
-				// fall through
-			} 
-			next.delete();
-		}
-		dest.delete();
-	}
 }
--- a/test/org/tmatesoft/hg/test/TestStorePath.java	Thu Jun 06 19:39:06 2013 +0200
+++ b/test/org/tmatesoft/hg/test/TestStorePath.java	Fri Jun 07 12:32:15 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
@@ -60,7 +60,7 @@
 	public TestStorePath() {
 		propertyOverrides.put("hg.consolelog.debug", true);
 		sessionCtx = new BasicSessionContext(propertyOverrides, null);
-		repoInit = new RepoInitializer().setRequires(STORE + FNCACHE + DOTENCODE);
+		repoInit = new RepoInitializer().setRequires(REVLOGV1 | STORE | FNCACHE | DOTENCODE);
 		storePathHelper = repoInit.buildDataFilesHelper(sessionCtx);
 	}