diff options
author | Michael Muré <batolettre@gmail.com> | 2020-12-08 14:42:13 +0100 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2020-12-08 14:42:13 +0100 |
commit | c884d557bf5e0ebdbe6e3b20535af24c2e97d29f (patch) | |
tree | 3bb95fcf0d6a2a19e6915cdcc1da4d70bc448bb4 /repository | |
parent | 71e1303234ef227851998f08c98c7c69670c9966 (diff) | |
download | git-bug-c884d557bf5e0ebdbe6e3b20535af24c2e97d29f.tar.gz |
repo: move bleve there
Diffstat (limited to 'repository')
-rw-r--r-- | repository/git.go | 86 | ||||
-rw-r--r-- | repository/gogit.go | 76 | ||||
-rw-r--r-- | repository/mock_repo.go | 47 | ||||
-rw-r--r-- | repository/repo.go | 14 |
4 files changed, 215 insertions, 8 deletions
diff --git a/repository/git.go b/repository/git.go index 2348f5d5..993e6cc6 100644 --- a/repository/git.go +++ b/repository/git.go @@ -9,6 +9,7 @@ import ( "strings" "sync" + "github.com/blevesearch/bleve" "github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5/osfs" @@ -30,12 +31,15 @@ type GitRepo struct { clocksMutex sync.Mutex clocks map[string]lamport.Clock + indexesMutex sync.Mutex + indexes map[string]bleve.Index + keyring Keyring } -// NewGitRepo determines if the given working directory is inside of a git repository, +// OpenGitRepo determines if the given working directory is inside of a git repository, // and returns the corresponding GitRepo instance if it is. -func NewGitRepo(path string, clockLoaders []ClockLoader) (*GitRepo, error) { +func OpenGitRepo(path string, clockLoaders []ClockLoader) (*GitRepo, error) { k, err := defaultKeyring() if err != nil { return nil, err @@ -45,6 +49,7 @@ func NewGitRepo(path string, clockLoaders []ClockLoader) (*GitRepo, error) { gitCli: gitCli{path: path}, path: path, clocks: make(map[string]lamport.Clock), + indexes: make(map[string]bleve.Index), keyring: k, } @@ -84,9 +89,10 @@ func NewGitRepo(path string, clockLoaders []ClockLoader) (*GitRepo, error) { // InitGitRepo create a new empty git repo at the given path func InitGitRepo(path string) (*GitRepo, error) { repo := &GitRepo{ - gitCli: gitCli{path: path}, - path: path + "/.git", - clocks: make(map[string]lamport.Clock), + gitCli: gitCli{path: path}, + path: path + "/.git", + clocks: make(map[string]lamport.Clock), + indexes: make(map[string]bleve.Index), } _, err := repo.runGitCommand("init", path) @@ -100,9 +106,10 @@ func InitGitRepo(path string) (*GitRepo, error) { // InitBareGitRepo create a new --bare empty git repo at the given path func InitBareGitRepo(path string) (*GitRepo, error) { repo := &GitRepo{ - gitCli: gitCli{path: path}, - path: path, - clocks: make(map[string]lamport.Clock), + gitCli: gitCli{path: path}, + path: path, + clocks: make(map[string]lamport.Clock), + indexes: make(map[string]bleve.Index), } _, err := repo.runGitCommand("init", "--bare", path) @@ -113,6 +120,17 @@ func InitBareGitRepo(path string) (*GitRepo, error) { return repo, nil } +func (repo *GitRepo) Close() error { + var firstErr error + for _, index := range repo.indexes { + err := index.Close() + if err != nil && firstErr == nil { + firstErr = err + } + } + return firstErr +} + // LocalConfig give access to the repository scoped configuration func (repo *GitRepo) LocalConfig() Config { return newGitConfig(repo.gitCli, false) @@ -183,6 +201,58 @@ func (repo *GitRepo) LocalStorage() billy.Filesystem { return osfs.New(repo.path) } +// GetBleveIndex return a bleve.Index that can be used to index documents +func (repo *GitRepo) GetBleveIndex(name string) (bleve.Index, error) { + repo.indexesMutex.Lock() + defer repo.indexesMutex.Unlock() + + if index, ok := repo.indexes[name]; ok { + return index, nil + } + + path := filepath.Join(repo.path, "indexes", name) + + index, err := bleve.Open(path) + if err == nil { + repo.indexes[name] = index + return index, nil + } + + err = os.MkdirAll(path, os.ModeDir) + if err != nil { + return nil, err + } + + mapping := bleve.NewIndexMapping() + mapping.DefaultAnalyzer = "en" + + index, err = bleve.New(path, mapping) + if err != nil { + return nil, err + } + + repo.indexes[name] = index + + return index, nil +} + +// ClearBleveIndex will wipe the given index +func (repo *GitRepo) ClearBleveIndex(name string) error { + repo.indexesMutex.Lock() + defer repo.indexesMutex.Unlock() + + path := filepath.Join(repo.path, "indexes", name) + + err := os.RemoveAll(path) + if err != nil { + return err + } + + delete(repo.indexes, name) + + return nil +} + // FetchRefs fetch git refs from a remote func (repo *GitRepo) FetchRefs(remote, refSpec string) (string, error) { stdout, err := repo.runGitCommand("fetch", remote, refSpec) diff --git a/repository/gogit.go b/repository/gogit.go index 741982aa..74fe3fc5 100644 --- a/repository/gogit.go +++ b/repository/gogit.go @@ -12,6 +12,7 @@ import ( "sync" "time" + "github.com/blevesearch/bleve" "github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5/osfs" gogit "github.com/go-git/go-git/v5" @@ -33,6 +34,9 @@ type GoGitRepo struct { clocksMutex sync.Mutex clocks map[string]lamport.Clock + indexesMutex sync.Mutex + indexes map[string]bleve.Index + keyring Keyring localStorage billy.Filesystem } @@ -58,6 +62,7 @@ func OpenGoGitRepo(path string, clockLoaders []ClockLoader) (*GoGitRepo, error) r: r, path: path, clocks: make(map[string]lamport.Clock), + indexes: make(map[string]bleve.Index), keyring: k, localStorage: osfs.New(filepath.Join(path, "git-bug")), } @@ -97,6 +102,7 @@ func InitGoGitRepo(path string) (*GoGitRepo, error) { r: r, path: filepath.Join(path, ".git"), clocks: make(map[string]lamport.Clock), + indexes: make(map[string]bleve.Index), keyring: k, localStorage: osfs.New(filepath.Join(path, ".git", "git-bug")), }, nil @@ -118,6 +124,7 @@ func InitBareGoGitRepo(path string) (*GoGitRepo, error) { r: r, path: path, clocks: make(map[string]lamport.Clock), + indexes: make(map[string]bleve.Index), keyring: k, localStorage: osfs.New(filepath.Join(path, "git-bug")), }, nil @@ -179,6 +186,17 @@ func isGitDir(path string) (bool, error) { return true, nil } +func (repo *GoGitRepo) Close() error { + var firstErr error + for _, index := range repo.indexes { + err := index.Close() + if err != nil && firstErr == nil { + firstErr = err + } + } + return firstErr +} + // LocalConfig give access to the repository scoped configuration func (repo *GoGitRepo) LocalConfig() Config { return newGoGitLocalConfig(repo.r) @@ -274,6 +292,64 @@ func (repo *GoGitRepo) LocalStorage() billy.Filesystem { return repo.localStorage } +// GetBleveIndex return a bleve.Index that can be used to index documents +func (repo *GoGitRepo) GetBleveIndex(name string) (bleve.Index, error) { + repo.indexesMutex.Lock() + defer repo.indexesMutex.Unlock() + + if index, ok := repo.indexes[name]; ok { + return index, nil + } + + path := filepath.Join(repo.path, "git-bug", "indexes", name) + + index, err := bleve.Open(path) + if err == nil { + repo.indexes[name] = index + return index, nil + } + + err = os.MkdirAll(path, os.ModePerm) + if err != nil { + return nil, err + } + + mapping := bleve.NewIndexMapping() + mapping.DefaultAnalyzer = "en" + + index, err = bleve.New(path, mapping) + if err != nil { + return nil, err + } + + repo.indexes[name] = index + + return index, nil +} + +// ClearBleveIndex will wipe the given index +func (repo *GoGitRepo) ClearBleveIndex(name string) error { + repo.indexesMutex.Lock() + defer repo.indexesMutex.Unlock() + + path := filepath.Join(repo.path, "indexes", name) + + err := os.RemoveAll(path) + if err != nil { + return err + } + + if index, ok := repo.indexes[name]; ok { + err = index.Close() + if err != nil { + return err + } + delete(repo.indexes, name) + } + + return nil +} + // FetchRefs fetch git refs from a remote func (repo *GoGitRepo) FetchRefs(remote string, refSpec string) (string, error) { buf := bytes.NewBuffer(nil) diff --git a/repository/mock_repo.go b/repository/mock_repo.go index 02e5010f..8a1724ef 100644 --- a/repository/mock_repo.go +++ b/repository/mock_repo.go @@ -7,6 +7,7 @@ import ( "sync" "github.com/99designs/keyring" + "github.com/blevesearch/bleve" "github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5/memfs" @@ -22,16 +23,20 @@ type mockRepoForTest struct { *mockRepoKeyring *mockRepoCommon *mockRepoStorage + *mockRepoBleve *mockRepoData *mockRepoClock } +func (m *mockRepoForTest) Close() error { return nil } + func NewMockRepoForTest() *mockRepoForTest { return &mockRepoForTest{ mockRepoConfig: NewMockRepoConfig(), mockRepoKeyring: NewMockRepoKeyring(), mockRepoCommon: NewMockRepoCommon(), mockRepoStorage: NewMockRepoStorage(), + mockRepoBleve: newMockRepoBleve(), mockRepoData: NewMockRepoData(), mockRepoClock: NewMockRepoClock(), } @@ -126,6 +131,48 @@ func (m *mockRepoStorage) LocalStorage() billy.Filesystem { return m.localFs } +var _ RepoBleve = &mockRepoBleve{} + +type mockRepoBleve struct { + indexesMutex sync.Mutex + indexes map[string]bleve.Index +} + +func newMockRepoBleve() *mockRepoBleve { + return &mockRepoBleve{ + indexes: make(map[string]bleve.Index), + } +} + +func (m *mockRepoBleve) GetBleveIndex(name string) (bleve.Index, error) { + m.indexesMutex.Lock() + defer m.indexesMutex.Unlock() + + if index, ok := m.indexes[name]; ok { + return index, nil + } + + mapping := bleve.NewIndexMapping() + mapping.DefaultAnalyzer = "en" + + index, err := bleve.NewMemOnly(mapping) + if err != nil { + return nil, err + } + + m.indexes[name] = index + + return index, nil +} + +func (m *mockRepoBleve) ClearBleveIndex(name string) error { + m.indexesMutex.Lock() + defer m.indexesMutex.Unlock() + + delete(m.indexes, name) + return nil +} + var _ RepoData = &mockRepoData{} type commit struct { diff --git a/repository/repo.go b/repository/repo.go index d8fe44e6..eb9296d4 100644 --- a/repository/repo.go +++ b/repository/repo.go @@ -4,6 +4,7 @@ package repository import ( "errors" + "github.com/blevesearch/bleve" "github.com/go-git/go-billy/v5" "github.com/MichaelMure/git-bug/util/lamport" @@ -23,6 +24,9 @@ type Repo interface { RepoCommon RepoData RepoStorage + RepoBleve + + Close() error } type RepoCommonStorage interface { @@ -69,11 +73,21 @@ type RepoCommon interface { GetRemotes() (map[string]string, error) } +// RepoStorage give access to the filesystem type RepoStorage interface { // LocalStorage return a billy.Filesystem giving access to $RepoPath/.git/git-bug LocalStorage() billy.Filesystem } +// RepoBleve give access to Bleve to implement full-text search indexes. +type RepoBleve interface { + // GetBleveIndex return a bleve.Index that can be used to index documents + GetBleveIndex(name string) (bleve.Index, error) + + // ClearBleveIndex will wipe the given index + ClearBleveIndex(name string) error +} + // RepoData give access to the git data storage type RepoData interface { // FetchRefs fetch git refs from a remote |