diff options
author | Michael Muré <batolettre@gmail.com> | 2020-11-08 17:54:28 +0100 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2021-02-14 12:15:41 +0100 |
commit | fb0c5fd06184f33a03d8d4fb29a3aef8b1dafe78 (patch) | |
tree | a0d87d04a991368840645591f11284b7ea27160c /repository | |
parent | 44d7587940f842a343a64d9107601591bdfb1027 (diff) | |
download | git-bug-fb0c5fd06184f33a03d8d4fb29a3aef8b1dafe78.tar.gz |
repo: expose all lamport clocks, move clocks in their own folder
Diffstat (limited to 'repository')
-rw-r--r-- | repository/git.go | 98 | ||||
-rw-r--r-- | repository/gogit.go | 55 | ||||
-rw-r--r-- | repository/mock_repo.go | 70 | ||||
-rw-r--r-- | repository/mock_repo_test.go | 2 | ||||
-rw-r--r-- | repository/repo.go | 11 | ||||
-rw-r--r-- | repository/repo_testing.go | 13 |
6 files changed, 207 insertions, 42 deletions
diff --git a/repository/git.go b/repository/git.go index bc9d8772..57c07c89 100644 --- a/repository/git.go +++ b/repository/git.go @@ -4,6 +4,7 @@ package repository import ( "bytes" "fmt" + "io/ioutil" "os" "path/filepath" "strings" @@ -16,10 +17,6 @@ import ( "github.com/MichaelMure/git-bug/util/lamport" ) -const ( - clockPath = "git-bug" -) - var _ ClockedRepo = &GitRepo{} var _ TestedRepo = &GitRepo{} @@ -34,7 +31,8 @@ type GitRepo struct { indexesMutex sync.Mutex indexes map[string]bleve.Index - keyring Keyring + keyring Keyring + localStorage billy.Filesystem } // OpenGitRepo determines if the given working directory is inside of a git repository, @@ -66,6 +64,7 @@ func OpenGitRepo(path string, clockLoaders []ClockLoader) (*GitRepo, error) { // Fix the path to be sure we are at the root repo.path = stdout repo.gitCli.path = stdout + repo.localStorage = osfs.New(filepath.Join(path, "git-bug")) for _, loader := range clockLoaders { allExist := true @@ -88,14 +87,21 @@ func OpenGitRepo(path string, clockLoaders []ClockLoader) (*GitRepo, error) { // InitGitRepo create a new empty git repo at the given path func InitGitRepo(path string) (*GitRepo, error) { + k, err := defaultKeyring() + if err != nil { + return nil, err + } + repo := &GitRepo{ - gitCli: gitCli{path: path}, - path: path + "/.git", - clocks: make(map[string]lamport.Clock), - indexes: make(map[string]bleve.Index), + gitCli: gitCli{path: path}, + 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")), } - _, err := repo.runGitCommand("init", path) + _, err = repo.runGitCommand("init", path) if err != nil { return nil, err } @@ -105,14 +111,21 @@ func InitGitRepo(path string) (*GitRepo, error) { // InitBareGitRepo create a new --bare empty git repo at the given path func InitBareGitRepo(path string) (*GitRepo, error) { + k, err := defaultKeyring() + if err != nil { + return nil, err + } + repo := &GitRepo{ - gitCli: gitCli{path: path}, - path: path, - clocks: make(map[string]lamport.Clock), - indexes: make(map[string]bleve.Index), + gitCli: gitCli{path: path}, + path: path, + clocks: make(map[string]lamport.Clock), + indexes: make(map[string]bleve.Index), + keyring: k, + localStorage: osfs.New(filepath.Join(path, "git-bug")), } - _, err := repo.runGitCommand("init", "--bare", path) + _, err = repo.runGitCommand("init", "--bare", path) if err != nil { return nil, err } @@ -198,7 +211,7 @@ func (repo *GitRepo) GetRemotes() (map[string]string, error) { // LocalStorage return a billy.Filesystem giving access to $RepoPath/.git/git-bug func (repo *GitRepo) LocalStorage() billy.Filesystem { - return osfs.New(repo.path) + return repo.localStorage } // GetBleveIndex return a bleve.Index that can be used to index documents @@ -434,6 +447,37 @@ func (repo *GitRepo) GetTreeHash(commit Hash) (Hash, error) { return Hash(stdout), nil } +func (repo *GitRepo) AllClocks() (map[string]lamport.Clock, error) { + repo.clocksMutex.Lock() + defer repo.clocksMutex.Unlock() + + result := make(map[string]lamport.Clock) + + files, err := ioutil.ReadDir(filepath.Join(repo.path, "git-bug", clockPath)) + if os.IsNotExist(err) { + return nil, nil + } + if err != nil { + return nil, err + } + + for _, file := range files { + name := file.Name() + if c, ok := repo.clocks[name]; ok { + result[name] = c + } else { + c, err := lamport.LoadPersistedClock(repo.LocalStorage(), filepath.Join(clockPath, name)) + if err != nil { + return nil, err + } + repo.clocks[name] = c + result[name] = c + } + } + + return result, nil +} + // GetOrCreateClock return a Lamport clock stored in the Repo. // If the clock doesn't exist, it's created. func (repo *GitRepo) GetOrCreateClock(name string) (lamport.Clock, error) { @@ -448,7 +492,7 @@ func (repo *GitRepo) GetOrCreateClock(name string) (lamport.Clock, error) { return nil, err } - c, err = lamport.NewPersistedClock(repo.LocalStorage(), name+"-clock") + c, err = lamport.NewPersistedClock(repo.LocalStorage(), filepath.Join(clockPath, name)) if err != nil { return nil, err } @@ -462,7 +506,7 @@ func (repo *GitRepo) getClock(name string) (lamport.Clock, error) { return c, nil } - c, err := lamport.LoadPersistedClock(repo.LocalStorage(), name+"-clock") + c, err := lamport.LoadPersistedClock(repo.LocalStorage(), filepath.Join(clockPath, name)) if err == nil { repo.clocks[name] = c return c, nil @@ -473,6 +517,24 @@ func (repo *GitRepo) getClock(name string) (lamport.Clock, error) { return nil, err } +// Increment is equivalent to c = GetOrCreateClock(name) + c.Increment() +func (repo *GitRepo) Increment(name string) (lamport.Time, error) { + c, err := repo.GetOrCreateClock(name) + if err != nil { + return lamport.Time(0), err + } + return c.Increment() +} + +// Witness is equivalent to c = GetOrCreateClock(name) + c.Witness(time) +func (repo *GitRepo) Witness(name string, time lamport.Time) error { + c, err := repo.GetOrCreateClock(name) + if err != nil { + return err + } + return c.Witness(time) +} + // AddRemote add a new remote to the repository // Not in the interface because it's only used for testing func (repo *GitRepo) AddRemote(name string, url string) error { diff --git a/repository/gogit.go b/repository/gogit.go index bdac259d..5abdef39 100644 --- a/repository/gogit.go +++ b/repository/gogit.go @@ -24,6 +24,8 @@ import ( "github.com/MichaelMure/git-bug/util/lamport" ) +const clockPath = "clocks" + var _ ClockedRepo = &GoGitRepo{} var _ TestedRepo = &GoGitRepo{} @@ -677,6 +679,37 @@ func (repo *GoGitRepo) ListCommits(ref string) ([]Hash, error) { return hashes, nil } +func (repo *GoGitRepo) AllClocks() (map[string]lamport.Clock, error) { + repo.clocksMutex.Lock() + defer repo.clocksMutex.Unlock() + + result := make(map[string]lamport.Clock) + + files, err := ioutil.ReadDir(filepath.Join(repo.path, "git-bug", clockPath)) + if os.IsNotExist(err) { + return nil, nil + } + if err != nil { + return nil, err + } + + for _, file := range files { + name := file.Name() + if c, ok := repo.clocks[name]; ok { + result[name] = c + } else { + c, err := lamport.LoadPersistedClock(repo.LocalStorage(), filepath.Join(clockPath, name)) + if err != nil { + return nil, err + } + repo.clocks[name] = c + result[name] = c + } + } + + return result, nil +} + // GetOrCreateClock return a Lamport clock stored in the Repo. // If the clock doesn't exist, it's created. func (repo *GoGitRepo) GetOrCreateClock(name string) (lamport.Clock, error) { @@ -691,7 +724,7 @@ func (repo *GoGitRepo) GetOrCreateClock(name string) (lamport.Clock, error) { return nil, err } - c, err = lamport.NewPersistedClock(repo.localStorage, name+"-clock") + c, err = lamport.NewPersistedClock(repo.LocalStorage(), filepath.Join(clockPath, name)) if err != nil { return nil, err } @@ -705,7 +738,7 @@ func (repo *GoGitRepo) getClock(name string) (lamport.Clock, error) { return c, nil } - c, err := lamport.LoadPersistedClock(repo.localStorage, name+"-clock") + c, err := lamport.LoadPersistedClock(repo.LocalStorage(), filepath.Join(clockPath, name)) if err == nil { repo.clocks[name] = c return c, nil @@ -716,6 +749,24 @@ func (repo *GoGitRepo) getClock(name string) (lamport.Clock, error) { return nil, err } +// Increment is equivalent to c = GetOrCreateClock(name) + c.Increment() +func (repo *GoGitRepo) Increment(name string) (lamport.Time, error) { + c, err := repo.GetOrCreateClock(name) + if err != nil { + return lamport.Time(0), err + } + return c.Increment() +} + +// Witness is equivalent to c = GetOrCreateClock(name) + c.Witness(time) +func (repo *GoGitRepo) Witness(name string, time lamport.Time) error { + c, err := repo.GetOrCreateClock(name) + if err != nil { + return err + } + return c.Witness(time) +} + // AddRemote add a new remote to the repository // Not in the interface because it's only used for testing func (repo *GoGitRepo) AddRemote(name string, url string) error { diff --git a/repository/mock_repo.go b/repository/mock_repo.go index 8a1724ef..974c3fb2 100644 --- a/repository/mock_repo.go +++ b/repository/mock_repo.go @@ -14,11 +14,11 @@ import ( "github.com/MichaelMure/git-bug/util/lamport" ) -var _ ClockedRepo = &mockRepoForTest{} -var _ TestedRepo = &mockRepoForTest{} +var _ ClockedRepo = &mockRepo{} +var _ TestedRepo = &mockRepo{} -// mockRepoForTest defines an instance of Repo that can be used for testing. -type mockRepoForTest struct { +// mockRepo defines an instance of Repo that can be used for testing. +type mockRepo struct { *mockRepoConfig *mockRepoKeyring *mockRepoCommon @@ -26,12 +26,13 @@ type mockRepoForTest struct { *mockRepoBleve *mockRepoData *mockRepoClock + *mockRepoTest } -func (m *mockRepoForTest) Close() error { return nil } +func (m *mockRepo) Close() error { return nil } -func NewMockRepoForTest() *mockRepoForTest { - return &mockRepoForTest{ +func NewMockRepo() *mockRepo { + return &mockRepo{ mockRepoConfig: NewMockRepoConfig(), mockRepoKeyring: NewMockRepoKeyring(), mockRepoCommon: NewMockRepoCommon(), @@ -39,6 +40,7 @@ func NewMockRepoForTest() *mockRepoForTest { mockRepoBleve: newMockRepoBleve(), mockRepoData: NewMockRepoData(), mockRepoClock: NewMockRepoClock(), + mockRepoTest: NewMockRepoTest(), } } @@ -371,18 +373,7 @@ func (r *mockRepoData) GetTreeHash(commit Hash) (Hash, error) { return c.treeHash, nil } -func (r *mockRepoData) AddRemote(name string, url string) error { - panic("implement me") -} - -func (m mockRepoForTest) GetLocalRemote() string { - panic("implement me") -} - -func (m mockRepoForTest) EraseFromDisk() error { - // nothing to do - return nil -} +var _ RepoClock = &mockRepoClock{} type mockRepoClock struct { mu sync.Mutex @@ -395,6 +386,10 @@ func NewMockRepoClock() *mockRepoClock { } } +func (r *mockRepoClock) AllClocks() (map[string]lamport.Clock, error) { + return r.clocks, nil +} + func (r *mockRepoClock) GetOrCreateClock(name string) (lamport.Clock, error) { r.mu.Lock() defer r.mu.Unlock() @@ -407,3 +402,40 @@ func (r *mockRepoClock) GetOrCreateClock(name string) (lamport.Clock, error) { r.clocks[name] = c return c, nil } + +func (r *mockRepoClock) Increment(name string) (lamport.Time, error) { + c, err := r.GetOrCreateClock(name) + if err != nil { + return lamport.Time(0), err + } + return c.Increment() +} + +func (r *mockRepoClock) Witness(name string, time lamport.Time) error { + c, err := r.GetOrCreateClock(name) + if err != nil { + return err + } + return c.Witness(time) +} + +var _ repoTest = &mockRepoTest{} + +type mockRepoTest struct{} + +func NewMockRepoTest() *mockRepoTest { + return &mockRepoTest{} +} + +func (r *mockRepoTest) AddRemote(name string, url string) error { + panic("implement me") +} + +func (r mockRepoTest) GetLocalRemote() string { + panic("implement me") +} + +func (r mockRepoTest) EraseFromDisk() error { + // nothing to do + return nil +} diff --git a/repository/mock_repo_test.go b/repository/mock_repo_test.go index b56b94f2..dec09380 100644 --- a/repository/mock_repo_test.go +++ b/repository/mock_repo_test.go @@ -3,7 +3,7 @@ package repository import "testing" func TestMockRepo(t *testing.T) { - creator := func(bare bool) TestedRepo { return NewMockRepoForTest() } + creator := func(bare bool) TestedRepo { return NewMockRepo() } cleaner := func(repos ...Repo) {} RepoTest(t, creator, cleaner) diff --git a/repository/repo.go b/repository/repo.go index eb9296d4..625e0143 100644 --- a/repository/repo.go +++ b/repository/repo.go @@ -22,9 +22,9 @@ type Repo interface { RepoConfig RepoKeyring RepoCommon - RepoData RepoStorage RepoBleve + RepoData Close() error } @@ -142,9 +142,18 @@ type RepoData interface { // RepoClock give access to Lamport clocks type RepoClock interface { + // AllClocks return all the known clocks + AllClocks() (map[string]lamport.Clock, error) + // GetOrCreateClock return a Lamport clock stored in the Repo. // If the clock doesn't exist, it's created. GetOrCreateClock(name string) (lamport.Clock, error) + + // Increment is equivalent to c = GetOrCreateClock(name) + c.Increment() + Increment(name string) (lamport.Time, error) + + // Witness is equivalent to c = GetOrCreateClock(name) + c.Witness(time) + Witness(name string, time lamport.Time) error } // ClockLoader hold which logical clock need to exist for an entity and diff --git a/repository/repo_testing.go b/repository/repo_testing.go index c0e1fa79..2c8705d6 100644 --- a/repository/repo_testing.go +++ b/repository/repo_testing.go @@ -191,13 +191,17 @@ func RepoDataTest(t *testing.T, repo RepoData) { // helper to test a RepoClock func RepoClockTest(t *testing.T, repo RepoClock) { + allClocks, err := repo.AllClocks() + require.NoError(t, err) + require.Len(t, allClocks, 0) + clock, err := repo.GetOrCreateClock("foo") require.NoError(t, err) require.Equal(t, lamport.Time(1), clock.Time()) time, err := clock.Increment() require.NoError(t, err) - require.Equal(t, lamport.Time(1), time) + require.Equal(t, lamport.Time(2), time) require.Equal(t, lamport.Time(2), clock.Time()) clock2, err := repo.GetOrCreateClock("foo") @@ -207,6 +211,13 @@ func RepoClockTest(t *testing.T, repo RepoClock) { clock3, err := repo.GetOrCreateClock("bar") require.NoError(t, err) require.Equal(t, lamport.Time(1), clock3.Time()) + + allClocks, err = repo.AllClocks() + require.NoError(t, err) + require.Equal(t, map[string]lamport.Clock{ + "foo": clock, + "bar": clock3, + }, allClocks) } func randomData() []byte { |