Files
indra/pkg/proc/cmds/env.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
}