go-ipfs-config: refactor(config, repo): all writes go through FSRepo. next: privatize these
Brian Tiger Chow committed
Jan 12, 2015 at 15:00 UTC
20cc7a451b66054dca1e5e17f5ae54ac73b5c298
4 files changed
+13
-194
config/config.go
+11
-23
@@ -3,6 +3,7 @@ package config
3
4
import (
5
"encoding/base64"
6
+ "encoding/json"
7
"errors"
8
"os"
9
"path/filepath"
@@ -13,7 +14,6 @@ import (
14
15
ic "github.com/jbenet/go-ipfs/p2p/crypto"
16
u "github.com/jbenet/go-ipfs/util"
16
- "github.com/jbenet/go-ipfs/util/debugerror"
17
)
18
19
var log = u.Logger("config")
@@ -191,29 +191,17 @@ func (i *Identity) DecodePrivateKey(passphrase string) (ic.PrivKey, error) {
191
return ic.UnmarshalPrivateKey(pkb)
192
}
193
194
-// Load reads given file and returns the read config, or error.
195
-func Load(filename string) (*Config, error) {
196
- // if nothing is there, fail. User must run 'ipfs init'
197
- if !u.FileExists(filename) {
198
- return nil, debugerror.New("ipfs not initialized, please run 'ipfs init'")
194
+// HumanOutput gets a config value ready for printing
195
+func HumanOutput(value interface{}) ([]byte, error) {
196
+ s, ok := value.(string)
197
+ if ok {
198
+ return []byte(strings.Trim(s, "\n")), nil
199
}
200
-
201
- var cfg Config
202
- err := ReadConfigFile(filename, &cfg)
203
- if err != nil {
204
- return nil, err
205
- }
206
-
207
- // tilde expansion on datastore path
208
- cfg.Datastore.Path, err = u.TildeExpansion(cfg.Datastore.Path)
209
- if err != nil {
210
- return nil, err
211
- }
212
-
213
- return &cfg, err
200
+ return Marshal(value)
201
}
202
216
-// Set sets the value of a particular config key
217
-func Set(filename, key, value string) error {
218
- return WriteConfigKey(filename, key, value)
203
+// Marshal configuration with JSON
204
+func Marshal(value interface{}) ([]byte, error) {
205
+ // need to prettyprint, hence MarshalIndent, instead of Encoder
206
+ return json.MarshalIndent(value, "", " ")
207
}
config/config_test.go
deleted
-24
@@ -1,24 +0,0 @@
1
-package config
2
-
3
-import (
4
- "testing"
5
-)
6
-
7
-func TestConfig(t *testing.T) {
8
- const filename = ".ipfsconfig"
9
- const dsPath = "/path/to/datastore"
10
- cfgWritten := new(Config)
11
- cfgWritten.Datastore.Path = dsPath
12
- err := WriteConfigFile(filename, cfgWritten)
13
- if err != nil {
14
- t.Error(err)
15
- }
16
- cfgRead, err := Load(filename)
17
- if err != nil {
18
- t.Error(err)
19
- return
20
- }
21
- if cfgWritten.Datastore.Path != cfgRead.Datastore.Path {
22
- t.Fail()
23
- }
24
-}
config/serialize.go
deleted
-144
@@ -1,144 +0,0 @@
1
-package config
2
-
3
-import (
4
- "encoding/json"
5
- "fmt"
6
- "io"
7
- "os"
8
- "path/filepath"
9
- "strings"
10
-)
11
-
12
-// ReadConfigFile reads the config from `filename` into `cfg`.
13
-func ReadConfigFile(filename string, cfg interface{}) error {
14
- f, err := os.Open(filename)
15
- if err != nil {
16
- return err
17
- }
18
- defer f.Close()
19
-
20
- if err := Decode(f, cfg); err != nil {
21
- return fmt.Errorf("Failure to decode config: %s", err)
22
- }
23
- return nil
24
-}
25
-
26
-// WriteConfigFile writes the config from `cfg` into `filename`.
27
-func WriteConfigFile(filename string, cfg interface{}) error {
28
- err := os.MkdirAll(filepath.Dir(filename), 0775)
29
- if err != nil {
30
- return err
31
- }
32
-
33
- f, err := os.Create(filename)
34
- if err != nil {
35
- return err
36
- }
37
- defer f.Close()
38
-
39
- return Encode(f, cfg)
40
-}
41
-
42
-// WriteFile writes the buffer at filename
43
-func WriteFile(filename string, buf []byte) error {
44
- err := os.MkdirAll(filepath.Dir(filename), 0775)
45
- if err != nil {
46
- return err
47
- }
48
-
49
- f, err := os.Create(filename)
50
- if err != nil {
51
- return err
52
- }
53
- defer f.Close()
54
-
55
- _, err = f.Write(buf)
56
- return err
57
-}
58
-
59
-// HumanOutput gets a config value ready for printing
60
-func HumanOutput(value interface{}) ([]byte, error) {
61
- s, ok := value.(string)
62
- if ok {
63
- return []byte(strings.Trim(s, "\n")), nil
64
- }
65
- return Marshal(value)
66
-}
67
-
68
-// Marshal configuration with JSON
69
-func Marshal(value interface{}) ([]byte, error) {
70
- // need to prettyprint, hence MarshalIndent, instead of Encoder
71
- return json.MarshalIndent(value, "", " ")
72
-}
73
-
74
-// Encode configuration with JSON
75
-func Encode(w io.Writer, value interface{}) error {
76
- // need to prettyprint, hence MarshalIndent, instead of Encoder
77
- buf, err := Marshal(value)
78
- if err != nil {
79
- return err
80
- }
81
-
82
- _, err = w.Write(buf)
83
- return err
84
-}
85
-
86
-// Decode configuration with JSON
87
-func Decode(r io.Reader, value interface{}) error {
88
- return json.NewDecoder(r).Decode(value)
89
-}
90
-
91
-// ReadConfigKey retrieves only the value of a particular key
92
-func ReadConfigKey(filename, key string) (interface{}, error) {
93
- var cfg interface{}
94
- if err := ReadConfigFile(filename, &cfg); err != nil {
95
- return nil, err
96
- }
97
-
98
- var ok bool
99
- cursor := cfg
100
- parts := strings.Split(key, ".")
101
- for i, part := range parts {
102
- cursor, ok = cursor.(map[string]interface{})[part]
103
- if !ok {
104
- sofar := strings.Join(parts[:i], ".")
105
- return nil, fmt.Errorf("%s key has no attributes", sofar)
106
- }
107
- }
108
- return cursor, nil
109
-}
110
-
111
-// WriteConfigKey writes the value of a particular key
112
-func WriteConfigKey(filename, key string, value interface{}) error {
113
- var cfg interface{}
114
- if err := ReadConfigFile(filename, &cfg); err != nil {
115
- return err
116
- }
117
-
118
- var ok bool
119
- var mcursor map[string]interface{}
120
- cursor := cfg
121
-
122
- parts := strings.Split(key, ".")
123
- for i, part := range parts {
124
- mcursor, ok = cursor.(map[string]interface{})
125
- if !ok {
126
- sofar := strings.Join(parts[:i], ".")
127
- return fmt.Errorf("%s key is not a map", sofar)
128
- }
129
-
130
- // last part? set here
131
- if i == (len(parts) - 1) {
132
- mcursor[part] = value
133
- break
134
- }
135
-
136
- cursor, ok = mcursor[part]
137
- if !ok { // create map if this is empty
138
- mcursor[part] = map[string]interface{}{}
139
- cursor = mcursor[part]
140
- }
141
- }
142
-
143
- return WriteConfigFile(filename, cfg)
144
-}
config/version_test.go
+2
-3
@@ -1,6 +1,7 @@
1
package config
2
3
import (
4
+ "encoding/json"
5
"strings"
6
"testing"
7
)
@@ -23,8 +24,7 @@ func TestAutoUpdateValues(t *testing.T) {
24
}
25
26
for i, tc := range tests {
26
- err := Decode(strings.NewReader(tc.input), &tval)
27
- if err != tc.err {
27
+ if err := json.NewDecoder(strings.NewReader(tc.input)).Decode(&tval); err != tc.err {
28
t.Fatalf("%d failed - got err %q wanted %v", i, err, tc.err)
29
}
30
@@ -32,5 +32,4 @@ func TestAutoUpdateValues(t *testing.T) {
32
t.Fatalf("%d failed - got val %q where we wanted %q", i, tval.AutoUpdate, tc.val)
33
}
34
}
35
-
35
}