64 lines
1.7 KiB
Go
64 lines
1.7 KiB
Go
package view
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
// Env represent K9s and K8s available environment variables.
|
|
type Env map[string]string
|
|
|
|
// EnvRX match $XXX, $!XXX, ${XXX} or ${!XXX} custom arg.
|
|
// |
|
|
// | (g2)(group 3) (g5)( group 6 )
|
|
// | ( group 1 ) ( group 4 )
|
|
// | ( group 0 )
|
|
var envRX = regexp.MustCompile(`(\$(!?)([\w\-]+))|(\$\{(!?)([\w\-%/: ]+)})`)
|
|
|
|
// keyFromSubmatch extracts the name and inverse flag of a match.
|
|
func keyFromSubmatch(m []string) (key string, inverse bool) {
|
|
// group 1 matches $XXX and $!XXX args.
|
|
if m[1] != "" {
|
|
return m[3], m[2] == "!"
|
|
}
|
|
// group 4 matches ${XXX} and ${!XXX} args.
|
|
return m[6], m[5] == "!"
|
|
}
|
|
|
|
// Substitute replaces env variable keys from in a string with their corresponding values.
|
|
func (e Env) Substitute(arg string) (string, error) {
|
|
matches := envRX.FindAllStringSubmatch(arg, -1)
|
|
if len(matches) == 0 {
|
|
return arg, nil
|
|
}
|
|
|
|
// To prevent the substitution starts with the shorter environment variable,
|
|
// sort with the length of the found environment variables.
|
|
sort.Slice(matches, func(i, j int) bool {
|
|
return len(matches[i][0]) > len(matches[j][0])
|
|
})
|
|
|
|
for _, m := range matches {
|
|
key, inverse := keyFromSubmatch(m)
|
|
v, ok := e[strings.ToUpper(key)]
|
|
if !ok {
|
|
log.Warn().Msgf("no k9s environment matching key %q:%q", m[0], key)
|
|
continue
|
|
}
|
|
if b, err := strconv.ParseBool(v); err == nil {
|
|
if inverse {
|
|
b = !b
|
|
}
|
|
v = fmt.Sprintf("%t", b)
|
|
}
|
|
arg = strings.Replace(arg, m[0], v, -1)
|
|
}
|
|
|
|
return arg, nil
|
|
}
|