|
1 | 1 | package main |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "flag" |
5 | 4 | "fmt" |
6 | 5 | "os" |
7 | | - "strings" |
8 | 6 |
|
| 7 | + "github.com/spf13/cobra" |
9 | 8 | bolt "go.etcd.io/bbolt" |
10 | 9 | ) |
11 | 10 |
|
12 | | -// getCommand represents the "get" command execution. |
13 | | -type getCommand struct { |
14 | | - baseCommand |
15 | | -} |
16 | | - |
17 | | -// newGetCommand returns a getCommand. |
18 | | -func newGetCommand(m *Main) *getCommand { |
19 | | - c := &getCommand{} |
20 | | - c.baseCommand = m.baseCommand |
21 | | - return c |
22 | | -} |
23 | | - |
24 | | -// Run executes the command. |
25 | | -func (cmd *getCommand) Run(args ...string) error { |
26 | | - // Parse CLI flags. |
27 | | - fs := flag.NewFlagSet("", flag.ContinueOnError) |
28 | | - var parseFormat string |
29 | | - var format string |
30 | | - fs.StringVar(&parseFormat, "parse-format", "ascii-encoded", "Input format. One of: ascii-encoded|hex (default: ascii-encoded)") |
31 | | - fs.StringVar(&format, "format", "auto", "Output format. One of: "+FORMAT_MODES+" (default: auto)") |
32 | | - help := fs.Bool("h", false, "") |
33 | | - if err := fs.Parse(args); err != nil { |
34 | | - return err |
35 | | - } else if *help { |
36 | | - fmt.Fprintln(cmd.Stderr, cmd.Usage()) |
37 | | - return ErrUsage |
38 | | - } |
39 | | - |
40 | | - // Validate arguments. |
41 | | - relevantArgs := fs.Args() |
42 | | - if len(relevantArgs) < 3 { |
43 | | - return ErrNotEnoughArgs |
44 | | - } |
45 | | - path := relevantArgs[0] |
46 | | - buckets := relevantArgs[1 : len(relevantArgs)-1] |
47 | | - keyStr := relevantArgs[len(relevantArgs)-1] |
48 | | - |
49 | | - key, err := parseBytes(keyStr, parseFormat) |
50 | | - if err != nil { |
51 | | - return err |
52 | | - } |
53 | | - if path == "" { |
54 | | - return ErrPathRequired |
55 | | - } else if _, err := os.Stat(path); os.IsNotExist(err) { |
56 | | - return ErrFileNotFound |
57 | | - } else if len(buckets) == 0 { |
58 | | - return ErrBucketRequired |
59 | | - } else if len(key) == 0 { |
60 | | - } else if len(key) == 0 { |
61 | | - return fmt.Errorf("key required") |
| 11 | +func newGetCommand(m *Main) *cobra.Command { |
| 12 | + var parseFormat, format string |
| 13 | + |
| 14 | + cmd := &cobra.Command{ |
| 15 | + Use: "get PATH [BUCKET..] KEY", |
| 16 | + Short: "Get the value of a key from a (sub)bucket in a bbolt database", |
| 17 | + Args: cobra.MinimumNArgs(3), |
| 18 | + RunE: func(cmd *cobra.Command, args []string) error { |
| 19 | + path := args[0] |
| 20 | + buckets := args[1 : len(args)-1] |
| 21 | + keyStr := args[len(args)-1] |
| 22 | + |
| 23 | + key, err := parseBytes(keyStr, parseFormat) |
| 24 | + if err != nil { |
| 25 | + return err |
| 26 | + } |
| 27 | + if path == "" { |
| 28 | + return ErrPathRequired |
| 29 | + } else if _, err := os.Stat(path); os.IsNotExist(err) { |
| 30 | + return ErrFileNotFound |
| 31 | + } else if len(buckets) == 0 { |
| 32 | + return ErrBucketRequired |
| 33 | + } else if len(key) == 0 { |
| 34 | + return fmt.Errorf("key required") |
| 35 | + } |
| 36 | + |
| 37 | + db, err := bolt.Open(path, 0600, &bolt.Options{ReadOnly: true}) |
| 38 | + if err != nil { |
| 39 | + return err |
| 40 | + } |
| 41 | + defer db.Close() |
| 42 | + |
| 43 | + return db.View(func(tx *bolt.Tx) error { |
| 44 | + lastBucket, err := findLastBucket(tx, buckets) |
| 45 | + if err != nil { |
| 46 | + return err |
| 47 | + } |
| 48 | + val := lastBucket.Get(key) |
| 49 | + if val == nil { |
| 50 | + return fmt.Errorf("Error %w for key: %q hex: \"%x\"", ErrKeyNotFound, key, key) |
| 51 | + } |
| 52 | + return writelnBytes(cmd.OutOrStdout(), val, format) |
| 53 | + }) |
| 54 | + }, |
62 | 55 | } |
63 | | - // Open database. |
64 | | - db, err := bolt.Open(path, 0600, &bolt.Options{ReadOnly: true}) |
65 | | - if err != nil { |
66 | | - return err |
67 | | - } |
68 | | - defer db.Close() |
69 | | - |
70 | | - // Fetch value. |
71 | | - return db.View(func(tx *bolt.Tx) error { |
72 | | - lastBucket, err := findLastBucket(tx, buckets) |
73 | | - if err != nil { |
74 | | - return err |
75 | | - } |
76 | | - val := lastBucket.Get(key) |
77 | | - if val == nil { |
78 | | - return fmt.Errorf("Error %w for key: %q hex: \"%x\"", ErrKeyNotFound, key, key) |
79 | | - } |
80 | | - return writelnBytes(cmd.Stdout, val, format) |
81 | | - }) |
82 | | -} |
83 | | - |
84 | | -// Usage returns the help message. |
85 | | -func (cmd *getCommand) Usage() string { |
86 | | - return strings.TrimLeft(` |
87 | | -usage: bolt get PATH [BUCKET..] KEY |
88 | | -
|
89 | | -Print the value of the given key in the given (sub)bucket. |
90 | 56 |
|
91 | | -Additional options include: |
| 57 | + cmd.Flags().StringVar(&parseFormat, "parse-format", "ascii-encoded", "Input format. One of: ascii-encoded|hex") |
| 58 | + cmd.Flags().StringVar(&format, "format", "auto", "Output format. One of: ascii|hex|auto") |
92 | 59 |
|
93 | | - --format |
94 | | - Output format. One of: `+FORMAT_MODES+` (default=auto) |
95 | | - --parse-format |
96 | | - Input format (of key). One of: ascii-encoded|hex (default=ascii-encoded) |
97 | | -`, "\n") |
| 60 | + return cmd |
98 | 61 | } |
0 commit comments