cmd/cue/cmd: allow specifying field type for path flag
The current new format does not allow indicating
whether a label is for a definition or regular field.
Reintroduce the old method, but require it to end in
a colon.
Change-Id: I81161b4d66ccbdd5fb42cb7b54e8f14324d113fa
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/5241
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cmd/cue/cmd/orphans.go b/cmd/cue/cmd/orphans.go
index dd31d9d..f7b764d 100644
--- a/cmd/cue/cmd/orphans.go
+++ b/cmd/cue/cmd/orphans.go
@@ -15,11 +15,13 @@
package cmd
import (
+ "errors"
"fmt"
"path/filepath"
"regexp"
"strconv"
+ "cuelang.org/go/cue"
"cuelang.org/go/cue/ast"
"cuelang.org/go/cue/build"
"cuelang.org/go/cue/parser"
@@ -132,6 +134,7 @@
// Compute a path different from root.
var pathElems []ast.Label
+ var pathTokens []token.Token
switch {
case len(flagPath.StringArray(cmd)) > 0:
@@ -152,7 +155,14 @@
for _, str := range flagPath.StringArray(cmd) {
l, err := parser.ParseExpr("--path", str)
if err != nil {
- return nil, fmt.Errorf(`labels are of form "cue import -l foo -l 'strings.ToLower(bar)'": %v`, err)
+ labels, tokens, err := parseFullPath(inst, str)
+ if err != nil {
+ return nil, fmt.Errorf(
+ `labels must be expressions (-l foo -l 'strings.ToLower(bar)') or full paths (-l '"foo": "\(strings.ToLower(bar))":) : %v`, err)
+ }
+ pathElems = append(pathElems, labels...)
+ pathTokens = append(pathTokens, tokens...)
+ continue
}
str, err := inst.Eval(l).String()
@@ -160,6 +170,7 @@
return nil, fmt.Errorf("unsupported label path type: %v", err)
}
pathElems = append(pathElems, ast.NewString(str))
+ pathTokens = append(pathTokens, 0)
}
}
@@ -187,10 +198,12 @@
f.Decls = append(f.Decls, obj.Elts...)
} else {
field := &ast.Field{Label: pathElems[0]}
+ field.Token = pathTokens[0]
f.Decls = append(f.Decls, field)
- for _, e := range pathElems[1:] {
+ for i, e := range pathElems[1:] {
newField := &ast.Field{Label: e}
newVal := ast.NewStruct(newField)
+ newField.Token = pathTokens[i+1]
field.Value = newVal
field = newField
}
@@ -217,6 +230,55 @@
return f, nil
}
+func parseFullPath(inst *cue.Instance, exprs string) (p []ast.Label, t []token.Token, err error) {
+ f, err := parser.ParseFile("--path", exprs+"_")
+ if err != nil {
+ return nil, nil, fmt.Errorf("parser error in path %q: %v", exprs, err)
+ }
+
+ if len(f.Decls) != 1 {
+ return nil, nil, errors.New("path flag must be a space-separated sequence of labels")
+ }
+
+ for d := f.Decls[0]; ; {
+ field, ok := d.(*ast.Field)
+ if !ok {
+ // This should never happen
+ return nil, nil, errors.New("%q not a sequence of labels")
+ }
+
+ t = append(t, field.Token)
+
+ switch x := field.Label.(type) {
+ case *ast.Ident, *ast.BasicLit:
+ p = append(p, x)
+
+ case *ast.TemplateLabel:
+ return nil, nil, fmt.Errorf("template labels not supported in path flag")
+
+ case ast.Expr:
+ v := inst.Eval(x)
+ if v.Kind() == cue.BottomKind {
+ return nil, nil, v.Err()
+ }
+ p = append(p, v.Syntax().(ast.Label))
+
+ }
+
+ v, ok := field.Value.(*ast.StructLit)
+ if !ok {
+ break
+ }
+
+ if len(v.Elts) != 1 {
+ return nil, nil, errors.New("path value may not contain a struct")
+ }
+
+ d = v.Elts[0]
+ }
+ return p, t, nil
+}
+
type listIndex struct {
index map[string]*listIndex
field *ast.Field
diff --git a/cmd/cue/cmd/testdata/script/import_context.txt b/cmd/cue/cmd/testdata/script/import_context.txt
index 34860ca..648604b 100644
--- a/cmd/cue/cmd/testdata/script/import_context.txt
+++ b/cmd/cue/cmd/testdata/script/import_context.txt
@@ -1,3 +1,5 @@
+cue import -o - -f --with-context -l '"\(path.Ext(filename)):\(index+1)/\(recordCount)": "\(data["@name"])":' ./import
+cmp stdout expect-stdout
cue import -o - -f --with-context -l '"\(path.Ext(filename)):\(index+1)/\(recordCount)"' -l 'data["@name"]' ./import
cmp stdout expect-stdout
-- expect-stdout --
diff --git a/cmd/cue/cmd/testdata/script/import_hoiststr.txt b/cmd/cue/cmd/testdata/script/import_hoiststr.txt
index e0f50f6..5172148 100644
--- a/cmd/cue/cmd/testdata/script/import_hoiststr.txt
+++ b/cmd/cue/cmd/testdata/script/import_hoiststr.txt
@@ -1,3 +1,6 @@
+cue import -o - -f --list -l '"\(strings.ToLower(kind))": "\(name)":' --recursive ./import
+cmp stdout expect-stdout
+
cue import -o - -f --list -l 'strings.ToLower(kind)' -l name --recursive ./import
cmp stdout expect-stdout
-- expect-stdout --
diff --git a/cmd/cue/cmd/testdata/script/import_path.txt b/cmd/cue/cmd/testdata/script/import_path.txt
index b6715a6..ff50b4b 100644
--- a/cmd/cue/cmd/testdata/script/import_path.txt
+++ b/cmd/cue/cmd/testdata/script/import_path.txt
@@ -1,3 +1,6 @@
+cue import -o - -f -l '"\(strings.ToLower(kind))": "\(name)":' ./import
+cmp stdout expect-stdout
+
cue import -o - -f -l 'strings.ToLower(kind)' -l name ./import
cmp stdout expect-stdout
-- expect-stdout --