Commit 80323eba authored by Juan Batiz-Benet's avatar Juan Batiz-Benet

config: redo to use other serialization functions

parent bf7cb198
...@@ -2,6 +2,7 @@ package main ...@@ -2,6 +2,7 @@ package main
import ( import (
"errors" "errors"
"fmt"
"github.com/gonuts/flag" "github.com/gonuts/flag"
"github.com/jbenet/commander" "github.com/jbenet/commander"
config "github.com/jbenet/go-ipfs/config" config "github.com/jbenet/go-ipfs/config"
...@@ -67,19 +68,28 @@ func configCmd(c *commander.Command, inp []string) error { ...@@ -67,19 +68,28 @@ func configCmd(c *commander.Command, inp []string) error {
// Getter (1 param) // Getter (1 param)
if len(inp) == 1 { if len(inp) == 1 {
value, err := config.GetValueInConfigFile(inp[0]) value, err := config.ReadConfigKey(filename, inp[0])
if err != nil { 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 return nil
} }
// Setter (>1 params) // Setter (>1 params)
err = config.SetValueInConfigFile(inp[0], inp[1:]) err = config.WriteConfigKey(filename, inp[0], inp[1])
if err != nil { 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 return nil
......
...@@ -67,7 +67,7 @@ func main() { ...@@ -67,7 +67,7 @@ func main() {
func localNode() (*core.IpfsNode, error) { func localNode() (*core.IpfsNode, error) {
//todo implement config file flag //todo implement config file flag
cfg, err := config.LoadConfig("") cfg, err := config.ConfigLoad("")
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -32,6 +32,7 @@ var defaultConfigFile = `{ ...@@ -32,6 +32,7 @@ var defaultConfigFile = `{
} }
` `
// ConfigFilename returns the proper tilde expanded config filename.
func ConfigFilename(filename string) (string, error) { func ConfigFilename(filename string) (string, error) {
if len(filename) == 0 { if len(filename) == 0 {
filename = defaultConfigFilePath filename = defaultConfigFilePath
...@@ -41,8 +42,8 @@ func ConfigFilename(filename string) (string, error) { ...@@ -41,8 +42,8 @@ func ConfigFilename(filename string) (string, error) {
return u.TildeExpansion(filename) return u.TildeExpansion(filename)
} }
// LoadConfig reads given file and returns the read config, or error. // ConfigLoad reads given file and returns the read config, or error.
func LoadConfig(filename string) (*Config, error) { func ConfigLoad(filename string) (*Config, error) {
filename, err := ConfigFilename(filename) filename, err := ConfigFilename(filename)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -67,3 +68,8 @@ func LoadConfig(filename string) (*Config, error) { ...@@ -67,3 +68,8 @@ func LoadConfig(filename string) (*Config, error) {
return &cfg, err return &cfg, err
} }
// Set sets the value of a particular config key
func Set(filename, key, value string) error {
return nil
}
...@@ -7,7 +7,7 @@ import ( ...@@ -7,7 +7,7 @@ import (
func TestConfig(t *testing.T) { func TestConfig(t *testing.T) {
cfg, err := LoadConfig("") cfg, err := ConfigLoad("")
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return return
......
...@@ -2,120 +2,114 @@ package config ...@@ -2,120 +2,114 @@ package config
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
u "github.com/jbenet/go-ipfs/util" "io"
"io/ioutil"
"os" "os"
"path"
"strings" "strings"
) )
// WriteFile writes the given buffer `buf` into file named `filename`. // ReadConfigFile reads the config from `filename` into `cfg`.
func WriteFile(filename string, buf []byte) error { func ReadConfigFile(filename string, cfg interface{}) error {
err := os.MkdirAll(path.Dir(filename), 0777) f, err := os.Open(filename)
if err != nil { if err != nil {
return err return err
} }
defer f.Close()
return ioutil.WriteFile(filename, buf, 0666) return Decode(f, cfg)
} }
// ReadConfigFile reads the config from `filename` into `cfg`. // WriteConfigFile writes the config from `cfg` into `filename`.
func ReadConfigFile(filename string, cfg *Config) error { func WriteConfigFile(filename string, cfg interface{}) error {
buf, err := ioutil.ReadFile(filename) f, err := os.Create(filename)
if err != nil { if err != nil {
return err return err
} }
defer f.Close()
return json.Unmarshal(buf, cfg) return Encode(f, cfg)
} }
// WriteConfigFile writes the config from `cfg` into `filename`. // WriteFile writes the buffer at filename
func WriteConfigFile(filename string, cfg *Config) error { func WriteFile(filename string, buf []byte) error {
buf, err := json.MarshalIndent(cfg, "", " ") f, err := os.Create(filename)
if err != nil { if err != nil {
return err return err
} }
defer f.Close()
return WriteFile(filename, buf) _, err = f.Write(buf)
return err
} }
// WriteConfigFile writes the config from `cfg` into `filename`. // Encode configuration with JSON
func GetValueInConfigFile(key string) (value string, err error) { func Encode(w io.Writer, value interface{}) error {
// reading config file // need to prettyprint, hence MarshalIndent, instead of Encoder
attrs := strings.Split(key, ".") buf, err := json.MarshalIndent(value, "", " ")
filename, _ := u.TildeExpansion(defaultConfigFilePath)
buf, err := ioutil.ReadFile(filename)
if err != nil { if err != nil {
return "", err return err
} }
// deserializing json _, err = w.Write(buf)
var cfg interface{} return err
var exists bool }
err = json.Unmarshal(buf, &cfg) // Decode configuration with JSON
if err != nil { func Decode(r io.Reader, value interface{}) error {
return "", err 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
} }
for i := range attrs { var ok bool
cfgMap, isMap := cfg.(map[string]interface{}) cursor := cfg
if !isMap { parts := strings.Split(key, ".")
return "", errors.New(fmt.Sprintf("%s has no attributes", strings.Join(attrs[:i], "."))) for i, part := range parts {
} cursor, ok = cursor.(map[string]interface{})[part]
cfg, exists = cfgMap[attrs[i]] if !ok {
if !exists { sofar := strings.Join(parts[:i], ".")
return "", errors.New(fmt.Sprintf("Configuration option key \"%s\" not recognized", strings.Join(attrs[:i+1], "."))) return nil, fmt.Errorf("%s key has no attributes", sofar)
}
val, is_string := cfg.(string)
if is_string {
return val, nil
} }
} }
return "", errors.New(fmt.Sprintf("%s is not a string", key)) return cursor, nil
} }
// WriteConfigFile writes the config from `cfg` into `filename`. // WriteConfigKey writes the value of a particular key
func SetValueInConfigFile(key string, values []string) error { func WriteConfigKey(filename, key string, value interface{}) error {
assignee := strings.Join(values, " ") var cfg interface{}
attrs := strings.Split(key, ".") if err := ReadConfigFile(filename, &cfg); err != nil {
filename, _ := u.TildeExpansion(defaultConfigFilePath)
buf, err := ioutil.ReadFile(filename)
if err != nil {
return err return err
} }
// deserializing json var ok bool
var cfg, orig interface{} var mcursor map[string]interface{}
var exists, isMap bool cursor := cfg
cfgMap := make(map[string]interface{})
err = json.Unmarshal(buf, &orig) parts := strings.Split(key, ".")
cfg = orig for i, part := range parts {
if err != nil { mcursor, ok = cursor.(map[string]interface{})
return err if !ok {
} sofar := strings.Join(parts[:i], ".")
return fmt.Errorf("%s key is not a map", sofar)
}
for i := 0; i < len(attrs); i++ { // last part? set here
cfgMap, isMap = cfg.(map[string]interface{}) if i == (len(parts) - 1) {
// curs = append(curs, cfgMap) mcursor[part] = value
if !isMap { break
return errors.New(fmt.Sprintf("%s has no attributes", strings.Join(attrs[:i], ".")))
} }
cfg, exists = cfgMap[attrs[i]]
if !exists { cursor, ok = mcursor[part]
return errors.New(fmt.Sprintf("Configuration option key \"%s\" not recognized", strings.Join(attrs[:i+1], "."))) 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, "", " ") return WriteConfigFile(filename, cfg)
if err != nil {
return err
}
WriteFile(filename, buf)
return nil
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment