encoding/openapi: fix title handling regression
This regression was a result of forgetting to unskip the
def_openapi test in the move to v0.3, which allowed the
regression to be introduced by 304a3e0e to go unnoticed.
This partially unwinds 304a3e0e: it still assumes the main
operation is based on Value, but if available, it also stores
the Instance so that its meta information can be extracted.
In principle all information available in the Instance is also
available in the auxiliary structures of the Value (conjuncts).
But for now this is an easier approach.
The tests have a few changes as a result. The updated meta
data is correct. Furthermore there are additional file comments
at the top. It is debatable whether the latter is desirable or not,
but we'll leave it for now, as it is the current behavior.
Change-Id: Iaf40a9e525ff582e24ab4bc9fe690a40fa146559
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9066
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Paul Jolly <paul@myitcv.org.uk>
diff --git a/cmd/cue/cmd/common.go b/cmd/cue/cmd/common.go
index cbe713e..1b51472 100644
--- a/cmd/cue/cmd/common.go
+++ b/cmd/cue/cmd/common.go
@@ -169,7 +169,8 @@
type iterator interface {
scan() bool
value() cue.Value
- file() *ast.File // may return nil
+ instance() *cue.Instance // may return nil
+ file() *ast.File // may return nil
err() error
close()
id() string
@@ -186,11 +187,12 @@
return i.i < len(i.a) && i.e == nil
}
-func (i *instanceIterator) close() {}
-func (i *instanceIterator) err() error { return i.e }
-func (i *instanceIterator) value() cue.Value { return i.a[i.i].Value() }
-func (i *instanceIterator) file() *ast.File { return nil }
-func (i *instanceIterator) id() string { return i.a[i.i].Dir }
+func (i *instanceIterator) close() {}
+func (i *instanceIterator) err() error { return i.e }
+func (i *instanceIterator) value() cue.Value { return i.a[i.i].Value() }
+func (i *instanceIterator) instance() *cue.Instance { return i.a[i.i] }
+func (i *instanceIterator) file() *ast.File { return nil }
+func (i *instanceIterator) id() string { return i.a[i.i].Dir }
type streamingIterator struct {
r *cue.Runtime
@@ -239,8 +241,9 @@
return i
}
-func (i *streamingIterator) file() *ast.File { return i.f }
-func (i *streamingIterator) value() cue.Value { return i.v }
+func (i *streamingIterator) file() *ast.File { return i.f }
+func (i *streamingIterator) value() cue.Value { return i.v }
+func (i *streamingIterator) instance() *cue.Instance { return nil }
func (i *streamingIterator) id() string {
if i.inst != nil {
@@ -333,7 +336,8 @@
return true
}
-func (i *expressionIter) file() *ast.File { return nil }
+func (i *expressionIter) file() *ast.File { return nil }
+func (i *expressionIter) instance() *cue.Instance { return nil }
func (i *expressionIter) value() cue.Value {
if len(i.expr) == 0 {
diff --git a/cmd/cue/cmd/def.go b/cmd/cue/cmd/def.go
index edba0e6..5b7040d 100644
--- a/cmd/cue/cmd/def.go
+++ b/cmd/cue/cmd/def.go
@@ -60,13 +60,15 @@
iter := b.instances()
defer iter.close()
for i := 0; iter.scan(); i++ {
+ var err error
if f := iter.file(); f != nil {
- err := e.EncodeFile(f)
- exitOnErr(cmd, err, true)
+ err = e.EncodeFile(f)
+ } else if i := iter.instance(); i != nil {
+ err = e.EncodeInstance(iter.instance())
} else {
- err := e.Encode(iter.value())
- exitOnErr(cmd, err, true)
+ err = e.Encode(iter.value())
}
+ exitOnErr(cmd, err, true)
}
exitOnErr(cmd, iter.err(), true)
return nil
diff --git a/cmd/cue/cmd/testdata/script/def_openapi.txt b/cmd/cue/cmd/testdata/script/def_openapi.txt
index d56adf5..1cf3ab7 100644
--- a/cmd/cue/cmd/testdata/script/def_openapi.txt
+++ b/cmd/cue/cmd/testdata/script/def_openapi.txt
@@ -1,5 +1,3 @@
-skip 'fix comments and value printing'
-
cue def openapi+cue: expect-cue-out -o -
cue def foo.cue -o openapi:-
@@ -255,11 +253,14 @@
}
-- expect-cue3 --
// My OpenAPI
+
+// My OpenAPI2
package foo
info: {
- title: string | *_|_
- version: *"v1alpha1" | string}
+ title: (*"My OpenAPI" | string) & (*"My OpenAPI2" | string)
+ version: (*"v1alpha1" | string) & (*"v1alpha1" | string)
+}
#Bar: {
foo: #Foo
...
diff --git a/internal/encoding/encoder.go b/internal/encoding/encoder.go
index 764d482..40db53f 100644
--- a/internal/encoding/encoder.go
+++ b/internal/encoding/encoder.go
@@ -45,6 +45,7 @@
encValue func(cue.Value) error
autoSimplify bool
concrete bool
+ instance *cue.Instance
}
// IsConcrete reports whether the output is required to be concrete.
@@ -80,7 +81,10 @@
// TODO: get encoding options
cfg := &openapi.Config{}
e.interpret = func(v cue.Value) (*ast.File, error) {
- i := internal.MakeInstance(v).(*cue.Instance)
+ i := e.instance
+ if i == nil {
+ i = internal.MakeInstance(v).(*cue.Instance)
+ }
return openapi.Generate(i, cfg)
}
// case build.JSONSchema:
@@ -205,6 +209,15 @@
return e.encodeFile(f, e.interpret)
}
+// EncodeInstance is as Encode, but stores instance information. This should
+// all be retrievable from the value itself.
+func (e *Encoder) EncodeInstance(v *cue.Instance) error {
+ e.instance = v
+ err := e.Encode(v.Value())
+ e.instance = nil
+ return err
+}
+
func (e *Encoder) Encode(v cue.Value) error {
e.autoSimplify = true
if e.interpret != nil {