@cryptotaxi247 / kubo / commits / 86258face

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