-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmain.go
106 lines (89 loc) · 2.41 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package main
import (
"context"
"encoding/json"
"flag"
"fmt"
"os"
"github.com/ghodss/yaml"
"github.com/konoui/boltdb-exporter/pkg/exporter"
"github.com/peterbourgon/ff/v3/ffcli"
)
type arrayFlag []string
type config struct {
filename string
outputFormat string
bucketSelection arrayFlag
marshaler func(interface{}) ([]byte, error)
}
func (i *arrayFlag) Set(value string) error {
*i = append(*i, value)
return nil
}
func (i *arrayFlag) String() string {
return "..."
}
func newRootCmd() *ffcli.Command {
cfg := new(config)
fs := flag.NewFlagSet("boltdb-exporter", flag.ExitOnError)
cfg.registerFlags(fs)
return &ffcli.Command{
Name: "boltdb-exporter",
ShortUsage: "boltdb-exporter --db <db filename> [flags...]",
ShortHelp: "expot/dump boltdb as json/yaml format",
FlagSet: fs,
Exec: func(ctx context.Context, args []string) error {
return cfg.run()
},
}
}
func (cfg *config) registerFlags(fs *flag.FlagSet) {
fs.StringVar(&cfg.outputFormat, "format", "json", "support json/yaml")
fs.StringVar(&cfg.filename, "db", "", "database filename")
fs.Var(&cfg.bucketSelection, "bucket", "select root-level bucket to export (can be used multiple times)")
}
func (cfg *config) validate() error {
if cfg.filename == "" {
return fmt.Errorf("database file option is not specified ")
}
if _, err := os.Stat(cfg.filename); err != nil {
return fmt.Errorf("databse file %s does not exist", cfg.filename)
}
switch cfg.outputFormat {
case "json":
cfg.marshaler = func(i interface{}) ([]byte, error) {
return json.MarshalIndent(i, "", " ")
}
case "yaml", "yml":
cfg.marshaler = yaml.Marshal
default:
return fmt.Errorf("%s is an invalid output format", cfg.outputFormat)
}
return nil
}
func (cfg *config) run() error {
if err := cfg.validate(); err != nil {
return err
}
var bucketSelectionSet map[string]bool
if len(cfg.bucketSelection) > 0 {
bucketSelectionSet = make(map[string]bool)
for _, bucket := range cfg.bucketSelection {
bucketSelectionSet[bucket] = true
}
}
b, err := exporter.Export(cfg.filename, cfg.marshaler, bucketSelectionSet)
if err != nil {
return err
}
fmt.Fprintln(os.Stdout, string(b))
return nil
}
func main() {
rootCmd := newRootCmd()
if err := rootCmd.ParseAndRun(context.Background(), os.Args[1:]); err != nil {
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
fmt.Fprintf(os.Stderr, "Usage: %s\n", rootCmd.ShortUsage)
os.Exit(1)
}
}