repository: add ReadTimestamp methods and improve naming

amine created

Change summary

repository/config.go         |  7 +++
repository/config_git.go     | 21 +++++++++-
repository/config_mem.go     | 74 ++++++++++++++++++++++++++++++++++++++
repository/config_runtime.go | 59 ------------------------------
repository/git.go            |  4 +-
repository/mock_repo.go      |  4 +-
6 files changed, 104 insertions(+), 65 deletions(-)

Detailed changes

repository/config.go 🔗

@@ -1,5 +1,7 @@
 package repository
 
+import "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
@@ -18,6 +20,11 @@ type Config interface {
 	// there is zero or more than one entry for this key
 	ReadString(key string) (string, error)
 
+	// ReadTimestamp read a single timestamp value from the config
+	// Return ErrNoConfigEntry or ErrMultipleConfigEntry if
+	// there is zero or more than one entry for this key
+	ReadTimestamp(key string) (*time.Time, error)
+
 	// RemoveAll removes all key/value pair matching the key prefix
 	RemoveAll(keyPrefix string) error
 }

repository/config_git.go 🔗

@@ -4,17 +4,20 @@ import (
 	"fmt"
 	"strconv"
 	"strings"
+	"time"
 
 	"github.com/blang/semver"
 	"github.com/pkg/errors"
 )
 
+var _ Config = &gitConfig{}
+
 type gitConfig struct {
 	version *semver.Version
 	execFn  func(args ...string) (string, error)
 }
 
-func NewGitConfig(repo *GitRepo, global bool) *gitConfig {
+func newGitConfig(repo *GitRepo, global bool) *gitConfig {
 	version, _ := repo.GitVersion()
 
 	if global {
@@ -29,7 +32,7 @@ func NewGitConfig(repo *GitRepo, global bool) *gitConfig {
 
 	return &gitConfig{
 		execFn: func(args ...string) (string, error) {
-			args = append([]string{"config"}, args...)
+			args = append([]string{"config", "--local"}, args...)
 			return repo.runGitCommand(args...)
 		},
 		version: version,
@@ -111,6 +114,20 @@ func (gc *gitConfig) ReadBool(key string) (bool, error) {
 	return strconv.ParseBool(val)
 }
 
+func (gc *gitConfig) ReadTimestamp(key string) (*time.Time, error) {
+	value, err := gc.ReadString(key)
+	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
+}
+
 func (gc *gitConfig) rmSection(keyPrefix string) error {
 	_, err := gc.execFn("--remove-section", keyPrefix)
 	return err

repository/config_mem.go 🔗

@@ -0,0 +1,74 @@
+package repository
+
+import (
+	"strconv"
+	"strings"
+	"time"
+)
+
+type memConfig struct {
+	config map[string]string
+}
+
+func newMemConfig(config map[string]string) *memConfig {
+	return &memConfig{config: config}
+}
+
+func (mc *memConfig) Store(key, value string) error {
+	mc.config[key] = value
+	return nil
+}
+
+func (mc *memConfig) ReadAll(keyPrefix string) (map[string]string, error) {
+	result := make(map[string]string)
+	for key, val := range mc.config {
+		if strings.HasPrefix(key, keyPrefix) {
+			result[key] = val
+		}
+	}
+	return result, nil
+}
+
+func (mc *memConfig) ReadString(key string) (string, error) {
+	// unlike git, the mock can only store one value for the same key
+	val, ok := mc.config[key]
+	if !ok {
+		return "", ErrNoConfigEntry
+	}
+
+	return val, nil
+}
+
+func (mc *memConfig) ReadBool(key string) (bool, error) {
+	// unlike git, the mock can only store one value for the same key
+	val, ok := mc.config[key]
+	if !ok {
+		return false, ErrNoConfigEntry
+	}
+
+	return strconv.ParseBool(val)
+}
+
+func (mc *memConfig) ReadTimestamp(key string) (*time.Time, error) {
+	value, err := mc.ReadString(key)
+	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
+}
+
+// RmConfigs remove all key/value pair matching the key prefix
+func (mc *memConfig) RemoveAll(keyPrefix string) error {
+	for key := range mc.config {
+		if strings.HasPrefix(key, keyPrefix) {
+			delete(mc.config, key)
+		}
+	}
+	return nil
+}

repository/config_runtime.go 🔗

@@ -1,59 +0,0 @@
-package repository
-
-import (
-	"strconv"
-	"strings"
-)
-
-type runtimeConfig struct {
-	config map[string]string
-}
-
-func newRuntimeConfig(config map[string]string) *runtimeConfig {
-	return &runtimeConfig{config: config}
-}
-
-func (rtc *runtimeConfig) Store(key, value string) error {
-	rtc.config[key] = value
-	return nil
-}
-
-func (rtc *runtimeConfig) ReadAll(keyPrefix string) (map[string]string, error) {
-	result := make(map[string]string)
-	for key, val := range rtc.config {
-		if strings.HasPrefix(key, keyPrefix) {
-			result[key] = val
-		}
-	}
-	return result, nil
-}
-
-func (rtc *runtimeConfig) ReadString(key string) (string, error) {
-	// unlike git, the mock can only store one value for the same key
-	val, ok := rtc.config[key]
-	if !ok {
-		return "", ErrNoConfigEntry
-	}
-
-	return val, nil
-}
-
-func (rtc *runtimeConfig) ReadBool(key string) (bool, error) {
-	// unlike git, the mock can only store one value for the same key
-	val, ok := rtc.config[key]
-	if !ok {
-		return false, ErrNoConfigEntry
-	}
-
-	return strconv.ParseBool(val)
-}
-
-// RmConfigs remove all key/value pair matching the key prefix
-func (rtc *runtimeConfig) RemoveAll(keyPrefix string) error {
-	for key := range rtc.config {
-		if strings.HasPrefix(key, keyPrefix) {
-			delete(rtc.config, key)
-		}
-	}
-	return nil
-}

repository/git.go 🔗

@@ -34,12 +34,12 @@ type GitRepo struct {
 
 // LocalConfig .
 func (repo *GitRepo) LocalConfig() Config {
-	return NewGitConfig(repo, false)
+	return newGitConfig(repo, false)
 }
 
 // GlobalConfig .
 func (repo *GitRepo) GlobalConfig() Config {
-	return NewGitConfig(repo, true)
+	return newGitConfig(repo, true)
 }
 
 // Run the given git command with the given I/O reader/writers, returning an error if it fails.

repository/mock_repo.go 🔗

@@ -42,11 +42,11 @@ func NewMockRepoForTest() *mockRepoForTest {
 }
 
 func (r *mockRepoForTest) LocalConfig() Config {
-	return newRuntimeConfig(r.config)
+	return newMemConfig(r.config)
 }
 
 func (r *mockRepoForTest) GlobalConfig() Config {
-	return newRuntimeConfig(r.globalConfig)
+	return newMemConfig(r.globalConfig)
 }
 
 // GetPath returns the path to the repo.