-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcli.go
142 lines (117 loc) · 2.54 KB
/
cli.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
package main
import (
"bytes"
"fmt"
"io"
"os/exec"
"reflect"
"strings"
flags "github.com/jessevdk/go-flags"
"github.com/tatsuyafw/amc/aws"
)
const (
exitCodeOK = iota
exitCodeParserFlagError
exitCodeArgumentError
)
type cli struct {
outStream, errStream io.Writer
}
type options struct {
OptDryRun bool `short:"d" long:"dry-run" description:"Perform a dry-run"`
OptHelp bool `short:"h" long:"help" description:"Show this help message and exit"`
OptVersion bool `short:"v" long:"version" description:"Print the version and exit"`
}
func newCli(o io.Writer, e io.Writer) *cli {
return &cli{outStream: o, errStream: e}
}
func (c *cli) Run(args []string) int {
opts, parsed, err := c.parseOptions(args)
if err != nil {
return exitCodeParserFlagError
}
if opts.OptHelp {
c.outStream.Write(c.help())
return exitCodeOK
}
if opts.OptVersion {
c.outStream.Write(c.version())
return exitCodeOK
}
if len(parsed) == 0 {
c.showHelp()
return exitCodeArgumentError
}
var service string
var query string
if len(parsed) > 0 {
service = parsed[0]
}
if len(parsed) > 1 {
query = parsed[1]
}
a, err := aws.New(service, query)
if err != nil {
c.showHelp() // TODO: show more details about an error.
return exitCodeArgumentError
}
u := a.URL()
fmt.Println(u)
if !opts.OptDryRun {
c.open(u)
}
return exitCodeOK
}
func (c *cli) open(url string) {
// TODO: handling an error
exec.Command("open", url).Run()
}
func (c *cli) parseOptions(args []string) (*options, []string, error) {
opts := &options{}
p := flags.NewParser(opts, flags.PrintErrors)
args, err := p.ParseArgs(args)
if err != nil {
c.errStream.Write(c.help())
return nil, nil, err
}
return opts, args, nil
}
func (cli) version() []byte {
buf := bytes.Buffer{}
fmt.Fprintln(&buf, "amc version "+version)
return buf.Bytes()
}
func optionMessages() []string {
o := options{}
t := reflect.TypeOf(o)
messages := make([]string, 0, t.NumField())
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
s := f.Tag.Get("short")
l := f.Tag.Get("long")
d := f.Tag.Get("description")
m := "-" + s + ", --" + l + ":\t" + d
messages = append(messages, m)
}
return messages
}
func (c *cli) showHelp() {
c.outStream.Write(c.help())
}
func (c *cli) help() []byte {
buf := bytes.Buffer{}
fmt.Fprintf(&buf, `
Usage: amc [options] AWS_SERVICE
AWS_SERVICE:
`)
a := aws.Supported()
s := strings.Join(a, ",")
fmt.Fprintln(&buf, " "+s)
fmt.Fprintf(&buf, `
Options:
`)
for _, m := range optionMessages() {
fmt.Fprintln(&buf, "\t"+m)
}
return buf.Bytes()
}