diff options
author | Michael Muré <batolettre@gmail.com> | 2021-04-04 15:49:16 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-04 15:49:16 +0200 |
commit | fc04af34f5d6dff930003cc1f27ead972d424324 (patch) | |
tree | 8b9750d46182fff88d72fcc891e89d5a79ed83b0 /cache | |
parent | 2055bd5d0afb534cc98cd11bd9802d66acbb0c8f (diff) | |
parent | cb9b06551ddc1fae33046733f79ede20f8d09f9a (diff) | |
download | git-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.go | 4 | ||||
-rw-r--r-- | cache/bug_excerpt.go | 2 | ||||
-rw-r--r-- | cache/identity_cache.go | 8 | ||||
-rw-r--r-- | cache/repo_cache.go | 5 | ||||
-rw-r--r-- | cache/repo_cache_bug.go | 54 | ||||
-rw-r--r-- | cache/repo_cache_common.go | 15 | ||||
-rw-r--r-- | cache/repo_cache_identity.go | 13 | ||||
-rw-r--r-- | cache/repo_cache_test.go | 8 |
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") |