master
go 72 lines 1.5 KB
Raw
1 package fsrepo
2
3 import (
4 "encoding/json"
5 "errors"
6 "fmt"
7 "io"
8 "os"
9 "path/filepath"
10
11 "github.com/ipfs/kubo/config"
12
13 "github.com/facebookgo/atomicfile"
14 )
15
16 // ErrNotInitialized is returned when we fail to read the config because the
17 // repo doesn't exist.
18 var ErrNotInitialized = errors.New("ipfs not initialized, please run 'ipfs init'")
19
20 // ReadConfigFile reads the config from `filename` into `cfg`.
21 func ReadConfigFile(filename string, cfg any) error {
22 f, err := os.Open(filename)
23 if err != nil {
24 if os.IsNotExist(err) {
25 err = ErrNotInitialized
26 }
27 return err
28 }
29 defer f.Close()
30 if err := json.NewDecoder(f).Decode(cfg); err != nil {
31 return fmt.Errorf("failure to decode config: %w", err)
32 }
33 return nil
34 }
35
36 // WriteConfigFile writes the config from `cfg` into `filename`.
37 func WriteConfigFile(filename string, cfg any) error {
38 err := os.MkdirAll(filepath.Dir(filename), 0o755)
39 if err != nil {
40 return err
41 }
42
43 f, err := atomicfile.New(filename, 0o600)
44 if err != nil {
45 return err
46 }
47 defer f.Close()
48
49 return encode(f, cfg)
50 }
51
52 // encode configuration with JSON.
53 func encode(w io.Writer, value any) error {
54 // need to prettyprint, hence MarshalIndent, instead of Encoder
55 buf, err := config.Marshal(value)
56 if err != nil {
57 return err
58 }
59 _, err = w.Write(buf)
60 return err
61 }
62
63 // Load reads given file and returns the read config, or error.
64 func Load(filename string) (*config.Config, error) {
65 var cfg config.Config
66 err := ReadConfigFile(filename, &cfg)
67 if err != nil {
68 return nil, err
69 }
70
71 return &cfg, err
72 }