internal/cli: hoist cli parsing code from tool/env
Change-Id: I4983d7e1dd13816b4bb2db798b87bfb421ffb52b
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/4901
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/internal/cli/cli.go b/internal/cli/cli.go
new file mode 100644
index 0000000..f6ffd25
--- /dev/null
+++ b/internal/cli/cli.go
@@ -0,0 +1,91 @@
+// Copyright 2020 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cli
+
+import (
+ "strings"
+
+ "cuelang.org/go/cue"
+ "cuelang.org/go/cue/ast"
+ "cuelang.org/go/cue/errors"
+ "cuelang.org/go/cue/parser"
+ "cuelang.org/go/cue/token"
+)
+
+func ParseValue(pos token.Pos, name, str string, k cue.Kind) (x ast.Expr, errs errors.Error) {
+ var expr ast.Expr
+
+ if k&cue.NumberKind != 0 {
+ var err error
+ expr, err = parser.ParseExpr(name, str)
+ if err != nil {
+ errs = errors.Wrapf(err, pos,
+ "invalid number for environment variable %s", name)
+ }
+ }
+
+ if k&cue.BoolKind != 0 {
+ str = strings.TrimSpace(str)
+ b, ok := boolValues[str]
+ if !ok {
+ errs = errors.Append(errs, errors.Newf(pos,
+ "invalid boolean value %q for environment variable %s", str, name))
+ } else if expr != nil || k&cue.StringKind != 0 {
+ // Convert into an expression
+ bl := ast.NewBool(b)
+ if expr != nil {
+ expr = &ast.BinaryExpr{Op: token.OR, X: expr, Y: bl}
+ } else {
+ expr = bl
+ }
+ } else {
+ x = ast.NewBool(b)
+ }
+ }
+
+ if k&cue.StringKind != 0 {
+ if expr != nil {
+ expr = &ast.BinaryExpr{Op: token.OR, X: expr, Y: ast.NewString(str)}
+ } else {
+ x = ast.NewString(str)
+ }
+ }
+
+ switch {
+ case expr != nil:
+ return expr, nil
+ case x != nil:
+ return x, nil
+ case errs == nil:
+ return nil, errors.Newf(pos,
+ "invalid type for environment variable %s", name)
+ }
+ return nil, errs
+}
+
+var boolValues = map[string]bool{
+ "1": true,
+ "0": false,
+ "t": true,
+ "f": false,
+ "T": true,
+ "F": false,
+ "true": true,
+ "false": false,
+ "TRUE": true,
+ "FALSE": false,
+ "True": true,
+ "False": false,
+}
diff --git a/pkg/tool/os/env.go b/pkg/tool/os/env.go
index 32880ff..962ec03 100644
--- a/pkg/tool/os/env.go
+++ b/pkg/tool/os/env.go
@@ -24,8 +24,7 @@
"cuelang.org/go/cue"
"cuelang.org/go/cue/ast"
"cuelang.org/go/cue/errors"
- "cuelang.org/go/cue/parser"
- "cuelang.org/go/cue/token"
+ "cuelang.org/go/internal/cli"
"cuelang.org/go/internal/task"
)
@@ -205,70 +204,7 @@
return nil
}
-func fromString(name, str string, v cue.Value) (x interface{}, err error) {
+func fromString(name, str string, v cue.Value) (x ast.Node, err error) {
k := v.IncompleteKind()
-
- var expr ast.Expr
- var errs errors.Error
-
- if k&cue.NumberKind != 0 {
- expr, err = parser.ParseExpr(name, str)
- if err != nil {
- errs = errors.Wrapf(err, v.Pos(),
- "invalid number for environment variable %s", name)
- }
- }
-
- if k&cue.BoolKind != 0 {
- str = strings.TrimSpace(str)
- b, ok := boolValues[str]
- if !ok {
- errors.Append(errs, errors.Newf(v.Pos(),
- "invalid boolean value %q for environment variable %s", str, name))
- } else if expr != nil || k&cue.StringKind != 0 {
- // Convert into an expression
- bl := ast.NewBool(b)
- if expr != nil {
- expr = &ast.BinaryExpr{Op: token.OR, X: expr, Y: bl}
- } else {
- expr = bl
- }
- } else {
- x = b
- }
- }
-
- if k&cue.StringKind != 0 {
- if expr != nil {
- expr = &ast.BinaryExpr{Op: token.OR, X: expr, Y: ast.NewString(str)}
- } else {
- x = str
- }
- }
-
- switch {
- case expr != nil:
- return expr, nil
- case x != nil:
- return x, nil
- case errs == nil:
- return nil, errors.Newf(v.Pos(),
- "invalid type for environment variable %s", name)
- }
- return nil, errs
-}
-
-var boolValues = map[string]bool{
- "1": true,
- "0": false,
- "t": true,
- "f": false,
- "T": true,
- "F": false,
- "true": true,
- "false": false,
- "TRUE": true,
- "FALSE": false,
- "True": true,
- "False": false,
+ return cli.ParseValue(v.Pos(), name, str, k)
}
diff --git a/pkg/tool/os/env_test.go b/pkg/tool/os/env_test.go
index a234cab..a5bfae9 100644
--- a/pkg/tool/os/env_test.go
+++ b/pkg/tool/os/env_test.go
@@ -95,8 +95,8 @@
}`
want := map[string]interface{}{
- "CUEOSTESTMOOD": "yippie",
- "CUEOSTESTTRUE": true,
+ "CUEOSTESTMOOD": ast.NewString("yippie"),
+ "CUEOSTESTTRUE": ast.NewBool(true),
"CUEOSTESTFALSE": &ast.BinaryExpr{
Op: token.OR,
X: ast.NewBool(false),
@@ -108,7 +108,7 @@
Y: ast.NewBool(true),
},
"CUEOSTESTNUM": &ast.BasicLit{Kind: token.INT, Value: "34K"},
- "CUEOSTESTNUMD": "not a num",
+ "CUEOSTESTNUMD": ast.NewString("not a num"),
"CUEOSTESTMULTI": &ast.BinaryExpr{
Op: token.OR,
X: &ast.BasicLit{Kind: token.INT, Value: "10"},