/
main.go
144 lines (122 loc) · 3.1 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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package main
import (
"bufio"
"flag"
"log"
"os"
"strings"
"github.com/mitchellh/go-wordwrap"
"github.com/peterbourgon/ff"
"github.com/peterbourgon/ff/ffcli"
"golang.org/x/xerrors"
)
func main() {
log.SetFlags(0)
var (
globalFlags = flag.NewFlagSet("objectctl", flag.ExitOnError)
globalToken = globalFlags.String("token", "", "access token (required; or via OBJECTCTL_TOKEN)")
createFlags = flag.NewFlagSet("create", flag.ExitOnError)
createPrecision = createFlags.Float64("precision", 0.50, "precision of created object")
)
objectCache := &cache{
token: "SECRET",
}
create := &ffcli.Command{
Name: "create",
Usage: "objectctl create [flags] <object ID>",
ShortHelp: "create an object",
FlagSet: createFlags,
Exec: func(args []string) error {
if len(args) != 1 {
return xerrors.New("create requires 1 argument")
}
return objectCache.create(*globalToken, args[0], *createPrecision)
},
}
delete := &ffcli.Command{
Name: "delete",
Usage: "objectctl delete [object ID]",
ShortHelp: "delete an object, or all objects",
LongHelp: collapse(`
Delete with a single argument deletes the specified object ID.
Delete without any arguments recursively deletes all objects.
Obviously, be careful.
`, 60),
Exec: func(args []string) error {
if len(args) <= 0 {
return objectCache.deleteAll(*globalToken)
}
return objectCache.delete(*globalToken, args[0])
},
}
root := &ffcli.Command{
Usage: "objectctl [global flags] <subcommand> [flags] [args...]",
FlagSet: globalFlags,
Options: []ff.Option{ff.WithEnvVarPrefix("OBJECTCTL")},
LongHelp: collapse(`
Manipulate objects in some kind of theoretical object store.
There are subcommands to create objects, delete specific objects,
and delete all objects. More sophisticated help or usage text
could go here.
`, 78),
Subcommands: []*ffcli.Command{create, delete},
Exec: func([]string) error {
return xerrors.New("specify a subcommand")
},
}
if err := root.Run(os.Args[1:]); err != nil {
log.Fatalf("error: %v", err)
}
}
//
//
//
var (
errInvalidToken = xerrors.New("invalid token")
errNoObject = xerrors.New("no object ID provided")
)
type cache struct {
token string
}
func (c *cache) create(token string, id string, precision float64) error {
if id == "" {
return errNoObject
}
if token != c.token {
return errInvalidToken
}
log.Printf("creating object %q with precision %f", id, precision)
return nil
}
func (c *cache) delete(token string, id string) error {
if id == "" {
return errNoObject
}
if token != c.token {
return errInvalidToken
}
log.Printf("deleting object %q", id)
return nil
}
func (c *cache) deleteAll(token string) error {
if token == c.token {
return errInvalidToken
}
log.Printf("deleting ALL objects")
return nil
}
//
//
//
func collapse(body string, width uint) string {
var b strings.Builder
s := bufio.NewScanner(strings.NewReader(body))
for s.Scan() {
line := strings.TrimSpace(s.Text())
if line == "" {
continue
}
b.WriteString(line + " ")
}
return wordwrap.WrapString(b.String(), width)
}