cmd/cue/cmd: ignore optional fields for trim
There are rare cases where trim might remove an
optional field, but optional fields are more likely
to interfere with the removal logic.
Change-Id: Iab5b680cee9dbf0e0f4b06979ef43d2f0a5c6001
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/1804
Reviewed-by: Marcel van Lohuizen <mpvl@google.com>
diff --git a/cmd/cue/cmd/trim.go b/cmd/cue/cmd/trim.go
index 1da1dce..ae64826 100644
--- a/cmd/cue/cmd/trim.go
+++ b/cmd/cue/cmd/trim.go
@@ -100,6 +100,16 @@
)
func runTrim(cmd *cobra.Command, args []string) error {
+ // TODO: Do something more fine-grained. Optional fields are mostly not
+ // useful to consider as an optional field will almost never subsume
+ // another value. However, an optional field may subsume and therefore
+ // trigger the removal of another optional field.
+ // For now this is the better approach: trimming is not 100% accurate,
+ // and optional fields are just more likely to cause edge cases that may
+ // block a removal.
+ internal.DropOptional = true
+ defer func() { internal.DropOptional = false }()
+
log.SetOutput(cmd.OutOrStderr())
ctxt := build.NewContext(build.ParseOptions(parser.ParseComments))
@@ -352,7 +362,7 @@
// Build map of mixin fields.
valueMap := map[key]cue.Value{}
- for mIter, _ := in.Fields(cue.All()); mIter.Next(); {
+ for mIter, _ := in.Fields(cue.All(), cue.Optional(false)); mIter.Next(); {
valueMap[iterKey(mIter)] = mIter.Value()
}
diff --git a/cue/ast.go b/cue/ast.go
index c4a2366..5246b30 100644
--- a/cue/ast.go
+++ b/cue/ast.go
@@ -22,6 +22,7 @@
"cuelang.org/go/cue/build"
"cuelang.org/go/cue/literal"
"cuelang.org/go/cue/token"
+ "cuelang.org/go/internal"
)
// insertFile inserts the given file at the root of the instance.
@@ -285,6 +286,9 @@
}
case *ast.BasicLit, *ast.Ident:
+ if internal.DropOptional && opt {
+ break
+ }
attrs, err := createAttrs(v.ctx(), newNode(n), n.Attrs)
if err != nil {
return err
diff --git a/internal/internal.go b/internal/internal.go
index f9ff342..88b4b76 100644
--- a/internal/internal.go
+++ b/internal/internal.go
@@ -39,3 +39,7 @@
// instance must be of type *cue.Instance.
// The returned value is a cue.Value, which the caller must cast to.
var FromGoType func(instance, x interface{}) interface{}
+
+// DropOptional is a blanket override of handling optional values during
+// compilation. TODO: should we make this a build option?
+var DropOptional bool