From 7228c8fe486b539ab3ba7961c22d6639093ad7b6 Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Wed, 5 Nov 2014 16:22:47 -0800 Subject: [PATCH] core/commands2: Added 'config' command --- core/commands2/config.go | 188 +++++++++++++++++++++++++++++++++++++++ core/commands2/root.go | 1 + 2 files changed, 189 insertions(+) create mode 100644 core/commands2/config.go diff --git a/core/commands2/config.go b/core/commands2/config.go new file mode 100644 index 000000000..1eaf2332d --- /dev/null +++ b/core/commands2/config.go @@ -0,0 +1,188 @@ +package commands + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "os" + "os/exec" + + cmds "github.com/jbenet/go-ipfs/commands" + config "github.com/jbenet/go-ipfs/config" +) + +type ConfigField struct { + Key string + Value interface{} +} + +var configCmd = &cmds.Command{ + Arguments: []cmds.Argument{ + cmds.Argument{"key", cmds.ArgString, true, false}, + cmds.Argument{"value", cmds.ArgString, false, false}, + }, + Help: `ipfs config [value] - Get/Set ipfs config values. + + ipfs config - Get value of + ipfs config - Set value of to + ipfs config show - Show config file + ipfs config edit - Edit config file in $EDITOR + +Examples: + + Get the value of the 'datastore.path' key: + + ipfs config datastore.path + + Set the value of the 'datastore.path' key: + + ipfs config datastore.path ~/.go-ipfs/datastore + +`, + Run: func(res cmds.Response, req cmds.Request) { + args := req.Arguments() + + key, ok := args[0].(string) + if !ok { + res.SetError(errors.New("cast error"), cmds.ErrNormal) + return + } + + filename, err := config.Filename(req.Context().ConfigRoot) + if err != nil { + res.SetError(err, cmds.ErrNormal) + return + } + + var value string + if len(args) == 2 { + var ok bool + value, ok = args[1].(string) + if !ok { + res.SetError(errors.New("cast error"), cmds.ErrNormal) + return + } + + field, err := setConfig(filename, key, value) + if err != nil { + res.SetError(err, cmds.ErrNormal) + return + } + + res.SetOutput(field) + return + + } else { + field, err := getConfig(filename, key) + if err != nil { + res.SetError(err, cmds.ErrNormal) + return + } + + res.SetOutput(field) + return + } + }, + Marshallers: map[cmds.EncodingType]cmds.Marshaller{ + cmds.Text: func(res cmds.Response) ([]byte, error) { + v := res.Output().(*ConfigField) + + s := "" + if len(res.Request().Arguments()) == 2 { + s += fmt.Sprintf("'%s' set to: ", v.Key) + } + + marshalled, err := json.Marshal(v.Value) + if err != nil { + return nil, err + } + s += fmt.Sprintf("%s\n", marshalled) + + return []byte(s), nil + }, + }, + Type: &ConfigField{}, + Subcommands: map[string]*cmds.Command{ + "show": configShowCmd, + "edit": configEditCmd, + }, +} + +var configShowCmd = &cmds.Command{ + Run: func(res cmds.Response, req cmds.Request) { + filename, err := config.Filename(req.Context().ConfigRoot) + if err != nil { + res.SetError(err, cmds.ErrNormal) + return + } + + reader, err := showConfig(filename) + if err != nil { + res.SetError(err, cmds.ErrNormal) + return + } + + res.SetOutput(reader) + }, +} + +var configEditCmd = &cmds.Command{ + Run: func(res cmds.Response, req cmds.Request) { + filename, err := config.Filename(req.Context().ConfigRoot) + if err != nil { + res.SetError(err, cmds.ErrNormal) + return + } + + err = editConfig(filename) + if err != nil { + res.SetError(err, cmds.ErrNormal) + return + } + }, +} + +func getConfig(filename string, key string) (*ConfigField, error) { + value, err := config.ReadConfigKey(filename, key) + if err != nil { + return nil, fmt.Errorf("Failed to get config value: %s", err) + } + + return &ConfigField{ + Key: key, + Value: value, + }, nil +} + +func setConfig(filename string, key, value string) (*ConfigField, error) { + err := config.WriteConfigKey(filename, key, value) + if err != nil { + return nil, fmt.Errorf("Failed to set config value: %s", err) + } + + return getConfig(filename, key) +} + +func showConfig(filename string) (io.Reader, error) { + // MAYBE_TODO: maybe we should omit privkey so we don't accidentally leak it? + + file, err := os.Open(filename) + if err != nil { + return nil, err + } + //defer file.Close() + + return file, nil +} + +func editConfig(filename string) error { + editor := os.Getenv("EDITOR") + if editor == "" { + return errors.New("ENV variable $EDITOR not set") + } + + cmd := exec.Command("sh", "-c", editor+" "+filename) + cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr + return cmd.Run() +} diff --git a/core/commands2/root.go b/core/commands2/root.go index a17210d67..9238832d3 100644 --- a/core/commands2/root.go +++ b/core/commands2/root.go @@ -66,6 +66,7 @@ var rootSubcommands = map[string]*cmds.Command{ "pin": pinCmd, "unpin": unpinCmd, "version": versionCmd, + "config": configCmd, // test subcommands // TODO: remove these when we don't need them anymore