More classes return Result<T> values

This commit is contained in:
Paul Campbell 2018-06-30 20:37:32 +01:00
parent 98b81a44dc
commit 9eff624a05
8 changed files with 103 additions and 79 deletions

View file

@ -21,7 +21,7 @@
<jgit.version>4.11.0.201803080745-r</jgit.version> <jgit.version>4.11.0.201803080745-r</jgit.version>
<junit.version>5.2.0</junit.version> <junit.version>5.2.0</junit.version>
<assertj.version>3.10.0</assertj.version> <assertj.version>3.10.0</assertj.version>
<mon.version>0.7.0</mon.version> <mon.version>0.8.0</mon.version>
<mockito.version>2.18.3</mockito.version> <mockito.version>2.18.3</mockito.version>
<java-semver.version>0.9.0</java-semver.version> <java-semver.version>0.9.0</java-semver.version>
</properties> </properties>

View file

@ -31,7 +31,6 @@ import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
import java.io.IOException;
import java.util.function.Function; import java.util.function.Function;
/** /**
@ -81,14 +80,10 @@ class GitDBBranchImpl implements GitDBBranch {
@Override @Override
public Result<GitDBBranch> put(final String key, final String value) { public Result<GitDBBranch> 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 String message = String.format("Add key [%s] = [%s]", key, value);
final Result<Ref> newBranch = gitDBRepo.writeCommit(branchRef, newTree, message, userName, userEmailAddress); return gitDBRepo.writeValue(branchRef, KEY_PREFIX + key, value)
return newBranch.flatMap(b -> select(b, gitDBRepo, userName, userEmailAddress)); .flatMap(nt -> gitDBRepo.writeCommit(branchRef, nt, message, userName, userEmailAddress))
} catch (IOException e) { .flatMap(nb -> select(nb, gitDBRepo, userName, userEmailAddress));
return Result.error(e);
}
} }
@Override @Override

View file

@ -65,12 +65,11 @@ class GitDBRepo {
* @param key the key to insert * @param key the key to insert
* @param valueId id of the value * @param valueId id of the value
* @return the id of the inserted tree * @return the id of the inserted tree
* @throws IOException the tree could not be stored
*/ */
ObjectId insertNewTree( Result<ObjectId> insertNewTree(
final String key, final String key,
final ObjectId valueId final ObjectId valueId
) throws IOException { ) {
return keyWriter.writeFirst(key, valueId); return keyWriter.writeFirst(key, valueId);
} }
@ -94,11 +93,7 @@ class GitDBRepo {
} }
private Result<Stream<NamedRevBlob>> streamTree(final Ref branchRef, final GitTreeReader treeFilter) { private Result<Stream<NamedRevBlob>> streamTree(final Ref branchRef, final GitTreeReader treeFilter) {
try { return treeFilter.stream(branchRef);
return Result.ok(treeFilter.stream(branchRef));
} catch (IOException e) {
return Result.error(e);
}
} }
/** /**
@ -110,11 +105,10 @@ class GitDBRepo {
* @param key the key to place the value under * @param key the key to place the value under
* @param value the value * @param value the value
* @return the id of the updated tree containing the update * @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 { Result<ObjectId> writeValue(final Ref branchRef, final String key, final String value) {
final ObjectId blob = valueWriter.write(value.getBytes(StandardCharsets.UTF_8)); return valueWriter.write(value.getBytes(StandardCharsets.UTF_8))
return keyWriter.write(key, blob, branchRef); .flatMap(b -> keyWriter.write(key, b, branchRef));
} }
/** /**

View file

@ -23,15 +23,20 @@ package net.kemitix.gitdb.impl;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import net.kemitix.mon.result.Result;
import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository; 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.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.PathFilter; import org.eclipse.jgit.treewalk.filter.PathFilter;
import org.eclipse.jgit.treewalk.filter.TreeFilter; import org.eclipse.jgit.treewalk.filter.TreeFilter;
import java.io.IOException;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
@ -51,23 +56,55 @@ class GitTreeReader {
* *
* @param branchRef the branch to read * @param branchRef the branch to read
* @return a stream of key/value pairs as NamedRevBlobs * @return a stream of key/value pairs as NamedRevBlobs
* @throws IOException if there is an error reading the commit or walking the tree
*/ */
Stream<NamedRevBlob> stream(final Ref branchRef) throws IOException { Result<Stream<NamedRevBlob>> stream(final Ref branchRef) {
final TreeWalk treeWalk = new TreeWalk(repository); final TreeWalk treeWalk = new TreeWalk(repository);
final RevWalk revWalk = new RevWalk(repository); final RevWalk revWalk = new RevWalk(repository);
treeWalk.addTree(revWalk.parseCommit(branchRef.getObjectId()).getTree()); return Result.of(parseBranchCommit(branchRef, revWalk))
treeWalk.setRecursive(false); .map(RevCommit::getTree)
Optional.ofNullable(treeFilter) .flatMap(addTreeTo(treeWalk))
.ifPresent(treeWalk::setFilter); .peek(disableRecursion(treeWalk))
.peek(setTreeFilter(treeWalk))
.flatMap(streamMatching(treeWalk, revWalk));
}
private Function<Void, Result<Stream<NamedRevBlob>>> streamMatching(
final TreeWalk treeWalk,
final RevWalk revWalk
) {
return x -> Result.of(() -> {
final Stream.Builder<NamedRevBlob> builder = Stream.builder(); final Stream.Builder<NamedRevBlob> builder = Stream.builder();
while (treeWalk.next()) { while (treeWalk.next()) {
builder.add(new NamedRevBlob( builder.add(namedRevBlob(treeWalk, revWalk));
treeWalk.getNameString(),
revWalk.lookupBlob(treeWalk.getObjectId(0)),
repository));
} }
return builder.build(); return builder.build();
});
}
private NamedRevBlob namedRevBlob(TreeWalk treeWalk, RevWalk revWalk) {
return new NamedRevBlob(
treeWalk.getNameString(),
revWalk.lookupBlob(treeWalk.getObjectId(0)),
repository);
}
private Consumer<Void> setTreeFilter(TreeWalk treeWalk) {
return x -> Optional.ofNullable(treeFilter).ifPresent(treeWalk::setFilter);
}
private Consumer<Void> disableRecursion(TreeWalk treeWalk) {
return x -> treeWalk.setRecursive(false);
}
private Function<RevTree, Result<Void>> addTreeTo(TreeWalk treeWalk) {
return tree -> Result.of(() -> {
treeWalk.addTree(tree);
return null;
});
}
private Callable<RevCommit> parseBranchCommit(Ref branchRef, RevWalk revWalk) {
return () -> revWalk.parseCommit(branchRef.getObjectId());
} }
/** /**
@ -77,7 +114,7 @@ class GitTreeReader {
* @return the GitTreeReader * @return the GitTreeReader
*/ */
GitTreeReader treeFilter(final String path) { GitTreeReader treeFilter(final String path) {
this.treeFilter = PathFilter.create(path); treeFilter = PathFilter.create(path);
return this; return this;
} }

View file

@ -79,13 +79,16 @@ class InitGitDBRepo {
return dbDir; return dbDir;
} }
private void createInitialBranchOnMaster(final Repository repository) throws IOException { private Result<Void> createInitialBranchOnMaster(final Repository repository) {
final GitDBRepo repo = new GitDBRepo(repository); final GitDBRepo repo = new GitDBRepo(repository);
final ValueWriter valueWriter = new ValueWriter(repository); return new ValueWriter(repository)
final ObjectId objectId = valueWriter.write(new FormatVersion().toBytes()); .write(new FormatVersion().toBytes())
final ObjectId treeId = repo.insertNewTree(GIT_DB_VERSION, objectId); .flatMap(oid -> repo.insertNewTree(GIT_DB_VERSION, oid))
final ObjectId commitId = repo.initialCommit(treeId, INIT_MESSAGE, INIT_USER, INIT_EMAIL); .flatMap(tid -> Result.of(() -> repo.initialCommit(tid, INIT_MESSAGE, INIT_USER, INIT_EMAIL)))
createBranch(repository, commitId, MASTER); .flatMap(cid -> Result.of(() -> {
createBranch(repository, cid, MASTER);
return null;
}));
} }
private void verifyIsNotAFile(final File dbDir) throws NotDirectoryException { private void verifyIsNotAFile(final File dbDir) throws NotDirectoryException {
@ -102,14 +105,17 @@ class InitGitDBRepo {
} }
} }
private void createBranch( private Result<Void> createBranch(
final Repository repository, final Repository repository,
final ObjectId commitId, final ObjectId commitId,
final String branchName final String branchName
) throws IOException { ) {
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(() -> {
Files.write(branchRefPath, commitIdBytes); Files.write(branchRefPath, commitIdBytes);
return null;
});
} }
private Path branchRefPath( private Path branchRefPath(

View file

@ -51,16 +51,12 @@ class KeyRemover {
Result<Maybe<ObjectId>> remove(final Ref branchRef, final String key) { Result<Maybe<ObjectId>> remove(final Ref branchRef, final String key) {
final TreeFormatter treeFormatter = new TreeFormatter(); final TreeFormatter treeFormatter = new TreeFormatter();
final AtomicBoolean removed = new AtomicBoolean(false); final AtomicBoolean removed = new AtomicBoolean(false);
try {
new GitTreeReader(repository) new GitTreeReader(repository)
.stream(branchRef) .stream(branchRef)
.peek(flagIfFound(key, removed)) .peek(s -> s.peek(flagIfFound(key, removed))
.filter(isNotKey(key)) .filter(isNotKey(key))
.forEach(addToTree(treeFormatter)); .forEach(addToTree(treeFormatter)));
return insertTree(treeFormatter).maybe(oi -> removed.get()); return insertTree(treeFormatter).maybe(oi -> removed.get());
} catch (IOException e) {
return Result.error(e);
}
} }
/** /**

View file

@ -21,10 +21,9 @@
package net.kemitix.gitdb.impl; package net.kemitix.gitdb.impl;
import net.kemitix.mon.result.Result;
import org.eclipse.jgit.lib.*; import org.eclipse.jgit.lib.*;
import java.io.IOException;
/** /**
* Writes Keys into the Git Repository. * Writes Keys into the Git Repository.
* *
@ -51,9 +50,8 @@ class KeyWriter {
* @param key the key * @param key the key
* @param valueId the id of the value * @param valueId the id of the value
* @return the id of the new tree * @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<ObjectId> writeFirst(final String key, final ObjectId valueId) {
return writeTree(key, valueId, new TreeFormatter()); return writeTree(key, valueId, new TreeFormatter());
} }
@ -64,26 +62,26 @@ class KeyWriter {
* @param valueId the id of the value * @param valueId the id of the value
* @param branchRef the branch whose tree should be updated * @param branchRef the branch whose tree should be updated
* @return the id of the updated tree * @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 { Result<ObjectId> write(final String key, final ObjectId valueId, final Ref branchRef) {
return writeTree(key, valueId, getTreeFormatter(branchRef)); return getTreeFormatter(branchRef)
.flatMap(f -> writeTree(key, valueId, f));
} }
private TreeFormatter getTreeFormatter(final Ref branchRef) throws IOException { private Result<TreeFormatter> getTreeFormatter(final Ref branchRef) {
final TreeFormatter treeFormatter = new TreeFormatter(); final TreeFormatter treeFormatter = new TreeFormatter();
final GitTreeReader gitTreeReader = new GitTreeReader(repository); final GitTreeReader gitTreeReader = new GitTreeReader(repository);
gitTreeReader.stream(branchRef) return gitTreeReader.stream(branchRef)
.forEach(item -> treeFormatter.append(item.getName(), item.getRevBlob())); .peek(s -> s.forEach(item -> treeFormatter.append(item.getName(), item.getRevBlob())))
return treeFormatter; .map(x -> treeFormatter);
} }
private ObjectId writeTree( private Result<ObjectId> writeTree(
final String key, final String key,
final ObjectId valueId, final ObjectId valueId,
final TreeFormatter treeFormatter final TreeFormatter treeFormatter
) throws IOException { ) {
treeFormatter.append(key, FileMode.REGULAR_FILE, valueId); treeFormatter.append(key, FileMode.REGULAR_FILE, valueId);
return objectInserter.insert(treeFormatter); return Result.of(() -> objectInserter.insert(treeFormatter));
} }
} }

View file

@ -21,13 +21,12 @@
package net.kemitix.gitdb.impl; package net.kemitix.gitdb.impl;
import net.kemitix.mon.result.Result;
import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
import java.io.IOException;
/** /**
* Writes Values into the Git Repository. * Writes Values into the Git Repository.
* *
@ -51,9 +50,8 @@ class ValueWriter {
* *
* @param blob the value blob * @param blob the value blob
* @return the id of the value object * @return the id of the value object
* @throws IOException if there is an error writing the value
*/ */
ObjectId write(final byte[] blob) throws IOException { Result<ObjectId> write(final byte[] blob) {
return objectInserter.insert(Constants.OBJ_BLOB, blob); return Result.of(() -> objectInserter.insert(Constants.OBJ_BLOB, blob));
} }
} }