-
Notifications
You must be signed in to change notification settings - Fork 162
/
factory.go
128 lines (98 loc) · 2.92 KB
/
factory.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
package cmd
import (
"bytes"
"errors"
"fmt"
"reflect"
"strings"
// Should only be imported here to avoid leaking use of goflags through project
goflags "github.com/jessevdk/go-flags"
)
type Factory struct {
deps BasicDeps
}
func NewFactory(deps BasicDeps) Factory {
return Factory{deps: deps}
}
func (f Factory) New(args []string) (Cmd, error) {
var cmdOpts interface{}
boshOpts := &BoshOpts{}
boshOpts.VersionOpt = func() error {
return &goflags.Error{
Type: goflags.ErrHelp,
Message: fmt.Sprintf("version %s\n", VersionLabel),
}
}
parser := goflags.NewParser(boshOpts, goflags.HelpFlag|goflags.PassDoubleDash)
for _, c := range parser.Commands() {
docsURL := "https://bosh.io/docs/cli-v2#" + c.Name
c.LongDescription = c.ShortDescription + "\n\n" + docsURL
fillerLen := 50 - len(c.ShortDescription)
if fillerLen < 0 {
fillerLen = 0
}
c.ShortDescription += strings.Repeat(" ", fillerLen+1) + docsURL
}
parser.CommandHandler = func(command goflags.Commander, extraArgs []string) error {
if opts, ok := command.(*SSHOpts); ok {
if len(opts.Command) == 0 {
opts.Command = extraArgs
extraArgs = []string{}
}
}
if opts, ok := command.(*AliasEnvOpts); ok {
opts.URL = boshOpts.EnvironmentOpt
opts.CACert = boshOpts.CACertOpt
}
if opts, ok := command.(*EventsOpts); ok {
opts.Deployment = boshOpts.DeploymentOpt
}
if opts, ok := command.(*VMsOpts); ok {
opts.Deployment = boshOpts.DeploymentOpt
}
if opts, ok := command.(*InstancesOpts); ok {
opts.Deployment = boshOpts.DeploymentOpt
}
if opts, ok := command.(*TasksOpts); ok {
opts.Deployment = boshOpts.DeploymentOpt
}
if opts, ok := command.(*TaskOpts); ok {
opts.Deployment = boshOpts.DeploymentOpt
}
if len(extraArgs) > 0 {
errMsg := "Command '%T' does not support extra arguments: %s"
return fmt.Errorf(errMsg, command, strings.Join(extraArgs, ", "))
}
cmdOpts = command
return nil
}
boshOpts.SSH.GatewayFlags.UUIDGen = f.deps.UUIDGen
boshOpts.SCP.GatewayFlags.UUIDGen = f.deps.UUIDGen
boshOpts.Logs.GatewayFlags.UUIDGen = f.deps.UUIDGen
goflags.FactoryFunc = func(val interface{}) {
stype := reflect.Indirect(reflect.ValueOf(val))
if stype.Kind() == reflect.Struct {
field := stype.FieldByName("FS")
if field.IsValid() {
field.Set(reflect.ValueOf(f.deps.FS))
}
}
}
helpText := bytes.NewBufferString("")
parser.WriteHelp(helpText)
_, err := parser.ParseArgs(args)
if boshOpts.UsernameOpt != "" {
return Cmd{}, errors.New("BOSH_USER is deprecated use BOSH_CLIENT instead")
}
// --help and --version result in errors; turn them into successful output cmds
if typedErr, ok := err.(*goflags.Error); ok {
if typedErr.Type == goflags.ErrHelp {
cmdOpts = &MessageOpts{Message: typedErr.Message}
err = nil
}
}
if _, ok := cmdOpts.(*HelpOpts); ok {
cmdOpts = &MessageOpts{Message: helpText.String()}
}
return NewCmd(*boshOpts, cmdOpts, f.deps), err
}