aboutsummaryrefslogtreecommitdiffstats
path: root/cache
diff options
context:
space:
mode:
Diffstat (limited to 'cache')
-rw-r--r--cache/bug_cache.go47
-rw-r--r--cache/repo_cache.go26
2 files changed, 72 insertions, 1 deletions
diff --git a/cache/bug_cache.go b/cache/bug_cache.go
index b7c80a0c..52e9eafb 100644
--- a/cache/bug_cache.go
+++ b/cache/bug_cache.go
@@ -1,6 +1,8 @@
package cache
import (
+ "fmt"
+ "strings"
"time"
"github.com/MichaelMure/git-bug/bug"
@@ -35,6 +37,51 @@ func (c *BugCache) notifyUpdated() error {
return c.repoCache.bugUpdated(c.bug.Id())
}
+var ErrNoMatchingOp = fmt.Errorf("no matching operation found")
+
+type ErrMultipleMatchOp struct {
+ Matching []git.Hash
+}
+
+func (e ErrMultipleMatchOp) Error() string {
+ casted := make([]string, len(e.Matching))
+
+ for i := range e.Matching {
+ casted[i] = string(e.Matching[i])
+ }
+
+ return fmt.Sprintf("Multiple matching operation found:\n%s", strings.Join(casted, "\n"))
+}
+
+// ResolveTargetWithMetadata will find an operation that has the matching metadata
+func (c *BugCache) ResolveTargetWithMetadata(key string, value string) (git.Hash, error) {
+ // preallocate but empty
+ matching := make([]git.Hash, 0, 5)
+
+ it := bug.NewOperationIterator(c.bug)
+ for it.Next() {
+ op := it.Value()
+ opValue, ok := op.GetMetadata(key)
+ if ok && value == opValue {
+ h, err := op.Hash()
+ if err != nil {
+ return "", err
+ }
+ matching = append(matching, h)
+ }
+ }
+
+ if len(matching) == 0 {
+ return "", ErrNoMatchingOp
+ }
+
+ if len(matching) > 1 {
+ return "", ErrMultipleMatchOp{Matching: matching}
+ }
+
+ return matching[0], nil
+}
+
func (c *BugCache) AddComment(message string) error {
return c.AddCommentWithFiles(message, nil)
}
diff --git a/cache/repo_cache.go b/cache/repo_cache.go
index 74fc87c0..2cb6a030 100644
--- a/cache/repo_cache.go
+++ b/cache/repo_cache.go
@@ -244,7 +244,31 @@ func (c *RepoCache) ResolveBugPrefix(prefix string) (*BugCache, error) {
}
if len(matching) > 1 {
- return nil, fmt.Errorf("Multiple matching bug found:\n%s", strings.Join(matching, "\n"))
+ return nil, bug.ErrMultipleMatch{Matching: matching}
+ }
+
+ if len(matching) == 0 {
+ return nil, bug.ErrBugNotExist
+ }
+
+ return c.ResolveBug(matching[0])
+}
+
+// ResolveBugCreateMetadata retrieve a bug that has the exact given metadata on
+// its Create operation, that is, the first operation. It fails if multiple bugs
+// match.
+func (c *RepoCache) ResolveBugCreateMetadata(key string, value string) (*BugCache, error) {
+ // preallocate but empty
+ matching := make([]string, 0, 5)
+
+ for id, excerpt := range c.excerpts {
+ if excerpt.CreateMetadata[key] == value {
+ matching = append(matching, id)
+ }
+ }
+
+ if len(matching) > 1 {
+ return nil, bug.ErrMultipleMatch{Matching: matching}
}
if len(matching) == 0 {