1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package os
16
17 import (
18 "os"
19 "strings"
20
21 "cuelang.org/go/cue"
22 "cuelang.org/go/cue/ast"
23 "cuelang.org/go/cue/errors"
24 "cuelang.org/go/internal/cli"
25 "cuelang.org/go/internal/task"
26 )
27
28 func init() {
29 task.Register("tool/os.Getenv", newGetenvCmd)
30 task.Register("tool/os.Environ", newEnvironCmd)
31
32
33
34
35
36
37
38
39
40 }
41
42 type getenvCmd struct{}
43
44 func newGetenvCmd(v cue.Value) (task.Runner, error) {
45 return &getenvCmd{}, nil
46 }
47
48 func (c *getenvCmd) Run(ctx *task.Context) (res interface{}, err error) {
49 iter, err := ctx.Obj.Fields()
50 if err != nil {
51 return nil, err
52 }
53
54 update := map[string]interface{}{}
55
56 for iter.Next() {
57 name := iter.Label()
58 if strings.HasPrefix(name, "$") {
59 continue
60 }
61 v := iter.Value()
62
63 if err := v.Err(); err != nil {
64 return nil, err
65 }
66
67 if err := validateEntry(name, v); err != nil {
68 return nil, err
69 }
70
71 str, ok := os.LookupEnv(name)
72 if !ok {
73 update[name] = nil
74 continue
75 }
76 x, err := fromString(name, str, v)
77 if err != nil {
78 return nil, err
79 }
80 update[name] = x
81 }
82
83 return update, nil
84 }
85
86 type environCmd struct{}
87
88 func newEnvironCmd(v cue.Value) (task.Runner, error) {
89 return &environCmd{}, nil
90 }
91
92 func (c *environCmd) Run(ctx *task.Context) (res interface{}, err error) {
93 iter, err := ctx.Obj.Fields()
94 if err != nil {
95 return nil, err
96 }
97
98 update := map[string]interface{}{}
99
100 for _, kv := range os.Environ() {
101 name, str, _ := strings.Cut(kv, "=")
102 if v := ctx.Obj.Lookup(name); v.Exists() {
103 update[name], err = fromString(name, str, v)
104 if err != nil {
105 return nil, err
106 }
107 } else {
108 update[name] = str
109 }
110 }
111
112 for iter.Next() {
113 name := iter.Label()
114 if strings.HasPrefix(name, "$") {
115 continue
116 }
117 v := iter.Value()
118 if err := v.Err(); err != nil {
119 return nil, err
120 }
121 if err := validateEntry(name, v); err != nil {
122 return nil, err
123 }
124 if _, ok := update[name]; !ok {
125 update[name] = nil
126 }
127 }
128
129 return update, nil
130 }
131
132 func validateEntry(name string, v cue.Value) error {
133 if k := v.IncompleteKind(); k&^(cue.NumberKind|cue.NullKind|cue.BoolKind|cue.StringKind) != 0 {
134 return errors.Newf(v.Pos(),
135 "invalid type %s for environment variable %s", k, name)
136 }
137 return nil
138 }
139
140 func fromString(name, str string, v cue.Value) (x ast.Node, err error) {
141 k := v.IncompleteKind()
142 return cli.ParseValue(v.Pos(), name, str, k)
143 }
144
View as plain text