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/cmd/cue/cmd/custom.go b/cmd/cue/cmd/custom.go
index a8d5f82..60a9576 100644
--- a/cmd/cue/cmd/custom.go
+++ b/cmd/cue/cmd/custom.go
@@ -32,6 +32,7 @@
"cuelang.org/go/cue"
"cuelang.org/go/internal"
itask "cuelang.org/go/internal/task"
+ "cuelang.org/go/internal/walk"
_ "cuelang.org/go/pkg/tool/cli" // Register tasks
_ "cuelang.org/go/pkg/tool/exec"
_ "cuelang.org/go/pkg/tool/file"
@@ -292,10 +293,13 @@
switch op, args := v.Expr(); op {
case cue.NoOp:
- v.Walk(nil, func(w cue.Value) {
- if v != w {
- a = appendReferences(a, root, w)
- }
+ walk.Value(v, &walk.Config{
+ Opts: []cue.Option{cue.All()},
+ After: func(w cue.Value) {
+ if v != w {
+ a = appendReferences(a, root, w)
+ }
+ },
})
default:
for _, arg := range args {
diff --git a/cmd/cue/cmd/testdata/script/cmd_dep.txt b/cmd/cue/cmd/testdata/script/cmd_dep.txt
new file mode 100644
index 0000000..dcd7ec4
--- /dev/null
+++ b/cmd/cue/cmd/testdata/script/cmd_dep.txt
@@ -0,0 +1,32 @@
+cue cmd do
+cmp stdout expect-stdout
+
+-- expect-stdout --
+{"b":"cue\n"}
+-- task_tool.cue --
+package home
+
+import (
+ "encoding/json"
+ "tool/cli"
+ "tool/exec"
+)
+
+foo: {
+ a :: string
+ b: a
+}
+
+command: do: {
+ task: name: exec.Run & {
+ cmd: "echo cue"
+ stdout: string
+ }
+ task: out: cli.Print & {
+ text: json.Marshal(foo & { a :: task.name.stdout })
+ }
+}
+
+-- task.cue --
+package home
+-- cue.mod --
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)
+ }
+}