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.gitdb.FormatVersion;
|
||||||
import net.kemitix.mon.result.Result;
|
import net.kemitix.mon.result.Result;
|
||||||
|
import net.kemitix.mon.result.WithResultContinuation;
|
||||||
import org.eclipse.jgit.lib.ObjectId;
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.lib.RepositoryCache;
|
import org.eclipse.jgit.lib.RepositoryCache;
|
||||||
|
@ -31,13 +32,16 @@ import org.eclipse.jgit.util.FS;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import static net.kemitix.conditional.Condition.where;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise a new GitDB Repo.
|
* Initialise a new GitDB Repo.
|
||||||
*
|
*
|
||||||
* @author Paul Campbell (pcampbell@kemitix.net)
|
* @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_MESSAGE = "Initialise GitDB v1";
|
||||||
private static final String INIT_USER = "GitDB";
|
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 GIT_DB_VERSION = "GitDB.Version";
|
||||||
private static final String REFS_HEADS_FORMAT = "refs/heads/%s";
|
private static final String REFS_HEADS_FORMAT = "refs/heads/%s";
|
||||||
|
|
||||||
|
private InitGitDBRepo() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise a new GitDB repo.
|
* Initialise a new GitDB repo.
|
||||||
*
|
*
|
||||||
|
@ -53,69 +61,73 @@ class InitGitDBRepo {
|
||||||
* @return a Result containing the created Repository
|
* @return a Result containing the created Repository
|
||||||
*/
|
*/
|
||||||
static Result<Repository> create(final Path dbDir) {
|
static Result<Repository> create(final Path dbDir) {
|
||||||
final InitGitDBRepo initRepo = new InitGitDBRepo();
|
return validDbDir(dbDir.toFile())
|
||||||
return initRepo.validDbDir(dbDir.toFile())
|
|
||||||
.peek(File::mkdirs)
|
.peek(File::mkdirs)
|
||||||
.map(dir -> RepositoryCache.FileKey.exact(dir, FS.DETECTED))
|
.map(InitGitDBRepo::exactDirectory)
|
||||||
.andThen(fileKey -> () -> fileKey.open(false))
|
.andThen(InitGitDBRepo::openRepository)
|
||||||
.thenWith(repository -> () -> repository.create(true))
|
.thenWith(InitGitDBRepo::createRepoDirectory)
|
||||||
.thenWith(repository -> () -> initRepo.createInitialBranchOnMaster(repository));
|
.thenWith(InitGitDBRepo::createInitialMasterBranch);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result<File> validDbDir(final File dbDir) {
|
private static Result<File> validDbDir(final File dbDir) {
|
||||||
return Result.ok(dbDir)
|
return Result.ok(dbDir)
|
||||||
.flatMap(this::verifyIsNotAFile)
|
.flatMap(InitGitDBRepo::isNotAFile)
|
||||||
.flatMap(this::isEmptyIfExists);
|
.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);
|
final GitDBRepo repo = new GitDBRepo(repository);
|
||||||
return new ValueWriter(repository)
|
new ValueWriter(repository)
|
||||||
.write(new FormatVersion().toBytes())
|
.write(new FormatVersion().toBytes())
|
||||||
.flatMap(oid -> repo.insertNewTree(GIT_DB_VERSION, oid))
|
.flatMap(oid -> repo.insertNewTree(GIT_DB_VERSION, oid))
|
||||||
.flatMap(tid -> repo.initialCommit(tid, INIT_MESSAGE, INIT_USER, INIT_EMAIL))
|
.flatMap(tid -> repo.initialCommit(tid, INIT_MESSAGE, INIT_USER, INIT_EMAIL))
|
||||||
.flatMap(cid -> Result.of(() -> {
|
.flatMap(cid -> createBranch(repository, cid, MASTER));
|
||||||
createBranch(repository, cid, MASTER);
|
};
|
||||||
return null;
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result<File> verifyIsNotAFile(final File dbDir) {
|
private static Result<Path> createBranch(
|
||||||
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(
|
|
||||||
final Repository repository,
|
final Repository repository,
|
||||||
final ObjectId commitId,
|
final ObjectId commitId,
|
||||||
final String branchName
|
final String branchName
|
||||||
) {
|
) {
|
||||||
final Path branchRefPath = branchRefPath(repository, branchName);
|
final Path branchRefPath = branchRefPath(repository, branchName);
|
||||||
final byte[] commitIdBytes = commitId.name().getBytes(StandardCharsets.UTF_8);
|
final byte[] commitIdBytes = commitId.name().getBytes(StandardCharsets.UTF_8);
|
||||||
return Result.of(() -> {
|
return Result.of(() -> Files.write(branchRefPath, commitIdBytes));
|
||||||
Files.write(branchRefPath, commitIdBytes);
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Path branchRefPath(
|
private static Path branchRefPath(
|
||||||
final Repository repository,
|
final Repository repository,
|
||||||
final String branchName
|
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