blob: 0d0a535f0064b96a95396857c3e0e4b2cce5d2af [file] [log] [blame]
Marcel van Lohuizen42346df2019-12-19 14:09:54 +01001// Copyright 2019 CUE Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package os
16
17//go:generate go run gen.go
Paul Jolly238d8212020-05-15 09:56:41 +010018//go:generate gofmt -s -w .
Marcel van Lohuizen42346df2019-12-19 14:09:54 +010019
20import (
Marcel van Lohuizen42346df2019-12-19 14:09:54 +010021 "os"
22 "strings"
23
Marcel van Lohuizen845df052020-07-26 13:15:45 +020024 "cuelang.org/go/cue"
Marcel van Lohuizen42346df2019-12-19 14:09:54 +010025 "cuelang.org/go/cue/ast"
26 "cuelang.org/go/cue/errors"
Marcel van Lohuizenaae80a02020-02-03 17:05:02 +010027 "cuelang.org/go/internal/cli"
Marcel van Lohuizen42346df2019-12-19 14:09:54 +010028 "cuelang.org/go/internal/task"
29)
30
31func init() {
Marcel van Lohuizen42346df2019-12-19 14:09:54 +010032 task.Register("tool/os.Getenv", newGetenvCmd)
33 task.Register("tool/os.Environ", newEnvironCmd)
Marcel van Lohuizen42346df2019-12-19 14:09:54 +010034
35 // TODO:
36 // Tasks:
37 // - Exit?
38 // - Getwd/ Setwd (or in tool/file?)
39
40 // Functions:
41 // - Hostname
42 // - UserCache/Home/Config (or in os/user?)
43}
44
Marcel van Lohuizen42346df2019-12-19 14:09:54 +010045type getenvCmd struct{}
46
47func newGetenvCmd(v cue.Value) (task.Runner, error) {
48 return &getenvCmd{}, nil
49}
50
Marcel van Lohuizena7b4ca82019-12-24 11:31:28 +010051func (c *getenvCmd) Run(ctx *task.Context) (res interface{}, err error) {
52 iter, err := ctx.Obj.Fields()
Marcel van Lohuizen42346df2019-12-19 14:09:54 +010053 if err != nil {
54 return nil, err
55 }
56
57 update := map[string]interface{}{}
58
59 for iter.Next() {
60 name := iter.Label()
61 if strings.HasPrefix(name, "$") {
62 continue
63 }
64 v := iter.Value()
65
Marcel van Lohuizenfbc6f862020-07-25 12:17:55 +020066 if err := v.Err(); err != nil {
67 return nil, err
68 }
69
Marcel van Lohuizen42346df2019-12-19 14:09:54 +010070 if err := validateEntry(name, v); err != nil {
71 return nil, err
72 }
73
74 str, ok := os.LookupEnv(name)
75 if !ok {
76 update[name] = nil
77 continue
78 }
79 x, err := fromString(name, str, v)
80 if err != nil {
81 return nil, err
82 }
83 update[name] = x
84 }
85
86 return update, nil
87}
88
89type environCmd struct{}
90
91func newEnvironCmd(v cue.Value) (task.Runner, error) {
92 return &environCmd{}, nil
93}
94
Marcel van Lohuizena7b4ca82019-12-24 11:31:28 +010095func (c *environCmd) Run(ctx *task.Context) (res interface{}, err error) {
96 iter, err := ctx.Obj.Fields()
Marcel van Lohuizen42346df2019-12-19 14:09:54 +010097 if err != nil {
98 return nil, err
99 }
100
101 update := map[string]interface{}{}
102
103 for _, kv := range os.Environ() {
104 a := strings.SplitN(kv, "=", 2)
105
106 name := a[0]
107 str := a[1]
108
Marcel van Lohuizena7b4ca82019-12-24 11:31:28 +0100109 if v := ctx.Obj.Lookup(name); v.Exists() {
Marcel van Lohuizen42346df2019-12-19 14:09:54 +0100110 update[name], err = fromString(name, str, v)
111 if err != nil {
112 return nil, err
113 }
114 } else {
115 update[name] = str
116 }
117 }
118
119 for iter.Next() {
120 name := iter.Label()
121 if strings.HasPrefix(name, "$") {
122 continue
123 }
Marcel van Lohuizenfbc6f862020-07-25 12:17:55 +0200124 v := iter.Value()
125 if err := v.Err(); err != nil {
126 return nil, err
127 }
128 if err := validateEntry(name, v); err != nil {
Marcel van Lohuizen42346df2019-12-19 14:09:54 +0100129 return nil, err
130 }
131 if _, ok := update[name]; !ok {
132 update[name] = nil
133 }
134 }
135
136 return update, nil
137}
138
139func validateEntry(name string, v cue.Value) error {
140 if k := v.IncompleteKind(); k&^(cue.NumberKind|cue.NullKind|cue.BoolKind|cue.StringKind) != 0 {
141 return errors.Newf(v.Pos(),
142 "invalid type %s for environment variable %s", k, name)
143 }
144 return nil
145}
146
Marcel van Lohuizenaae80a02020-02-03 17:05:02 +0100147func fromString(name, str string, v cue.Value) (x ast.Node, err error) {
Marcel van Lohuizen42346df2019-12-19 14:09:54 +0100148 k := v.IncompleteKind()
Marcel van Lohuizenaae80a02020-02-03 17:05:02 +0100149 return cli.ParseValue(v.Pos(), name, str, k)
Marcel van Lohuizen42346df2019-12-19 14:09:54 +0100150}