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}