diff --git a/pom.xml b/pom.xml index c40c88c..aaa405f 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ 4.11.0.201803080745-r 5.2.0 3.10.0 - 0.7.0 + 0.8.0 2.18.3 0.9.0 diff --git a/src/main/java/net/kemitix/gitdb/impl/GitDBBranchImpl.java b/src/main/java/net/kemitix/gitdb/impl/GitDBBranchImpl.java index 9b90a36..92b495b 100644 --- a/src/main/java/net/kemitix/gitdb/impl/GitDBBranchImpl.java +++ b/src/main/java/net/kemitix/gitdb/impl/GitDBBranchImpl.java @@ -31,7 +31,6 @@ import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; -import java.io.IOException; import java.util.function.Function; /** @@ -81,14 +80,10 @@ class GitDBBranchImpl implements GitDBBranch { @Override public Result put(final String key, final String value) { - try { - final ObjectId newTree = gitDBRepo.writeValue(branchRef, KEY_PREFIX + key, value); - final String message = String.format("Add key [%s] = [%s]", key, value); - final Result newBranch = gitDBRepo.writeCommit(branchRef, newTree, message, userName, userEmailAddress); - return newBranch.flatMap(b -> select(b, gitDBRepo, userName, userEmailAddress)); - } catch (IOException e) { - return Result.error(e); - } + final String message = String.format("Add key [%s] = [%s]", key, value); + return gitDBRepo.writeValue(branchRef, KEY_PREFIX + key, value) + .flatMap(nt -> gitDBRepo.writeCommit(branchRef, nt, message, userName, userEmailAddress)) + .flatMap(nb -> select(nb, gitDBRepo, userName, userEmailAddress)); } @Override diff --git a/src/main/java/net/kemitix/gitdb/impl/GitDBRepo.java b/src/main/java/net/kemitix/gitdb/impl/GitDBRepo.java index ffc12c3..3a9e1ab 100644 --- a/src/main/java/net/kemitix/gitdb/impl/GitDBRepo.java +++ b/src/main/java/net/kemitix/gitdb/impl/GitDBRepo.java @@ -65,12 +65,11 @@ class GitDBRepo { * @param key the key to insert * @param valueId id of the value * @return the id of the inserted tree - * @throws IOException the tree could not be stored */ - ObjectId insertNewTree( + Result insertNewTree( final String key, final ObjectId valueId - ) throws IOException { + ) { return keyWriter.writeFirst(key, valueId); } @@ -94,11 +93,7 @@ class GitDBRepo { } private Result> streamTree(final Ref branchRef, final GitTreeReader treeFilter) { - try { - return Result.ok(treeFilter.stream(branchRef)); - } catch (IOException e) { - return Result.error(e); - } + return treeFilter.stream(branchRef); } /** @@ -110,11 +105,10 @@ class GitDBRepo { * @param key the key to place the value under * @param value the value * @return the id of the updated tree containing the update - * @throws IOException if there was an error writing the value */ - ObjectId writeValue(final Ref branchRef, final String key, final String value) throws IOException { - final ObjectId blob = valueWriter.write(value.getBytes(StandardCharsets.UTF_8)); - return keyWriter.write(key, blob, branchRef); + Result writeValue(final Ref branchRef, final String key, final String value) { + return valueWriter.write(value.getBytes(StandardCharsets.UTF_8)) + .flatMap(b -> keyWriter.write(key, b, branchRef)); } /** diff --git a/src/main/java/net/kemitix/gitdb/impl/GitTreeReader.java b/src/main/java/net/kemitix/gitdb/impl/GitTreeReader.java index 5abd235..76c82f7 100644 --- a/src/main/java/net/kemitix/gitdb/impl/GitTreeReader.java +++ b/src/main/java/net/kemitix/gitdb/impl/GitTreeReader.java @@ -23,15 +23,20 @@ package net.kemitix.gitdb.impl; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; +import net.kemitix.mon.result.Result; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.filter.PathFilter; import org.eclipse.jgit.treewalk.filter.TreeFilter; -import java.io.IOException; import java.util.Optional; +import java.util.concurrent.Callable; +import java.util.function.Consumer; +import java.util.function.Function; import java.util.stream.Stream; /** @@ -51,23 +56,55 @@ class GitTreeReader { * * @param branchRef the branch to read * @return a stream of key/value pairs as NamedRevBlobs - * @throws IOException if there is an error reading the commit or walking the tree */ - Stream stream(final Ref branchRef) throws IOException { + Result> stream(final Ref branchRef) { final TreeWalk treeWalk = new TreeWalk(repository); final RevWalk revWalk = new RevWalk(repository); - treeWalk.addTree(revWalk.parseCommit(branchRef.getObjectId()).getTree()); - treeWalk.setRecursive(false); - Optional.ofNullable(treeFilter) - .ifPresent(treeWalk::setFilter); - final Stream.Builder builder = Stream.builder(); - while (treeWalk.next()) { - builder.add(new NamedRevBlob( - treeWalk.getNameString(), - revWalk.lookupBlob(treeWalk.getObjectId(0)), - repository)); - } - return builder.build(); + return Result.of(parseBranchCommit(branchRef, revWalk)) + .map(RevCommit::getTree) + .flatMap(addTreeTo(treeWalk)) + .peek(disableRecursion(treeWalk)) + .peek(setTreeFilter(treeWalk)) + .flatMap(streamMatching(treeWalk, revWalk)); + } + + private Function>> streamMatching( + final TreeWalk treeWalk, + final RevWalk revWalk + ) { + return x -> Result.of(() -> { + final Stream.Builder builder = Stream.builder(); + while (treeWalk.next()) { + builder.add(namedRevBlob(treeWalk, revWalk)); + } + return builder.build(); + }); + } + + private NamedRevBlob namedRevBlob(TreeWalk treeWalk, RevWalk revWalk) { + return new NamedRevBlob( + treeWalk.getNameString(), + revWalk.lookupBlob(treeWalk.getObjectId(0)), + repository); + } + + private Consumer setTreeFilter(TreeWalk treeWalk) { + return x -> Optional.ofNullable(treeFilter).ifPresent(treeWalk::setFilter); + } + + private Consumer disableRecursion(TreeWalk treeWalk) { + return x -> treeWalk.setRecursive(false); + } + + private Function> addTreeTo(TreeWalk treeWalk) { + return tree -> Result.of(() -> { + treeWalk.addTree(tree); + return null; + }); + } + + private Callable parseBranchCommit(Ref branchRef, RevWalk revWalk) { + return () -> revWalk.parseCommit(branchRef.getObjectId()); } /** @@ -77,7 +114,7 @@ class GitTreeReader { * @return the GitTreeReader */ GitTreeReader treeFilter(final String path) { - this.treeFilter = PathFilter.create(path); + treeFilter = PathFilter.create(path); return this; } diff --git a/src/main/java/net/kemitix/gitdb/impl/InitGitDBRepo.java b/src/main/java/net/kemitix/gitdb/impl/InitGitDBRepo.java index 25b4fb4..41004bd 100644 --- a/src/main/java/net/kemitix/gitdb/impl/InitGitDBRepo.java +++ b/src/main/java/net/kemitix/gitdb/impl/InitGitDBRepo.java @@ -79,13 +79,16 @@ class InitGitDBRepo { return dbDir; } - private void createInitialBranchOnMaster(final Repository repository) throws IOException { + private Result createInitialBranchOnMaster(final Repository repository) { final GitDBRepo repo = new GitDBRepo(repository); - final ValueWriter valueWriter = new ValueWriter(repository); - final ObjectId objectId = valueWriter.write(new FormatVersion().toBytes()); - final ObjectId treeId = repo.insertNewTree(GIT_DB_VERSION, objectId); - final ObjectId commitId = repo.initialCommit(treeId, INIT_MESSAGE, INIT_USER, INIT_EMAIL); - createBranch(repository, commitId, MASTER); + return new ValueWriter(repository) + .write(new FormatVersion().toBytes()) + .flatMap(oid -> repo.insertNewTree(GIT_DB_VERSION, oid)) + .flatMap(tid -> Result.of(() -> repo.initialCommit(tid, INIT_MESSAGE, INIT_USER, INIT_EMAIL))) + .flatMap(cid -> Result.of(() -> { + createBranch(repository, cid, MASTER); + return null; + })); } private void verifyIsNotAFile(final File dbDir) throws NotDirectoryException { @@ -102,14 +105,17 @@ class InitGitDBRepo { } } - private void createBranch( + private Result createBranch( final Repository repository, final ObjectId commitId, final String branchName - ) throws IOException { + ) { final Path branchRefPath = branchRefPath(repository, branchName); final byte[] commitIdBytes = commitId.name().getBytes(StandardCharsets.UTF_8); - Files.write(branchRefPath, commitIdBytes); + return Result.of(() -> { + Files.write(branchRefPath, commitIdBytes); + return null; + }); } private Path branchRefPath( diff --git a/src/main/java/net/kemitix/gitdb/impl/KeyRemover.java b/src/main/java/net/kemitix/gitdb/impl/KeyRemover.java index 6146f0c..392e540 100644 --- a/src/main/java/net/kemitix/gitdb/impl/KeyRemover.java +++ b/src/main/java/net/kemitix/gitdb/impl/KeyRemover.java @@ -51,16 +51,12 @@ class KeyRemover { Result> remove(final Ref branchRef, final String key) { final TreeFormatter treeFormatter = new TreeFormatter(); final AtomicBoolean removed = new AtomicBoolean(false); - try { - new GitTreeReader(repository) - .stream(branchRef) - .peek(flagIfFound(key, removed)) - .filter(isNotKey(key)) - .forEach(addToTree(treeFormatter)); - return insertTree(treeFormatter).maybe(oi -> removed.get()); - } catch (IOException e) { - return Result.error(e); - } + new GitTreeReader(repository) + .stream(branchRef) + .peek(s -> s.peek(flagIfFound(key, removed)) + .filter(isNotKey(key)) + .forEach(addToTree(treeFormatter))); + return insertTree(treeFormatter).maybe(oi -> removed.get()); } /** diff --git a/src/main/java/net/kemitix/gitdb/impl/KeyWriter.java b/src/main/java/net/kemitix/gitdb/impl/KeyWriter.java index 1dc00c1..0c7364b 100644 --- a/src/main/java/net/kemitix/gitdb/impl/KeyWriter.java +++ b/src/main/java/net/kemitix/gitdb/impl/KeyWriter.java @@ -21,10 +21,9 @@ package net.kemitix.gitdb.impl; +import net.kemitix.mon.result.Result; import org.eclipse.jgit.lib.*; -import java.io.IOException; - /** * Writes Keys into the Git Repository. * @@ -48,42 +47,41 @@ class KeyWriter { /** * Write the first key into a new tree. * - * @param key the key + * @param key the key * @param valueId the id of the value * @return the id of the new tree - * @throws IOException if there is an error writing the key */ - ObjectId writeFirst(final String key, final ObjectId valueId) throws IOException { + Result writeFirst(final String key, final ObjectId valueId) { return writeTree(key, valueId, new TreeFormatter()); } /** * Write the key into a tree. * - * @param key the key - * @param valueId the id of the value + * @param key the key + * @param valueId the id of the value * @param branchRef the branch whose tree should be updated * @return the id of the updated tree - * @throws IOException if there is an error writing the key */ - ObjectId write(final String key, final ObjectId valueId, final Ref branchRef) throws IOException { - return writeTree(key, valueId, getTreeFormatter(branchRef)); + Result write(final String key, final ObjectId valueId, final Ref branchRef) { + return getTreeFormatter(branchRef) + .flatMap(f -> writeTree(key, valueId, f)); } - private TreeFormatter getTreeFormatter(final Ref branchRef) throws IOException { + private Result getTreeFormatter(final Ref branchRef) { final TreeFormatter treeFormatter = new TreeFormatter(); final GitTreeReader gitTreeReader = new GitTreeReader(repository); - gitTreeReader.stream(branchRef) - .forEach(item -> treeFormatter.append(item.getName(), item.getRevBlob())); - return treeFormatter; + return gitTreeReader.stream(branchRef) + .peek(s -> s.forEach(item -> treeFormatter.append(item.getName(), item.getRevBlob()))) + .map(x -> treeFormatter); } - private ObjectId writeTree( + private Result writeTree( final String key, final ObjectId valueId, final TreeFormatter treeFormatter - ) throws IOException { + ) { treeFormatter.append(key, FileMode.REGULAR_FILE, valueId); - return objectInserter.insert(treeFormatter); + return Result.of(() -> objectInserter.insert(treeFormatter)); } } diff --git a/src/main/java/net/kemitix/gitdb/impl/ValueWriter.java b/src/main/java/net/kemitix/gitdb/impl/ValueWriter.java index f066551..7fa9b37 100644 --- a/src/main/java/net/kemitix/gitdb/impl/ValueWriter.java +++ b/src/main/java/net/kemitix/gitdb/impl/ValueWriter.java @@ -21,13 +21,12 @@ package net.kemitix.gitdb.impl; +import net.kemitix.mon.result.Result; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.Repository; -import java.io.IOException; - /** * Writes Values into the Git Repository. * @@ -51,9 +50,8 @@ class ValueWriter { * * @param blob the value blob * @return the id of the value object - * @throws IOException if there is an error writing the value */ - ObjectId write(final byte[] blob) throws IOException { - return objectInserter.insert(Constants.OBJ_BLOB, blob); + Result write(final byte[] blob) { + return Result.of(() -> objectInserter.insert(Constants.OBJ_BLOB, blob)); } }