remove(String key);
/**
* Returns the GitDB format for the current branch.
@@ -67,8 +63,7 @@ public interface GitDBBranch {
* Different branches can have different versions.
*
* @return the format as per semantic versioning, i.e. "x.y.z" within an Optional
- * @throws IOException error reading version
*/
- Optional getFormatVersion() throws IOException;
+ Result> getFormatVersion();
}
diff --git a/src/main/java/net/kemitix/gitdb/impl/CommitWriter.java b/src/main/java/net/kemitix/gitdb/impl/CommitWriter.java
index 4f9cf11..9b2dd07 100644
--- a/src/main/java/net/kemitix/gitdb/impl/CommitWriter.java
+++ b/src/main/java/net/kemitix/gitdb/impl/CommitWriter.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;
-
/**
* Commits Key/Value updates into the Git Repository.
*
@@ -52,15 +51,14 @@ class CommitWriter {
* @param userName the user name
* @param userEmailAddress the user email address
* @return the id of the commit
- * @throws IOException if there is an error writing the value
*/
- ObjectId write(
+ Result write(
final ObjectId treeId,
final ObjectId parentId,
final String message,
final String userName,
final String userEmailAddress
- ) throws IOException {
+ ) {
final CommitBuilder commitBuilder = new CommitBuilder();
commitBuilder.setTreeId(treeId);
commitBuilder.setMessage(message);
@@ -68,7 +66,7 @@ class CommitWriter {
commitBuilder.setAuthor(ident);
commitBuilder.setCommitter(ident);
commitBuilder.setParentId(parentId);
- return objectInserter.insert(commitBuilder);
+ return Result.of(() -> objectInserter.insert(commitBuilder));
}
/**
@@ -82,15 +80,14 @@ class CommitWriter {
* @param userName the user name
* @param userEmailAddress the user email address
* @return the id of the commit
- * @throws IOException if there is an error writing the value
*/
- ObjectId write(
+ Result write(
final ObjectId treeId,
final Ref branchRef,
final String message,
final String userName,
final String userEmailAddress
- ) throws IOException {
+ ) {
return write(treeId, branchRef.getObjectId(), message, userName, userEmailAddress);
}
}
diff --git a/src/main/java/net/kemitix/gitdb/impl/GitDBBranchImpl.java b/src/main/java/net/kemitix/gitdb/impl/GitDBBranchImpl.java
index 097c646..92b495b 100644
--- a/src/main/java/net/kemitix/gitdb/impl/GitDBBranchImpl.java
+++ b/src/main/java/net/kemitix/gitdb/impl/GitDBBranchImpl.java
@@ -25,12 +25,12 @@ import com.github.zafarkhaja.semver.Version;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import net.kemitix.gitdb.GitDBBranch;
+import net.kemitix.mon.maybe.Maybe;
+import net.kemitix.mon.result.Result;
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.Optional;
import java.util.function.Function;
/**
@@ -48,15 +48,6 @@ class GitDBBranchImpl implements GitDBBranch {
private final String userEmailAddress;
private final String name;
- private static GitDBBranch select(
- final Ref branchRef,
- final GitDBRepo gitDBRepo,
- final String userName,
- final String userEmailAddress
- ) {
- return new GitDBBranchImpl(branchRef, gitDBRepo, userName, userEmailAddress, branchRef.getName());
- }
-
/**
* Initialise the creation of new GitDBBranch instances.
*
@@ -65,7 +56,7 @@ class GitDBBranchImpl implements GitDBBranch {
* @param userEmailAddress the user's email address to record against changes
* @return a Function for creating a GitDBBranch when supplied with a Ref for a branch
*/
- static Function[ init(
+ static Function][> init(
final Repository repository,
final String userName,
final String userEmailAddress
@@ -73,38 +64,52 @@ class GitDBBranchImpl implements GitDBBranch {
return ref -> select(ref, new GitDBRepo(repository), userName, userEmailAddress);
}
+ private static Result select(
+ final Ref branchRef,
+ final GitDBRepo gitDBRepo,
+ final String userName,
+ final String userEmailAddress
+ ) {
+ return Result.ok(new GitDBBranchImpl(branchRef, gitDBRepo, userName, userEmailAddress, branchRef.getName()));
+ }
+
@Override
- public Optional get(final String key) throws IOException {
+ public Result> get(final String key) {
return gitDBRepo.readValue(branchRef, KEY_PREFIX + key);
}
@Override
- public GitDBBranch put(final String key, final String value) throws IOException {
- final ObjectId newTree = gitDBRepo.writeValue(branchRef, KEY_PREFIX + key, value);
+ public Result put(final String key, final String value) {
final String message = String.format("Add key [%s] = [%s]", key, value);
- final Ref newBranch = gitDBRepo.writeCommit(branchRef, newTree, message, userName, userEmailAddress);
- return select(newBranch, gitDBRepo, userName, userEmailAddress);
+ 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
- public GitDBBranch remove(final String key) throws IOException {
- final Optional newTree = gitDBRepo.removeKey(branchRef, KEY_PREFIX + key);
- if (newTree.isPresent()) {
- final Ref newBranch =
- gitDBRepo.writeCommit(
- branchRef, newTree.get(),
- String.format("Remove Key [%s]", key),
- userName,
- userEmailAddress);
- return select(newBranch, gitDBRepo, userName, userEmailAddress);
- }
- return this;
+ public Result remove(final String key) {
+ return gitDBRepo.removeKey(branchRef, KEY_PREFIX + key).flatMap(treeId ->
+ writeRemoveKeyCommit(key, treeId)
+ .map(selectUpdatedBranch())
+ .orElse(Result.ok(this)));
+ }
+
+ private Maybe> writeRemoveKeyCommit(final String key, final Maybe idMaybe) {
+ return idMaybe.map(objectId -> {
+ final String message = String.format("Remove Key [%s]", key);
+ return gitDBRepo.writeCommit(branchRef, objectId, message, userName, userEmailAddress);
+ });
+ }
+
+ private Function, Result> selectUpdatedBranch() {
+ return refResult -> refResult.flatMap(ref ->
+ select(ref, gitDBRepo, userName, userEmailAddress));
}
@Override
- public Optional getFormatVersion() throws IOException {
+ public Result> getFormatVersion() {
return gitDBRepo.readValue(branchRef, "GitDB.Version")
- .map(Version::valueOf);
+ .map(version -> version.map(Version::valueOf));
}
}
diff --git a/src/main/java/net/kemitix/gitdb/impl/GitDBRepo.java b/src/main/java/net/kemitix/gitdb/impl/GitDBRepo.java
index 1efbe7c..8bdedce 100644
--- a/src/main/java/net/kemitix/gitdb/impl/GitDBRepo.java
+++ b/src/main/java/net/kemitix/gitdb/impl/GitDBRepo.java
@@ -21,14 +21,14 @@
package net.kemitix.gitdb.impl;
-import lombok.val;
+import net.kemitix.mon.maybe.Maybe;
+import net.kemitix.mon.result.Result;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
-import java.io.IOException;
import java.nio.charset.StandardCharsets;
-import java.util.Optional;
+import java.util.stream.Stream;
/**
* Wrapper for interacting with the GitDB Repository.
@@ -47,7 +47,7 @@ class GitDBRepo {
/**
* Creates a new instance of this class.
*
- * @param repository the Git Repository
+ * @param repository the Git Repository
*/
GitDBRepo(final Repository repository) {
this.repository = repository;
@@ -64,56 +64,35 @@ 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);
}
- /**
- * Insert a commit into the store, returning its unique id.
- *
- * @param treeId id of the tree
- * @param branchRef the branch to commit to
- * @param message the message
- * @param userName the user name
- * @param userEmailAddress the user email address
- * @return the id of the commit
- * @throws IOException the commit could not be stored
- */
- ObjectId insertCommit(
- final ObjectId treeId,
- final String message,
- final String userName,
- final String userEmailAddress,
- final Ref branchRef
- ) throws IOException {
- return commitWriter.write(treeId, branchRef, message, userName, userEmailAddress);
- }
-
/**
* Reads a value from the branch with the given key.
*
* @param branchRef the branch to select from
* @param key the key to get the value for
* @return an Optional containing the value if found, or empty
- * @throws IOException if there was an error reading the value
*/
- Optional readValue(
+ Result> readValue(
final Ref branchRef,
final String key
- ) throws IOException {
- val blob = new GitTreeReader(repository)
- .treeFilter(key)
- .stream(branchRef)
- .findFirst();
- if (blob.isPresent()) {
- return Optional.of(blob.get().blobAsString());
- }
- return Optional.empty();
+ ) {
+ final GitTreeReader treeFilter = new GitTreeReader(repository).treeFilter(key);
+ return streamTree(branchRef, treeFilter).flatMap(s ->
+ Result.invert(s.findFirst()
+ .map(NamedRevBlob::blobAsString)
+ .map(Maybe::just)
+ .orElseGet(Maybe::nothing)));
+ }
+
+ private Result> streamTree(final Ref branchRef, final GitTreeReader treeFilter) {
+ return treeFilter.stream(branchRef);
}
/**
@@ -125,11 +104,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));
}
/**
@@ -141,17 +119,37 @@ class GitDBRepo {
* @param userName the user name
* @param userEmailAddress the user email address
* @return the Ref of the updated branch
- * @throws IOException if there was an error writing the branch
*/
- Ref writeCommit(
+ Result][ writeCommit(
final Ref branchRef,
final ObjectId tree,
final String message,
final String userName,
final String userEmailAddress
- ) throws IOException {
- final ObjectId commitId = insertCommit(tree, message, userName, userEmailAddress, branchRef);
- return headWriter.write(branchRef.getName(), commitId);
+ ) {
+ return insertCommit(tree, message, userName, userEmailAddress, branchRef)
+ .flatMap(cid -> Result.of(() ->
+ headWriter.write(branchRef.getName(), cid)));
+ }
+
+ /**
+ * Insert a commit into the store, returning its unique id.
+ *
+ * @param treeId id of the tree
+ * @param branchRef the branch to commit to
+ * @param message the message
+ * @param userName the user name
+ * @param userEmailAddress the user email address
+ * @return the id of the commit
+ */
+ Result insertCommit(
+ final ObjectId treeId,
+ final String message,
+ final String userName,
+ final String userEmailAddress,
+ final Ref branchRef
+ ) {
+ return commitWriter.write(treeId, branchRef, message, userName, userEmailAddress);
}
/**
@@ -162,14 +160,13 @@ class GitDBRepo {
* @param initUser the user name
* @param initEmail the user email address
* @return the id of the commit
- * @throws IOException if there was an error writing the commit
*/
- ObjectId initialCommit(
+ Result initialCommit(
final ObjectId treeId,
final String initMessage,
final String initUser,
final String initEmail
- ) throws IOException {
+ ) {
return commitWriter.write(treeId, ObjectId.zeroId(), initMessage, initUser, initEmail);
}
@@ -182,9 +179,8 @@ class GitDBRepo {
* @param key the key to place the value under
* @return an Optional containing the id of the updated tree containing the update, if the key was found, or an
* empty Optional if there key was not found, the there was no changes made
- * @throws IOException if there was an error writing the value
*/
- Optional removeKey(final Ref branchRef, final String key) throws IOException {
+ Result> removeKey(final Ref branchRef, final String key) {
return keyRemover.remove(branchRef, key);
}
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/HeadWriter.java b/src/main/java/net/kemitix/gitdb/impl/HeadWriter.java
index 39f2107..c9d6351 100644
--- a/src/main/java/net/kemitix/gitdb/impl/HeadWriter.java
+++ b/src/main/java/net/kemitix/gitdb/impl/HeadWriter.java
@@ -22,11 +22,11 @@
package net.kemitix.gitdb.impl;
import lombok.RequiredArgsConstructor;
+import net.kemitix.mon.result.Result;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
-import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -47,16 +47,17 @@ class HeadWriter {
* @param branchName the branch name
* @param commitId the commit to point the branch at
* @return the Ref of the new branch
- * @throws IOException error writing branch head
*/
- Ref write(final String branchName, final ObjectId commitId) throws IOException {
+ Result][ write(final String branchName, final ObjectId commitId) {
final Path branchRefPath = repository
.getDirectory()
.toPath()
.resolve(branchName)
.toAbsolutePath();
final byte[] commitIdBytes = commitId.name().getBytes(StandardCharsets.UTF_8);
- Files.write(branchRefPath, commitIdBytes);
- return repository.findRef(branchName);
+ return Result.of(() -> {
+ Files.write(branchRefPath, commitIdBytes);
+ return repository.findRef(branchName);
+ });
}
}
diff --git a/src/main/java/net/kemitix/gitdb/impl/InitGitDBRepo.java b/src/main/java/net/kemitix/gitdb/impl/InitGitDBRepo.java
index a2bd757..b2cc831 100644
--- a/src/main/java/net/kemitix/gitdb/impl/InitGitDBRepo.java
+++ b/src/main/java/net/kemitix/gitdb/impl/InitGitDBRepo.java
@@ -22,6 +22,7 @@
package net.kemitix.gitdb.impl;
import net.kemitix.gitdb.FormatVersion;
+import net.kemitix.mon.result.Result;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache;
@@ -50,35 +51,73 @@ class InitGitDBRepo {
* Initialise a new GitDB repo.
*
* @param dbDir the directory to initialise the repo in
- * @throws IOException if there is an error in creating the repo files
*/
- static void create(final Path dbDir) throws IOException {
+ static Result create(final Path dbDir) {
final InitGitDBRepo initRepo = new InitGitDBRepo();
- final File validDbDir = initRepo.validDbDir(dbDir.toFile());
- validDbDir.mkdirs();
- try (Repository repository = RepositoryCache.FileKey.exact(validDbDir, FS.DETECTED).open(false)) {
- repository.create(true);
- initRepo.createInitialBranchOnMaster(repository);
- }
+ return initRepo.validDbDir(dbDir.toFile())
+ .peek(File::mkdirs)
+ .flatMap(dir -> {
+ try (Repository repository = RepositoryCache.FileKey.exact(dir, FS.DETECTED).open(false)) {
+ repository.create(true);
+ initRepo.createInitialBranchOnMaster(repository);
+ } catch (IOException e) {
+ return Result.error(e);
+ }
+ return Result.ok(null);
+ });
}
- private void createInitialBranchOnMaster(final Repository repository) throws IOException {
+ private Result validDbDir(final File dbDir) {
+ return Result.ok(dbDir)
+ .flatMap(this::verifyIsNotAFile)
+ .flatMap(this::isEmptyIfExists);
+ }
+
+ 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 -> repo.initialCommit(tid, INIT_MESSAGE, INIT_USER, INIT_EMAIL))
+ .flatMap(cid -> Result.of(() -> {
+ createBranch(repository, cid, MASTER);
+ return null;
+ }));
}
- private void createBranch(
+ private Result verifyIsNotAFile(final File dbDir) {
+ if (dbDir.isFile()) {
+ return Result.error(new NotDirectoryException(dbDir.toString()));
+ }
+ return Result.ok(dbDir);
+ }
+
+ private Result isEmptyIfExists(final File dbDir) {
+ if (dbDir.exists()) {
+ return Result.of(() -> {
+ try (DirectoryStream directoryStream = Files.newDirectoryStream(dbDir.toPath())) {
+ if (directoryStream.iterator().hasNext()) {
+ throw new DirectoryNotEmptyException(dbDir.toString());
+ }
+ }
+ return dbDir;
+ }
+ );
+ }
+ return Result.ok(dbDir);
+ }
+
+ 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(
@@ -90,26 +129,4 @@ class InitGitDBRepo {
.resolve(String.format(REFS_HEADS_FORMAT, branchName))
.toAbsolutePath();
}
-
- private File validDbDir(final File dbDir) throws IOException {
- verifyIsNotAFile(dbDir);
- if (dbDir.exists()) {
- verifyIsEmpty(dbDir);
- }
- return dbDir;
- }
-
- private void verifyIsEmpty(final File dbDir) throws IOException {
- try (DirectoryStream directoryStream = Files.newDirectoryStream(dbDir.toPath())) {
- if (directoryStream.iterator().hasNext()) {
- throw new DirectoryNotEmptyException(dbDir.toString());
- }
- }
- }
-
- private void verifyIsNotAFile(final File dbDir) throws NotDirectoryException {
- if (dbDir.isFile()) {
- throw new NotDirectoryException(dbDir.toString());
- }
- }
}
diff --git a/src/main/java/net/kemitix/gitdb/impl/KeyRemover.java b/src/main/java/net/kemitix/gitdb/impl/KeyRemover.java
index f8cd7d0..392e540 100644
--- a/src/main/java/net/kemitix/gitdb/impl/KeyRemover.java
+++ b/src/main/java/net/kemitix/gitdb/impl/KeyRemover.java
@@ -22,10 +22,11 @@
package net.kemitix.gitdb.impl;
import lombok.RequiredArgsConstructor;
+import net.kemitix.mon.maybe.Maybe;
+import net.kemitix.mon.result.Result;
import org.eclipse.jgit.lib.*;
import java.io.IOException;
-import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -40,6 +41,24 @@ class KeyRemover {
private final Repository repository;
+ /**
+ * Remove a key from the repository.
+ *
+ * @param branchRef the branch to update
+ * @param key the key to remove
+ * @return the id of the updated tree
+ */
+ Result> remove(final Ref branchRef, final String key) {
+ final TreeFormatter treeFormatter = new TreeFormatter();
+ final AtomicBoolean removed = new AtomicBoolean(false);
+ 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());
+ }
+
/**
* Sets the boolean to true if the key matches a NamedRevBlob's name.
*
@@ -75,38 +94,17 @@ class KeyRemover {
return item -> treeFormatter.append(item.getName(), item.getRevBlob());
}
- /**
- * Remove a key from the repository.
- *
- * @param branchRef the branch to update
- * @param key the key to remove
- * @return the id of the updated tree
- * @throws IOException if there is an error writing the value
- */
- Optional remove(final Ref branchRef, final String key) throws IOException {
- final TreeFormatter treeFormatter = new TreeFormatter();
- final AtomicBoolean removed = new AtomicBoolean(false);
- new GitTreeReader(repository)
- .stream(branchRef)
- .peek(flagIfFound(key, removed))
- .filter(isNotKey(key))
- .forEach(addToTree(treeFormatter));
- if (removed.get()) {
- return Optional.of(insertTree(treeFormatter));
- }
- return Optional.empty();
- }
-
/**
* Insert a tree into the repo, returning its id.
*
* @param treeFormatter the formatter containing the proposed tree's data.
* @return the name of the tree object.
- * @throws IOException the object could not be stored.
*/
- private ObjectId insertTree(final TreeFormatter treeFormatter) throws IOException {
+ private Result insertTree(final TreeFormatter treeFormatter) {
try (ObjectInserter inserter = repository.getObjectDatabase().newInserter()) {
- return inserter.insert(treeFormatter);
+ return Result.ok(inserter.insert(treeFormatter));
+ } catch (IOException e) {
+ return Result.error(e);
}
}
}
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/LocalGitDB.java b/src/main/java/net/kemitix/gitdb/impl/LocalGitDB.java
index b6bbb09..0965c62 100644
--- a/src/main/java/net/kemitix/gitdb/impl/LocalGitDB.java
+++ b/src/main/java/net/kemitix/gitdb/impl/LocalGitDB.java
@@ -22,8 +22,8 @@
package net.kemitix.gitdb.impl;
import net.kemitix.gitdb.GitDB;
+import net.kemitix.mon.result.Result;
-import java.io.IOException;
import java.nio.file.Path;
/**
@@ -40,9 +40,8 @@ public interface LocalGitDB extends GitDB {
* @param userName the user name
* @param userEmailAddress the user email address
* @return a GitDB instance for the created local gitdb
- * @throws IOException if there {@code dbDir} is a file or a non-empty directory
*/
- static GitDB init(final Path dbDir, final String userName, final String userEmailAddress) throws IOException {
+ static Result init(final Path dbDir, final String userName, final String userEmailAddress) {
return LocalGitDBImpl.init(dbDir, userName, userEmailAddress);
}
@@ -54,7 +53,7 @@ public interface LocalGitDB extends GitDB {
* @param userEmailAddress the user email address
* @return a GitDB instance for the created local gitdb
*/
- static GitDB open(final Path dbDir, final String userName, final String userEmailAddress) {
+ static Result open(final Path dbDir, final String userName, final String userEmailAddress) {
return LocalGitDBImpl.open(dbDir, userName, userEmailAddress);
}
diff --git a/src/main/java/net/kemitix/gitdb/impl/LocalGitDBImpl.java b/src/main/java/net/kemitix/gitdb/impl/LocalGitDBImpl.java
index 7d9f4d7..9164a96 100644
--- a/src/main/java/net/kemitix/gitdb/impl/LocalGitDBImpl.java
+++ b/src/main/java/net/kemitix/gitdb/impl/LocalGitDBImpl.java
@@ -24,12 +24,14 @@ package net.kemitix.gitdb.impl;
import net.kemitix.gitdb.GitDB;
import net.kemitix.gitdb.GitDBBranch;
import net.kemitix.gitdb.InvalidRepositoryException;
+import net.kemitix.mon.maybe.Maybe;
+import net.kemitix.mon.result.Result;
import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.lib.*;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
import java.io.IOException;
import java.nio.file.Path;
-import java.util.Optional;
import java.util.function.Function;
/**
@@ -43,10 +45,8 @@ final class LocalGitDBImpl implements GitDB, LocalGitDB {
private static final String ERROR_OPENING_REPOSITORY = "Error opening repository";
private final Repository repository;
- private final String userName;
- private final String userEmailAddress;
- private final Function][ branchInit;
+ private final Function][> branchInit;
private LocalGitDBImpl(
final Repository repository,
@@ -54,9 +54,7 @@ final class LocalGitDBImpl implements GitDB, LocalGitDB {
final String userEmailAddress
) {
this.repository = repository;
- this.userName = userName;
- this.userEmailAddress = userEmailAddress;
- branchInit = GitDBBranchImpl.init(this.repository, this.userName, this.userEmailAddress);
+ branchInit = GitDBBranchImpl.init(this.repository, userName, userEmailAddress);
}
/**
@@ -66,15 +64,14 @@ final class LocalGitDBImpl implements GitDB, LocalGitDB {
* @param userName the user name
* @param userEmailAddress the user email address
* @return a GitDB instance for the created local gitdb
- * @throws IOException if there {@code dbDir} is a file or a non-empty directory
*/
- static GitDB init(
+ static Result init(
final Path dbDir,
final String userName,
final String userEmailAddress
- ) throws IOException {
- InitGitDBRepo.create(dbDir);
- return open(dbDir, userName, userEmailAddress);
+ ) {
+ return InitGitDBRepo.create(dbDir)
+ .flatMap(c -> open(dbDir, userName, userEmailAddress));
}
/**
@@ -85,25 +82,43 @@ final class LocalGitDBImpl implements GitDB, LocalGitDB {
* @param userEmailAddress the user email address
* @return a GitDB instance for the created local gitdb
*/
- static GitDB open(
+ static Result open(
final Path dbDir,
final String userName,
final String userEmailAddress
) {
+ return gitOpen(dbDir)
+ .map(Git::getRepository)
+ .maybe(Repository::isBare)
+ .flatMap(asErrorIfNotBare(dbDir))
+ .map(toLocalGitDB(userName, userEmailAddress));
+ }
+
+ private static Result gitOpen(Path dbDir) {
try {
- return Optional.of(Git.open(dbDir.toFile()))
- .map(Git::getRepository)
- .filter(Repository::isBare)
- .map(repository -> new LocalGitDBImpl(repository, userName, userEmailAddress))
- .orElseThrow(() -> new InvalidRepositoryException(NOT_A_BARE_REPO, dbDir));
+ return Result.ok(Git.open(dbDir.toFile()));
} catch (IOException e) {
- throw new InvalidRepositoryException(ERROR_OPENING_REPOSITORY, dbDir, e);
+ return Result.error(new InvalidRepositoryException(ERROR_OPENING_REPOSITORY, dbDir, e));
}
}
+ private static Function, Result> asErrorIfNotBare(final Path dbDir) {
+ return maybe -> Result.fromMaybe(maybe, () -> new InvalidRepositoryException(NOT_A_BARE_REPO, dbDir));
+ }
+
+ private static Function toLocalGitDB(final String userName, final String userEmailAddress) {
+ return repository -> new LocalGitDBImpl(repository, userName, userEmailAddress);
+ }
+
@Override
- public Optional branch(final String name) throws IOException {
- return Optional.ofNullable(repository.findRef(name)).map(branchInit);
+ public Result> branch(final String name) {
+ try {
+ return Result.invert(Maybe.maybe(
+ repository.findRef(name))
+ .map(branchInit::apply));
+ } catch (IOException e) {
+ return Result.error(e);
+ }
}
}
diff --git a/src/main/java/net/kemitix/gitdb/impl/NamedRevBlob.java b/src/main/java/net/kemitix/gitdb/impl/NamedRevBlob.java
index 09a39ec..d8376b6 100644
--- a/src/main/java/net/kemitix/gitdb/impl/NamedRevBlob.java
+++ b/src/main/java/net/kemitix/gitdb/impl/NamedRevBlob.java
@@ -24,7 +24,9 @@ package net.kemitix.gitdb.impl;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
+import net.kemitix.mon.result.Result;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevBlob;
@@ -48,10 +50,15 @@ class NamedRevBlob {
* Converts the blob to a String.
*
* @return a string
- * @throws IOException of there was an error reading the blob
*/
- String blobAsString() throws IOException {
- return new String(repository.open(revBlob.getId(), Constants.OBJ_BLOB).getBytes());
+ Result blobAsString() {
+ try {
+ return Result.ok(repository.open(revBlob.getId(), Constants.OBJ_BLOB))
+ .map(ObjectLoader::getBytes)
+ .map(String::new);
+ } catch (IOException e) {
+ return Result.error(e);
+ }
}
}
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));
}
}
diff --git a/src/test/java/net/kemitix/gitdb/test/GitDBTest.java b/src/test/java/net/kemitix/gitdb/test/GitDBTest.java
index c2736b7..fdf15b8 100644
--- a/src/test/java/net/kemitix/gitdb/test/GitDBTest.java
+++ b/src/test/java/net/kemitix/gitdb/test/GitDBTest.java
@@ -5,58 +5,53 @@ import net.kemitix.gitdb.FormatVersion;
import net.kemitix.gitdb.GitDB;
import net.kemitix.gitdb.GitDBBranch;
import net.kemitix.gitdb.InvalidRepositoryException;
+import net.kemitix.mon.maybe.Maybe;
+import net.kemitix.mon.result.Result;
import org.assertj.core.api.WithAssertions;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.junit.jupiter.MockitoExtension;
-import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.PrintStream;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.Files;
import java.nio.file.NotDirectoryException;
import java.nio.file.Path;
-import java.util.Optional;
import java.util.UUID;
+import java.util.function.Consumer;
+import java.util.function.Function;
import java.util.function.Supplier;
-import static org.assertj.core.api.Assumptions.assumeThat;
-
-@ExtendWith(MockitoExtension.class)
class GitDBTest implements WithAssertions {
private final Supplier stringSupplier = UUID.randomUUID()::toString;
private final String userName = stringSupplier.get();
private final String userEmailAddress = stringSupplier.get();
- private static void tree(final Path dbDir, final PrintStream out) throws IOException {
- final Process treeProcess = new ProcessBuilder("tree", dbDir.toString()).start();
- try (final BufferedReader reader = new BufferedReader(new InputStreamReader(treeProcess.getInputStream()))) {
- String line;
- while (null != (line = reader.readLine())) {
- out.println("line = " + line);
- }
- }
- }
-
// When initialising a repo in a dir that doesn't exist then a bare repo is created
@Test
void initRepo_whenDirNotExist_thenCreateBareRepo() throws IOException {
//given
final Path dir = dirDoesNotExist();
//when
- final GitDB gitDB = GitDB.initLocal(dir, userName, userEmailAddress);
+ final Result gitDB = GitDB.initLocal(dir, userName, userEmailAddress);
//then
- assertThat(gitDB).isNotNull();
+ assertThatResultIsOkay(gitDB);
assertThatIsBareRepo(dir);
}
+ private Path dirDoesNotExist() throws IOException {
+ final Path directory = Files.createTempDirectory("gitdb");
+ Files.delete(directory);
+ return directory;
+ }
+
+ private void assertThatResultIsOkay(final Result result) {
+ assertThat(result.isOkay()).isTrue();
+ }
+
private void assertThatIsBareRepo(final Path dbDir) throws IOException {
final Git git = Git.open(dbDir.toFile());
final Repository repository = git.getRepository();
@@ -65,56 +60,64 @@ class GitDBTest implements WithAssertions {
assertThat(repository.getDirectory()).isEqualTo(dbDir.toFile());
}
- private Path dirDoesNotExist() throws IOException {
- final Path directory = Files.createTempDirectory("gitdb");
- Files.delete(directory);
- return directory;
- }
-
// When initialising a repo in a dir that is a file then an exception is thrown
@Test
void initRepo_whenDirIsFile_thenThrowException() throws IOException {
//given
final Path dir = fileExists();
+ //when
+ final Result gitDBResult = GitDB.initLocal(dir, userName, userEmailAddress);
//then
- assertThatExceptionOfType(NotDirectoryException.class)
- .isThrownBy(() -> GitDB.initLocal(dir, userName, userEmailAddress))
- .withMessageContaining(dir.toString());
+ gitDBResult.match(
+ failOnSuccess("Is a file not a directory"),
+ error -> assertThat(error)
+ .isInstanceOf(NotDirectoryException.class)
+ .hasMessageContaining(dir.toString())
+ );
}
private Path fileExists() throws IOException {
return Files.createTempFile("gitdb", "file");
}
+ private Consumer failOnSuccess(String message) {
+ return success -> fail(message);
+ }
+
// When initialising a repo in a non-empty dir then an exception is thrown
@Test
void initRepo_whenNotEmptyDir_thenThrowException() throws IOException {
//given
final Path dir = dirExists();
filesExistIn(dir);
+ //when
+ final Result gitDBResult = GitDB.initLocal(dir, userName, userEmailAddress);
//then
- assertThatExceptionOfType(DirectoryNotEmptyException.class)
- .isThrownBy(() -> GitDB.initLocal(dir, userName, userEmailAddress))
- .withMessageContaining(dir.toString());
- }
-
- private void filesExistIn(final Path dir) throws IOException {
- Files.createTempFile(dir, "gitdb", "file");
+ gitDBResult.match(
+ failOnSuccess("Directory is not empty"),
+ error -> assertThat(error)
+ .isInstanceOf(DirectoryNotEmptyException.class)
+ .hasMessageContaining(dir.toString())
+ );
}
private Path dirExists() throws IOException {
return Files.createTempDirectory("gitdb");
}
+ private void filesExistIn(final Path dir) throws IOException {
+ Files.createTempFile(dir, "gitdb", "file");
+ }
+
// When initialising a repo in a empty dir then a bare repo is created
@Test
void initRepo_whenEmptyDir_thenCreateBareRepo() throws IOException {
//given
final Path dir = dirExists();
//when
- final GitDB gitDB = GitDB.initLocal(dir, userName, userEmailAddress);
+ final Result gitDB = GitDB.initLocal(dir, userName, userEmailAddress);
//then
- assertThat(gitDB).isNotNull();
+ assertThatResultIsOkay(gitDB);
assertThatIsBareRepo(dir);
}
@@ -123,10 +126,16 @@ class GitDBTest implements WithAssertions {
void openRepo_NotBareRepo_thenThrowException() throws IOException {
//given
final Path dir = dirExists();
+ //when
+ final Result gitDBResult = GitDB.openLocal(dir, userName, userEmailAddress);
//then
- assertThatExceptionOfType(InvalidRepositoryException.class)
- .isThrownBy(() -> GitDB.openLocal(dir, userName, userEmailAddress))
- .withMessageContaining(dir.toString());
+ gitDBResult.match(
+ failOnSuccess("Not a bare repo"),
+ error -> assertThat(error)
+ .isInstanceOf(InvalidRepositoryException.class)
+ .hasMessageContaining(dir.toString())
+ );
+
}
// When opening a repo in a dir that is a file then an exception is thrown
@@ -134,10 +143,15 @@ class GitDBTest implements WithAssertions {
void openRepo_whenDirIsFile_thenThrowException() throws IOException {
//given
final Path dir = fileExists();
+ //when
+ final Result gitDBResult = GitDB.openLocal(dir, userName, userEmailAddress);
//then
- assertThatExceptionOfType(InvalidRepositoryException.class)
- .isThrownBy(() -> GitDB.openLocal(dir, userName, userEmailAddress))
- .withMessageContaining(dir.toString());
+ gitDBResult.match(
+ failOnSuccess("Directory is a file"),
+ error -> assertThat(error)
+ .isInstanceOf(InvalidRepositoryException.class)
+ .hasMessageContaining(dir.toString())
+ );
}
// When opening a repo in a dir that doesn't exist then an exception is thrown
@@ -145,10 +159,15 @@ class GitDBTest implements WithAssertions {
void openRepo_whenDirNotExist_thenThrowException() throws IOException {
//given
final Path dir = dirDoesNotExist();
+ //when
+ final Result gitDBResult = GitDB.openLocal(dir, userName, userEmailAddress);
//then
- assertThatExceptionOfType(InvalidRepositoryException.class)
- .isThrownBy(() -> GitDB.openLocal(dir, userName, userEmailAddress))
- .withMessageContaining(dir.toString());
+ gitDBResult.match(
+ failOnSuccess("Directory does not exist"),
+ error -> assertThat(error)
+ .isInstanceOf(InvalidRepositoryException.class)
+ .hasMessageContaining(dir.toString())
+ );
}
// When opening a repo in a dir that is not a bare repo then an exception is thrown
@@ -156,12 +175,17 @@ class GitDBTest implements WithAssertions {
void openRepo_whenRepoNotBare_thenThrowException() throws IOException, GitAPIException {
//given
final Path dir = nonBareRepo();
+ //when
+ final Result gitDBResult = GitDB.openLocal(dir, userName, userEmailAddress);
//then
- assertThatExceptionOfType(InvalidRepositoryException.class)
- .isThrownBy(() -> GitDB.openLocal(dir, userName, userEmailAddress))
- .withMessageContaining("Invalid GitDB repo")
- .withMessageContaining("Not a bare repo")
- .withMessageContaining(dir.toString());
+ gitDBResult.match(
+ failOnSuccess("Not a bare repo"),
+ error -> assertThat(error)
+ .isInstanceOf(InvalidRepositoryException.class)
+ .hasMessageContaining("Invalid GitDB repo")
+ .hasMessageContaining("Not a bare repo")
+ .hasMessageContaining(dir.toString())
+ );
}
private Path nonBareRepo() throws IOException, GitAPIException {
@@ -176,9 +200,13 @@ class GitDBTest implements WithAssertions {
//given
final Path dir = gitDBRepoPath();
//when
- final GitDB gitDB = GitDB.openLocal(dir, userName, userEmailAddress);
+ final Result gitDB = GitDB.openLocal(dir, userName, userEmailAddress);
//then
- assertThat(gitDB).isNotNull();
+ assertThat(gitDB.isOkay()).isTrue();
+ gitDB.match(
+ success -> assertThat(success).isNotNull(),
+ error -> fail("did not open local repo")
+ );
}
private Path gitDBRepoPath() throws IOException {
@@ -189,144 +217,179 @@ class GitDBTest implements WithAssertions {
// Given a valid GitDb handle
- private GitDB gitDB(final Path dbDir) throws IOException {
+ // When select a branch that doesn't exist then an empty Optional is returned
+ @Test
+ void selectBranch_whenBranchNotExist_thenEmptyOptional() throws Throwable {
+ //given
+ final Result gitDb = gitDB(dirDoesNotExist());
+ //when
+ final Result> branch = gitDb.flatMap(selectBranch("unknown"));
+ //then
+ assertThat(branch.orElseThrow().toOptional()).isEmpty();
+ }
+
+ private Result gitDB(final Path dbDir) {
return GitDB.initLocal(dbDir, userName, userEmailAddress);
}
- // When select a branch that doesn't exist then an empty Optional is returned
- @Test
- void selectBranch_whenBranchNotExist_thenEmptyOptional() throws IOException {
- //given
- final GitDB gitDb = gitDB(dirDoesNotExist());
- //when
- final Optional branch = gitDb.branch("unknown");
- //then
- assertThat(branch).isEmpty();
- }
-
- // When select a valid branch then a GitDbBranch is returned
- @Test
- void selectBranch_branchExists_thenReturnBranch() throws IOException {
- //given
- final Path dbDir = dirDoesNotExist();
- final GitDB gitDb = gitDB(dbDir);
- //when
- final Optional branch = gitDb.branch("master");
- //then
- assertThat(branch).as("Branch master exists").isNotEmpty();
+ private Function>> selectBranch(final String branchName) {
+ return db -> db.branch(branchName);
}
// Given a valid GitDbBranch handle
- private GitDBBranch gitDBBranch() throws IOException {
- final GitDB gitDB = gitDB(dirDoesNotExist());
- final Optional branchOptional = gitDB.branch("master");
- assumeThat(branchOptional).isNotEmpty();
- return branchOptional.get();
+ // When select a valid branch then a GitDbBranch is returned
+ @Test
+ void selectBranch_branchExists_thenReturnBranch() throws Throwable {
+ //given
+ final Path dbDir = dirDoesNotExist();
+ final Result gitDb = gitDB(dbDir);
+ //when
+ final Result> branch = gitDb.flatMap(selectBranch("master"));
+ //then
+ assertThat(branch.orElseThrow().toOptional()).as("Branch master exists").isNotEmpty();
}
// When getting a key that does not exist then return an empty Optional
@Test
- void getKey_whenKeyNotExist_thenReturnEmptyOptional() throws IOException, ClassNotFoundException {
+ void getKey_whenKeyNotExist_thenReturnEmptyOptional() {
//given
final GitDBBranch branch = gitDBBranch();
//when
- final Optional value = branch.get("unknown");
+ final Result> value = branch.get("unknown");
//then
- assertThat(value).isEmpty();
+ value.match(
+ success -> assertThat(success.toOptional()).isEmpty(),
+ failOnError()
+ );
+ }
+
+ private GitDBBranch gitDBBranch() {
+ try {
+ return gitDB(dirDoesNotExist())
+ .flatMap(selectBranch("master"))
+ .orElseThrow().orElse(null);
+ } catch (Throwable throwable) {
+ throw new RuntimeException("Couldn't create master branch", throwable);
+ }
+ }
+
+ private Consumer failOnError() {
+ return error -> fail("Not an error");
}
// When getting the format version it matches expected
@Test
- void getVersionFormat_thenFormatIsSet() throws IOException {
+ void getVersionFormat_thenFormatIsSet() {
//given
final GitDBBranch gitDBBranch = gitDBBranch();
- //when
- final Optional formatVersion = gitDBBranch.getFormatVersion();
- //then
final Version version = new FormatVersion().getVersion();
- assertThat(formatVersion).contains(version);
- assertThat(formatVersion.get()).isNotSameAs(version);
+ //when
+ final Result> formatVersion = gitDBBranch.getFormatVersion();
+ //then
+ formatVersion.match(
+ success -> success.peek(v -> assertThat(v).isEqualTo(version).isNotSameAs(version)),
+ failOnError()
+ );
}
// When putting a key/value pair then a GitDbBranch is returned
@Test
- void putValue_thenReturnUpdatedGitDBBranch() throws IOException {
+ void putValue_thenReturnUpdatedGitDBBranch() {
//given
final GitDBBranch originalBranch = gitDBBranch();
//when
- final GitDBBranch updatedBranch = originalBranch.put("key-name", "value");
+ final Result updatedBranch = originalBranch.put("key-name", "value");
//then
- assertThat(updatedBranch).isNotNull();
- assertThat(updatedBranch).isNotSameAs(originalBranch);
+ updatedBranch.match(
+ success -> assertThat(success).isNotNull().isNotSameAs(originalBranch),
+ failOnError()
+ );
}
// When getting a key that does exist then the value is returned inside an Optional
@Test
- void getKey_whenExists_thenReturnValueInOptional() throws IOException, ClassNotFoundException {
+ void getKey_whenExists_thenReturnValueInOptional() {
//given
final String key = stringSupplier.get();
final String value = stringSupplier.get();
final GitDBBranch originalBranch = gitDBBranch();
- final GitDBBranch updatedBranch = originalBranch.put(key, value);
+ final Result updatedBranch = originalBranch.put(key, value);
//when
- final Optional result = updatedBranch.get(key);
+ final Result> result = updatedBranch.flatMap(b -> b.get(key));
//then
- assertThat(result).contains(value);
+ result.match(
+ success -> success.map(v -> assertThat(v).contains(value)),
+ failOnError()
+ );
}
// When removing a key that does not exist then the GitDbBranch is returned
@Test
- void removeKey_whenNotExist_thenReturnOriginal() throws IOException {
+ void removeKey_whenNotExist_thenReturnOriginal() {
//given
final GitDBBranch gitDBBranch = gitDBBranch();
//when
- final GitDBBranch result = gitDBBranch.remove("unknown");
+ final Result result = gitDBBranch.remove("unknown");
//then
- assertThat(result).isSameAs(gitDBBranch);
+ result.match(
+ success -> assertThat(success).isSameAs(gitDBBranch),
+ failOnError()
+ );
}
// When removing a key that does exist then a GitDbBranch is returned
@Test
- void removeKey_whenExists_thenReturnUpdatedBranch() throws IOException {
+ void removeKey_whenExists_thenReturnUpdatedBranch() {
//given
final String key = stringSupplier.get();
final String value = stringSupplier.get();
- final GitDBBranch originalBranch = gitDBBranchWithKeyValue(key, value);
+ final Result originalBranch = gitDBBranchWithKeyValue(key, value);
//when
- final GitDBBranch updatedBranch = originalBranch.remove(key);
+ final Result updatedBranch = originalBranch.flatMap(b -> b.remove(key));
//then
- assertThat(updatedBranch).isNotSameAs(originalBranch);
+ updatedBranch.match(
+ success -> assertThat(success).isNotSameAs(originalBranch),
+ failOnError()
+ );
}
- private GitDBBranch gitDBBranchWithKeyValue(final String key, final String value) throws IOException {
+ private Result gitDBBranchWithKeyValue(final String key, final String value) {
return gitDBBranch().put(key, value);
}
// When removing a key that does exist then original GitDbBranch can still find it
@Test
- void removeKey_whenExists_thenOriginalCanStillFind() throws IOException {
+ void removeKey_whenExists_thenOriginalCanStillFind() {
//given
final String key = stringSupplier.get();
final String value = stringSupplier.get();
- final GitDBBranch originalBranch = gitDBBranchWithKeyValue(key, value);
+ final Result originalBranch = gitDBBranchWithKeyValue(key, value);
//when
- final GitDBBranch updatedBranch = originalBranch.remove(key);
+ final Result updatedBranch = originalBranch.flatMap(b -> b.remove(key));
//then
- assertThat(originalBranch.get(key)).contains(value);
+ originalBranch.flatMap(b -> b.get(key))
+ .match(
+ success -> assertThat(success.toOptional()).contains(value),
+ failOnError()
+ );
}
// When removing a key that does exist then the updated GitDbBranch can't find it
@Test
- void removeKey_whenExists_thenUpdatedCanNotFind() throws IOException {
+ void removeKey_whenExists_thenUpdatedCanNotFind() {
//given
final String key = stringSupplier.get();
final String value = stringSupplier.get();
- final GitDBBranch originalBranch = gitDBBranchWithKeyValue(key, value);
+ final Result originalBranch = gitDBBranchWithKeyValue(key, value);
//when
- final GitDBBranch updatedBranch = originalBranch.remove(key);
+ final Result updatedBranch = originalBranch.flatMap(b -> b.remove(key));
//then
- assertThat(updatedBranch.get(key)).isEmpty();
+ updatedBranch.flatMap(b -> b.get(key))
+ .match(
+ success -> assertThat(success.toOptional()).isEmpty(),
+ failOnError()
+ );
}
}
]