This repository has been archived by the owner on Apr 27, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 21
/
staert.go
158 lines (144 loc) · 4.07 KB
/
staert.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
package staert
import (
"github.com/BurntSushi/toml"
"github.com/containous/flaeg"
"os"
"path/filepath"
"strings"
)
// Source interface must be satisfy to Add any kink of Source to Staert as like as TomlFile or Flaeg
type Source interface {
Parse(cmd *flaeg.Command) (*flaeg.Command, error)
}
// Staert contains the struct to configure, thee default values inside structs and the sources
type Staert struct {
command *flaeg.Command
sources []Source
}
// NewStaert creats and return a pointer on Staert. Need defaultConfig and defaultPointersConfig given by references
func NewStaert(rootCommand *flaeg.Command) *Staert {
s := Staert{
command: rootCommand,
}
return &s
}
// AddSource adds new Source to Staert, give it by reference
func (s *Staert) AddSource(src Source) {
s.sources = append(s.sources, src)
}
// getConfig for a flaeg.Command run sources Parse func in the raw
func (s *Staert) parseConfigAllSources(cmd *flaeg.Command) error {
for _, src := range s.sources {
var err error
_, err = src.Parse(cmd)
if err != nil {
return err
}
}
return nil
}
// LoadConfig check which command is called and parses config
// It returns the the parsed config or an error if it fails
func (s *Staert) LoadConfig() (interface{}, error) {
for _, src := range s.sources {
//Type assertion
f, ok := src.(*flaeg.Flaeg)
if ok {
if fCmd, err := f.GetCommand(); err != nil {
return nil, err
} else if s.command != fCmd {
//IF fleag sub-command
s.command, err = f.Parse(fCmd)
return s.command.Config, err
}
}
}
err := s.parseConfigAllSources(s.command)
return s.command.Config, err
}
// Run calls the Run func of the command
// Warning, Run doesn't parse the config
func (s *Staert) Run() error {
return s.command.Run()
}
//TomlSource impement Source
type TomlSource struct {
filename string
dirNfullpath []string
fullpath string
}
// NewTomlSource creats and return a pointer on TomlSource.
// Parameter filename is the file name (without extension type, ".toml" will be added)
// dirNfullpath may contain directories or fullpath to the file.
func NewTomlSource(filename string, dirNfullpath []string) *TomlSource {
return &TomlSource{filename, dirNfullpath, ""}
}
// ConfigFileUsed return config file used
func (ts *TomlSource) ConfigFileUsed() string {
return ts.fullpath
}
func preprocessDir(dirIn string) (string, error) {
dirOut := dirIn
if strings.HasPrefix(dirIn, "$") {
end := strings.Index(dirIn, string(os.PathSeparator))
if end == -1 {
end = len(dirIn)
}
dirOut = os.Getenv(dirIn[1:end]) + dirIn[end:]
}
dirOut, err := filepath.Abs(dirOut)
return dirOut, err
}
func findFile(filename string, dirNfile []string) string {
for _, df := range dirNfile {
if df != "" {
fullpath, _ := preprocessDir(df)
if fileinfo, err := os.Stat(fullpath); err == nil && !fileinfo.IsDir() {
return fullpath
}
fullpath = fullpath + "/" + filename + ".toml"
if fileinfo, err := os.Stat(fullpath); err == nil && !fileinfo.IsDir() {
return fullpath
}
}
}
return ""
}
// Parse calls Flaeg Load Function
func (ts *TomlSource) Parse(cmd *flaeg.Command) (*flaeg.Command, error) {
ts.fullpath = findFile(ts.filename, ts.dirNfullpath)
if len(ts.fullpath) < 2 {
return cmd, nil
}
metadata, err := toml.DecodeFile(ts.fullpath, cmd.Config)
if err != nil {
return nil, err
}
flaegArgs := []string{}
keys := metadata.Keys()
for i, key := range keys {
// fmt.Println(key)
if metadata.Type(key.String()) == "Hash" {
//Ptr case
// fmt.Printf("%s is a ptr\n", key)
hasUnderField := false
for j := i; j < len(keys); j++ {
// fmt.Printf("%s =? %s\n", keys[j].String(), "."+key.String())
if strings.Contains(keys[j].String(), key.String()+".") {
hasUnderField = true
break
}
}
if !hasUnderField {
flaegArgs = append(flaegArgs, "--"+strings.ToLower(key.String()))
}
}
}
// fmt.Println(flaegArgs)
err = flaeg.Load(cmd.Config, cmd.DefaultPointersConfig, flaegArgs)
//if err!= missing parser err
if err != nil && !strings.Contains(err.Error(), "No parser for type") {
return nil, err
}
return cmd, nil
}