diff --git a/config/config.go b/config/config.go index d33e4d36d..939c4564c 100644 --- a/config/config.go +++ b/config/config.go @@ -3,6 +3,7 @@ package config import ( "encoding/base64" + "encoding/json" "errors" "os" "path/filepath" @@ -13,7 +14,6 @@ import ( ic "github.com/jbenet/go-ipfs/p2p/crypto" u "github.com/jbenet/go-ipfs/util" - "github.com/jbenet/go-ipfs/util/debugerror" ) var log = u.Logger("config") @@ -191,29 +191,17 @@ func (i *Identity) DecodePrivateKey(passphrase string) (ic.PrivKey, error) { return ic.UnmarshalPrivateKey(pkb) } -// Load reads given file and returns the read config, or error. -func Load(filename string) (*Config, error) { - // if nothing is there, fail. User must run 'ipfs init' - if !u.FileExists(filename) { - return nil, debugerror.New("ipfs not initialized, please run 'ipfs init'") +// HumanOutput gets a config value ready for printing +func HumanOutput(value interface{}) ([]byte, error) { + s, ok := value.(string) + if ok { + return []byte(strings.Trim(s, "\n")), nil } - - var cfg Config - err := ReadConfigFile(filename, &cfg) - if err != nil { - return nil, err - } - - // tilde expansion on datastore path - cfg.Datastore.Path, err = u.TildeExpansion(cfg.Datastore.Path) - if err != nil { - return nil, err - } - - return &cfg, err + return Marshal(value) } -// Set sets the value of a particular config key -func Set(filename, key, value string) error { - return WriteConfigKey(filename, key, value) +// Marshal configuration with JSON +func Marshal(value interface{}) ([]byte, error) { + // need to prettyprint, hence MarshalIndent, instead of Encoder + return json.MarshalIndent(value, "", " ") } diff --git a/config/config_test.go b/config/config_test.go deleted file mode 100644 index c891d6c51..000000000 --- a/config/config_test.go +++ /dev/null @@ -1,24 +0,0 @@ -package config - -import ( - "testing" -) - -func TestConfig(t *testing.T) { - const filename = ".ipfsconfig" - const dsPath = "/path/to/datastore" - cfgWritten := new(Config) - cfgWritten.Datastore.Path = dsPath - err := WriteConfigFile(filename, cfgWritten) - if err != nil { - t.Error(err) - } - cfgRead, err := Load(filename) - if err != nil { - t.Error(err) - return - } - if cfgWritten.Datastore.Path != cfgRead.Datastore.Path { - t.Fail() - } -} diff --git a/config/serialize.go b/config/serialize.go deleted file mode 100644 index b71d945b0..000000000 --- a/config/serialize.go +++ /dev/null @@ -1,144 +0,0 @@ -package config - -import ( - "encoding/json" - "fmt" - "io" - "os" - "path/filepath" - "strings" -) - -// ReadConfigFile reads the config from `filename` into `cfg`. -func ReadConfigFile(filename string, cfg interface{}) error { - f, err := os.Open(filename) - if err != nil { - return err - } - defer f.Close() - - if err := Decode(f, cfg); err != nil { - return fmt.Errorf("Failure to decode config: %s", err) - } - return nil -} - -// WriteConfigFile writes the config from `cfg` into `filename`. -func WriteConfigFile(filename string, cfg interface{}) error { - err := os.MkdirAll(filepath.Dir(filename), 0775) - if err != nil { - return err - } - - f, err := os.Create(filename) - if err != nil { - return err - } - defer f.Close() - - return Encode(f, cfg) -} - -// WriteFile writes the buffer at filename -func WriteFile(filename string, buf []byte) error { - err := os.MkdirAll(filepath.Dir(filename), 0775) - if err != nil { - return err - } - - f, err := os.Create(filename) - if err != nil { - return err - } - defer f.Close() - - _, err = f.Write(buf) - return err -} - -// HumanOutput gets a config value ready for printing -func HumanOutput(value interface{}) ([]byte, error) { - s, ok := value.(string) - if ok { - return []byte(strings.Trim(s, "\n")), nil - } - return Marshal(value) -} - -// Marshal configuration with JSON -func Marshal(value interface{}) ([]byte, error) { - // need to prettyprint, hence MarshalIndent, instead of Encoder - return json.MarshalIndent(value, "", " ") -} - -// Encode configuration with JSON -func Encode(w io.Writer, value interface{}) error { - // need to prettyprint, hence MarshalIndent, instead of Encoder - buf, err := Marshal(value) - if err != nil { - return err - } - - _, err = w.Write(buf) - return err -} - -// Decode configuration with JSON -func Decode(r io.Reader, value interface{}) error { - return json.NewDecoder(r).Decode(value) -} - -// ReadConfigKey retrieves only the value of a particular key -func ReadConfigKey(filename, key string) (interface{}, error) { - var cfg interface{} - if err := ReadConfigFile(filename, &cfg); err != nil { - return nil, err - } - - var ok bool - cursor := cfg - parts := strings.Split(key, ".") - for i, part := range parts { - cursor, ok = cursor.(map[string]interface{})[part] - if !ok { - sofar := strings.Join(parts[:i], ".") - return nil, fmt.Errorf("%s key has no attributes", sofar) - } - } - return cursor, nil -} - -// WriteConfigKey writes the value of a particular key -func WriteConfigKey(filename, key string, value interface{}) error { - var cfg interface{} - if err := ReadConfigFile(filename, &cfg); err != nil { - return err - } - - var ok bool - var mcursor map[string]interface{} - cursor := cfg - - parts := strings.Split(key, ".") - for i, part := range parts { - mcursor, ok = cursor.(map[string]interface{}) - if !ok { - sofar := strings.Join(parts[:i], ".") - return fmt.Errorf("%s key is not a map", sofar) - } - - // last part? set here - if i == (len(parts) - 1) { - mcursor[part] = value - break - } - - cursor, ok = mcursor[part] - if !ok { // create map if this is empty - mcursor[part] = map[string]interface{}{} - cursor = mcursor[part] - } - } - - return WriteConfigFile(filename, cfg) -} diff --git a/config/version_test.go b/config/version_test.go index 37160c478..c4b8aeb5a 100644 --- a/config/version_test.go +++ b/config/version_test.go @@ -1,6 +1,7 @@ package config import ( + "encoding/json" "strings" "testing" ) @@ -23,8 +24,7 @@ func TestAutoUpdateValues(t *testing.T) { } for i, tc := range tests { - err := Decode(strings.NewReader(tc.input), &tval) - if err != tc.err { + if err := json.NewDecoder(strings.NewReader(tc.input)).Decode(&tval); err != tc.err { t.Fatalf("%d failed - got err %q wanted %v", i, err, tc.err) } @@ -32,5 +32,4 @@ func TestAutoUpdateValues(t *testing.T) { t.Fatalf("%d failed - got val %q where we wanted %q", i, tval.AutoUpdate, tc.val) } } - }