@cryptotaxi247 / kubo / commits / 20bce4749

ipfs config cmd with git-style get/set

Adds "ipfs config" command designed in git style. See specific config's values with: $ipfs config datastore.path ~/.go-ipfs/datastore Assign a new value with: $ipfs config datastore.path ~/.go-ipfs/datastore Open the config file in your default $EDITOR: ipfs config edit

Peter Borzov committed Jul 29, 2014 at 21:45 UTC 20bce474911e98e8d54fa77961f8885c769b2be6
4 files changed +159 -3
cmd/ipfs/config.go new
+72
@@ -0,0 +1,72 @@
1 +package main
2 +
3 +import (
4 + "github.com/jbenet/commander"
5 + config "github.com/jbenet/go-ipfs/config"
6 + u "github.com/jbenet/go-ipfs/util"
7 + "os"
8 + "os/exec"
9 +)
10 +
11 +var cmdIpfsConfig = &commander.Command{
12 + UsageLine: "config",
13 + Short: "See and Edit ipfs options",
14 + Long: `ipfs config - See or Edit ipfs configuration.
15 +
16 + See specific config's values with:
17 + ipfs config datastore.path
18 + Assign a new value with:
19 + ipfs config datastore.path ~/.go-ipfs/datastore
20 +
21 + Open the config file in your editor(from $EDITOR):
22 + ipfs config edit
23 + `,
24 + Run: configCmd,
25 + Subcommands: []*commander.Command{
26 + cmdIpfsConfigEdit,
27 + },
28 +}
29 +
30 +var cmdIpfsConfigEdit = &commander.Command{
31 + UsageLine: "edit",
32 + Short: "Opens the configuration file in the editor.",
33 + Long: `Looks up environment variable $EDITOR and
34 + attempts to open the config file with it.
35 + `,
36 + Run: configEditCmd,
37 +}
38 +
39 +func configCmd(c *commander.Command, inp []string) error {
40 + if len(inp) == 0 {
41 + // "ipfs config" run without parameters
42 + u.POut(c.Long + "\n")
43 + return nil
44 + }
45 +
46 + if len(inp) == 1 {
47 + // "ipfs config" run without one parameter, so this is a value getter
48 + value, err := config.GetValueInConfigFile(inp[0])
49 + if err != nil {
50 + u.POut("Failed to get config value: " + err.Error() + "\n")
51 + } else {
52 + u.POut(value + "\n")
53 + }
54 + return nil
55 + }
56 +
57 + // "ipfs config" run without two parameter, so this is a value setter
58 + err := config.SetValueInConfigFile(inp[0], inp[1:])
59 + if err != nil {
60 + u.POut("Failed to set config value: " + err.Error() + "\n")
61 + }
62 + return nil
63 +}
64 +
65 +func configEditCmd(c *commander.Command, _ []string) error {
66 + if editor := os.Getenv("EDITOR"); editor == "" {
67 + u.POut("ENVIRON variable $EDITOR is not assigned \n")
68 + } else {
69 + exec.Command("sh", "-c", editor+" "+config.DefaultConfigFilePath).Start()
70 + }
71 + return nil
72 +}
cmd/ipfs/ipfs.go
+1
@@ -41,6 +41,7 @@ Use "ipfs help <command>" for more information about a command.
41 cmdIpfsCat,
42 cmdIpfsLs,
43 cmdIpfsRefs,
44 + cmdIpfsConfig,
45 cmdIpfsVersion,
46 cmdIpfsCommands,
47 cmdIpfsMount,
config/config.go
+3 -3
@@ -1,8 +1,8 @@
1 package config
2
3 import (
4 - "os"
4 u "github.com/jbenet/go-ipfs/util"
5 + "os"
6 )
7
8 // Identity tracks the configuration of the local node's identity.
@@ -22,7 +22,7 @@ type Config struct {
22 Datastore *Datastore
23 }
24
25 -var defaultConfigFilePath = "~/.go-ipfs/config"
25 +var DefaultConfigFilePath = "~/.go-ipfs/config"
26 var defaultConfigFile = `{
27 "identity": {},
28 "datastore": {
@@ -35,7 +35,7 @@ var defaultConfigFile = `{
35 // LoadConfig reads given file and returns the read config, or error.
36 func LoadConfig(filename string) (*Config, error) {
37 if len(filename) == 0 {
38 - filename = defaultConfigFilePath
38 + filename = DefaultConfigFilePath
39 }
40
41 // tilde expansion on config file
config/serialize.go
+83
@@ -2,9 +2,13 @@ package config
2
3 import (
4 "encoding/json"
5 + "errors"
6 + "fmt"
7 + u "github.com/jbenet/go-ipfs/util"
8 "io/ioutil"
9 "os"
10 "path"
11 + "strings"
12 )
13
14 // WriteFile writes the given buffer `buf` into file named `filename`.
@@ -36,3 +40,82 @@ func WriteConfigFile(filename string, cfg *Config) error {
40
41 return WriteFile(filename, buf)
42 }
43 +
44 +// WriteConfigFile writes the config from `cfg` into `filename`.
45 +func GetValueInConfigFile(key string) (value string, err error) {
46 + // reading config file
47 + attrs := strings.Split(key, ".")
48 +
49 + filename, _ := u.TildeExpansion(DefaultConfigFilePath)
50 + buf, err := ioutil.ReadFile(filename)
51 + if err != nil {
52 + return "", err
53 + }
54 +
55 + // deserializing json
56 + var cfg interface{}
57 + var exists bool
58 +
59 + err = json.Unmarshal(buf, &cfg)
60 + if err != nil {
61 + return "", err
62 + }
63 +
64 + for i := range attrs {
65 + cfgMap, isMap := cfg.(map[string]interface{})
66 + if !isMap {
67 + return "", errors.New(fmt.Sprintf("%s has no attributes", strings.Join(attrs[:i], ".")))
68 + }
69 + cfg, exists = cfgMap[attrs[i]]
70 + if !exists {
71 + return "", errors.New(fmt.Sprintf("Configuration option key \"%s\" not recognized", strings.Join(attrs[:i+1], ".")))
72 + }
73 + val, is_string := cfg.(string)
74 + if is_string {
75 + return val, nil
76 + }
77 + }
78 + return "", errors.New(fmt.Sprintf("%s is not a string", key))
79 +}
80 +
81 +// WriteConfigFile writes the config from `cfg` into `filename`.
82 +func SetValueInConfigFile(key string, values []string) error {
83 + assignee := strings.Join(values, " ")
84 + attrs := strings.Split(key, ".")
85 +
86 + filename, _ := u.TildeExpansion(DefaultConfigFilePath)
87 + buf, err := ioutil.ReadFile(filename)
88 + if err != nil {
89 + return err
90 + }
91 +
92 + // deserializing json
93 + var cfg, orig interface{}
94 + var exists, isMap bool
95 + cfgMap := make(map[string]interface{})
96 +
97 + err = json.Unmarshal(buf, &orig)
98 + cfg = orig
99 + if err != nil {
100 + return err
101 + }
102 +
103 + for i := 0; i < len(attrs); i++ {
104 + cfgMap, isMap = cfg.(map[string]interface{})
105 + // curs = append(curs, cfgMap)
106 + if !isMap {
107 + return errors.New(fmt.Sprintf("%s has no attributes", strings.Join(attrs[:i], ".")))
108 + }
109 + cfg, exists = cfgMap[attrs[i]]
110 + if !exists {
111 + return errors.New(fmt.Sprintf("Configuration option key \"%s\" not recognized", strings.Join(attrs[:i+1], ".")))
112 + }
113 + }
114 + cfgMap[attrs[len(attrs)-1]] = assignee
115 + buf, err = json.MarshalIndent(orig, "", " ")
116 + if err != nil {
117 + return err
118 + }
119 + WriteFile(filename, buf)
120 + return nil
121 +}