cmd/cue/cmd: track dependencies in definitions
Fixes #237
Change-Id: I338039742184bc7475e447cf5a6e21f11f81920e
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/4440
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/internal/walk/walk.go b/internal/walk/walk.go
new file mode 100644
index 0000000..8e3c9f9
--- /dev/null
+++ b/internal/walk/walk.go
@@ -0,0 +1,69 @@
+// Copyright 2019 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package walk allows walking over CUE values.
+//
+// This package replicates Value.Walk in the cue package.
+// There are several different internal uses of walk. This
+// package is intended as a single implementation that on
+// which all these implementations should converge. Once a
+// satisfactory API has been established, it can be made public.
+package walk
+
+import "cuelang.org/go/cue"
+
+// TODO:
+// - allow overriding options for descendants.
+// Perhaps func(f cue.Value) *Config?
+// - Get field information.
+
+// Alternatives:
+// type Visitor struct {}
+// func (v *Visitor) Do(cue.Value)
+// - less typing
+// - two elements are grouped together in UI.
+
+type Config struct {
+ Before func(f cue.Value) bool
+ After func(f cue.Value)
+ Opts []cue.Option
+}
+
+func Value(v cue.Value, c *Config) {
+ switch v.Kind() {
+ case cue.StructKind:
+ if c.Before != nil && !c.Before(v) {
+ return
+ }
+ iter, _ := v.Fields(c.Opts...)
+ for iter.Next() {
+ Value(iter.Value(), c)
+ }
+ case cue.ListKind:
+ if c.Before != nil && !c.Before(v) {
+ return
+ }
+ list, _ := v.List()
+ for list.Next() {
+ Value(list.Value(), c)
+ }
+ default:
+ if c.Before != nil {
+ c.Before(v)
+ }
+ }
+ if c.After != nil {
+ c.After(v)
+ }
+}