-
Notifications
You must be signed in to change notification settings - Fork 1
/
RunSettings.go
165 lines (132 loc) · 4.1 KB
/
RunSettings.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package main
import (
"errors"
"flag"
"fmt"
"path/filepath"
"time"
"strings"
)
/*
Represents arguments given by the user to this program.
*/
type RunSettings struct {
parameters map[string][]string
skeletonPath string
targetPath string
basicAuthUser string
basicAuthPass string
inspectionRun bool
addRegistry bool
showRegistry bool
forceGenerate GenerateMode
blankParameters bool
flagList bool
}
type GenerateMode uint8
const (
GENERATE_NONE GenerateMode = iota
GENERATE_OVERWRITE
GENERATE_DELETE
)
var FLAGS = []string{
"-p",
"-i",
"-a",
"-l",
"-f",
"-w",
"-b",
"-bu",
"-bp",
"-flags",
}
/*
Parses runtime flags and positional arguments, returning the result.
*/
func FindRunSettings() (RunSettings, error) {
var ret RunSettings
var parameterGroup string
var forceGenerate, forceDelete bool
var err error
flag.StringVar(¶meterGroup, "p", "", "Semicolon-separated list of parameters in k=v form.")
flag.StringVar(&ret.basicAuthUser, "bu", "", "The 'user' to use when a remote archive requests Basic Authentication")
flag.StringVar(&ret.basicAuthPass, "bp", "", "The 'password' to use when a remote archive requests Basic Authentication")
flag.BoolVar(&ret.inspectionRun, "i", false, "Whether or not to show a list of available parameters for the skeleton")
flag.BoolVar(&ret.addRegistry, "a", false, "Whether or not to register the template at the given path (can be http/https URLs)")
flag.BoolVar(&ret.showRegistry, "l", false, "Whether or not to show a list of all available registered templates")
flag.BoolVar(&forceGenerate, "f", false, "Whether or not to overwrite existing files during generation")
flag.BoolVar(&forceDelete, "d", false, "Whether or not to delete every existing file in the output path first (only valid when -f is specified)")
flag.BoolVar(&ret.blankParameters, "b", false, "Whether or not to replace unspecified parameters with blank strings")
flag.BoolVar(&ret.flagList, "flags", false, "Whether or not to list the flags")
flag.Parse()
ret.skeletonPath = flag.Arg(0)
ret.targetPath = flag.Arg(1)
if(ret.flagList || ret.showRegistry) {
return ret, nil
}
// if we're not just showing the registry, and not skeleton path is specified...
if ret.skeletonPath == "" {
errorMsg := fmt.Sprintf("Skeleton project path not specified")
return ret, errors.New(errorMsg)
}
// if we're actually generating a project, and no target path is specified...
if !ret.inspectionRun &&
!ret.addRegistry &&
ret.targetPath == "" {
errorMsg := fmt.Sprintf("Target output path not specified")
return ret, errors.New(errorMsg)
}
// set up overwrite strategy
if(forceGenerate) {
if(forceDelete) {
ret.forceGenerate = GENERATE_DELETE
} else {
ret.forceGenerate = GENERATE_OVERWRITE
}
} else {
ret.forceGenerate = GENERATE_NONE
}
// make parameters, set default project.name
ret.parameters = make(map[string][]string)
ret.parameters["project.name"] = []string{filepath.Base(ret.targetPath)}
ret.parameters["project.createdDate"] = []string{time.Now().Format("2006-01-02")}
err = parseParametersTo(parameterGroup, ret.parameters)
if err != nil {
return ret, err
}
return ret, nil
}
/*
Given a sequence of k=v strings, this parses them out into a map.
*/
func parseParametersTo(parameterGroup string, destination map[string][]string) error {
var groups, pair, values []string
var key, value string
parameterGroup = strings.Trim(parameterGroup, " ")
if len(parameterGroup) == 0 {
return nil
}
groups = strings.Split(parameterGroup, ";")
if len(groups) == 0 {
groups = []string{
parameterGroup,
}
}
for _, group := range groups {
pair = strings.Split(group, "=")
if len(pair) != 2 {
errorMsg := fmt.Sprintf("Unable to parse parameters, expected exactly one '=' per semicolon-separated set")
return errors.New(errorMsg)
}
key = strings.Trim(pair[0], " ")
value = strings.Trim(pair[1], " ")
values = strings.Split(value, ",")
if len(values) <= 0 {
errorMsg := fmt.Sprintf("Unable to parse parameters, parameter '%s', value was empty\n", key)
return errors.New(errorMsg)
}
destination[key] = values
}
return nil
}