cue: implement "front-style" list comprehensions
This now also allows any of the non-JSON keywords
to be used as references. Previously, these were already
supported as field names.
Issue #339
Issue #165
Change-Id: I721d054c8220ba3536f680fe2e3e502a62f99b6b
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/5683
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cmd/cue/cmd/fix_test.go b/cmd/cue/cmd/fix_test.go
index 198c844..26c0cb2 100644
--- a/cmd/cue/cmd/fix_test.go
+++ b/cmd/cue/cmd/fix_test.go
@@ -54,6 +54,14 @@
ref: X1 & x
}
`,
+ }, {
+ in: `
+ y: [1, 2, 3, 4]
+ a: [ x for x in y ]
+ `,
+ out: `y: [1, 2, 3, 4]
+a: [ for x in y { x } ]
+`,
// }, {
// name: "slice",
// in: `package foo
diff --git a/cmd/cue/cmd/testdata/script/legacy.txt b/cmd/cue/cmd/testdata/script/legacy.txt
index 8cb4a6e..8fee102 100644
--- a/cmd/cue/cmd/testdata/script/legacy.txt
+++ b/cmd/cue/cmd/testdata/script/legacy.txt
@@ -1,14 +1,16 @@
-! cue eval foo.cue
+cue eval foo.cue
cmp stderr expect-stderr
-! cue export foo.cue
+cue export foo.cue
cmp stderr expect-stderr
-! cue fmt foo.cue
-cmp stderr expect-stderr
+cue fmt foo.cue
+cmp foo.cue bar.cue
-- expect-stderr --
-missing ',' in struct literal:
- ./foo.cue:1:8
-- foo.cue --
-"x": 3 for x in a
+a: [1]
+b: [ x for x in a ]
+-- bar.cue --
+a: [1]
+b: [ for x in a { x } ]
diff --git a/cue/ast.go b/cue/ast.go
index fa1331c..04058b2 100644
--- a/cue/ast.go
+++ b/cue/ast.go
@@ -301,10 +301,39 @@
parent: v,
}
+ if len(n.Elts) == 1 {
+ if c, ok := n.Elts[0].(*ast.Comprehension); ok {
+ yielder := &yield{baseValue: newExpr(c.Value)}
+ lc := &listComprehension{
+ newExpr(c),
+ wrapClauses(v, yielder, c.Clauses),
+ }
+ // we don't support key for lists (yet?)
+
+ // TODO(hack): unwrap struct lit if embedding of one element.
+ // We do this as we do not yet support embedding of scalar
+ // values in general. This prohibits:
+ // - having fields alongside embedded values
+ // - having more than one embedded value.
+ // The latter would not be too hard to circumvent.
+ expr := c.Value
+ if s, ok := expr.(*ast.StructLit); ok && len(s.Elts) == 1 {
+ if e, ok := s.Elts[0].(*ast.EmbedDecl); ok {
+ expr = e.Expr
+ }
+ }
+ yielder.value = v.walk(expr)
+ return lc
+ }
+ }
+
elts, ellipsis := internal.ListEllipsis(n)
arcs := []arc{}
for i, e := range elts {
+ if _, ok := e.(*ast.Comprehension); ok {
+ return v.errf(e, "comprehensions must be a single element within list (for now)")
+ }
elem := v1.walk(e)
if elem == nil {
// TODO: it would be consistent to allow aliasing in lists
diff --git a/cue/ast/ast.go b/cue/ast/ast.go
index 3238a99..b33204d 100644
--- a/cue/ast/ast.go
+++ b/cue/ast/ast.go
@@ -347,10 +347,11 @@
// A Comprehension node represents a comprehension declaration.
type Comprehension struct {
Clauses []Clause // There must be at least one clause.
- Value Expr // Must be a struct
+ Value Expr // Must be a struct TODO: change to Struct
comments
decl
+ expr // TODO: only allow Comprehension in "Embedding" productions.
}
func (x *Comprehension) Pos() token.Pos { return getPos(x) }
@@ -551,6 +552,8 @@
// A ListLit node represents a literal list.
type ListLit struct {
Lbrack token.Pos // position of "["
+
+ // TODO: change to embedding or similar.
Elts []Expr // list of composite elements; or nil
Rbrack token.Pos // position of "]"
diff --git a/cue/ast_test.go b/cue/ast_test.go
index 3cc17bd..cb2e519 100644
--- a/cue/ast_test.go
+++ b/cue/ast_test.go
@@ -313,7 +313,7 @@
out: `<0>{a: <1>{ <2>for k, v in <0>.b yield <3>{""+<2>.v+"": <2>.v}}, b: <4>{a: "aa", b: "bb", c: "cc"}}`,
}, {
in: `
- a: [ v for _, v in b ]
+ a: [ for _, v in b { v } ]
b: { a: 1, b: 2, c: 3 }
`,
out: `<0>{a: [ <1>for _, v in <0>.b yield <1>.v ], b: <2>{a: 1, b: 2, c: 3}}`,
diff --git a/cue/export_test.go b/cue/export_test.go
index 6967acb..88c5b62 100644
--- a/cue/export_test.go
+++ b/cue/export_test.go
@@ -251,11 +251,11 @@
}`),
}, {
raw: true,
- in: `{ a: [1, 2], b: [ v for k, v in a ] }`,
+ in: `{ a: [1, 2], b: [ for k, v in a { v }] }`,
out: unindent(`
{
a: [1, 2]
- b: [ v for k, v in a ]
+ b: [ for k, v in a { v } ]
}`),
}, {
raw: true,
diff --git a/cue/format/node.go b/cue/format/node.go
index d306d70..ba6797d 100644
--- a/cue/format/node.go
+++ b/cue/format/node.go
@@ -184,7 +184,36 @@
f.after(nil)
}
-func (f *formatter) walkExprList(list []ast.Expr, depth int) {
+func (f *formatter) walkListElems(list []ast.Expr) {
+ f.before(nil)
+ for _, x := range list {
+ f.before(x)
+ switch n := x.(type) {
+ case *ast.Comprehension:
+ f.walkClauseList(n.Clauses, blank)
+ f.print(blank, nooverride)
+ f.expr(n.Value)
+
+ case *ast.Ellipsis:
+ f.ellipsis(n)
+
+ case *ast.Alias:
+ f.expr(n.Ident)
+ f.print(n.Equal, token.BIND)
+ f.expr(n.Expr)
+
+ // TODO: ast.CommentGroup: allows comment groups in ListLits.
+
+ case ast.Expr:
+ f.exprRaw(n, token.LowestPrec, 1)
+ }
+ f.print(comma, blank)
+ f.after(x)
+ }
+ f.after(nil)
+}
+
+func (f *formatter) walkArgsList(list []ast.Expr, depth int) {
f.before(nil)
for _, x := range list {
f.before(x)
@@ -235,7 +264,6 @@
}
func (f *formatter) decl(decl ast.Decl) {
-
if decl == nil {
return
}
@@ -307,14 +335,6 @@
f.print(formfeed)
}
- case *ast.Comprehension:
- if !n.Pos().HasRelPos() || n.Pos().RelPos() >= token.Newline {
- f.print(formfeed)
- }
- f.walkClauseList(n.Clauses, blank)
- f.print(blank, nooverride)
- f.expr(n.Value)
-
case *ast.BadDecl:
f.print(n.From, "*bad decl*", declcomma)
@@ -350,6 +370,29 @@
f.expr(n.Expr)
f.print(newline, noblank)
+ case *ast.Attribute:
+ f.print(n.At, n)
+
+ case *ast.CommentGroup:
+ f.print(newsection)
+ f.printComment(n)
+ f.print(newsection)
+
+ case ast.Expr:
+ f.embedding(n)
+ }
+}
+
+func (f *formatter) embedding(decl ast.Expr) {
+ switch n := decl.(type) {
+ case *ast.Comprehension:
+ if !n.Pos().HasRelPos() || n.Pos().RelPos() >= token.Newline {
+ f.print(formfeed)
+ }
+ f.walkClauseList(n.Clauses, blank)
+ f.print(blank, nooverride)
+ f.expr(n.Value)
+
case *ast.Ellipsis:
f.ellipsis(n)
@@ -362,13 +405,10 @@
f.expr(n.Expr)
f.print(declcomma) // implied
- case *ast.Attribute:
- f.print(n.At, n)
+ // TODO: ast.CommentGroup: allows comment groups in ListLits.
- case *ast.CommentGroup:
- f.print(newsection)
- f.printComment(n)
- f.print(newsection)
+ case ast.Expr:
+ f.exprRaw(n, token.LowestPrec, 1)
}
}
@@ -570,7 +610,7 @@
}
wasIndented := f.possibleSelectorExpr(x.Fun, token.HighestPrec, depth)
f.print(x.Lparen, token.LPAREN)
- f.walkExprList(x.Args, depth)
+ f.walkArgsList(x.Args, depth)
f.print(trailcomma, noblank, x.Rparen, token.RPAREN)
if wasIndented {
f.print(unindent)
@@ -612,7 +652,7 @@
case *ast.ListLit:
f.print(x.Lbrack, token.LBRACK, indent)
- f.walkExprList(x.Elts, 1)
+ f.walkListElems(x.Elts)
f.print(trailcomma, noblank)
f.visitComments(f.current.pos)
f.matchUnindent()
@@ -623,9 +663,16 @@
case *ast.ListComprehension:
f.print(x.Lbrack, token.LBRACK, blank, indent)
- f.expr(x.Expr)
f.print(blank)
f.walkClauseList(x.Clauses, blank)
+ f.print(blank, nooverride)
+ if _, ok := x.Expr.(*ast.StructLit); ok {
+ f.expr(x.Expr)
+ } else {
+ f.print(token.LBRACE, blank)
+ f.expr(x.Expr)
+ f.print(blank, token.RBRACE)
+ }
f.print(unindent, f.wsOverride(blank), x.Rbrack, token.RBRACK)
default:
diff --git a/cue/format/testdata/expressions.golden b/cue/format/testdata/expressions.golden
index 0dbc658..019abde 100644
--- a/cue/format/testdata/expressions.golden
+++ b/cue/format/testdata/expressions.golden
@@ -14,7 +14,7 @@
alias = 3.14
"g\("en")"?: 4
- alias2 = foo
+ alias2 = foo // with comment
aaalias = foo
b: bar
@@ -140,13 +140,16 @@
e: [...int]
e: [...int]
e: [...int | float]
- e: [ x for x in someObject if x > 9 ]
- e: [ x
+ e: [ for x in someObject if x > 9 {
+ x
+ }]
+ e: [ for x in someObject if x > 9 { x } ]
+ e: [
for x in someObject
- if x > 9 ]
- e: [ x
+ if x > 9 { x } ]
+ e: [
for x in someObject
- if x > 9
+ if x > 9 { x }
]
for k, v in someObject {
"\(k)": v
diff --git a/cue/format/testdata/expressions.input b/cue/format/testdata/expressions.input
index 8b19de6..d153771 100644
--- a/cue/format/testdata/expressions.input
+++ b/cue/format/testdata/expressions.input
@@ -14,7 +14,7 @@
alias = 3.14
"g\("en")"?: 4
- alias2 = foo
+ alias2 = foo // with comment
aaalias = foo
b: bar
@@ -138,6 +138,9 @@
e: [...int]
e: [...int,]
e: [...int | float]
+ e: [ for x in someObject if x > 9 {
+ x
+ }]
e: [ x for x in someObject if x > 9 ]
e: [ x
for x in someObject
@@ -159,11 +162,11 @@
"\(k)":v
}
}
-
+
e: { for k, v in someObject if k > "a" {"\(k)":v} }
e: { for k, v in someObject if k > "a" {
"\(k)":v }}
-
+
e: {
for k, v in someObject
if k > "a" {
diff --git a/cue/parser/parser.go b/cue/parser/parser.go
index eb3a06a..d9ea14c 100644
--- a/cue/parser/parser.go
+++ b/cue/parser/parser.go
@@ -368,6 +368,8 @@
}
}
+// assertV0 indicates the last version at which a certain feature was
+// supported.
func (p *parser) assertV0(pos token.Pos, minor, patch int, name string) {
v := version0(minor, patch)
if p.version != 0 && p.version > v {
@@ -539,6 +541,16 @@
return ident
}
+func (p *parser) parseKeyIdent() *ast.Ident {
+ c := p.openComments()
+ pos := p.pos
+ name := p.lit
+ p.next()
+ ident := &ast.Ident{NamePos: pos, Name: name}
+ c.closeNode(p, ident)
+ return ident
+}
+
// ----------------------------------------------------------------------------
// Expressions
@@ -589,6 +601,11 @@
Lparen: lparen,
X: x,
Rparen: rparen}
+
+ default:
+ if p.tok.IsKeyword() {
+ return p.parseKeyIdent()
+ }
}
// we have an error
@@ -681,7 +698,7 @@
for p.tok != token.RBRACE && p.tok != token.ELLIPSIS && p.tok != token.EOF {
switch p.tok {
- case token.FOR, token.IF, token.LET:
+ case token.FOR, token.IF:
list = append(list, p.parseComprehension())
case token.ATTRIBUTE:
@@ -726,33 +743,42 @@
opt := token.NoPos
tok = p.tok
pos = p.pos
- if p.tok == token.OPTION {
+ switch p.tok {
+ case token.COMMA, token.EOF:
+ decl = &ast.EmbedDecl{Expr: lab}
+
+ case token.OPTION:
opt = pos
p.next()
tok = p.tok
pos = p.pos
- }
- p.next()
- rhs := p.parseRHS()
- // Field or alias.
- switch tok {
- case token.BIND:
- decl = &ast.Alias{Ident: lab, Equal: pos, Expr: rhs}
- case token.ISA, token.COLON:
- decl = &ast.Field{
- Label: lab,
- Optional: opt,
- TokenPos: pos,
- Token: tok,
- Value: rhs,
- Attrs: p.parseAttributes(),
- }
+ fallthrough
+
default:
- decl = &ast.BadDecl{From: lab.Pos(), To: rhs.End()}
+ p.next()
+ rhs := p.parseRHS()
+
+ // Field or alias.
+ switch tok {
+ case token.BIND:
+ decl = &ast.Alias{Ident: lab, Equal: pos, Expr: rhs}
+ case token.ISA, token.COLON:
+ decl = &ast.Field{
+ Label: lab,
+ Optional: opt,
+ TokenPos: pos,
+ Token: tok,
+ Value: rhs,
+ Attrs: p.parseAttributes(),
+ }
+ default:
+ decl = &ast.BadDecl{From: lab.Pos(), To: rhs.End()}
+ }
}
+
fc.closeNode(p, decl)
- if p.atComma("struct literal", token.RBRACE) { // TODO: may be EOF
+ if p.atComma("struct literal", token.RBRACE, token.EOF) {
p.next()
}
@@ -833,14 +859,15 @@
p.expectComma() // sync parser.
fallthrough
- case token.RBRACE:
+ case token.RBRACE, token.EOF:
if i == 0 {
if a, ok := expr.(*ast.Alias); ok {
return a
}
switch tok {
case token.IDENT, token.LBRACK, token.STRING, token.INTERPOLATION,
- token.NULL, token.TRUE, token.FALSE:
+ token.NULL, token.TRUE, token.FALSE,
+ token.FOR, token.IF, token.LET, token.IN:
return &ast.EmbedDecl{Expr: expr}
}
}
@@ -940,7 +967,8 @@
tok := p.tok
switch tok {
case token.IDENT, token.STRING, token.INTERPOLATION,
- token.NULL, token.TRUE, token.FALSE:
+ token.NULL, token.TRUE, token.FALSE,
+ token.FOR, token.IF, token.LET, token.IN:
expr = p.parseExpr()
switch x := expr.(type) {
@@ -983,29 +1011,6 @@
// Note: caller must verify this list is suitable as a label.
label, ok = x, true
}
-
- case token.IF, token.FOR, token.IN, token.LET:
- // Keywords representing clauses.
- pos := p.pos
- ident := &ast.Ident{
- NamePos: pos,
- Name: p.lit,
- }
- c := p.openComments()
- p.next()
- expr = c.closeExpr(p, ident)
-
- if p.tok != token.COLON && p.tok != token.ISA {
- c = p.openComments()
- p.errf(pos, "expected operand, found '%s'", ident.Name)
- expr = &ast.BadExpr{From: pos, To: p.pos}
- // Sync expression.
- expr = p.parseBinaryExprTail(token.LowestPrec+1, expr)
- expr = c.closeExpr(p, expr)
- break
- }
- label = ident
- ok = true
}
return label, expr, ok
}
@@ -1056,7 +1061,8 @@
forPos := p.expect(token.FOR)
if first {
switch p.tok {
- case token.COLON, token.ISA, token.BIND, token.OPTION:
+ case token.COLON, token.ISA, token.BIND, token.OPTION,
+ token.COMMA, token.EOF:
return nil, c
}
}
@@ -1085,7 +1091,8 @@
ifPos := p.expect(token.IF)
if first {
switch p.tok {
- case token.COLON, token.ISA, token.BIND, token.OPTION:
+ case token.COLON, token.ISA, token.BIND, token.OPTION,
+ token.COMMA, token.EOF:
return nil, c
}
}
@@ -1095,7 +1102,12 @@
Condition: p.parseRHS(),
}))
+ // TODO:
// case token.LET:
+ // c := p.openComments()
+ // p.expect(token.LET)
+ // return nil, c
+
default:
return clauses, nil
}
@@ -1118,6 +1130,7 @@
if clauses, _ := p.parseComprehensionClauses(false); clauses != nil {
var expr ast.Expr
+ p.assertV0(p.pos, 1, 1, "old-style list comprehensions")
if len(elts) != 1 {
p.errf(lbrack.Add(1), "list comprehension must have exactly one element")
}
@@ -1170,6 +1183,12 @@
}
}
+ for _, v := range list {
+ if _, ok := v.(*ast.Comprehension); ok && len(list) != 1 {
+ p.errf(v.Pos(), "multiple comprehensions per list not yet supported")
+ }
+ }
+
return
}
@@ -1180,7 +1199,37 @@
c := p.openComments()
defer func() { c.closeNode(p, expr) }()
- expr = p.parseBinaryExprTail(token.LowestPrec+1, p.parseUnaryExpr())
+ switch p.tok {
+ case token.FOR, token.IF:
+ tok := p.tok
+ pos := p.pos
+ clauses, fc := p.parseComprehensionClauses(true)
+ if clauses != nil {
+ sc := p.openComments()
+ expr := p.parseStruct()
+ sc.closeExpr(p, expr)
+
+ if p.atComma("struct literal", token.RBRACK) { // TODO: may be EOF
+ p.next()
+ }
+
+ return &ast.Comprehension{
+ Clauses: clauses,
+ Value: expr,
+ }, true
+ }
+
+ expr = &ast.Ident{
+ NamePos: pos,
+ Name: tok.String(),
+ }
+ fc.closeNode(p, expr)
+
+ default:
+ expr = p.parseUnaryExpr()
+ }
+
+ expr = p.parseBinaryExprTail(token.LowestPrec+1, expr)
expr = p.parseAlias(expr)
// Enforce there is an explicit comma. We could also allow the
diff --git a/cue/parser/parser_test.go b/cue/parser/parser_test.go
index 92734f4..7e4f61b 100644
--- a/cue/parser/parser_test.go
+++ b/cue/parser/parser_test.go
@@ -34,7 +34,7 @@
}, {
"basic lits", `"a","b", 3,3.4,5,2_3`, `"a", "b", 3, 3.4, 5, 2_3`,
}, {
- "keyword basic lits", `true,false,null`, `true, false, null`,
+ "keyword basic lits", `true,false,null,for,in,if,let`, `true, false, null, for, in, if, let`,
}, {
"keywords as labels",
`if: 0, for: 1, in: 2, where: 3, div: 4, quo: 5`,
@@ -239,9 +239,9 @@
"list comprehensions",
`{
y: [1,2,3]
- b: [ x for x in y if x == 1 ],
+ b: [ for x in y if x == 1 { x } ],
}`,
- `{y: [1, 2, 3], b: [x for x in y if x==1 ]}`,
+ `{y: [1, 2, 3], b: [for x in y if x==1 {x}]}`,
}, {
"field comprehensions",
`{
@@ -443,11 +443,11 @@
`X1=[X2=<"d"]: {name: X2}, ` +
`Y1=foo: {Y2=bar: [Y1, Y2]}`,
}, {
- desc: "error when keyword is used in expression",
+ desc: "allow keyword in expression",
in: `
foo: in & 2
`,
- out: "foo: <*ast.BadExpr>&2\nexpected operand, found 'in'",
+ out: "foo: in&2",
}, {
desc: "dot import",
in: `
diff --git a/cue/resolve_test.go b/cue/resolve_test.go
index 591b3c5..7126bf3 100644
--- a/cue/resolve_test.go
+++ b/cue/resolve_test.go
@@ -2248,22 +2248,21 @@
}, {
desc: "list comprehension",
in: `
- // a: [ k for k: v in b if k < "d" if v > b.a ] // TODO test error using common iso colon
- a: [ k for k, v in b if k < "d" if v > b.a ]
+ a: [ for k, v in b if k < "d" if v > b.a { k }]
b: {
a: 1
b: 2
c: 3
d: 4
}
- c: [ x for _, x in b for _, y in b if x < y ]
- d: [ x for x, _ in a ]
+ c: [ for _, x in b for _, y in b if x < y { x } ]
+ d: [ for x, _ in a { x } ]
`,
out: `<0>{a: ["b","c"], b: <1>{a: 1, b: 2, c: 3, d: 4}, c: [1,1,1,2,2,3], d: [0,1]}`,
}, {
desc: "struct comprehension with template",
in: `
- result: [ v for _, v in service ]
+ result: [ for _, v in service { v } ]
service: [Name=string]: {
name: *Name | string
@@ -2336,7 +2335,7 @@
}, {
desc: "complex interaction of groundness",
in: `
- res: [ y & { d: "b" } for x in a for y in x ]
+ res: [ for x in a for y in x { y & { d: "b" } }]
res: [ a.b.c & { d: "b" } ]
a: b: [C=string]: { d: string, s: "a" + d }
@@ -2584,7 +2583,7 @@
[jobID=string]: {
}
}
- JobID :: or([ k for k, _ in jobs ])
+ JobID :: or([ for k, _ in jobs { k } ])
}
foo: Workflow & {
@@ -2867,7 +2866,7 @@
desc: "alias reuse in nested scope",
in: `
Foo :: {
- X = or([ k for k, _ in {} ])
+ X = or([ for k, _ in {} { k } ])
connection: [X]: X
}
A :: {
diff --git a/cue/types_test.go b/cue/types_test.go
index 1c90aec..2320bc4 100644
--- a/cue/types_test.go
+++ b/cue/types_test.go
@@ -564,7 +564,7 @@
value: `>=5*[1,2,3, ...int]`,
err: "incomplete",
}, {
- value: `[x for x in y if x > 1]
+ value: `[for x in y if x > 1 { x }]
y :: [1,2,3]`,
res: "[2,3,]",
}, {
@@ -1191,7 +1191,7 @@
dst: intList(),
want: *intList(1, 2, 3),
}, {
- value: `[x for x in y if x > 1]
+ value: `[for x in y if x > 1 { x }]
y :: [1,2,3]`,
dst: intList(),
want: *intList(2, 3),
diff --git a/doc/tutorial/basics/6_expressions/40_listcomp.txt b/doc/tutorial/basics/6_expressions/40_listcomp.txt
index 88eb177..dbc5132 100644
--- a/doc/tutorial/basics/6_expressions/40_listcomp.txt
+++ b/doc/tutorial/basics/6_expressions/40_listcomp.txt
@@ -11,7 +11,7 @@
The example shows the use of `for` loops and `if` guards.
-- listcomp.cue --
-[ x*x for x in items if x rem 2 == 0]
+[ for x in items if x rem 2 == 0 { x*x } ]
items :: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
diff --git a/doc/tutorial/kubernetes/README.md b/doc/tutorial/kubernetes/README.md
index 19c86df..4c998e1 100644
--- a/doc/tutorial/kubernetes/README.md
+++ b/doc/tutorial/kubernetes/README.md
@@ -498,13 +498,15 @@
service: "\(k)": {
spec: selector: v.spec.template.metadata.labels
- spec: ports: [ {
- Port = p.containerPort // Port is an alias
- port: *Port | int
- targetPort: *Port | int
- } for c in v.spec.template.spec.containers
+ spec: ports: [
+ for c in v.spec.template.spec.containers
for p in c.ports
- if p._export ]
+ if p._export {
+ Port = p.containerPort // Port is an alias
+ port: *Port | int
+ targetPort: *Port | int
+ }
+ ]
}
}
EOF
@@ -856,7 +858,7 @@
$ cat <<EOF > kube_tool.cue
package kube
-objects: [ x for v in objectSets for x in v ]
+objects: [ for v in objectSets for x in v { x } ]
objectSets: [
service,
@@ -891,8 +893,9 @@
command: ls: {
task: print: cli.Print & {
text: tabwriter.Write([
- "\(x.kind) \t\(x.metadata.labels.component) \t\(x.metadata.name)"
- for x in objects
+ for x in objects {
+ "\(x.kind) \t\(x.metadata.labels.component) \t\(x.metadata.name)"
+ }
])
}
@@ -1176,7 +1179,7 @@
Arguments can be specified as a map.
```
arg: [string]: string
- args: [ "-\(k)=\(v)" for k, v in arg ] | [...string]
+ args: [ for k, v in arg { "-\(k)=\(v)" } ] | [...string]
```
If order matters, users could explicitly specify the list as well.
@@ -1281,7 +1284,7 @@
metadata: labels: x.label
spec: selector: x.label
- spec: ports: [ p for p in x.port ]
+ spec: ports: [ for p in x.port { p } ]
}
}
}
diff --git a/doc/tutorial/kubernetes/manual/services/cloud.cue b/doc/tutorial/kubernetes/manual/services/cloud.cue
index bf86197..e16bbff 100644
--- a/doc/tutorial/kubernetes/manual/services/cloud.cue
+++ b/doc/tutorial/kubernetes/manual/services/cloud.cue
@@ -26,7 +26,7 @@
port: [string]: int
arg: [string]: string
- args: [ "-\(k)=\(v)" for k, v in arg ] | [...string]
+ args: [ for k, v in arg { "-\(k)=\(v)" } ] | [...string]
// Environment variables
env: [string]: string
diff --git a/doc/tutorial/kubernetes/manual/services/k8s.cue b/doc/tutorial/kubernetes/manual/services/k8s.cue
index cefab64..381e483 100644
--- a/doc/tutorial/kubernetes/manual/services/k8s.cue
+++ b/doc/tutorial/kubernetes/manual/services/k8s.cue
@@ -84,13 +84,13 @@
image: X.image
args: X.args
if len(X.envSpec) > 0 {
- env: [ {name: k} & v for k, v in X.envSpec ]
+ env: [ for k, v in X.envSpec {v, name: k} ]
}
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
}]
}
@@ -98,7 +98,11 @@
spec: template: spec: {
if len(X.volume) > 0 {
volumes: [
- v.kubernetes & {name: v.name} for v in X.volume
+ for v in X.volume {
+ v.kubernetes
+
+ name: v.name
+ }
]
}
@@ -106,16 +110,17 @@
// TODO: using conversions this would look like:
// volumeMounts: [ k8s.VolumeMount(v) for v in d.volume ]
if len(X.volume) > 0 {
- volumeMounts: [ {
- name: v.name
- mountPath: v.mountPath
- if v.subPath != null | true {
- subPath: v.subPath
+ volumeMounts: [
+ for v in X.volume {
+ name: v.name
+ mountPath: v.mountPath
+ if v.subPath != null | true {
+ subPath: v.subPath
+ }
+ if v.readOnly {
+ readOnly: v.readOnly
+ }
}
- if v.readOnly {
- readOnly: v.readOnly
- }
- } for v in X.volume
]
}
}]
diff --git a/doc/tutorial/kubernetes/manual/services/kube_tool.cue b/doc/tutorial/kubernetes/manual/services/kube_tool.cue
index b41cea0..0ca9d0f 100644
--- a/doc/tutorial/kubernetes/manual/services/kube_tool.cue
+++ b/doc/tutorial/kubernetes/manual/services/kube_tool.cue
@@ -1,6 +1,6 @@
package kube
-objects: [ x for v in objectSets for x in v ]
+objects: [ for v in objectSets for x in v { x } ]
objectSets: [
kubernetes.services,
diff --git a/doc/tutorial/kubernetes/manual/services/ls_tool.cue b/doc/tutorial/kubernetes/manual/services/ls_tool.cue
index d82e2af..d5739ba 100644
--- a/doc/tutorial/kubernetes/manual/services/ls_tool.cue
+++ b/doc/tutorial/kubernetes/manual/services/ls_tool.cue
@@ -6,8 +6,10 @@
task: print: {
kind: "print"
Lines = [
- "\(x.kind) \t\(x.metadata.labels.component) \t\(x.metadata.name)"
- for x in objects ]
+ for x in objects {
+ "\(x.kind) \t\(x.metadata.labels.component) \t\(x.metadata.name)"
+ }
+ ]
text: strings.Join(Lines, "\n")
}
}
diff --git a/doc/tutorial/kubernetes/quick/services/kube.cue b/doc/tutorial/kubernetes/quick/services/kube.cue
index bf6ae39..394b15e 100644
--- a/doc/tutorial/kubernetes/quick/services/kube.cue
+++ b/doc/tutorial/kubernetes/quick/services/kube.cue
@@ -95,12 +95,14 @@
service: "\(k)": {
spec: selector: v.spec.template.metadata.labels
- spec: ports: [ {
- Port = p.containerPort // Port is an alias
- port: *Port | int
- targetPort: *Port | int
- } for c in v.spec.template.spec.containers
+ spec: ports: [
+ for c in v.spec.template.spec.containers
for p in c.ports
- if p._export ]
+ if p._export {
+ Port = p.containerPort // Port is an alias
+ port: *Port | int
+ targetPort: *Port | int
+ },
+ ]
}
}
diff --git a/doc/tutorial/kubernetes/quick/services/kube_tool.cue b/doc/tutorial/kubernetes/quick/services/kube_tool.cue
index 929ad34..b9c92f3 100644
--- a/doc/tutorial/kubernetes/quick/services/kube_tool.cue
+++ b/doc/tutorial/kubernetes/quick/services/kube_tool.cue
@@ -1,6 +1,6 @@
package kube
-objects: [ x for v in objectSets for x in v ]
+objects: [ for v in objectSets for x in v { x } ]
objectSets: [
service,
diff --git a/doc/tutorial/kubernetes/quick/services/ls_tool.cue b/doc/tutorial/kubernetes/quick/services/ls_tool.cue
index 1c73beb..7fc5231 100644
--- a/doc/tutorial/kubernetes/quick/services/ls_tool.cue
+++ b/doc/tutorial/kubernetes/quick/services/ls_tool.cue
@@ -9,8 +9,9 @@
command: ls: {
task: print: cli.Print & {
text: tabwriter.Write([
- "\(x.kind) \t\(x.metadata.labels.component) \t\(x.metadata.name)"
- for x in objects
+ for x in objects {
+ "\(x.kind) \t\(x.metadata.labels.component) \t\(x.metadata.name)"
+ }
])
}
diff --git a/doc/tutorial/kubernetes/testdata/manual.out b/doc/tutorial/kubernetes/testdata/manual.out
index e13b62f..4f0b732 100644
--- a/doc/tutorial/kubernetes/testdata/manual.out
+++ b/doc/tutorial/kubernetes/testdata/manual.out
@@ -27,17 +27,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -46,13 +47,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -98,17 +100,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -117,13 +120,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -284,17 +288,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -303,13 +308,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -473,17 +479,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -492,13 +499,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -659,17 +667,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -678,13 +687,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -845,17 +855,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -864,13 +875,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -1034,17 +1046,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -1053,13 +1066,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -1220,17 +1234,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -1239,13 +1254,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -1409,17 +1425,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -1428,13 +1445,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -1480,17 +1498,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -1499,13 +1518,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -1651,17 +1671,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -1670,13 +1691,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -2000,17 +2022,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -2019,13 +2042,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -2248,17 +2272,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -2267,13 +2292,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -2471,17 +2497,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -2490,13 +2517,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -2665,17 +2693,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -2684,13 +2713,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -2877,17 +2907,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -2896,13 +2927,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -2948,17 +2980,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -2967,13 +3000,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -3255,17 +3289,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -3274,13 +3309,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -3559,17 +3595,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -3578,13 +3615,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -3842,17 +3880,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -3861,13 +3900,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -4124,17 +4164,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -4143,13 +4184,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -4410,17 +4452,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -4429,13 +4472,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -4696,17 +4740,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -4715,13 +4760,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -4929,17 +4975,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -4948,13 +4995,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -5029,17 +5077,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -5048,13 +5097,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -5316,17 +5366,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -5335,13 +5386,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -5569,17 +5621,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -5588,13 +5641,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -5836,17 +5890,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -5855,13 +5910,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -6555,17 +6611,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -6574,13 +6631,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -6626,17 +6684,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -6645,13 +6704,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -6942,17 +7002,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -6961,13 +7022,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -7152,17 +7214,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -7171,13 +7234,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
@@ -7792,17 +7856,18 @@
name: X.name
image: X.image
args: X.args
- ports: [ {
+ ports: [ for k, p in X.expose.port & X.port {
name: k
containerPort: p
- } for k, p in X.expose.port & X.port ]
+ } ]
if len(X.envSpec) > 0 {
- env: [ {
+ env: [ for k, v in X.envSpec {
name: k
- } & v for k, v in X.envSpec ]
+ v
+ } ]
}
if len(X.volume) > 0 {
- volumeMounts: [ {
+ volumeMounts: [ for v in X.volume {
name: v.name
mountPath: v.mountPath
if v.subPath != null | true {
@@ -7811,13 +7876,14 @@
if v.readOnly {
readOnly: v.readOnly
}
- } for v in X.volume ]
+ } ]
}
}]
if len(X.volume) > 0 {
- volumes: [ v.kubernetes & {
+ volumes: [ for v in X.volume {
name: v.name
- } for v in X.volume ]
+ v.kubernetes
+ } ]
}
}
metadata: {
diff --git a/encoding/jsonschema/decode.go b/encoding/jsonschema/decode.go
index 72bd2cb..db9007d 100644
--- a/encoding/jsonschema/decode.go
+++ b/encoding/jsonschema/decode.go
@@ -419,7 +419,7 @@
default:
if !n.IsConcrete() {
- s.errf(n, "invalid non-concerte value")
+ s.errf(n, "invalid non-concrete value")
}
return n.Syntax(cue.Final()).(ast.Expr)
}
diff --git a/internal/encoding/json/encode_test.go b/internal/encoding/json/encode_test.go
index 0bf2814..e0432bb 100644
--- a/internal/encoding/json/encode_test.go
+++ b/internal/encoding/json/encode_test.go
@@ -154,9 +154,9 @@
a: 1
b: 3
}
- c: [1, [ x for x in m ]]
+ c: [1, [ for x in m { x } ]]
`,
- out: "json: unsupported node [x for x in m ] (*ast.ListComprehension)",
+ out: "json: unsupported node for x in m {x} (*ast.Comprehension)",
}, {
name: "disallowMultipleEmbeddings",
in: `