122 lines
2.5 KiB
Go
122 lines
2.5 KiB
Go
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||
|
|
||
|
package config
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"io"
|
||
|
"net/url"
|
||
|
"decl/internal/codec"
|
||
|
"decl/internal/command"
|
||
|
"encoding/json"
|
||
|
"gopkg.in/yaml.v3"
|
||
|
)
|
||
|
|
||
|
func init() {
|
||
|
ConfigTypes.Register([]string{"exec"}, func(u *url.URL) Configuration {
|
||
|
x := NewExec()
|
||
|
return x
|
||
|
})
|
||
|
}
|
||
|
|
||
|
type Exec struct {
|
||
|
Path string `yaml:"path" json:"path"`
|
||
|
Args []command.CommandArg `yaml:"args" json:"args"`
|
||
|
ValuesFormat codec.Format `yaml:"format" json:"format"`
|
||
|
Values map[string]any `yaml:"values" json:"values"`
|
||
|
ReadCommand *command.Command `yaml:"-" json:"-"`
|
||
|
}
|
||
|
|
||
|
func NewExec() *Exec {
|
||
|
x := &Exec{}
|
||
|
return x
|
||
|
}
|
||
|
|
||
|
func (x *Exec) Read(ctx context.Context) ([]byte, error) {
|
||
|
out, err := x.ReadCommand.Execute(x)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
exErr := x.ReadCommand.Extractor(out, x)
|
||
|
if exErr != nil {
|
||
|
return nil, exErr
|
||
|
}
|
||
|
return nil, exErr
|
||
|
}
|
||
|
|
||
|
func (x *Exec) Load(r io.Reader) (err error) {
|
||
|
err = codec.NewYAMLDecoder(r).Decode(x)
|
||
|
if err == nil {
|
||
|
_, err = x.Read(context.Background())
|
||
|
}
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
func (x *Exec) LoadYAML(yamlData string) (err error) {
|
||
|
err = codec.NewYAMLStringDecoder(yamlData).Decode(x)
|
||
|
if err == nil {
|
||
|
_, err = x.Read(context.Background())
|
||
|
}
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
func (x *Exec) UnmarshalJSON(data []byte) error {
|
||
|
if unmarshalErr := json.Unmarshal(data, x); unmarshalErr != nil {
|
||
|
return unmarshalErr
|
||
|
}
|
||
|
x.NewReadConfigCommand()
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (x *Exec) UnmarshalYAML(value *yaml.Node) error {
|
||
|
type decodeExec Exec
|
||
|
if unmarshalErr := value.Decode((*decodeExec)(x)); unmarshalErr != nil {
|
||
|
return unmarshalErr
|
||
|
}
|
||
|
x.NewReadConfigCommand()
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
|
||
|
func (x *Exec) Clone() Configuration {
|
||
|
clone := NewExec()
|
||
|
clone.Path = x.Path
|
||
|
clone.Args = x.Args
|
||
|
clone.ValuesFormat = x.ValuesFormat
|
||
|
clone.Values = x.Values
|
||
|
clone.ReadCommand = x.ReadCommand
|
||
|
return clone
|
||
|
}
|
||
|
|
||
|
func (x *Exec) Type() string {
|
||
|
return "exec"
|
||
|
}
|
||
|
|
||
|
func (x *Exec) GetValue(name string) (result any, err error) {
|
||
|
var ok bool
|
||
|
if result, ok = x.Values[name]; !ok {
|
||
|
err = ErrUnknownConfigurationKey
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
|
||
|
func (ex *Exec) NewReadConfigCommand() {
|
||
|
ex.ReadCommand = command.NewCommand()
|
||
|
ex.ReadCommand.Path = ex.Path
|
||
|
ex.ReadCommand.Args = ex.Args
|
||
|
|
||
|
ex.ReadCommand.Extractor = func(out []byte, target any) error {
|
||
|
x := target.(*Exec)
|
||
|
switch x.ValuesFormat {
|
||
|
case codec.FormatYaml:
|
||
|
return codec.NewYAMLStringDecoder(string(out)).Decode(&x.Values)
|
||
|
case codec.FormatJson:
|
||
|
return codec.NewJSONStringDecoder(string(out)).Decode(&x.Values)
|
||
|
case codec.FormatProtoBuf:
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
|