config: redo to use other serialization functions
Juan Batiz-Benet committed
Jul 31, 2014 at 02:30 UTC
80323ebae8760edd8fca9100ef7707a957e134ad
5 files changed
+94
-84
cmd/ipfs/config.go
+15
-5
@@ -2,6 +2,7 @@ package main
2
3
import (
4
"errors"
5
+ "fmt"
6
"github.com/gonuts/flag"
7
"github.com/jbenet/commander"
8
config "github.com/jbenet/go-ipfs/config"
@@ -67,19 +68,28 @@ func configCmd(c *commander.Command, inp []string) error {
68
69
// Getter (1 param)
70
if len(inp) == 1 {
70
- value, err := config.GetValueInConfigFile(inp[0])
71
+ value, err := config.ReadConfigKey(filename, inp[0])
72
if err != nil {
72
- return errors.New("Failed to get config value: " + err.Error())
73
+ return fmt.Errorf("Failed to get config value: %s", err)
74
}
75
75
- u.POut(value + "\n")
76
+ strval, ok := value.(string)
77
+ if ok {
78
+ u.POut("%s\n", strval)
79
+ return nil
80
+ }
81
+
82
+ if err := config.Encode(os.Stdout, value); err != nil {
83
+ return fmt.Errorf("Failed to encode config value: %s", err)
84
+ }
85
+ u.POut("\n")
86
return nil
87
}
88
89
// Setter (>1 params)
80
- err = config.SetValueInConfigFile(inp[0], inp[1:])
90
+ err = config.WriteConfigKey(filename, inp[0], inp[1])
91
if err != nil {
82
- return errors.New("Failed to set config value: " + err.Error())
92
+ return fmt.Errorf("Failed to set config value: %s", err)
93
}
94
95
return nil
cmd/ipfs/ipfs.go
+1
-1
@@ -67,7 +67,7 @@ func main() {
67
68
func localNode() (*core.IpfsNode, error) {
69
//todo implement config file flag
70
- cfg, err := config.LoadConfig("")
70
+ cfg, err := config.ConfigLoad("")
71
if err != nil {
72
return nil, err
73
}
config/config.go
+8
-2
@@ -32,6 +32,7 @@ var defaultConfigFile = `{
32
}
33
`
34
35
+// ConfigFilename returns the proper tilde expanded config filename.
36
func ConfigFilename(filename string) (string, error) {
37
if len(filename) == 0 {
38
filename = defaultConfigFilePath
@@ -41,8 +42,8 @@ func ConfigFilename(filename string) (string, error) {
42
return u.TildeExpansion(filename)
43
}
44
44
-// LoadConfig reads given file and returns the read config, or error.
45
-func LoadConfig(filename string) (*Config, error) {
45
+// ConfigLoad reads given file and returns the read config, or error.
46
+func ConfigLoad(filename string) (*Config, error) {
47
filename, err := ConfigFilename(filename)
48
if err != nil {
49
return nil, err
@@ -67,3 +68,8 @@ func LoadConfig(filename string) (*Config, error) {
68
69
return &cfg, err
70
}
71
+
72
+// Set sets the value of a particular config key
73
+func Set(filename, key, value string) error {
74
+ return nil
75
+}
config/config_test.go
+1
-1
@@ -7,7 +7,7 @@ import (
7
8
func TestConfig(t *testing.T) {
9
10
- cfg, err := LoadConfig("")
10
+ cfg, err := ConfigLoad("")
11
if err != nil {
12
t.Error(err)
13
return
config/serialize.go
+69
-75
@@ -2,120 +2,114 @@ package config
2
3
import (
4
"encoding/json"
5
- "errors"
5
"fmt"
7
- u "github.com/jbenet/go-ipfs/util"
8
- "io/ioutil"
6
+ "io"
7
"os"
10
- "path"
8
"strings"
9
)
10
14
-// WriteFile writes the given buffer `buf` into file named `filename`.
15
-func WriteFile(filename string, buf []byte) error {
16
- err := os.MkdirAll(path.Dir(filename), 0777)
11
+// ReadConfigFile reads the config from `filename` into `cfg`.
12
+func ReadConfigFile(filename string, cfg interface{}) error {
13
+ f, err := os.Open(filename)
14
if err != nil {
15
return err
16
}
17
+ defer f.Close()
18
21
- return ioutil.WriteFile(filename, buf, 0666)
19
+ return Decode(f, cfg)
20
}
21
24
-// ReadConfigFile reads the config from `filename` into `cfg`.
25
-func ReadConfigFile(filename string, cfg *Config) error {
26
- buf, err := ioutil.ReadFile(filename)
22
+// WriteConfigFile writes the config from `cfg` into `filename`.
23
+func WriteConfigFile(filename string, cfg interface{}) error {
24
+ f, err := os.Create(filename)
25
if err != nil {
26
return err
27
}
28
+ defer f.Close()
29
31
- return json.Unmarshal(buf, cfg)
30
+ return Encode(f, cfg)
31
}
32
34
-// WriteConfigFile writes the config from `cfg` into `filename`.
35
-func WriteConfigFile(filename string, cfg *Config) error {
36
- buf, err := json.MarshalIndent(cfg, "", " ")
33
+// WriteFile writes the buffer at filename
34
+func WriteFile(filename string, buf []byte) error {
35
+ f, err := os.Create(filename)
36
if err != nil {
37
return err
38
}
39
+ defer f.Close()
40
41
- return WriteFile(filename, buf)
41
+ _, err = f.Write(buf)
42
+ return err
43
}
44
44
-// WriteConfigFile writes the config from `cfg` into `filename`.
45
-func GetValueInConfigFile(key string) (value string, err error) {
46
- // reading config file
47
- attrs := strings.Split(key, ".")
48
-
49
- filename, _ := u.TildeExpansion(defaultConfigFilePath)
50
- buf, err := ioutil.ReadFile(filename)
45
+// Encode configuration with JSON
46
+func Encode(w io.Writer, value interface{}) error {
47
+ // need to prettyprint, hence MarshalIndent, instead of Encoder
48
+ buf, err := json.MarshalIndent(value, "", " ")
49
if err != nil {
52
- return "", err
50
+ return err
51
}
52
55
- // deserializing json
56
- var cfg interface{}
57
- var exists bool
53
+ _, err = w.Write(buf)
54
+ return err
55
+}
56
59
- err = json.Unmarshal(buf, &cfg)
60
- if err != nil {
61
- return "", err
57
+// Decode configuration with JSON
58
+func Decode(r io.Reader, value interface{}) error {
59
+ return json.NewDecoder(r).Decode(value)
60
+}
61
+
62
+// ReadConfigKey retrieves only the value of a particular key
63
+func ReadConfigKey(filename, key string) (interface{}, error) {
64
+ var cfg interface{}
65
+ if err := ReadConfigFile(filename, &cfg); err != nil {
66
+ return nil, err
67
}
68
64
- for i := range attrs {
65
- cfgMap, isMap := cfg.(map[string]interface{})
66
- if !isMap {
67
- return "", errors.New(fmt.Sprintf("%s has no attributes", strings.Join(attrs[:i], ".")))
68
- }
69
- cfg, exists = cfgMap[attrs[i]]
70
- if !exists {
71
- return "", errors.New(fmt.Sprintf("Configuration option key \"%s\" not recognized", strings.Join(attrs[:i+1], ".")))
72
- }
73
- val, is_string := cfg.(string)
74
- if is_string {
75
- return val, nil
69
+ var ok bool
70
+ cursor := cfg
71
+ parts := strings.Split(key, ".")
72
+ for i, part := range parts {
73
+ cursor, ok = cursor.(map[string]interface{})[part]
74
+ if !ok {
75
+ sofar := strings.Join(parts[:i], ".")
76
+ return nil, fmt.Errorf("%s key has no attributes", sofar)
77
}
78
}
78
- return "", errors.New(fmt.Sprintf("%s is not a string", key))
79
+ return cursor, nil
80
}
81
81
-// WriteConfigFile writes the config from `cfg` into `filename`.
82
-func SetValueInConfigFile(key string, values []string) error {
83
- assignee := strings.Join(values, " ")
84
- attrs := strings.Split(key, ".")
85
-
86
- filename, _ := u.TildeExpansion(defaultConfigFilePath)
87
- buf, err := ioutil.ReadFile(filename)
88
- if err != nil {
82
+// WriteConfigKey writes the value of a particular key
83
+func WriteConfigKey(filename, key string, value interface{}) error {
84
+ var cfg interface{}
85
+ if err := ReadConfigFile(filename, &cfg); err != nil {
86
return err
87
}
88
92
- // deserializing json
93
- var cfg, orig interface{}
94
- var exists, isMap bool
95
- cfgMap := make(map[string]interface{})
89
+ var ok bool
90
+ var mcursor map[string]interface{}
91
+ cursor := cfg
92
97
- err = json.Unmarshal(buf, &orig)
98
- cfg = orig
99
- if err != nil {
100
- return err
101
- }
93
+ parts := strings.Split(key, ".")
94
+ for i, part := range parts {
95
+ mcursor, ok = cursor.(map[string]interface{})
96
+ if !ok {
97
+ sofar := strings.Join(parts[:i], ".")
98
+ return fmt.Errorf("%s key is not a map", sofar)
99
+ }
100
103
- for i := 0; i < len(attrs); i++ {
104
- cfgMap, isMap = cfg.(map[string]interface{})
105
- // curs = append(curs, cfgMap)
106
- if !isMap {
107
- return errors.New(fmt.Sprintf("%s has no attributes", strings.Join(attrs[:i], ".")))
101
+ // last part? set here
102
+ if i == (len(parts) - 1) {
103
+ mcursor[part] = value
104
+ break
105
}
109
- cfg, exists = cfgMap[attrs[i]]
110
- if !exists {
111
- return errors.New(fmt.Sprintf("Configuration option key \"%s\" not recognized", strings.Join(attrs[:i+1], ".")))
106
+
107
+ cursor, ok = mcursor[part]
108
+ if !ok { // create map if this is empty
109
+ mcursor[part] = map[string]interface{}{}
110
+ cursor = mcursor[part]
111
}
112
}
114
- cfgMap[attrs[len(attrs)-1]] = assignee
115
- buf, err = json.MarshalIndent(orig, "", " ")
116
- if err != nil {
117
- return err
118
- }
119
- WriteFile(filename, buf)
120
- return nil
113
+
114
+ return WriteConfigFile(filename, cfg)
115
}