This repository has been archived by the owner on Oct 14, 2022. It is now read-only.
forked from sorenisanerd/gotty
/
flags.go
129 lines (114 loc) · 2.68 KB
/
flags.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
package utils
import (
"io/ioutil"
"log"
"os"
"reflect"
"strings"
"github.com/fatih/structs"
"github.com/urfave/cli/v2"
"github.com/yudai/hcl"
"github.com/sorenisanerd/gotty/pkg/homedir"
)
func GenerateFlags(options ...interface{}) (flags []cli.Flag, mappings map[string]string, err error) {
mappings = make(map[string]string)
for _, struct_ := range options {
o := structs.New(struct_)
for _, field := range o.Fields() {
flagName := field.Tag("flagName")
if flagName == "" {
continue
}
envName := "GOTTY_" + strings.ToUpper(strings.Join(strings.Split(flagName, "-"), "_"))
mappings[flagName] = field.Name()
flagShortName := field.Tag("flagSName")
var aliases []string
if flagShortName != "" {
aliases = []string{flagShortName}
}
flagDescription := field.Tag("flagDescribe")
switch field.Kind() {
case reflect.String:
flags = append(flags, &cli.StringFlag{
Name: flagName,
Value: field.Value().(string),
Usage: flagDescription,
EnvVars: []string{envName},
Aliases: aliases,
})
case reflect.Bool:
flags = append(flags, &cli.BoolFlag{
Name: flagName,
Usage: flagDescription,
EnvVars: []string{envName},
Aliases: aliases,
DefaultText: field.Tag("default"),
})
case reflect.Int:
flags = append(flags, &cli.IntFlag{
Name: flagName,
Value: field.Value().(int),
Usage: flagDescription,
EnvVars: []string{envName},
Aliases: aliases,
})
}
}
}
return
}
func ApplyFlags(
flags []cli.Flag,
mappingHint map[string]string,
c *cli.Context,
options ...interface{},
) {
objects := make([]*structs.Struct, len(options))
for i, struct_ := range options {
objects[i] = structs.New(struct_)
}
for flagName, fieldName := range mappingHint {
if !c.IsSet(flagName) {
continue
}
var field *structs.Field
var ok bool
for _, o := range objects {
field, ok = o.FieldOk(fieldName)
if ok {
break
}
}
if field == nil {
continue
}
var val interface{}
switch field.Kind() {
case reflect.String:
val = c.String(flagName)
case reflect.Bool:
val = c.Bool(flagName)
case reflect.Int:
val = c.Int(flagName)
}
field.Set(val)
}
}
func ApplyConfigFile(filePath string, options ...interface{}) error {
filePath = homedir.Expand(filePath)
if _, err := os.Stat(filePath); os.IsNotExist(err) {
return err
}
fileString := []byte{}
log.Printf("Loading config file at: %s", filePath)
fileString, err := ioutil.ReadFile(filePath)
if err != nil {
return err
}
for _, object := range options {
if err := hcl.Decode(object, string(fileString)); err != nil {
return err
}
}
return nil
}