Skip to content
This repository has been archived by the owner on Nov 18, 2021. It is now read-only.

Commit

Permalink
cmd/cue/cmd: allow specifying field type for path flag
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
mpvl committed Mar 7, 2020
1 parent f733746 commit 694303f
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 2 deletions.
66 changes: 64 additions & 2 deletions cmd/cue/cmd/orphans.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -132,6 +134,7 @@ func placeOrphans(cmd *Command, filename, pkg string, objs ...ast.Expr) (*ast.Fi

// Compute a path different from root.
var pathElems []ast.Label
var pathTokens []token.Token

switch {
case len(flagPath.StringArray(cmd)) > 0:
Expand All @@ -152,14 +155,22 @@ func placeOrphans(cmd *Command, filename, pkg string, objs ...ast.Expr) (*ast.Fi
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()
if err != nil {
return nil, fmt.Errorf("unsupported label path type: %v", err)
}
pathElems = append(pathElems, ast.NewString(str))
pathTokens = append(pathTokens, 0)
}
}

Expand Down Expand Up @@ -187,10 +198,12 @@ func placeOrphans(cmd *Command, filename, pkg string, objs ...ast.Expr) (*ast.Fi
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
}
Expand All @@ -217,6 +230,55 @@ func placeOrphans(cmd *Command, filename, pkg string, objs ...ast.Expr) (*ast.Fi
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
Expand Down
2 changes: 2 additions & 0 deletions cmd/cue/cmd/testdata/script/import_context.txt
Original file line number Diff line number Diff line change
@@ -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 --
Expand Down
3 changes: 3 additions & 0 deletions cmd/cue/cmd/testdata/script/import_hoiststr.txt
Original file line number Diff line number Diff line change
@@ -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 --
Expand Down
3 changes: 3 additions & 0 deletions cmd/cue/cmd/testdata/script/import_path.txt
Original file line number Diff line number Diff line change
@@ -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 --
Expand Down

0 comments on commit 694303f

Please sign in to comment.