refactor(config, repo): use repo.Interface to (Get|Set)ConfigKey
Brian Tiger Chow committed
Jan 12, 2015 at 17:06 UTC
86258face656005867a9d3f78881f16599c166ab
5 files changed
+108
-60
core/commands/config.go
+11
-11
@@ -10,6 +10,7 @@ import (
10
"os/exec"
11
12
cmds "github.com/jbenet/go-ipfs/commands"
13
+ repo "github.com/jbenet/go-ipfs/repo"
14
config "github.com/jbenet/go-ipfs/repo/config"
15
fsrepo "github.com/jbenet/go-ipfs/repo/fsrepo"
16
u "github.com/jbenet/go-ipfs/util"
@@ -58,18 +59,19 @@ Set the value of the 'datastore.path' key:
59
args := req.Arguments()
60
key := args[0]
61
61
- filename, err := config.Filename(req.Context().ConfigRoot)
62
- if err != nil {
62
+ r := fsrepo.At(req.Context().ConfigRoot)
63
+ if err := r.Open(); err != nil {
64
return nil, err
65
}
66
+ defer r.Close()
67
68
var value string
69
if len(args) == 2 {
70
value = args[1]
69
- return setConfig(filename, key, value)
71
+ return setConfig(r, key, value)
72
73
} else {
72
- return getConfig(filename, key)
74
+ return getConfig(r, key)
75
}
76
},
77
Marshalers: cmds.MarshalerMap{
@@ -141,25 +143,23 @@ variable set to your preferred text editor.
143
},
144
}
145
144
-func getConfig(filename string, key string) (*ConfigField, error) {
145
- value, err := fsrepo.ReadConfigKey(filename, key)
146
+func getConfig(r repo.Interface, key string) (*ConfigField, error) {
147
+ value, err := r.GetConfigKey(key)
148
if err != nil {
149
return nil, fmt.Errorf("Failed to get config value: %s", err)
150
}
149
-
151
return &ConfigField{
152
Key: key,
153
Value: value,
154
}, nil
155
}
156
156
-func setConfig(filename string, key, value string) (*ConfigField, error) {
157
- err := fsrepo.WriteConfigKey(filename, key, value)
157
+func setConfig(r repo.Interface, key, value string) (*ConfigField, error) {
158
+ err := r.SetConfigKey(key, value)
159
if err != nil {
160
return nil, fmt.Errorf("Failed to set config value: %s", err)
161
}
161
-
162
- return getConfig(filename, key)
162
+ return getConfig(r, key)
163
}
164
165
func showConfig(filename string) (io.Reader, error) {
repo/common/common.go
new
+48
@@ -0,0 +1,48 @@
1
+package common
2
+
3
+import (
4
+ "fmt"
5
+ "strings"
6
+)
7
+
8
+func MapGetKV(v map[string]interface{}, key string) (interface{}, error) {
9
+ var ok bool
10
+ var cursor interface{} = v
11
+ parts := strings.Split(key, ".")
12
+ for i, part := range parts {
13
+ cursor, ok = cursor.(map[string]interface{})[part]
14
+ if !ok {
15
+ sofar := strings.Join(parts[:i], ".")
16
+ return nil, fmt.Errorf("%s key has no attributes", sofar)
17
+ }
18
+ }
19
+ return cursor, nil
20
+}
21
+
22
+func MapSetKV(v map[string]interface{}, key string, value interface{}) error {
23
+ var ok bool
24
+ var mcursor map[string]interface{}
25
+ var cursor interface{} = v
26
+
27
+ parts := strings.Split(key, ".")
28
+ for i, part := range parts {
29
+ mcursor, ok = cursor.(map[string]interface{})
30
+ if !ok {
31
+ sofar := strings.Join(parts[:i], ".")
32
+ return fmt.Errorf("%s key is not a map", sofar)
33
+ }
34
+
35
+ // last part? set here
36
+ if i == (len(parts) - 1) {
37
+ mcursor[part] = value
38
+ break
39
+ }
40
+
41
+ cursor, ok = mcursor[part]
42
+ if !ok { // create map if this is empty
43
+ mcursor[part] = map[string]interface{}{}
44
+ cursor = mcursor[part]
45
+ }
46
+ }
47
+ return nil
48
+}
repo/fsrepo/fsrepo.go
+2
@@ -6,6 +6,7 @@ import (
6
"os"
7
"path/filepath"
8
9
+ "github.com/jbenet/go-ipfs/repo"
10
config "github.com/jbenet/go-ipfs/repo/config"
11
util "github.com/jbenet/go-ipfs/util"
12
"github.com/jbenet/go-ipfs/util/debugerror"
@@ -114,6 +115,7 @@ func (r *FSRepo) Close() error {
115
}
116
117
var _ io.Closer = &FSRepo{}
118
+var _ repo.Interface = &FSRepo{}
119
120
// IsInitialized returns true if the repo is initialized at provided |path|.
121
func IsInitialized(path string) bool {
repo/fsrepo/serialize.go
+43
-49
@@ -1,14 +1,15 @@
1
package fsrepo
2
3
import (
4
+ "bytes"
5
"encoding/json"
6
"fmt"
7
"io"
8
"os"
9
"path/filepath"
9
- "strings"
10
"time"
11
12
+ common "github.com/jbenet/go-ipfs/repo/common"
13
"github.com/jbenet/go-ipfs/repo/config"
14
"github.com/jbenet/go-ipfs/util"
15
"github.com/jbenet/go-ipfs/util/debugerror"
@@ -73,59 +74,55 @@ func Encode(w io.Writer, value interface{}) error {
74
return err
75
}
76
76
-// ReadConfigKey retrieves only the value of a particular key
77
-func ReadConfigKey(filename, key string) (interface{}, error) {
78
- var cfg interface{}
77
+// GetConfigKey retrieves only the value of a particular key
78
+func (r *FSRepo) GetConfigKey(key string) (interface{}, error) {
79
+ filename, err := config.Filename(r.path)
80
+ if err != nil {
81
+ return nil, err
82
+ }
83
+ var cfg map[string]interface{}
84
if err := ReadConfigFile(filename, &cfg); err != nil {
85
return nil, err
86
}
87
83
- var ok bool
84
- cursor := cfg
85
- parts := strings.Split(key, ".")
86
- for i, part := range parts {
87
- cursor, ok = cursor.(map[string]interface{})[part]
88
- if !ok {
89
- sofar := strings.Join(parts[:i], ".")
90
- return nil, fmt.Errorf("%s key has no attributes", sofar)
91
- }
92
- }
93
- return cursor, nil
88
+ return common.MapGetKV(cfg, key)
89
}
90
96
-// WriteConfigKey writes the value of a particular key
97
-func WriteConfigKey(filename, key string, value interface{}) error {
98
- var cfg interface{}
99
- if err := ReadConfigFile(filename, &cfg); err != nil {
91
+// SetConfigKey writes the value of a particular key
92
+func (r *FSRepo) SetConfigKey(key string, value interface{}) error {
93
+ filename, err := config.Filename(r.path)
94
+ if err != nil {
95
return err
96
}
102
-
103
- var ok bool
104
- var mcursor map[string]interface{}
105
- cursor := cfg
106
-
107
- parts := strings.Split(key, ".")
108
- for i, part := range parts {
109
- mcursor, ok = cursor.(map[string]interface{})
110
- if !ok {
111
- sofar := strings.Join(parts[:i], ".")
112
- return fmt.Errorf("%s key is not a map", sofar)
113
- }
114
-
115
- // last part? set here
116
- if i == (len(parts) - 1) {
117
- mcursor[part] = value
118
- break
119
- }
120
-
121
- cursor, ok = mcursor[part]
122
- if !ok { // create map if this is empty
123
- mcursor[part] = map[string]interface{}{}
124
- cursor = mcursor[part]
125
- }
97
+ var mapconf map[string]interface{}
98
+ if err := ReadConfigFile(filename, &mapconf); err != nil {
99
+ return err
100
+ }
101
+ if err := common.MapSetKV(mapconf, key, value); err != nil {
102
+ return err
103
}
104
+ // must use raw method because there may exist keys not present in the *config.Config struct
105
+ if err := writeConfigFile(filename, mapconf); err != nil {
106
+ return err
107
+ }
108
+ conf, err := convertMapToConfig(mapconf)
109
+ if err != nil {
110
+ return err
111
+ }
112
+ *r.config = *conf // copy so caller cannot modify the private config
113
+ return nil
114
+}
115
128
- return writeConfigFile(filename, cfg)
116
+func convertMapToConfig(v map[string]interface{}) (*config.Config, error) {
117
+ var buf bytes.Buffer
118
+ if err := json.NewEncoder(&buf).Encode(v); err != nil {
119
+ return nil, err
120
+ }
121
+ var conf config.Config
122
+ if err := json.NewDecoder(&buf).Decode(&conf); err != nil {
123
+ return nil, fmt.Errorf("Failure to decode config: %s", err)
124
+ }
125
+ return &conf, nil
126
}
127
128
// Load reads given file and returns the read config, or error.
@@ -150,13 +147,10 @@ func Load(filename string) (*config.Config, error) {
147
return &cfg, err
148
}
149
153
-// Set sets the value of a particular config key
154
-func Set(filename, key, value string) error {
155
- return WriteConfigKey(filename, key, value)
156
-}
157
-
150
// RecordUpdateCheck is called to record that an update check was performed,
151
// showing that the running version is the most recent one.
152
+//
153
+// DEPRECATED
154
func RecordUpdateCheck(cfg *config.Config, filename string) {
155
cfg.Version.CheckDate = time.Now()
156
repo/repo.go
+4
@@ -6,7 +6,11 @@ import (
6
)
7
8
type Interface interface {
9
+ Config() *config.Config
10
SetConfig(*config.Config) error
11
+
12
+ SetConfigKey(key string, value interface{}) error
13
+ GetConfigKey(key string) (interface{}, error)
14
}
15
16
// IsInitialized returns true if the path is home to an initialized IPFS