From 104224c9f081fbe79757976a8c1f903ae94c3f8a Mon Sep 17 00:00:00 2001 From: amine Date: Fri, 1 Nov 2019 18:39:45 +0100 Subject: repository: add StoreTimestamp/StoreBool to the config interface repository: move the gitVersion logic to *gitConfig struct --- repository/config.go | 25 ++++++++++++-- repository/config_git.go | 86 ++++++++++++++++++++++++++++++----------------- repository/config_mem.go | 12 ++++++- repository/git.go | 40 ---------------------- repository/git_test.go | 4 +-- repository/git_testing.go | 4 +-- 6 files changed, 93 insertions(+), 78 deletions(-) (limited to 'repository') diff --git a/repository/config.go b/repository/config.go index 70f11081..ec5094e0 100644 --- a/repository/config.go +++ b/repository/config.go @@ -1,11 +1,20 @@ package repository -import "time" +import ( + "strconv" + "time" +) // Config represent the common function interacting with the repository config storage type Config interface { - // Store writes a single key/value pair in the config of the repo - Store(key string, value string) error + // Store writes a single key/value pair in the config + StoreString(key, value string) error + + // Store writes a key and timestamp value to the config + StoreTimestamp(key string, value time.Time) error + + // Store writes a key and boolean value to the config + StoreBool(key string, value bool) error // ReadAll reads all key/value pair matching the key prefix ReadAll(keyPrefix string) (map[string]string, error) @@ -28,3 +37,13 @@ type Config interface { // RemoveAll removes all key/value pair matching the key prefix RemoveAll(keyPrefix string) error } + +func parseTimestamp(s string) (*time.Time, error) { + timestamp, err := strconv.Atoi(s) + if err != nil { + return nil, err + } + + t := time.Unix(int64(timestamp), 0) + return &t, nil +} diff --git a/repository/config_git.go b/repository/config_git.go index 80b23cc7..67ca3436 100644 --- a/repository/config_git.go +++ b/repository/config_git.go @@ -2,6 +2,7 @@ package repository import ( "fmt" + "regexp" "strconv" "strings" "time" @@ -13,42 +14,41 @@ import ( var _ Config = &gitConfig{} type gitConfig struct { - version *semver.Version - execFn func(args ...string) (string, error) + execFn func(args ...string) (string, error) } func newGitConfig(repo *GitRepo, global bool) *gitConfig { - version, _ := repo.GitVersion() - + configCmdFlag := "--local" if global { - return &gitConfig{ - execFn: func(args ...string) (string, error) { - args = append([]string{"config", "--global"}, args...) - return repo.runGitCommand(args...) - }, - version: version, - } + configCmdFlag = "--global" } - return &gitConfig{ execFn: func(args ...string) (string, error) { - args = append([]string{"config", "--local"}, args...) + if len(args) > 0 && args[0] == "config" { + args = append([]string{args[0], configCmdFlag}, args[1:]...) + } return repo.runGitCommand(args...) }, - version: version, } } // StoreConfig store a single key/value pair in the config of the repo -func (gc *gitConfig) Store(key string, value string) error { - _, err := gc.execFn("--replace-all", key, value) - +func (gc *gitConfig) StoreString(key string, value string) error { + _, err := gc.execFn("config", "--replace-all", key, value) return err } +func (gc *gitConfig) StoreBool(key string, value bool) error { + return gc.StoreString(key, strconv.FormatBool(value)) +} + +func (gc *gitConfig) StoreTimestamp(key string, value time.Time) error { + return gc.StoreString(key, strconv.Itoa(int(value.Unix()))) +} + // ReadConfigs read all key/value pair matching the key prefix func (gc *gitConfig) ReadAll(keyPrefix string) (map[string]string, error) { - stdout, err := gc.execFn("--get-regexp", keyPrefix) + stdout, err := gc.execFn("config", "--get-regexp", keyPrefix) // / \ // / ! \ @@ -81,7 +81,7 @@ func (gc *gitConfig) ReadAll(keyPrefix string) (map[string]string, error) { } func (gc *gitConfig) ReadString(key string) (string, error) { - stdout, err := gc.execFn("--get-all", key) + stdout, err := gc.execFn("config", "--get-all", key) // / \ // / ! \ @@ -119,22 +119,16 @@ func (gc *gitConfig) ReadTimestamp(key string) (*time.Time, error) { if err != nil { return nil, err } - timestamp, err := strconv.Atoi(value) - if err != nil { - return nil, err - } - - t := time.Unix(int64(timestamp), 0) - return &t, nil + return parseTimestamp(value) } func (gc *gitConfig) rmSection(keyPrefix string) error { - _, err := gc.execFn("--remove-section", keyPrefix) + _, err := gc.execFn("config", "--remove-section", keyPrefix) return err } func (gc *gitConfig) unsetAll(keyPrefix string) error { - _, err := gc.execFn("--unset-all", keyPrefix) + _, err := gc.execFn("config", "--unset-all", keyPrefix) return err } @@ -192,11 +186,43 @@ func (gc *gitConfig) RemoveAll(keyPrefix string) error { return nil } +func (gc *gitConfig) gitVersion() (*semver.Version, error) { + versionOut, err := gc.execFn("version") + if err != nil { + return nil, err + } + return parseGitVersion(versionOut) +} + +func parseGitVersion(versionOut string) (*semver.Version, error) { + // extract the version and truncate potential bad parts + // ex: 2.23.0.rc1 instead of 2.23.0-rc1 + r := regexp.MustCompile(`(\d+\.){1,2}\d+`) + + extracted := r.FindString(versionOut) + if extracted == "" { + return nil, fmt.Errorf("unreadable git version %s", versionOut) + } + + version, err := semver.Make(extracted) + if err != nil { + return nil, err + } + + return &version, nil +} + func (gc *gitConfig) gitVersionLT218() (bool, error) { - gitVersion218, err := semver.Make("2.18.0") + version, err := gc.gitVersion() + if err != nil { + return false, err + } + + version218string := "2.18.0" + gitVersion218, err := semver.Make(version218string) if err != nil { return false, err } - return gc.version.LT(gitVersion218), nil + return version.LT(gitVersion218), nil } diff --git a/repository/config_mem.go b/repository/config_mem.go index e8809f5e..e2cffd9c 100644 --- a/repository/config_mem.go +++ b/repository/config_mem.go @@ -6,6 +6,8 @@ import ( "time" ) +var _ Config = &memConfig{} + type memConfig struct { config map[string]string } @@ -14,11 +16,19 @@ func newMemConfig(config map[string]string) *memConfig { return &memConfig{config: config} } -func (mc *memConfig) Store(key, value string) error { +func (mc *memConfig) StoreString(key, value string) error { mc.config[key] = value return nil } +func (mc *memConfig) StoreBool(key string, value bool) error { + return mc.StoreString(key, strconv.FormatBool(value)) +} + +func (mc *memConfig) StoreTimestamp(key string, value time.Time) error { + return mc.StoreString(key, strconv.Itoa(int(value.Unix()))) +} + func (mc *memConfig) ReadAll(keyPrefix string) (map[string]string, error) { result := make(map[string]string) for key, val := range mc.config { diff --git a/repository/git.go b/repository/git.go index c25309f5..0951b577 100644 --- a/repository/git.go +++ b/repository/git.go @@ -7,10 +7,8 @@ import ( "io" "os/exec" "path" - "regexp" "strings" - "github.com/blang/semver" "github.com/pkg/errors" "github.com/MichaelMure/git-bug/util/git" @@ -206,44 +204,6 @@ func (repo *GitRepo) GetRemotes() (map[string]string, error) { return remotes, nil } -func (repo *GitRepo) GitVersion() (*semver.Version, error) { - versionOut, err := repo.runGitCommand("version") - if err != nil { - return nil, err - } - - // extract the version and truncate potential bad parts - // ex: 2.23.0.rc1 instead of 2.23.0-rc1 - r := regexp.MustCompile(`(\d+\.){1,2}\d+`) - - extracted := r.FindString(versionOut) - if extracted == "" { - return nil, fmt.Errorf("unreadable git version %s", versionOut) - } - - version, err := semver.Make(extracted) - if err != nil { - return nil, err - } - - return &version, nil -} - -func (repo *GitRepo) gitVersionLT218() (bool, error) { - version, err := repo.GitVersion() - if err != nil { - return false, err - } - - version218string := "2.18.0" - gitVersion218, err := semver.Make(version218string) - if err != nil { - return false, err - } - - return version.LT(gitVersion218), 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/git_test.go b/repository/git_test.go index 628e7911..cb115526 100644 --- a/repository/git_test.go +++ b/repository/git_test.go @@ -13,13 +13,13 @@ func TestConfig(t *testing.T) { config := repo.LocalConfig() - err := config.Store("section.key", "value") + err := config.StoreString("section.key", "value") assert.NoError(t, err) val, err := config.ReadString("section.key") assert.Equal(t, "value", val) - err = config.Store("section.true", "true") + err = config.StoreString("section.true", "true") assert.NoError(t, err) val2, err := config.ReadBool("section.true") diff --git a/repository/git_testing.go b/repository/git_testing.go index 5f1eaf7c..37a15d93 100644 --- a/repository/git_testing.go +++ b/repository/git_testing.go @@ -32,10 +32,10 @@ func CreateTestRepo(bare bool) *GitRepo { } config := repo.LocalConfig() - if err := config.Store("user.name", "testuser"); err != nil { + if err := config.StoreString("user.name", "testuser"); err != nil { log.Fatal("failed to set user.name for test repository: ", err) } - if err := config.Store("user.email", "testuser@example.com"); err != nil { + if err := config.StoreString("user.email", "testuser@example.com"); err != nil { log.Fatal("failed to set user.email for test repository: ", err) } -- cgit