1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
package repository
import (
"errors"
"strconv"
"time"
)
var (
ErrNoConfigEntry = errors.New("no config entry for the given key")
ErrMultipleConfigEntry = errors.New("multiple config entry for the given key")
)
// Config represent the common function interacting with the repository config storage
type Config interface {
ConfigRead
ConfigWrite
}
type ConfigRead interface {
// ReadAll reads all key/value pair matching the key prefix
ReadAll(keyPrefix string) (map[string]string, error)
// ReadBool read a single boolean value from the config
// Return ErrNoConfigEntry or ErrMultipleConfigEntry if
// there is zero or more than one entry for this key
ReadBool(key string) (bool, error)
// ReadBool read a single string value from the config
// Return ErrNoConfigEntry or ErrMultipleConfigEntry if
// 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)
}
type ConfigWrite interface {
// 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
// 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 time.Time{}, err
}
return time.Unix(int64(timestamp), 0), nil
}
// mergeConfig is a helper to easily support RepoConfig.AnyConfig()
// from two separate local and global Config
func mergeConfig(local ConfigRead, global ConfigRead) *mergedConfig {
return &mergedConfig{
local: local,
global: global,
}
}
var _ ConfigRead = &mergedConfig{}
type mergedConfig struct {
local ConfigRead
global ConfigRead
}
func (m *mergedConfig) ReadAll(keyPrefix string) (map[string]string, error) {
values, err := m.global.ReadAll(keyPrefix)
if err != nil {
return nil, err
}
locals, err := m.local.ReadAll(keyPrefix)
if err != nil {
return nil, err
}
for k, val := range locals {
values[k] = val
}
return values, nil
}
func (m *mergedConfig) ReadBool(key string) (bool, error) {
v, err := m.local.ReadBool(key)
if err == nil {
return v, nil
}
if err != ErrNoConfigEntry && err != ErrMultipleConfigEntry {
return false, err
}
return m.global.ReadBool(key)
}
func (m *mergedConfig) ReadString(key string) (string, error) {
val, err := m.local.ReadString(key)
if err == nil {
return val, nil
}
if err != ErrNoConfigEntry && err != ErrMultipleConfigEntry {
return "", err
}
return m.global.ReadString(key)
}
func (m *mergedConfig) ReadTimestamp(key string) (time.Time, error) {
val, err := m.local.ReadTimestamp(key)
if err == nil {
return val, nil
}
if err != ErrNoConfigEntry && err != ErrMultipleConfigEntry {
return time.Time{}, err
}
return m.global.ReadTimestamp(key)
}
var _ ConfigWrite = &configPanicWriter{}
type configPanicWriter struct{}
func (c configPanicWriter) StoreString(key, value string) error {
panic("not implemented")
}
func (c configPanicWriter) StoreTimestamp(key string, value time.Time) error {
panic("not implemented")
}
func (c configPanicWriter) StoreBool(key string, value bool) error {
panic("not implemented")
}
func (c configPanicWriter) RemoveAll(keyPrefix string) error {
panic("not implemented")
}
|