From 80323ebae8760edd8fca9100ef7707a957e134ad Mon Sep 17 00:00:00 2001 From: Juan Batiz-Benet Date: Thu, 31 Jul 2014 02:30:38 -0700 Subject: [PATCH] config: redo to use other serialization functions --- cmd/ipfs/config.go | 20 +++-- cmd/ipfs/ipfs.go | 2 +- config/config.go | 10 ++- config/config_test.go | 2 +- config/serialize.go | 170 ++++++++++++++++++++---------------------- 5 files changed, 107 insertions(+), 97 deletions(-) diff --git a/cmd/ipfs/config.go b/cmd/ipfs/config.go index 8bbf45b24..ec74280c4 100644 --- a/cmd/ipfs/config.go +++ b/cmd/ipfs/config.go @@ -2,6 +2,7 @@ package main import ( "errors" + "fmt" "github.com/gonuts/flag" "github.com/jbenet/commander" config "github.com/jbenet/go-ipfs/config" @@ -67,19 +68,28 @@ func configCmd(c *commander.Command, inp []string) error { // Getter (1 param) if len(inp) == 1 { - value, err := config.GetValueInConfigFile(inp[0]) + value, err := config.ReadConfigKey(filename, inp[0]) if err != nil { - return errors.New("Failed to get config value: " + err.Error()) + return fmt.Errorf("Failed to get config value: %s", err) } - u.POut(value + "\n") + strval, ok := value.(string) + if ok { + u.POut("%s\n", strval) + return nil + } + + if err := config.Encode(os.Stdout, value); err != nil { + return fmt.Errorf("Failed to encode config value: %s", err) + } + u.POut("\n") return nil } // Setter (>1 params) - err = config.SetValueInConfigFile(inp[0], inp[1:]) + err = config.WriteConfigKey(filename, inp[0], inp[1]) if err != nil { - return errors.New("Failed to set config value: " + err.Error()) + return fmt.Errorf("Failed to set config value: %s", err) } return nil diff --git a/cmd/ipfs/ipfs.go b/cmd/ipfs/ipfs.go index f997fadca..daa639606 100644 --- a/cmd/ipfs/ipfs.go +++ b/cmd/ipfs/ipfs.go @@ -67,7 +67,7 @@ func main() { func localNode() (*core.IpfsNode, error) { //todo implement config file flag - cfg, err := config.LoadConfig("") + cfg, err := config.ConfigLoad("") if err != nil { return nil, err } diff --git a/config/config.go b/config/config.go index 0a4a75d94..763943ae9 100644 --- a/config/config.go +++ b/config/config.go @@ -32,6 +32,7 @@ var defaultConfigFile = `{ } ` +// ConfigFilename returns the proper tilde expanded config filename. func ConfigFilename(filename string) (string, error) { if len(filename) == 0 { filename = defaultConfigFilePath @@ -41,8 +42,8 @@ func ConfigFilename(filename string) (string, error) { return u.TildeExpansion(filename) } -// LoadConfig reads given file and returns the read config, or error. -func LoadConfig(filename string) (*Config, error) { +// ConfigLoad reads given file and returns the read config, or error. +func ConfigLoad(filename string) (*Config, error) { filename, err := ConfigFilename(filename) if err != nil { return nil, err @@ -67,3 +68,8 @@ func LoadConfig(filename string) (*Config, error) { return &cfg, err } + +// Set sets the value of a particular config key +func Set(filename, key, value string) error { + return nil +} diff --git a/config/config_test.go b/config/config_test.go index 25236e071..a483c24e4 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -7,7 +7,7 @@ import ( func TestConfig(t *testing.T) { - cfg, err := LoadConfig("") + cfg, err := ConfigLoad("") if err != nil { t.Error(err) return diff --git a/config/serialize.go b/config/serialize.go index fe9889d93..10d774b8e 100644 --- a/config/serialize.go +++ b/config/serialize.go @@ -2,120 +2,114 @@ package config import ( "encoding/json" - "errors" "fmt" - u "github.com/jbenet/go-ipfs/util" - "io/ioutil" + "io" "os" - "path" "strings" ) -// WriteFile writes the given buffer `buf` into file named `filename`. -func WriteFile(filename string, buf []byte) error { - err := os.MkdirAll(path.Dir(filename), 0777) - if err != nil { - return err - } - - return ioutil.WriteFile(filename, buf, 0666) -} - // ReadConfigFile reads the config from `filename` into `cfg`. -func ReadConfigFile(filename string, cfg *Config) error { - buf, err := ioutil.ReadFile(filename) +func ReadConfigFile(filename string, cfg interface{}) error { + f, err := os.Open(filename) + if err != nil { + return err + } + defer f.Close() + + return Decode(f, cfg) +} + +// WriteConfigFile writes the config from `cfg` into `filename`. +func WriteConfigFile(filename string, cfg interface{}) error { + 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 { + f, err := os.Create(filename) + if err != nil { + return err + } + defer f.Close() + + _, err = f.Write(buf) + return err +} + +// Encode configuration with JSON +func Encode(w io.Writer, value interface{}) error { + // need to prettyprint, hence MarshalIndent, instead of Encoder + buf, err := json.MarshalIndent(value, "", " ") if err != nil { return err } - return json.Unmarshal(buf, cfg) + _, err = w.Write(buf) + return err } -// WriteConfigFile writes the config from `cfg` into `filename`. -func WriteConfigFile(filename string, cfg *Config) error { - buf, err := json.MarshalIndent(cfg, "", " ") - if err != nil { - return err - } - - return WriteFile(filename, buf) +// Decode configuration with JSON +func Decode(r io.Reader, value interface{}) error { + return json.NewDecoder(r).Decode(value) } -// WriteConfigFile writes the config from `cfg` into `filename`. -func GetValueInConfigFile(key string) (value string, err error) { - // reading config file - attrs := strings.Split(key, ".") - - filename, _ := u.TildeExpansion(defaultConfigFilePath) - buf, err := ioutil.ReadFile(filename) - if err != nil { - return "", err - } - - // deserializing json +// ReadConfigKey retrieves only the value of a particular key +func ReadConfigKey(filename, key string) (interface{}, error) { var cfg interface{} - var exists bool - - err = json.Unmarshal(buf, &cfg) - if err != nil { - return "", err + if err := ReadConfigFile(filename, &cfg); err != nil { + return nil, err } - for i := range attrs { - cfgMap, isMap := cfg.(map[string]interface{}) - if !isMap { - return "", errors.New(fmt.Sprintf("%s has no attributes", strings.Join(attrs[:i], "."))) - } - cfg, exists = cfgMap[attrs[i]] - if !exists { - return "", errors.New(fmt.Sprintf("Configuration option key \"%s\" not recognized", strings.Join(attrs[:i+1], "."))) - } - val, is_string := cfg.(string) - if is_string { - return val, nil + 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 "", errors.New(fmt.Sprintf("%s is not a string", key)) + return cursor, nil } -// WriteConfigFile writes the config from `cfg` into `filename`. -func SetValueInConfigFile(key string, values []string) error { - assignee := strings.Join(values, " ") - attrs := strings.Split(key, ".") - - filename, _ := u.TildeExpansion(defaultConfigFilePath) - buf, err := ioutil.ReadFile(filename) - if err != 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 } - // deserializing json - var cfg, orig interface{} - var exists, isMap bool - cfgMap := make(map[string]interface{}) + var ok bool + var mcursor map[string]interface{} + cursor := cfg - err = json.Unmarshal(buf, &orig) - cfg = orig - if err != nil { - return err - } - - for i := 0; i < len(attrs); i++ { - cfgMap, isMap = cfg.(map[string]interface{}) - // curs = append(curs, cfgMap) - if !isMap { - return errors.New(fmt.Sprintf("%s has no attributes", strings.Join(attrs[:i], "."))) + 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) } - cfg, exists = cfgMap[attrs[i]] - if !exists { - return errors.New(fmt.Sprintf("Configuration option key \"%s\" not recognized", strings.Join(attrs[:i+1], "."))) + + // 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] } } - cfgMap[attrs[len(attrs)-1]] = assignee - buf, err = json.MarshalIndent(orig, "", " ") - if err != nil { - return err - } - WriteFile(filename, buf) - return nil + + return WriteConfigFile(filename, cfg) }