InitGitDBRepo: refactored
This commit is contained in:
parent
a2c97b6170
commit
297a952f43
2 changed files with 73 additions and 43 deletions
|
@ -23,6 +23,7 @@ package net.kemitix.gitdb.impl;
|
|||
|
||||
import net.kemitix.gitdb.FormatVersion;
|
||||
import net.kemitix.mon.result.Result;
|
||||
import net.kemitix.mon.result.WithResultContinuation;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.RepositoryCache;
|
||||
|
@ -31,13 +32,16 @@ import org.eclipse.jgit.util.FS;
|
|||
import java.io.File;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.*;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import static net.kemitix.conditional.Condition.where;
|
||||
|
||||
/**
|
||||
* Initialise a new GitDB Repo.
|
||||
*
|
||||
* @author Paul Campbell (pcampbell@kemitix.net)
|
||||
*/
|
||||
class InitGitDBRepo {
|
||||
final class InitGitDBRepo {
|
||||
|
||||
private static final String INIT_MESSAGE = "Initialise GitDB v1";
|
||||
private static final String INIT_USER = "GitDB";
|
||||
|
@ -46,6 +50,10 @@ class InitGitDBRepo {
|
|||
private static final String GIT_DB_VERSION = "GitDB.Version";
|
||||
private static final String REFS_HEADS_FORMAT = "refs/heads/%s";
|
||||
|
||||
private InitGitDBRepo() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise a new GitDB repo.
|
||||
*
|
||||
|
@ -53,69 +61,73 @@ class InitGitDBRepo {
|
|||
* @return a Result containing the created Repository
|
||||
*/
|
||||
static Result<Repository> create(final Path dbDir) {
|
||||
final InitGitDBRepo initRepo = new InitGitDBRepo();
|
||||
return initRepo.validDbDir(dbDir.toFile())
|
||||
return validDbDir(dbDir.toFile())
|
||||
.peek(File::mkdirs)
|
||||
.map(dir -> RepositoryCache.FileKey.exact(dir, FS.DETECTED))
|
||||
.andThen(fileKey -> () -> fileKey.open(false))
|
||||
.thenWith(repository -> () -> repository.create(true))
|
||||
.thenWith(repository -> () -> initRepo.createInitialBranchOnMaster(repository));
|
||||
.map(InitGitDBRepo::exactDirectory)
|
||||
.andThen(InitGitDBRepo::openRepository)
|
||||
.thenWith(InitGitDBRepo::createRepoDirectory)
|
||||
.thenWith(InitGitDBRepo::createInitialMasterBranch);
|
||||
}
|
||||
|
||||
private Result<File> validDbDir(final File dbDir) {
|
||||
private static Result<File> validDbDir(final File dbDir) {
|
||||
return Result.ok(dbDir)
|
||||
.flatMap(this::verifyIsNotAFile)
|
||||
.flatMap(this::isEmptyIfExists);
|
||||
.flatMap(InitGitDBRepo::isNotAFile)
|
||||
.flatMap(InitGitDBRepo::ifExistsThenIsEmpty);
|
||||
}
|
||||
|
||||
private Result<Void> createInitialBranchOnMaster(final Repository repository) {
|
||||
private static Result<File> isNotAFile(final File dbDir) {
|
||||
return Result.ok(dbDir)
|
||||
.thenWith(dir -> () -> where(dir.isFile()).thenThrow(new NotDirectoryException(dbDir.toString())));
|
||||
}
|
||||
|
||||
private static Result<File> ifExistsThenIsEmpty(final File dbDir) {
|
||||
return Result.ok(dbDir)
|
||||
.thenWith(dir -> () -> {
|
||||
if (dir.exists()) {
|
||||
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(dbDir.toPath())) {
|
||||
where(directoryStream.iterator().hasNext())
|
||||
.thenThrow(new DirectoryNotEmptyException(dbDir.toString()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static RepositoryCache.FileKey exactDirectory(final File dir) {
|
||||
return RepositoryCache.FileKey.exact(dir, FS.DETECTED);
|
||||
}
|
||||
|
||||
private static Callable<Repository> openRepository(final RepositoryCache.FileKey fileKey) {
|
||||
return () -> fileKey.open(false);
|
||||
}
|
||||
|
||||
private static WithResultContinuation<Repository> createRepoDirectory(final Repository repository) {
|
||||
return () -> repository.create(true);
|
||||
}
|
||||
|
||||
private static WithResultContinuation<Repository> createInitialMasterBranch(
|
||||
final Repository repository
|
||||
) {
|
||||
return () -> {
|
||||
final GitDBRepo repo = new GitDBRepo(repository);
|
||||
return new ValueWriter(repository)
|
||||
new ValueWriter(repository)
|
||||
.write(new FormatVersion().toBytes())
|
||||
.flatMap(oid -> repo.insertNewTree(GIT_DB_VERSION, oid))
|
||||
.flatMap(tid -> repo.initialCommit(tid, INIT_MESSAGE, INIT_USER, INIT_EMAIL))
|
||||
.flatMap(cid -> Result.of(() -> {
|
||||
createBranch(repository, cid, MASTER);
|
||||
return null;
|
||||
}));
|
||||
.flatMap(cid -> createBranch(repository, cid, MASTER));
|
||||
};
|
||||
}
|
||||
|
||||
private Result<File> verifyIsNotAFile(final File dbDir) {
|
||||
if (dbDir.isFile()) {
|
||||
return Result.error(new NotDirectoryException(dbDir.toString()));
|
||||
}
|
||||
return Result.ok(dbDir);
|
||||
}
|
||||
|
||||
private Result<File> isEmptyIfExists(final File dbDir) {
|
||||
if (dbDir.exists()) {
|
||||
return Result.of(() -> {
|
||||
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(dbDir.toPath())) {
|
||||
if (directoryStream.iterator().hasNext()) {
|
||||
throw new DirectoryNotEmptyException(dbDir.toString());
|
||||
}
|
||||
}
|
||||
return dbDir;
|
||||
}
|
||||
);
|
||||
}
|
||||
return Result.ok(dbDir);
|
||||
}
|
||||
|
||||
private Result<Void> createBranch(
|
||||
private static Result<Path> createBranch(
|
||||
final Repository repository,
|
||||
final ObjectId commitId,
|
||||
final String branchName
|
||||
) {
|
||||
final Path branchRefPath = branchRefPath(repository, branchName);
|
||||
final byte[] commitIdBytes = commitId.name().getBytes(StandardCharsets.UTF_8);
|
||||
return Result.of(() -> {
|
||||
Files.write(branchRefPath, commitIdBytes);
|
||||
return null;
|
||||
});
|
||||
return Result.of(() -> Files.write(branchRefPath, commitIdBytes));
|
||||
}
|
||||
|
||||
private Path branchRefPath(
|
||||
private static Path branchRefPath(
|
||||
final Repository repository,
|
||||
final String branchName
|
||||
) {
|
||||
|
|
18
src/test/java/net/kemitix/gitdb/impl/InitGitDBRepoTest.java
Normal file
18
src/test/java/net/kemitix/gitdb/impl/InitGitDBRepoTest.java
Normal file
|
@ -0,0 +1,18 @@
|
|||
package net.kemitix.gitdb.impl;
|
||||
|
||||
import org.assertj.core.api.WithAssertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
class InitGitDBRepoTest implements WithAssertions {
|
||||
|
||||
@Test
|
||||
void utilityClassCannotBeInstantiated() throws NoSuchMethodException {
|
||||
final Constructor<InitGitDBRepo> constructor = InitGitDBRepo.class.getDeclaredConstructor();
|
||||
constructor.setAccessible(true);
|
||||
assertThatCode(constructor::newInstance)
|
||||
.hasCauseInstanceOf(UnsupportedOperationException.class);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue