Skip to content

Commit

Permalink
Merge pull request #803 from MichaelMure/feat/configurable-local-storage
Browse files Browse the repository at this point in the history
Feat/configurable local storage
  • Loading branch information
MichaelMure committed Jun 6, 2022
2 parents ee0bac6 + ccc342e commit dd8134b
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 32 deletions.
4 changes: 3 additions & 1 deletion commands/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"github.com/MichaelMure/git-bug/util/interrupt"
)

const gitBugNamespace = "git-bug"

// Env is the environment of a command
type Env struct {
repo repository.ClockedRepo
Expand Down Expand Up @@ -54,7 +56,7 @@ func loadRepo(env *Env) func(*cobra.Command, []string) error {
return fmt.Errorf("unable to get the current working directory: %q", err)
}

env.repo, err = repository.OpenGoGitRepo(cwd, []repository.ClockLoader{bug.ClockLoader})
env.repo, err = repository.OpenGoGitRepo(cwd, gitBugNamespace, []repository.ClockLoader{bug.ClockLoader})
if err == repository.ErrNotARepo {
return fmt.Errorf("%s must be run from within a git repo", rootCommandName)
}
Expand Down
7 changes: 5 additions & 2 deletions entity/dag/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,14 +336,17 @@ func Read(repo repository.ClockedRepo, id entity.Id) (*ProjectConfig, error) {
}

func Example_entity() {
const gitBugNamespace = "git-bug"
// Note: this example ignore errors for readability
// Note: variable names get a little confusing as we are simulating both side in the same function

// Let's start by defining two git repository and connecting them as remote
repoRenePath, _ := os.MkdirTemp("", "")
repoIsaacPath, _ := os.MkdirTemp("", "")
repoRene, _ := repository.InitGoGitRepo(repoRenePath)
repoIsaac, _ := repository.InitGoGitRepo(repoIsaacPath)
repoRene, _ := repository.InitGoGitRepo(repoRenePath, gitBugNamespace)
defer repoRene.Close()
repoIsaac, _ := repository.InitGoGitRepo(repoIsaacPath, gitBugNamespace)
defer repoIsaac.Close()
_ = repoRene.AddRemote("origin", repoIsaacPath)
_ = repoIsaac.AddRemote("origin", repoRenePath)

Expand Down
4 changes: 3 additions & 1 deletion misc/random_bugs/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
// This program will randomly generate a collection of bugs in the repository
// of the current path
func main() {
const gitBugNamespace = "git-bug"

dir, err := os.Getwd()
if err != nil {
panic(err)
Expand All @@ -20,7 +22,7 @@ func main() {
bug.ClockLoader,
}

repo, err := repository.OpenGoGitRepo(dir, loaders)
repo, err := repository.OpenGoGitRepo(dir, gitBugNamespace, loaders)
if err != nil {
panic(err)
}
Expand Down
52 changes: 31 additions & 21 deletions repository/gogit.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
)

const clockPath = "clocks"
const indexPath = "indexes"

var _ ClockedRepo = &GoGitRepo{}
var _ TestedRepo = &GoGitRepo{}
Expand All @@ -49,8 +50,11 @@ type GoGitRepo struct {
localStorage billy.Filesystem
}

// OpenGoGitRepo open an already existing repo at the given path
func OpenGoGitRepo(path string, clockLoaders []ClockLoader) (*GoGitRepo, error) {
// OpenGoGitRepo opens an already existing repo at the given path and
// with the specified LocalStorage namespace. Given a repository path
// of "~/myrepo" and a namespace of "git-bug", local storage for the
// GoGitRepo will be configured at "~/myrepo/.git/git-bug".
func OpenGoGitRepo(path, namespace string, clockLoaders []ClockLoader) (*GoGitRepo, error) {
path, err := detectGitPath(path)
if err != nil {
return nil, err
Expand All @@ -72,7 +76,7 @@ func OpenGoGitRepo(path string, clockLoaders []ClockLoader) (*GoGitRepo, error)
clocks: make(map[string]lamport.Clock),
indexes: make(map[string]bleve.Index),
keyring: k,
localStorage: osfs.New(filepath.Join(path, "git-bug")),
localStorage: osfs.New(filepath.Join(path, namespace)),
}

for _, loader := range clockLoaders {
Expand All @@ -94,8 +98,11 @@ func OpenGoGitRepo(path string, clockLoaders []ClockLoader) (*GoGitRepo, error)
return repo, nil
}

// InitGoGitRepo create a new empty git repo at the given path
func InitGoGitRepo(path string) (*GoGitRepo, error) {
// InitGoGitRepo creates a new empty git repo at the given path and
// with the specified LocalStorage namespace. Given a repository path
// of "~/myrepo" and a namespace of "git-bug", local storage for the
// GoGitRepo will be configured at "~/myrepo/.git/git-bug".
func InitGoGitRepo(path, namespace string) (*GoGitRepo, error) {
r, err := gogit.PlainInit(path, false)
if err != nil {
return nil, err
Expand All @@ -112,12 +119,15 @@ func InitGoGitRepo(path string) (*GoGitRepo, error) {
clocks: make(map[string]lamport.Clock),
indexes: make(map[string]bleve.Index),
keyring: k,
localStorage: osfs.New(filepath.Join(path, ".git", "git-bug")),
localStorage: osfs.New(filepath.Join(path, ".git", namespace)),
}, nil
}

// InitBareGoGitRepo create a new --bare empty git repo at the given path
func InitBareGoGitRepo(path string) (*GoGitRepo, error) {
// InitBareGoGitRepo creates a new --bare empty git repo at the given
// path and with the specified LocalStorage namespace. Given a repository
// path of "~/myrepo" and a namespace of "git-bug", local storage for the
// GoGitRepo will be configured at "~/myrepo/.git/git-bug".
func InitBareGoGitRepo(path, namespace string) (*GoGitRepo, error) {
r, err := gogit.PlainInit(path, true)
if err != nil {
return nil, err
Expand All @@ -134,7 +144,7 @@ func InitBareGoGitRepo(path string) (*GoGitRepo, error) {
clocks: make(map[string]lamport.Clock),
indexes: make(map[string]bleve.Index),
keyring: k,
localStorage: osfs.New(filepath.Join(path, "git-bug")),
localStorage: osfs.New(filepath.Join(path, namespace)),
}, nil
}

Expand Down Expand Up @@ -295,7 +305,8 @@ func (repo *GoGitRepo) GetRemotes() (map[string]string, error) {
return result, nil
}

// LocalStorage return a billy.Filesystem giving access to $RepoPath/.git/git-bug
// LocalStorage returns a billy.Filesystem giving access to
// $RepoPath/.git/$Namespace.
func (repo *GoGitRepo) LocalStorage() billy.Filesystem {
return repo.localStorage
}
Expand All @@ -309,7 +320,7 @@ func (repo *GoGitRepo) GetBleveIndex(name string) (bleve.Index, error) {
return index, nil
}

path := filepath.Join(repo.path, "git-bug", "indexes", name)
path := filepath.Join(repo.localStorage.Root(), indexPath, name)

index, err := bleve.Open(path)
if err == nil {
Expand Down Expand Up @@ -340,21 +351,20 @@ func (repo *GoGitRepo) ClearBleveIndex(name string) error {
repo.indexesMutex.Lock()
defer repo.indexesMutex.Unlock()

path := filepath.Join(repo.path, "git-bug", "indexes", name)

err := os.RemoveAll(path)
if err != nil {
return err
}

if index, ok := repo.indexes[name]; ok {
err = index.Close()
err := index.Close()
if err != nil {
return err
}
delete(repo.indexes, name)
}

path := filepath.Join(repo.localStorage.Root(), indexPath, name)
err := os.RemoveAll(path)
if err != nil {
return err
}

return nil
}

Expand Down Expand Up @@ -569,7 +579,7 @@ func (repo *GoGitRepo) StoreCommit(treeHash Hash, parents ...Hash) (Hash, error)
return repo.StoreSignedCommit(treeHash, nil, parents...)
}

// StoreCommit will store a Git commit with the given Git tree. If signKey is not nil, the commit
// StoreSignedCommit will store a Git commit with the given Git tree. If signKey is not nil, the commit
// will be signed accordingly.
func (repo *GoGitRepo) StoreSignedCommit(treeHash Hash, signKey *openpgp.Entity, parents ...Hash) (Hash, error) {
cfg, err := repo.r.Config()
Expand Down Expand Up @@ -781,7 +791,7 @@ func (repo *GoGitRepo) AllClocks() (map[string]lamport.Clock, error) {

result := make(map[string]lamport.Clock)

files, err := ioutil.ReadDir(filepath.Join(repo.path, "git-bug", clockPath))
files, err := ioutil.ReadDir(filepath.Join(repo.localStorage.Root(), clockPath))
if os.IsNotExist(err) {
return nil, nil
}
Expand Down
49 changes: 44 additions & 5 deletions repository/gogit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,25 @@ func TestNewGoGitRepo(t *testing.T) {
// Plain
plainRoot, err := ioutil.TempDir("", "")
require.NoError(t, err)
defer os.RemoveAll(plainRoot)
t.Cleanup(func() {
require.NoError(t, os.RemoveAll(plainRoot))
})

_, err = InitGoGitRepo(plainRoot)
plainRepo, err := InitGoGitRepo(plainRoot, namespace)
require.NoError(t, err)
require.NoError(t, plainRepo.Close())
plainGitDir := filepath.Join(plainRoot, ".git")

// Bare
bareRoot, err := ioutil.TempDir("", "")
require.NoError(t, err)
defer os.RemoveAll(bareRoot)
t.Cleanup(func() {
require.NoError(t, os.RemoveAll(bareRoot))
})

_, err = InitBareGoGitRepo(bareRoot)
bareRepo, err := InitBareGoGitRepo(bareRoot, namespace)
require.NoError(t, err)
require.NoError(t, bareRepo.Close())
bareGitDir := bareRoot

tests := []struct {
Expand All @@ -52,17 +58,50 @@ func TestNewGoGitRepo(t *testing.T) {
}

for i, tc := range tests {
r, err := OpenGoGitRepo(tc.inPath, nil)
r, err := OpenGoGitRepo(tc.inPath, namespace, nil)

if tc.err {
require.Error(t, err, i)
} else {
require.NoError(t, err, i)
assert.Equal(t, filepath.ToSlash(tc.outPath), filepath.ToSlash(r.path), i)
require.NoError(t, r.Close())
}
}
}

func TestGoGitRepo(t *testing.T) {
RepoTest(t, CreateGoGitTestRepo, CleanupTestRepos)
}

func TestGoGitRepo_Indexes(t *testing.T) {
plainRoot := t.TempDir()

repo, err := InitGoGitRepo(plainRoot, namespace)
require.NoError(t, err)
t.Cleanup(func() {
require.NoError(t, repo.Close())
})

// Can create indices
indexA, err := repo.GetBleveIndex("a")
require.NoError(t, err)
require.NotZero(t, indexA)
require.FileExists(t, filepath.Join(plainRoot, ".git", namespace, "indexes", "a", "index_meta.json"))
require.FileExists(t, filepath.Join(plainRoot, ".git", namespace, "indexes", "a", "store"))

indexB, err := repo.GetBleveIndex("b")
require.NoError(t, err)
require.NotZero(t, indexB)
require.DirExists(t, filepath.Join(plainRoot, ".git", namespace, "indexes", "b"))

// Can get an existing index
indexA, err = repo.GetBleveIndex("a")
require.NoError(t, err)
require.NotZero(t, indexA)

// Can delete an index
err = repo.ClearBleveIndex("a")
require.NoError(t, err)
require.NoDirExists(t, filepath.Join(plainRoot, ".git", namespace, "indexes", "a"))
}
6 changes: 4 additions & 2 deletions repository/gogit_testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"github.com/99designs/keyring"
)

const namespace = "git-bug"

// This is intended for testing only

func CreateGoGitTestRepo(bare bool) TestedRepo {
Expand All @@ -15,15 +17,15 @@ func CreateGoGitTestRepo(bare bool) TestedRepo {
log.Fatal(err)
}

var creator func(string) (*GoGitRepo, error)
var creator func(string, string) (*GoGitRepo, error)

if bare {
creator = InitBareGoGitRepo
} else {
creator = InitGoGitRepo
}

repo, err := creator(dir)
repo, err := creator(dir, namespace)
if err != nil {
log.Fatal(err)
}
Expand Down

0 comments on commit dd8134b

Please sign in to comment.