aboutsummaryrefslogtreecommitdiffstats
path: root/cache/repo_cache.go
diff options
context:
space:
mode:
Diffstat (limited to 'cache/repo_cache.go')
-rw-r--r--cache/repo_cache.go133
1 files changed, 104 insertions, 29 deletions
diff --git a/cache/repo_cache.go b/cache/repo_cache.go
index e58165d2..c73dbe9f 100644
--- a/cache/repo_cache.go
+++ b/cache/repo_cache.go
@@ -1,8 +1,12 @@
package cache
import (
+ "bytes"
+ "encoding/gob"
"fmt"
"io"
+ "os"
+ "path"
"strings"
"github.com/MichaelMure/git-bug/bug"
@@ -11,39 +15,110 @@ import (
"github.com/MichaelMure/git-bug/util"
)
-type RepoCacher interface {
- Repository() repository.Repo
- ResolveBug(id string) (BugCacher, error)
- ResolveBugPrefix(prefix string) (BugCacher, error)
- AllBugIds() ([]string, error)
- ClearAllBugs()
-
- // Mutations
- NewBug(title string, message string) (BugCacher, error)
- NewBugWithFiles(title string, message string, files []util.Hash) (BugCacher, error)
- Fetch(remote string) (string, error)
- MergeAll(remote string) <-chan bug.MergeResult
- Pull(remote string, out io.Writer) error
- Push(remote string) (string, error)
-}
-
type RepoCache struct {
- repo repository.Repo
- bugs map[string]BugCacher
+ repo repository.Repo
+ excerpts map[string]BugExcerpt
+ bugs map[string]*BugCache
}
-func NewRepoCache(r repository.Repo) RepoCacher {
- return &RepoCache{
+func NewRepoCache(r repository.Repo) (*RepoCache, error) {
+ c := &RepoCache{
repo: r,
- bugs: make(map[string]BugCacher),
+ bugs: make(map[string]*BugCache),
+ }
+
+ err := c.loadExcerpts()
+
+ if err == nil {
+ return c, nil
}
+
+ c.buildAllExcerpt()
+
+ return c, c.writeExcerpts()
}
func (c *RepoCache) Repository() repository.Repo {
return c.repo
}
-func (c *RepoCache) ResolveBug(id string) (BugCacher, error) {
+// bugUpdated is a callback to trigger when the excerpt of a bug changed,
+// that is each time a bug is updated
+func (c *RepoCache) bugUpdated(id string) error {
+ b, ok := c.bugs[id]
+ if !ok {
+ panic("missing bug in the cache")
+ }
+
+ c.excerpts[id] = NewBugExcerpt(b.bug, b.Snapshot())
+
+ return c.writeExcerpts()
+}
+
+// loadExcerpts will try to read from the disk the bug excerpt file
+func (c *RepoCache) loadExcerpts() error {
+ excerptsPath := repoExcerptsFilePath(c.repo)
+
+ f, err := os.Open(excerptsPath)
+ if err != nil {
+ return err
+ }
+
+ decoder := gob.NewDecoder(f)
+
+ var excerpts map[string]BugExcerpt
+
+ err = decoder.Decode(&excerpts)
+ if err != nil {
+ return err
+ }
+
+ c.excerpts = excerpts
+ return nil
+}
+
+// writeExcerpts will serialize on disk the BugExcerpt array
+func (c *RepoCache) writeExcerpts() error {
+ var data bytes.Buffer
+
+ encoder := gob.NewEncoder(&data)
+
+ err := encoder.Encode(c.excerpts)
+ if err != nil {
+ return err
+ }
+
+ excerptsPath := repoExcerptsFilePath(c.repo)
+
+ f, err := os.Create(excerptsPath)
+ if err != nil {
+ return err
+ }
+
+ _, err = f.Write(data.Bytes())
+ if err != nil {
+ return err
+ }
+
+ return f.Close()
+}
+
+func repoExcerptsFilePath(repo repository.Repo) string {
+ return path.Join(repo.GetPath(), ".git", "git-bug", excerptsFile)
+}
+
+func (c *RepoCache) buildAllExcerpt() {
+ c.excerpts = make(map[string]BugExcerpt)
+
+ allBugs := bug.ReadAllLocalBugs(c.repo)
+
+ for b := range allBugs {
+ snap := b.Bug.Compile()
+ c.excerpts[b.Bug.Id()] = NewBugExcerpt(b.Bug, &snap)
+ }
+}
+
+func (c *RepoCache) ResolveBug(id string) (*BugCache, error) {
cached, ok := c.bugs[id]
if ok {
return cached, nil
@@ -54,13 +129,13 @@ func (c *RepoCache) ResolveBug(id string) (BugCacher, error) {
return nil, err
}
- cached = NewBugCache(c.repo, b)
+ cached = NewBugCache(c, b)
c.bugs[id] = cached
return cached, nil
}
-func (c *RepoCache) ResolveBugPrefix(prefix string) (BugCacher, error) {
+func (c *RepoCache) ResolveBugPrefix(prefix string) (*BugCache, error) {
// preallocate but empty
matching := make([]string, 0, 5)
@@ -87,7 +162,7 @@ func (c *RepoCache) ResolveBugPrefix(prefix string) (BugCacher, error) {
return nil, err
}
- cached := NewBugCache(c.repo, b)
+ cached := NewBugCache(c, b)
c.bugs[b.Id()] = cached
return cached, nil
@@ -98,14 +173,14 @@ func (c *RepoCache) AllBugIds() ([]string, error) {
}
func (c *RepoCache) ClearAllBugs() {
- c.bugs = make(map[string]BugCacher)
+ c.bugs = make(map[string]*BugCache)
}
-func (c *RepoCache) NewBug(title string, message string) (BugCacher, error) {
+func (c *RepoCache) NewBug(title string, message string) (*BugCache, error) {
return c.NewBugWithFiles(title, message, nil)
}
-func (c *RepoCache) NewBugWithFiles(title string, message string, files []util.Hash) (BugCacher, error) {
+func (c *RepoCache) NewBugWithFiles(title string, message string, files []util.Hash) (*BugCache, error) {
author, err := bug.GetUser(c.repo)
if err != nil {
return nil, err
@@ -121,7 +196,7 @@ func (c *RepoCache) NewBugWithFiles(title string, message string, files []util.H
return nil, err
}
- cached := NewBugCache(c.repo, b)
+ cached := NewBugCache(c, b)
c.bugs[b.Id()] = cached
return cached, nil