From 666586c5b92b64a64aea22927cfb3754861623a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Mon, 24 Sep 2018 15:21:34 +0200 Subject: [PATCH] repo: add functions to read/write git config --- cache/repo_cache.go | 8 ++++++++ repository/git.go | 41 +++++++++++++++++++++++++++++++++++------ repository/mock_repo.go | 20 ++++++++++++++++++++ repository/repo.go | 7 +++++++ 4 files changed, 70 insertions(+), 6 deletions(-) diff --git a/cache/repo_cache.go b/cache/repo_cache.go index a43c668434deb93efa77dc4184613b0a3b4fc142..0f27090931f3751eb985edaf1388a483ae70afb3 100644 --- a/cache/repo_cache.go +++ b/cache/repo_cache.go @@ -75,6 +75,14 @@ func (c *RepoCache) GetUserEmail() (string, error) { return c.repo.GetUserEmail() } +func (c *RepoCache) StoreConfig(key string, value string) error { + return c.repo.StoreConfig(key, value) +} + +func (c *RepoCache) ReadConfigs(keyPrefix string) (map[string]string, error) { + return c.repo.ReadConfigs(keyPrefix) +} + func (c *RepoCache) lock() error { lockPath := repoLockFilePath(c.repo) diff --git a/repository/git.go b/repository/git.go index db411792ee6fadd112c973d3dd3b813fd1fd5dce..51c4f46bdfcbc821b28db26f4ddb3c912a2bbe3b 100644 --- a/repository/git.go +++ b/repository/git.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "os" "os/exec" "path" "strings" @@ -66,11 +65,6 @@ func (repo *GitRepo) runGitCommand(args ...string) (string, error) { return repo.runGitCommandWithStdin(nil, args...) } -// Run the given git command using the same stdin, stdout, and stderr as the review tool. -func (repo *GitRepo) runGitCommandInline(args ...string) error { - return repo.runGitCommandWithIO(os.Stdin, os.Stdout, os.Stderr, args...) -} - // NewGitRepo 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, witnesser func(repo *GitRepo) error) (*GitRepo, error) { @@ -165,6 +159,41 @@ func (repo *GitRepo) GetCoreEditor() (string, error) { return repo.runGitCommand("var", "GIT_EDITOR") } +// StoreConfig store a single key/value pair in the config of the repo +func (repo *GitRepo) StoreConfig(key string, value string) error { + _, err := repo.runGitCommand("config", "--replace-all", key, value) + + return err +} + +// ReadConfigs read all key/value pair matching the key prefix +func (repo *GitRepo) ReadConfigs(keyPrefix string) (map[string]string, error) { + stdout, err := repo.runGitCommand("config", "--get-regexp", keyPrefix) + + if err != nil { + return nil, err + } + + lines := strings.Split(stdout, "\n") + + result := make(map[string]string, len(lines)) + + for _, line := range lines { + if strings.TrimSpace(line) == "" { + continue + } + + parts := strings.Fields(line) + if len(parts) != 2 { + return nil, fmt.Errorf("bad git config: %s", line) + } + + result[parts[0]] = parts[1] + } + + return result, 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/mock_repo.go b/repository/mock_repo.go index 2b911783dc5d6bc85021fecc84a0b366d4c77290..2389a8e0014feae171115740dba9d894dcb1311c 100644 --- a/repository/mock_repo.go +++ b/repository/mock_repo.go @@ -3,6 +3,7 @@ package repository import ( "crypto/sha1" "fmt" + "strings" "github.com/MichaelMure/git-bug/util/git" "github.com/MichaelMure/git-bug/util/lamport" @@ -10,6 +11,7 @@ import ( // mockRepoForTest defines an instance of Repo that can be used for testing. type mockRepoForTest struct { + config map[string]string blobs map[git.Hash][]byte trees map[git.Hash]string commits map[git.Hash]commit @@ -25,6 +27,7 @@ type commit struct { func NewMockRepoForTest() *mockRepoForTest { return &mockRepoForTest{ + config: make(map[string]string), blobs: make(map[git.Hash][]byte), trees: make(map[git.Hash]string), commits: make(map[git.Hash]commit), @@ -53,6 +56,23 @@ func (r *mockRepoForTest) GetCoreEditor() (string, error) { return "vi", nil } +func (r *mockRepoForTest) StoreConfig(key string, value string) error { + r.config[key] = value + return nil +} + +func (r *mockRepoForTest) ReadConfigs(keyPrefix string) (map[string]string, error) { + result := make(map[string]string) + + for key, val := range r.config { + if strings.HasPrefix(key, keyPrefix) { + result[key] = val + } + } + + return result, nil +} + // PushRefs push git refs to a remote func (r *mockRepoForTest) PushRefs(remote string, refSpec string) (string, error) { return "", nil diff --git a/repository/repo.go b/repository/repo.go index 0cddf38a8a4291cd0f82ffee37c58b7cf3e3b711..c029a145af52694ca8faf83da1d702c68b55be47 100644 --- a/repository/repo.go +++ b/repository/repo.go @@ -9,6 +9,7 @@ import ( "github.com/MichaelMure/git-bug/util/lamport" ) +// RepoCommon represent the common function the we want all the repo to implement type RepoCommon interface { // GetPath returns the path to the repo. GetPath() string @@ -21,6 +22,12 @@ type RepoCommon interface { // GetCoreEditor returns the name of the editor that the user has used to configure git. GetCoreEditor() (string, error) + + // StoreConfig store a single key/value pair in the config of the repo + StoreConfig(key string, value string) error + + // ReadConfigs read all key/value pair matching the key prefix + ReadConfigs(keyPrefix string) (map[string]string, error) } // Repo represents a source code repository.