aboutsummaryrefslogtreecommitdiffstats
path: root/cache
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2021-04-04 15:49:16 +0200
committerGitHub <noreply@github.com>2021-04-04 15:49:16 +0200
commitfc04af34f5d6dff930003cc1f27ead972d424324 (patch)
tree8b9750d46182fff88d72fcc891e89d5a79ed83b0 /cache
parent2055bd5d0afb534cc98cd11bd9802d66acbb0c8f (diff)
parentcb9b06551ddc1fae33046733f79ede20f8d09f9a (diff)
downloadgit-bug-fc04af34f5d6dff930003cc1f27ead972d424324.tar.gz
Merge pull request #532 from MichaelMure/dag-entity
Work towards a reusable entity datastructure + commit signature
Diffstat (limited to 'cache')
-rw-r--r--cache/bug_cache.go4
-rw-r--r--cache/bug_excerpt.go2
-rw-r--r--cache/identity_cache.go8
-rw-r--r--cache/repo_cache.go5
-rw-r--r--cache/repo_cache_bug.go54
-rw-r--r--cache/repo_cache_common.go15
-rw-r--r--cache/repo_cache_identity.go13
-rw-r--r--cache/repo_cache_test.go8
8 files changed, 84 insertions, 25 deletions
diff --git a/cache/bug_cache.go b/cache/bug_cache.go
index ca526f7b..bbe9830f 100644
--- a/cache/bug_cache.go
+++ b/cache/bug_cache.go
@@ -51,9 +51,7 @@ func (c *BugCache) ResolveOperationWithMetadata(key string, value string) (entit
// preallocate but empty
matching := make([]entity.Id, 0, 5)
- it := bug.NewOperationIterator(c.bug)
- for it.Next() {
- op := it.Value()
+ for _, op := range c.bug.Operations() {
opValue, ok := op.GetMetadata(key)
if ok && value == opValue {
matching = append(matching, op.Id())
diff --git a/cache/bug_excerpt.go b/cache/bug_excerpt.go
index 6a9e7f75..152bdacf 100644
--- a/cache/bug_excerpt.go
+++ b/cache/bug_excerpt.go
@@ -87,7 +87,7 @@ func NewBugExcerpt(b bug.Interface, snap *bug.Snapshot) *BugExcerpt {
}
switch snap.Author.(type) {
- case *identity.Identity, *IdentityCache:
+ case *identity.Identity, *identity.IdentityStub, *IdentityCache:
e.AuthorId = snap.Author.Id()
default:
panic("unhandled identity type")
diff --git a/cache/identity_cache.go b/cache/identity_cache.go
index 25e273b9..e419387f 100644
--- a/cache/identity_cache.go
+++ b/cache/identity_cache.go
@@ -2,6 +2,7 @@ package cache
import (
"github.com/MichaelMure/git-bug/identity"
+ "github.com/MichaelMure/git-bug/repository"
)
var _ identity.Interface = &IdentityCache{}
@@ -23,8 +24,11 @@ func (i *IdentityCache) notifyUpdated() error {
return i.repoCache.identityUpdated(i.Identity.Id())
}
-func (i *IdentityCache) Mutate(f func(identity.Mutator) identity.Mutator) error {
- i.Identity.Mutate(f)
+func (i *IdentityCache) Mutate(repo repository.RepoClock, f func(*identity.Mutator)) error {
+ err := i.Identity.Mutate(repo, f)
+ if err != nil {
+ return err
+ }
return i.notifyUpdated()
}
diff --git a/cache/repo_cache.go b/cache/repo_cache.go
index b5b9ee54..58022bda 100644
--- a/cache/repo_cache.go
+++ b/cache/repo_cache.go
@@ -18,7 +18,8 @@ import (
// 1: original format
// 2: added cache for identities with a reference in the bug cache
// 3: no more legacy identity
-const formatVersion = 3
+// 4: entities make their IDs from data, not git commit
+const formatVersion = 4
// The maximum number of bugs loaded in memory. After that, eviction will be done.
const defaultMaxLoadedBugs = 1000
@@ -194,7 +195,7 @@ func (c *RepoCache) buildCache() error {
c.bugExcerpts = make(map[entity.Id]*BugExcerpt)
- allBugs := bug.ReadAllLocal(c.repo)
+ allBugs := bug.ReadAll(c.repo)
// wipe the index just to be sure
err := c.repo.ClearBleveIndex("bug")
diff --git a/cache/repo_cache_bug.go b/cache/repo_cache_bug.go
index 8d9914e3..c019da68 100644
--- a/cache/repo_cache_bug.go
+++ b/cache/repo_cache_bug.go
@@ -18,10 +18,7 @@ import (
"github.com/MichaelMure/git-bug/repository"
)
-const (
- bugCacheFile = "bug-cache"
- searchCacheDir = "search-cache"
-)
+const bugCacheFile = "bug-cache"
var errBugNotInCache = errors.New("bug missing from cache")
@@ -156,7 +153,7 @@ func (c *RepoCache) ResolveBug(id entity.Id) (*BugCache, error) {
}
c.muBug.RUnlock()
- b, err := bug.ReadLocalWithResolver(c.repo, newIdentityCacheResolver(c), id)
+ b, err := bug.ReadWithResolver(c.repo, newIdentityCacheResolver(c), id)
if err != nil {
return nil, err
}
@@ -263,6 +260,53 @@ func (c *RepoCache) resolveBugMatcher(f func(*BugExcerpt) bool) (entity.Id, erro
return matching[0], nil
}
+// ResolveComment search for a Bug/Comment combination matching the merged
+// bug/comment Id prefix. Returns the Bug containing the Comment and the Comment's
+// Id.
+func (c *RepoCache) ResolveComment(prefix string) (*BugCache, entity.Id, error) {
+ bugPrefix, _ := entity.SeparateIds(prefix)
+ bugCandidate := make([]entity.Id, 0, 5)
+
+ // build a list of possible matching bugs
+ c.muBug.RLock()
+ for _, excerpt := range c.bugExcerpts {
+ if excerpt.Id.HasPrefix(bugPrefix) {
+ bugCandidate = append(bugCandidate, excerpt.Id)
+ }
+ }
+ c.muBug.RUnlock()
+
+ matchingBugIds := make([]entity.Id, 0, 5)
+ matchingCommentId := entity.UnsetId
+ var matchingBug *BugCache
+
+ // search for matching comments
+ // searching every bug candidate allow for some collision with the bug prefix only,
+ // before being refined with the full comment prefix
+ for _, bugId := range bugCandidate {
+ b, err := c.ResolveBug(bugId)
+ if err != nil {
+ return nil, entity.UnsetId, err
+ }
+
+ for _, comment := range b.Snapshot().Comments {
+ if comment.Id().HasPrefix(prefix) {
+ matchingBugIds = append(matchingBugIds, bugId)
+ matchingBug = b
+ matchingCommentId = comment.Id()
+ }
+ }
+ }
+
+ if len(matchingBugIds) > 1 {
+ return nil, entity.UnsetId, entity.NewErrMultipleMatch("bug/comment", matchingBugIds)
+ } else if len(matchingBugIds) == 0 {
+ return nil, entity.UnsetId, errors.New("comment doesn't exist")
+ }
+
+ return matchingBug, matchingCommentId, nil
+}
+
// QueryBugs return the id of all Bug matching the given Query
func (c *RepoCache) QueryBugs(q *query.Query) ([]entity.Id, error) {
c.muBug.RLock()
diff --git a/cache/repo_cache_common.go b/cache/repo_cache_common.go
index 5dc19d22..e23315f9 100644
--- a/cache/repo_cache_common.go
+++ b/cache/repo_cache_common.go
@@ -95,6 +95,12 @@ func (c *RepoCache) MergeAll(remote string) <-chan entity.MergeResult {
go func() {
defer close(out)
+ author, err := c.GetUserIdentity()
+ if err != nil {
+ out <- entity.NewMergeError(err, "")
+ return
+ }
+
results := identity.MergeAll(c.repo, remote)
for result := range results {
out <- result
@@ -112,7 +118,7 @@ func (c *RepoCache) MergeAll(remote string) <-chan entity.MergeResult {
}
}
- results = bug.MergeAll(c.repo, remote)
+ results = bug.MergeAll(c.repo, remote, author)
for result := range results {
out <- result
@@ -130,11 +136,10 @@ func (c *RepoCache) MergeAll(remote string) <-chan entity.MergeResult {
}
}
- err := c.write()
-
- // No easy way out here ..
+ err = c.write()
if err != nil {
- panic(err)
+ out <- entity.NewMergeError(err, "")
+ return
}
}()
diff --git a/cache/repo_cache_identity.go b/cache/repo_cache_identity.go
index 8df5b810..75453cb8 100644
--- a/cache/repo_cache_identity.go
+++ b/cache/repo_cache_identity.go
@@ -225,17 +225,20 @@ func (c *RepoCache) NewIdentityFromGitUserRaw(metadata map[string]string) (*Iden
// NewIdentity create a new identity
// The new identity is written in the repository (commit)
func (c *RepoCache) NewIdentity(name string, email string) (*IdentityCache, error) {
- return c.NewIdentityRaw(name, email, "", "", nil)
+ return c.NewIdentityRaw(name, email, "", "", nil, nil)
}
// NewIdentityFull create a new identity
// The new identity is written in the repository (commit)
-func (c *RepoCache) NewIdentityFull(name string, email string, login string, avatarUrl string) (*IdentityCache, error) {
- return c.NewIdentityRaw(name, email, login, avatarUrl, nil)
+func (c *RepoCache) NewIdentityFull(name string, email string, login string, avatarUrl string, keys []*identity.Key) (*IdentityCache, error) {
+ return c.NewIdentityRaw(name, email, login, avatarUrl, keys, nil)
}
-func (c *RepoCache) NewIdentityRaw(name string, email string, login string, avatarUrl string, metadata map[string]string) (*IdentityCache, error) {
- i := identity.NewIdentityFull(name, email, login, avatarUrl)
+func (c *RepoCache) NewIdentityRaw(name string, email string, login string, avatarUrl string, keys []*identity.Key, metadata map[string]string) (*IdentityCache, error) {
+ i, err := identity.NewIdentityFull(c.repo, name, email, login, avatarUrl, keys)
+ if err != nil {
+ return nil, err
+ }
return c.finishIdentity(i, metadata)
}
diff --git a/cache/repo_cache_test.go b/cache/repo_cache_test.go
index 7e648ea9..fab8fff0 100644
--- a/cache/repo_cache_test.go
+++ b/cache/repo_cache_test.go
@@ -110,8 +110,8 @@ func TestCache(t *testing.T) {
require.NoError(t, err)
}
-func TestPushPull(t *testing.T) {
- repoA, repoB, remote := repository.SetupReposAndRemote()
+func TestCachePushPull(t *testing.T) {
+ repoA, repoB, remote := repository.SetupGoGitReposAndRemote()
defer repository.CleanupTestRepos(repoA, repoB, remote)
cacheA, err := NewRepoCache(repoA)
@@ -125,6 +125,10 @@ func TestPushPull(t *testing.T) {
require.NoError(t, err)
err = cacheA.SetUserIdentity(reneA)
require.NoError(t, err)
+ isaacB, err := cacheB.NewIdentity("Isaac Newton", "isaac@newton.uk")
+ require.NoError(t, err)
+ err = cacheB.SetUserIdentity(isaacB)
+ require.NoError(t, err)
// distribute the identity
_, err = cacheA.Push("origin")