From 54e8e770fbb651e303cfc6d2c55fe66758d1644f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sun, 22 Jul 2018 21:31:49 +0200 Subject: [PATCH] go-ipfs-config: move serialize package to config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Ɓukasz Magiera --- config/serialize/serialize.go | 71 ++++++++++++++++++++++++++++++ config/serialize/serialize_test.go | 37 ++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 config/serialize/serialize.go create mode 100644 config/serialize/serialize_test.go diff --git a/config/serialize/serialize.go b/config/serialize/serialize.go new file mode 100644 index 000000000..f1a482513 --- /dev/null +++ b/config/serialize/serialize.go @@ -0,0 +1,71 @@ +package fsrepo + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "os" + "path/filepath" + + "github.com/ipfs/go-ipfs/repo/config" + + "gx/ipfs/QmPdKqUcHGFdeSpvjVoaTRPPstGif9GBZb5Q56RVw9o69A/go-ipfs-util" + "gx/ipfs/QmdYwCmx8pZRkzdcd8MhmLJqYVoVTC1aGsy5Q4reMGLNLg/atomicfile" +) + +// 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 := json.NewDecoder(f).Decode(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 := atomicfile.New(filename, 0660) + if err != nil { + return err + } + defer f.Close() + + return encode(f, cfg) +} + +// encode configuration with JSON +func encode(w io.Writer, value interface{}) error { + // need to prettyprint, hence MarshalIndent, instead of Encoder + buf, err := config.Marshal(value) + if err != nil { + return err + } + _, err = w.Write(buf) + return err +} + +// Load reads given file and returns the read config, or error. +func Load(filename string) (*config.Config, error) { + // if nothing is there, fail. User must run 'ipfs init' + if !util.FileExists(filename) { + return nil, errors.New("ipfs not initialized, please run 'ipfs init'") + } + + var cfg config.Config + err := ReadConfigFile(filename, &cfg) + if err != nil { + return nil, err + } + + return &cfg, err +} diff --git a/config/serialize/serialize_test.go b/config/serialize/serialize_test.go new file mode 100644 index 000000000..443024ed8 --- /dev/null +++ b/config/serialize/serialize_test.go @@ -0,0 +1,37 @@ +package fsrepo + +import ( + "os" + "runtime" + "testing" + + config "github.com/ipfs/go-ipfs/repo/config" +) + +func TestConfig(t *testing.T) { + const filename = ".ipfsconfig" + cfgWritten := new(config.Config) + cfgWritten.Identity.PeerID = "faketest" + + err := WriteConfigFile(filename, cfgWritten) + if err != nil { + t.Fatal(err) + } + cfgRead, err := Load(filename) + if err != nil { + t.Fatal(err) + } + if cfgWritten.Identity.PeerID != cfgRead.Identity.PeerID { + t.Fatal() + } + st, err := os.Stat(filename) + if err != nil { + t.Fatalf("cannot stat config file: %v", err) + } + + if runtime.GOOS != "windows" { // see https://golang.org/src/os/types_windows.go + if g := st.Mode().Perm(); g&0117 != 0 { + t.Fatalf("config file should not be executable or accessible to world: %v", g) + } + } +}