2024-07-01 21:54:18 +00:00
|
|
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
|
|
|
|
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"io"
|
2024-09-24 19:15:47 +00:00
|
|
|
"fmt"
|
2024-07-01 21:54:18 +00:00
|
|
|
"net/url"
|
|
|
|
"decl/internal/codec"
|
|
|
|
"decl/internal/command"
|
2024-09-24 19:15:47 +00:00
|
|
|
"decl/internal/data"
|
|
|
|
"decl/internal/folio"
|
2024-07-01 21:54:18 +00:00
|
|
|
"encoding/json"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
2024-09-24 19:15:47 +00:00
|
|
|
folio.DocumentRegistry.ConfigurationTypes.Register([]string{"exec"}, func(u *url.URL) data.Configuration {
|
2024-07-01 21:54:18 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2024-09-24 19:15:47 +00:00
|
|
|
func (x *Exec) SetURI(uri string) error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-10-16 17:26:42 +00:00
|
|
|
func (x *Exec) SetParsedURI(uri data.URIParser) error {
|
2024-09-24 19:15:47 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (x *Exec) URI() string {
|
|
|
|
return fmt.Sprintf("%s://%s", x.Type(), x.Path)
|
|
|
|
}
|
|
|
|
|
2024-07-01 21:54:18 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-09-24 19:15:47 +00:00
|
|
|
func (x *Exec) Clone() data.Configuration {
|
2024-07-01 21:54:18 +00:00
|
|
|
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 {
|
2024-09-24 19:15:47 +00:00
|
|
|
err = data.ErrUnknownConfigurationKey
|
2024-07-01 21:54:18 +00:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-09-24 19:15:47 +00:00
|
|
|
func (x *Exec) Has(key string) (ok bool) {
|
|
|
|
_, ok = x.Values[key]
|
|
|
|
return
|
|
|
|
}
|
2024-07-01 21:54:18 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|