-
Notifications
You must be signed in to change notification settings - Fork 13
/
configuration.go
126 lines (100 loc) · 3.23 KB
/
configuration.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
package config
import (
"fmt"
"os"
"reflect"
"strconv"
"strings"
"unicode"
"flag"
"github.com/ProxeusApp/proxeus-core/sys/model"
)
const ProxeusEnvPrefix = "PROXEUS_"
// This configuration can be used in two ways:
// 1. Using the default meta in a struct
// 2. Using the specified arguments in flag
type Configuration struct {
SettingsFile string `json:"settingsFile" default:"~/.proxeus/settings/main.json" usage:"Path to the settings file"`
EthClientURL string `json:"ethClientURL" default:"https://sepolia.infura.io/v3/" usage:"Ethereum client URL"`
EthWebSocketURL string `json:"ethWebSocketURL" default:"wss://sepolia.infura.io/ws/v3/" usage:"Ethereum websocket URL"`
ServiceAddress string `json:"serviceAddress" default:":1323" usage:"address and port of this service"`
AutoTLS bool `json:"autoTLS" default:"false" usage:"Automatically generate Let's Encrypt certificate (Server must be reachable on port 443 from public internet)."`
XESContractAddress string `json:"XESContractAddress" default:"0x15FeA089CC48B4f4596242c138156e3B53579B37"`
AirdropWalletfile string `json:"airdropWalletfile" usage:"Path to File containing Private Key of the Wallet to fund Airdrops of XES and Ether."`
AirdropWalletkey string `json:"airdropWalletkey" usage:"Path to File containing the Key for the Airdrop Private Key."`
model.Settings // extend cmd line args with settings
}
var Config *Configuration
func Init() {
if Config != nil {
return
}
Config = New()
}
func New() *Configuration {
var c Configuration
flagFromStruct(flag.CommandLine, os.Environ(), &c)
flag.Parse()
return &c
}
func flagFromStruct(fs *flag.FlagSet, env []string, strct interface{}) {
v := reflect.ValueOf(strct)
if v.Kind() != reflect.Ptr {
return
}
v = v.Elem()
if v.Kind() != reflect.Struct {
return
}
t := v.Type()
em := envMap(env)
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
fname := f.Name
if f.Type.Kind() == reflect.Bool {
d, u := defaultAndUsage(f, fname, em)
bv, _ := strconv.ParseBool(d)
fs.BoolVar(v.Field(i).Addr().Interface().(*bool), fname, bv, u)
} else if f.Type.Kind() == reflect.String {
d, u := defaultAndUsage(f, fname, em)
fs.StringVar(v.Field(i).Addr().Interface().(*string), fname, d, u)
} else if f.Type.Kind() == reflect.Struct {
flagFromStruct(fs, env, v.Field(i).Addr().Interface())
}
}
}
func envMap(env []string) map[string]string {
m := map[string]string{}
for _, e := range env {
kv := strings.Split(e, "=")
m[kv[0]] = kv[1]
}
return m
}
func defaultAndUsage(f reflect.StructField, fname string, envMap map[string]string) (string, string) {
envName := fieldToEnv(fname)
if envValue := envMap[envName]; envValue != "" {
return envValue, fmt.Sprintf("%s (%s=%s)", f.Tag.Get("usage"), envName, envValue)
} else {
return f.Tag.Get("default"), fmt.Sprintf("%s (%s)", f.Tag.Get("usage"), envName)
}
}
func fieldToEnv(f string) string {
var e strings.Builder
e.WriteString(ProxeusEnvPrefix)
previous := '_'
for _, c := range f {
if c == '-' {
c = '_'
}
if previous == '_' && c == '_' {
continue
}
if previous != '_' && !unicode.IsUpper(previous) && unicode.IsUpper(c) {
e.WriteByte('_')
}
e.WriteRune(unicode.ToUpper(c))
previous = c
}
return e.String()
}