forked from koblas/s3-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.go
More file actions
124 lines (102 loc) · 3.16 KB
/
config.go
File metadata and controls
124 lines (102 loc) · 3.16 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
package main
import (
// "fmt"
"strings"
"reflect"
"github.com/go-ini/ini"
"github.com/urfave/cli"
"path"
)
// This is the global configuration, it's loaded from .s3cfg (by default) then with added
// overrides from the command line
//
// Command lines are by default the snake case version of the the struct names with "-" instead of "_"
//
type Config struct {
AccessKey string `ini:"access_key"`
SecretKey string `ini:"secret_key"`
CheckMD5 bool `ini:"check_md5" cli:"check-md5"`
DryRun bool `ini:"dry_run"`
Verbose bool `ini:"verbose"`
Recursive bool `ini:"recursive"`
Force bool `ini:"force"`
SkipExisting bool `ini:"skip_existing"`
}
// Read the configuration file if found, otherwise return default configuration
// Precedence order (most important to least):
// - Command Line options
// - Environment Variables
// - Config File
// - Default Values
func NewConfig(c *cli.Context) *Config {
cfgPath := "/.s3cfg"
if c.GlobalIsSet("config") {
cfgPath = c.GlobalString("config")
} else if c.IsSet("config") {
cfgPath = c.String("config")
} else {
if value := GetEnv("HOME"); value != nil {
cfgPath = path.Join(*value, ".s3cfg")
}
}
config := loadConfigFile(cfgPath)
parseOptions(config, c)
if c.GlobalIsSet("no-check-md5") || c.IsSet("no-check-md5") {
config.CheckMD5 = false
}
return config
}
// Load the config file if possible, but if there is an error return the default configuration file
func loadConfigFile(path string) *Config {
config := Config{CheckMD5: false}
// fmt.Println("Read config ", path)
if err := ini.MapTo(config, path); err != nil {
return &config
}
return &config
}
// Pull the options out of the cli.Context and save them into the configuration object
func parseOptions(config *Config, c *cli.Context) {
rt := reflect.TypeOf(*config)
rv := reflect.ValueOf(config)
for i := 0; i < rt.NumField(); i++ {
field := rt.Field(i)
name := ""
if field.Tag.Get("cli") != "" {
name = field.Tag.Get("cli")
} else {
name = strings.Replace(CamelToSnake(field.Name), "_", "-", -1)
}
gset := c.GlobalIsSet(name)
lset := c.IsSet(name)
// fmt.Println(name, gset, lset, c.String(name))
// FIXME: This isn't great, "IsSet()" isn't triggered for environment variables
if !gset && !lset && c.String(name) == "" {
continue
}
f := rv.Elem().FieldByName(field.Name)
if !f.IsValid() || !f.CanSet() {
continue
}
switch f.Kind() {
case reflect.Bool:
if lset {
f.SetBool(c.Bool(name))
} else {
f.SetBool(c.GlobalBool(name))
}
case reflect.String:
if lset {
f.SetString(c.String(name))
} else {
f.SetString(c.GlobalString(name))
}
case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64:
if lset {
f.SetInt(c.Int64(name))
} else {
f.SetInt(c.GlobalInt64(name))
}
}
}
}