github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/tiltfile/os/environ.go (about) 1 package os 2 3 import ( 4 "fmt" 5 "os" 6 "strings" 7 8 "go.starlark.net/starlark" 9 "go.starlark.net/syntax" 10 11 "github.com/tilt-dev/tilt/internal/tiltfile/value" 12 ) 13 14 // Exposes os.Environ as a Starlark dictionary. 15 type Environ struct { 16 } 17 18 func (Environ) Clear() error { 19 os.Clearenv() 20 return nil 21 } 22 23 func (Environ) Delete(k starlark.Value) (v starlark.Value, found bool, err error) { 24 str, ok := value.AsString(k) 25 if !ok { 26 return starlark.None, false, nil 27 } 28 29 val, found := os.LookupEnv(str) 30 if !found { 31 return starlark.None, false, nil 32 } 33 34 os.Unsetenv(str) 35 36 return starlark.String(val), true, nil 37 } 38 39 func (Environ) Get(k starlark.Value) (v starlark.Value, found bool, err error) { 40 str, ok := value.AsString(k) 41 if !ok { 42 return starlark.None, false, nil 43 } 44 45 val, found := os.LookupEnv(str) 46 return starlark.String(val), found, nil 47 } 48 49 func environAsDict() *starlark.Dict { 50 env := os.Environ() 51 result := starlark.NewDict(len(env)) 52 for _, e := range env { 53 pair := strings.SplitN(e, "=", 2) 54 _ = result.SetKey(starlark.String(pair[0]), starlark.String(pair[1])) 55 } 56 return result 57 } 58 59 func (Environ) Items() []starlark.Tuple { return environAsDict().Items() } 60 func (Environ) Keys() []starlark.Value { return environAsDict().Keys() } 61 func (Environ) Len() int { return len(os.Environ()) } 62 func (Environ) Iterate() starlark.Iterator { return environAsDict().Iterate() } 63 64 func (Environ) SetKey(k, v starlark.Value) error { 65 kStr, ok := value.AsString(k) 66 if !ok { 67 return fmt.Errorf("putenv() key must be a string, not %s", k.Type()) 68 } 69 vStr, ok := value.AsString(v) 70 if !ok { 71 return fmt.Errorf("putenv() value must be a string, not %s", v.Type()) 72 } 73 74 os.Setenv(kStr, vStr) 75 return nil 76 } 77 78 func (Environ) String() string { return environAsDict().String() } 79 func (Environ) Type() string { return "environ" } 80 func (Environ) Freeze() {} 81 func (Environ) Truth() starlark.Bool { return len(os.Environ()) > 0 } 82 func (Environ) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable type: environ") } 83 84 func (e Environ) Attr(name string) (starlark.Value, error) { 85 return builtinAttr(e, name, environMethods) 86 } 87 func (Environ) AttrNames() []string { return builtinAttrNames(environMethods) } 88 func (Environ) CompareSameType(op syntax.Token, y_ starlark.Value, depth int) (bool, error) { 89 return environAsDict().CompareSameType(op, y_, depth) 90 } 91 92 var _ starlark.HasSetKey = Environ{} 93 var _ starlark.IterableMapping = Environ{} 94 var _ starlark.Sequence = Environ{} 95 var _ starlark.Comparable = Environ{}