diff options
Diffstat (limited to 'cache')
-rw-r--r-- | cache/bug_cache.go | 47 | ||||
-rw-r--r-- | cache/repo_cache.go | 26 |
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 { |