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{}