# HG changeset patch # User Artem Tikhomirov # Date 1370601135 -7200 # Node ID 4a0bab2c6da1afdd2a5b2d833eb1850f90955f6a # Parent ffce73efa2c262588eee7d53fd5b825583775be7 HgInitCommand: expose repo init functionality diff -r ffce73efa2c2 -r 4a0bab2c6da1 src/org/tmatesoft/hg/core/HgCloneCommand.java --- 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; diff -r ffce73efa2c2 -r 4a0bab2c6da1 src/org/tmatesoft/hg/core/HgInitCommand.java --- /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. + *

+ * Two predefined alternatives are available, {@link #revlogV0() old} and {@link #revlogV1() new} mercurial format respectively. + *

+ * 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 { + 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; + } +} diff -r ffce73efa2c2 -r 4a0bab2c6da1 src/org/tmatesoft/hg/core/HgRepoFacade.java --- 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 null + */ + public HgInitCommand createInitCommand() { + return new HgInitCommand(new HgLookup(context)); + } public HgLogCommand createLogCommand() { return new HgLogCommand(repo/*, getCommandContext()*/); diff -r ffce73efa2c2 -r 4a0bab2c6da1 src/org/tmatesoft/hg/internal/RepoInitializer.java --- 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) { diff -r ffce73efa2c2 -r 4a0bab2c6da1 test/org/tmatesoft/hg/test/ComplexTest.java --- 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 diff -r ffce73efa2c2 -r 4a0bab2c6da1 test/org/tmatesoft/hg/test/RepoUtils.java --- 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 queue = new LinkedList(); + queue.addAll(Arrays.asList(dest.listFiles())); + while (!queue.isEmpty()) { + File next = queue.removeFirst(); + if (next.isDirectory()) { + List files = Arrays.asList(next.listFiles()); + if (!files.isEmpty()) { + queue.addAll(files); + queue.add(next); + } + // fall through + } + next.delete(); + } + dest.delete(); + } } diff -r ffce73efa2c2 -r 4a0bab2c6da1 test/org/tmatesoft/hg/test/TestClone.java --- 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 queue = new LinkedList(); - queue.addAll(Arrays.asList(dest.listFiles())); - while (!queue.isEmpty()) { - File next = queue.removeFirst(); - if (next.isDirectory()) { - List files = Arrays.asList(next.listFiles()); - if (!files.isEmpty()) { - queue.addAll(files); - queue.add(next); - } - // fall through - } - next.delete(); - } - dest.delete(); - } } diff -r ffce73efa2c2 -r 4a0bab2c6da1 test/org/tmatesoft/hg/test/TestStorePath.java --- 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); }