107 lines
2.3 KiB
Go
107 lines
2.3 KiB
Go
package cmds
|
|
|
|
import (
|
|
"os"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/indra-labs/indra/pkg/proc/opts/config"
|
|
"github.com/indra-labs/indra/pkg/util/path/path"
|
|
)
|
|
|
|
type Env struct {
|
|
Name path.Path
|
|
Opt config.Option
|
|
}
|
|
|
|
type Envs []Env
|
|
|
|
// ForEach runs a closure on each element of an Env item in an Envs and halts if
|
|
// one returns an error.
|
|
func (e Envs) ForEach(fn func(env string, opt config.Option) (err error)) (err error) {
|
|
for i := range e {
|
|
var name []string
|
|
for j := range e[i].Name {
|
|
name = append(name, strings.ToUpper(e[i].Name[j]))
|
|
}
|
|
err = fn(strings.Join(name, "_"), e[i].Opt)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// LoadFromEnvironment walks the Envs and reads the values found in the
|
|
// environment variables.
|
|
func (e Envs) LoadFromEnvironment() (err error) {
|
|
err = e.ForEach(func(env string, opt config.Option) (err error) {
|
|
v, exists := os.LookupEnv(env)
|
|
if exists {
|
|
err = opt.FromString(v)
|
|
if log.D.Chk(err) {
|
|
return err
|
|
}
|
|
}
|
|
return
|
|
})
|
|
return
|
|
}
|
|
|
|
// Len returns the number items in an Envs. This is a sort.Sorter interface
|
|
// implementation.
|
|
func (e Envs) Len() int { return len(e) }
|
|
|
|
// Less compares two items and returns whether the first is lesser than the
|
|
// second. This is a sort.Sorter interface implementation.
|
|
func (e Envs) Less(i, j int) (res bool) {
|
|
li, lj := len(e[i].Name), len(e[j].Name)
|
|
if li < lj {
|
|
return true
|
|
}
|
|
cursor := -1
|
|
for {
|
|
res = false
|
|
cursor++
|
|
if strings.Join(e[i].Name[:cursor], "_") <
|
|
strings.Join(e[j].Name[:cursor], "_") {
|
|
res = true
|
|
}
|
|
if cursor >= li || cursor >= lj {
|
|
break
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// Swap switches the position of two elements of an Envs. This is a sort.Sorter
|
|
// interface implementation.
|
|
func (e Envs) Swap(i, j int) { e[i], e[j] = e[j], e[i] }
|
|
|
|
// GetEnvs walks a Command tree and returns a slice containing all environment
|
|
// variable names and the related config.Option.
|
|
func (c *Command) GetEnvs(path ...string) (envs Envs) {
|
|
if path == nil {
|
|
path = []string{c.Name}
|
|
}
|
|
for {
|
|
for i := range c.Configs {
|
|
envs = append(envs, Env{
|
|
Name: append(path, i),
|
|
Opt: c.Configs[i],
|
|
})
|
|
}
|
|
if len(c.Commands) > 0 {
|
|
for i := range c.Commands {
|
|
envs = append(envs,
|
|
c.Commands[i].GetEnvs(
|
|
append(path, c.Commands[i].Name)...)...,
|
|
)
|
|
}
|
|
}
|
|
break
|
|
}
|
|
sort.Sort(envs)
|
|
return
|
|
}
|