81 lines
1.5 KiB
Go
81 lines
1.5 KiB
Go
package cmd
|
|
|
|
import (
|
|
"bytes"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/urfave/cli/v3"
|
|
"go.yaml.in/yaml/v3"
|
|
)
|
|
|
|
const (
|
|
FlagConfig = "config"
|
|
)
|
|
|
|
func ConfigFlags(defaultValue string) []cli.Flag {
|
|
return []cli.Flag{
|
|
&cli.StringFlag{
|
|
Name: FlagConfig,
|
|
Aliases: []string{"c"},
|
|
Usage: "Configuration file path",
|
|
Value: defaultValue,
|
|
},
|
|
}
|
|
}
|
|
|
|
type ConfigWithIncludes interface {
|
|
Includes() []string
|
|
}
|
|
|
|
func Load(logger *logrus.Logger, name string, config ConfigWithIncludes, parsed ...string) (err error) {
|
|
if !filepath.IsAbs(name) {
|
|
var abs string
|
|
if abs, err = filepath.Abs(name); err != nil {
|
|
return
|
|
}
|
|
logger.Tracef("config: canonicallize %s => %s", name, abs)
|
|
name = abs
|
|
}
|
|
|
|
logger.Tracef("config: parsed %s", parsed)
|
|
logger.Debugf("config: parse %s", name)
|
|
var data []byte
|
|
if data, err = os.ReadFile(name); err != nil {
|
|
return
|
|
}
|
|
|
|
decoder := yaml.NewDecoder(bytes.NewBuffer(data))
|
|
decoder.KnownFields(true)
|
|
if err = decoder.Decode(config); err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, include := range config.Includes() {
|
|
if contains(parsed, include) {
|
|
continue
|
|
}
|
|
if !filepath.IsAbs(include) {
|
|
abs := filepath.Clean(filepath.Join(filepath.Dir(name), include))
|
|
logger.Tracef("config: canonicallize %s => %s", include, abs)
|
|
include = abs
|
|
}
|
|
parsed = append(parsed, include)
|
|
if err = Load(logger, include, config, parsed...); err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func contains(ss []string, s string) bool {
|
|
for _, v := range ss {
|
|
if v == s {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|