github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/pkg/dos/env.go (about) 1 package dos 2 3 import ( 4 "context" 5 "os" 6 "sort" 7 "strings" 8 ) 9 10 // Env is an abstraction of the environment related functions with the same name in the os package. 11 type Env interface { 12 Environ() []string 13 ExpandEnv(string) string 14 Getenv(string) string 15 Setenv(string, string) error 16 Lookup(string) (string, bool) 17 } 18 19 type MapEnv map[string]string 20 21 // FromEnvPairs converts a slice of strings int the form KEY=VALUE into 22 // a map[string]string. 23 func FromEnvPairs(env []string) MapEnv { 24 m := make(MapEnv, len(env)) 25 m.MergeEnvPairs(env) 26 return m 27 } 28 29 // MergeEnvPairs merges env entries in the form of KEY=VALUE into the 30 // given map, giving the env entries higher priority. 31 func (e MapEnv) MergeEnvPairs(env []string) { 32 for _, ep := range env { 33 if ix := strings.IndexByte(ep, '='); ix > 0 { 34 e[ep[:ix]] = ep[ix+1:] 35 } 36 } 37 } 38 39 func (e MapEnv) Environ() []string { 40 ks := make([]string, len(e)) 41 i := 0 42 for k := range e { 43 ks[i] = k 44 i++ 45 } 46 sort.Strings(ks) 47 for i, k := range ks { 48 ks[i] = k + "=" + e[k] 49 } 50 return ks 51 } 52 53 func (e MapEnv) ExpandEnv(s string) string { 54 return os.Expand(s, e.Getenv) 55 } 56 57 func (e MapEnv) Getenv(key string) string { 58 return e[key] 59 } 60 61 func (e MapEnv) Setenv(key, value string) error { 62 e[key] = value 63 return nil 64 } 65 66 func (e MapEnv) Lookup(key string) (string, bool) { 67 s, ok := e[key] 68 return s, ok 69 } 70 71 type envKey struct{} 72 73 func WithEnv(ctx context.Context, env Env) context.Context { 74 return context.WithValue(ctx, envKey{}, env) 75 } 76 77 // EnvAPI returns the Env that has been registered with the given context, or 78 // the instance that delegates to the env functions in the os package. 79 func EnvAPI(ctx context.Context) Env { 80 if e, ok := ctx.Value(envKey{}).(Env); ok { 81 return e 82 } 83 return osEnv{} 84 } 85 86 func Environ(ctx context.Context) []string { 87 return EnvAPI(ctx).Environ() 88 } 89 90 func ExpandEnv(ctx context.Context, s string) string { 91 return EnvAPI(ctx).ExpandEnv(s) 92 } 93 94 func Getenv(ctx context.Context, key string) string { 95 return EnvAPI(ctx).Getenv(key) 96 } 97 98 func Setenv(ctx context.Context, key, value string) error { 99 return EnvAPI(ctx).Setenv(key, value) 100 } 101 102 func LookupEnv(ctx context.Context, key string) (string, bool) { 103 return EnvAPI(ctx).Lookup(key) 104 } 105 106 type osEnv struct{} 107 108 func (osEnv) Environ() []string { 109 return os.Environ() 110 } 111 112 func (osEnv) ExpandEnv(s string) string { 113 return os.ExpandEnv(s) 114 } 115 116 func (osEnv) Getenv(s string) string { 117 return os.Getenv(s) 118 } 119 120 func (osEnv) Setenv(key, value string) error { 121 return os.Setenv(key, value) 122 } 123 124 func (osEnv) Lookup(s string) (string, bool) { 125 return os.LookupEnv(s) 126 }