-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.go
More file actions
143 lines (130 loc) · 4.66 KB
/
Copy pathconfig.go
File metadata and controls
143 lines (130 loc) · 4.66 KB
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
package main
import (
"fmt"
"os"
"strings"
"github.com/golang/glog"
flag "github.com/spf13/pflag"
)
type config struct {
flagSet *flag.FlagSet
server *string
account *string
repository *string
directory *string
username *string
password *string
email *string
version *bool
initialize *bool
initonly *bool
frequency *int
direction *string
}
func newConfig() *config {
return &config{
server: flag.String("server", GitDefaultServer, "git repository host"),
account: flag.String("account", GitDefaultAccount, "git account/owner/organization for repository to clone"),
repository: flag.String("repository", GitDefaultRepo, "git repository to manage for archiving local updates"),
directory: flag.String("directory", "", "Required: The name of a new / existing repository directory to clone into / work in"),
username: flag.String("username", GitDefaultUser, "git remote login username"),
password: flag.String("password", "", "Required: git remote login password"),
email: flag.String("email", GitDefaultEmail, "Required: git user's email address"),
version: flag.Bool("version", false, "display version info and exit"),
initialize: flag.Bool("initial-clone", true, "initialize the state of the repository by cloning the remote"),
initonly: flag.Bool("init-only", false, "initialize the state of the repository only, then exit"),
frequency: flag.Int("sync-interval", 60, "number of seconds between upstream sync's when changes are present"),
direction: flag.String("sync-to", "remote", "must be one of `remote`, `local`, `both`. Sync changes to/from: `remote` push local commits to remote, `local` pull remote changes to local, `both` manage bi-directional updates."),
}
}
func (cfg *config) String() string {
return fmt.Sprintf("server: %s, account: %s, repository: %s, directory: %s, "+
"username: %s, password: %s, email: %s, frequency: %d, initialize: %t, "+
"initonly: %t, sync-to: %s, version: %t",
*cfg.server, *cfg.account, *cfg.repository, *cfg.directory,
*cfg.username, *cfg.password, *cfg.email, *cfg.frequency, *cfg.initialize,
*cfg.initonly, *cfg.direction, *cfg.version)
}
var envSupport = map[string]bool{
"server": true,
"account": true,
"repository": true,
"directory": true,
"username": true,
"password": true,
"email": true,
"version": false,
"initialize": true,
"initonly": true,
"frequency": true,
"direction": true,
}
func variableName(name string) string {
return "GA_" + strings.ToUpper(strings.Replace(name, "-", "_", -1))
}
// Just like Flags.Parse() except we try to get recognized values for the valid
// set of flags from environment variables. We choose to use the environment
// value if 1) the value hasen't already been set as command line flags and the
// flas is a member of the supported set (see map defined above).
func (cfg *config) envParse() error {
var err error
alreadySet := make(map[string]bool)
cfg.flagSet.Visit(func(f *flag.Flag) {
if envSupport[f.Name] {
alreadySet[variableName(f.Name)] = true
}
})
usedEnvKey := make(map[string]bool)
cfg.flagSet.VisitAll(func(f *flag.Flag) {
if envSupport[f.Name] {
key := variableName(f.Name)
if !alreadySet[key] {
val := os.Getenv(key)
if val != "" {
usedEnvKey[key] = true
if serr := cfg.flagSet.Set(f.Name, val); serr != nil {
err = fmt.Errorf("invalid value %q for %s: %v", val, key, serr)
}
glog.V(3).Infof("recognized and used environment variable %s=%s", key, val)
}
}
}
})
for _, env := range os.Environ() {
kv := strings.SplitN(env, "=", 2)
if len(kv) != 2 {
glog.Warningf("found invalid env %s", env)
}
if usedEnvKey[kv[0]] {
continue
}
if alreadySet[kv[0]] {
glog.V(3).Infof("recognized environment variable %s, but unused: superseeded by command line flag ", kv[0])
continue
}
if strings.HasPrefix(env, "GA_") {
glog.Warningf("unrecognized environment variable %s", env)
}
}
return err
}
func (cfg *config) validate() bool {
if *cfg.directory == "" {
glog.Error("Configuration flag: `--directory` can not be empty, a valid value is required.")
return false
}
if *cfg.password == "" {
glog.Error("Configuration flag: `--password` can not be empty, a valid value is required.")
return false
}
if *cfg.initialize == false && *cfg.initonly == true {
glog.Error("Configuration flags: `--initialize=false` and `--init-only=true` conflict.")
return false
}
if *cfg.direction == "" ||
(*cfg.direction != "remote" && *cfg.direction != "local" && *cfg.direction != "both") {
glog.Error("Configuration flag: `--direction` must be one of: `remote`, `local`, or `both`")
return false
}
return true
}