1package repository
  2
  3import (
  4	"strconv"
  5	"strings"
  6	"time"
  7)
  8
  9var _ Config = &MemConfig{}
 10
 11type MemConfig struct {
 12	config map[string]string
 13}
 14
 15func NewMemConfig() *MemConfig {
 16	return &MemConfig{
 17		config: make(map[string]string),
 18	}
 19}
 20
 21func (mc *MemConfig) StoreString(key, value string) error {
 22	key = normalizeKey(key)
 23	mc.config[key] = value
 24	return nil
 25}
 26
 27func (mc *MemConfig) StoreBool(key string, value bool) error {
 28	return mc.StoreString(key, strconv.FormatBool(value))
 29}
 30
 31func (mc *MemConfig) StoreTimestamp(key string, value time.Time) error {
 32	return mc.StoreString(key, strconv.Itoa(int(value.Unix())))
 33}
 34
 35func (mc *MemConfig) ReadAll(keyPrefix string) (map[string]string, error) {
 36	keyPrefix = normalizeKey(keyPrefix)
 37	result := make(map[string]string)
 38	for key, val := range mc.config {
 39		if strings.HasPrefix(key, keyPrefix) {
 40			result[key] = val
 41		}
 42	}
 43	return result, nil
 44}
 45
 46func (mc *MemConfig) ReadString(key string) (string, error) {
 47	// unlike git, the mock can only store one value for the same key
 48	key = normalizeKey(key)
 49	val, ok := mc.config[key]
 50	if !ok {
 51		return "", newErrNoConfigEntry(key)
 52	}
 53
 54	return val, nil
 55}
 56
 57func (mc *MemConfig) ReadBool(key string) (bool, error) {
 58	// unlike git, the mock can only store one value for the same key
 59	val, err := mc.ReadString(key)
 60	if err != nil {
 61		return false, err
 62	}
 63
 64	return strconv.ParseBool(val)
 65}
 66
 67func (mc *MemConfig) ReadTimestamp(key string) (time.Time, error) {
 68	value, err := mc.ReadString(key)
 69	if err != nil {
 70		return time.Time{}, err
 71	}
 72
 73	timestamp, err := strconv.Atoi(value)
 74	if err != nil {
 75		return time.Time{}, err
 76	}
 77
 78	return time.Unix(int64(timestamp), 0), nil
 79}
 80
 81// RemoveAll remove all key/value pair matching the key prefix
 82func (mc *MemConfig) RemoveAll(keyPrefix string) error {
 83	keyPrefix = normalizeKey(keyPrefix)
 84	for key := range mc.config {
 85		if strings.HasPrefix(key, keyPrefix) {
 86			delete(mc.config, key)
 87		}
 88	}
 89
 90	return nil
 91}
 92
 93func normalizeKey(key string) string {
 94	// this feels so wrong, but that's apparently how git behave.
 95	// only section and final segment are case insensitive, subsection in between are not.
 96	s := strings.Split(key, ".")
 97	s[0] = strings.ToLower(s[0])
 98	s[len(s)-1] = strings.ToLower(s[len(s)-1])
 99	return strings.Join(s, ".")
100}