-
Notifications
You must be signed in to change notification settings - Fork 0
/
commandargs.go
110 lines (88 loc) · 2.87 KB
/
commandargs.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
package webmgmt
import (
"bytes"
"errors"
"flag"
"fmt"
"io"
"strings"
"github.com/kballard/go-shellquote"
)
// CommandArgs is a struct that is used to store the contents of a parsed command line string.
type CommandArgs struct {
CmdLine string
CmdName string
Args []string
FlagSet *flag.FlagSet
output io.Writer
}
// String will return the CmdLine the original one that is parsed.
func (c *CommandArgs) String() string {
return c.CmdLine
}
// PealOff will return a command line string after N commands have been pealed off from the front of the command line.
func (c *CommandArgs) PealOff(pos int) string {
var buffer bytes.Buffer
for i := pos; i < len(c.Args); i++ {
if strings.Contains(c.Args[i], " ") || strings.Contains(c.Args[i], "\t") {
buffer.WriteString("\"")
buffer.WriteString(c.Args[i])
buffer.WriteString("\"")
} else {
buffer.WriteString(c.Args[i])
}
if i < len(c.Args) {
buffer.WriteString(" ")
}
}
return buffer.String()
}
// Debug will return a string listing the original command line and the parsed arguments and flags
func (c *CommandArgs) Debug() string {
var buffer bytes.Buffer
buffer.WriteString(fmt.Sprintf("CmdName: %v fullcmd: %v args: [%v]", c.CmdName, c.CmdLine, strings.Join(c.Args, ", ")))
buffer.WriteString(fmt.Sprintf("flagSet.NArg(): %v\n", c.FlagSet.NArg()))
for i, val := range c.FlagSet.Args() {
buffer.WriteString(fmt.Sprintf("flagSet.Args()[%d]: %v\n", i, val))
}
return buffer.String()
}
// Parse will use the defined FlagSet parsed and return an error if help is invoked or invalid flags
func (c *CommandArgs) Parse() error {
return c.FlagSet.Parse(c.Args)
}
// Shift will return a new CommandArgs after shifting the first cmd in the string
func (c *CommandArgs) Shift() (*CommandArgs, error) {
if strings.HasPrefix(c.CmdLine, c.CmdName) {
newCmdLine := c.CmdLine[len(c.CmdName):]
return NewCommandArgs(newCmdLine, c.output)
}
return nil, errors.New("Unable to shift command line. ")
}
// NewCommandArgs will take a raw string and output. The Raw string will be parsed into a CommandArgs structure.
// If an error is encountered such as empty command string it will be returned and the CommandArgs will be nil.
func NewCommandArgs(cmdLine string, output io.Writer) (*CommandArgs, error) {
if cmdLine == "" {
return nil, errors.New("empty command string")
}
words, err := shellquote.Split(cmdLine)
if err != nil {
return nil, err
} else if len(words) == 0 {
return nil, errors.New("no words parsed")
} else {
invoke := &CommandArgs{}
invoke.CmdLine = cmdLine
invoke.CmdName = words[0]
invoke.Args = words[1:]
invoke.output = output
invoke.FlagSet = flag.NewFlagSet(invoke.CmdName, flag.ContinueOnError)
if output != nil {
invoke.FlagSet.SetOutput(output)
}
return invoke, nil
}
// topic Hello World Stinky
// topic "Hello World" Stinky
// group 156 topic Hello World Stinky
}