cmd/cue/cmd: enable placement logic for vet, export, and eval

Issue #255

Change-Id: I4803256a5296798a80b3db23fb4238541eb56c0f
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/5027
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cmd/cue/cmd/eval.go b/cmd/cue/cmd/eval.go
index 0508d4e..62a71ed 100644
--- a/cmd/cue/cmd/eval.go
+++ b/cmd/cue/cmd/eval.go
@@ -50,6 +50,8 @@
 		RunE: mkRunE(c, runEval),
 	}
 
+	addOrphanFlags(cmd.Flags())
+
 	cmd.Flags().StringArrayP(string(flagExpression), "e", nil, "evaluate this expression only")
 
 	cmd.Flags().BoolP(string(flagConcrete), "c", false,
diff --git a/cmd/cue/cmd/export.go b/cmd/cue/cmd/export.go
index ab29fd1..7957a29 100644
--- a/cmd/cue/cmd/export.go
+++ b/cmd/cue/cmd/export.go
@@ -86,6 +86,9 @@
 
 		RunE: mkRunE(c, runExport),
 	}
+
+	addOrphanFlags(cmd.Flags())
+
 	flagMedia.Add(cmd)
 	cmd.Flags().Bool(string(flagEscape), false, "use HTML escaping")
 
diff --git a/cmd/cue/cmd/script_test.go b/cmd/cue/cmd/script_test.go
index c66e694..9cbf6f7 100644
--- a/cmd/cue/cmd/script_test.go
+++ b/cmd/cue/cmd/script_test.go
@@ -69,7 +69,7 @@
 // Usage Comment out t.Skip() and set file to test.
 func TestX(t *testing.T) {
 	t.Skip()
-	const path = "./testdata/script/help_hello.txt"
+	const path = "./testdata/script/eval_context.txt"
 
 	check := func(err error) {
 		t.Helper()
@@ -103,7 +103,13 @@
 			continue
 		}
 
-		c, err := New(strings.Split(cmd, " ")[1:])
+		// TODO: Ugly hack to get args. Do more principled parsing.
+		var args []string
+		for _, a := range strings.Split(cmd, " ")[1:] {
+			args = append(args, strings.Trim(a, "'"))
+		}
+
+		c, err := New(args)
 		check(err)
 		b := &bytes.Buffer{}
 		c.SetOutput(b)
diff --git a/cmd/cue/cmd/testdata/script/eval_context.txt b/cmd/cue/cmd/testdata/script/eval_context.txt
new file mode 100644
index 0000000..54f4131
--- /dev/null
+++ b/cmd/cue/cmd/testdata/script/eval_context.txt
@@ -0,0 +1,29 @@
+cue eval --with-context -l '"\(path.Ext(filename)):\(index+1)/\(recordCount)"' -l 'data["@name"]' -s services.jsonl
+cmp stdout expect-stdout
+-- expect-stdout --
+".jsonl:1/3": elem1: {
+    kind:    "Service"
+    "@name": "elem1"
+}
+".jsonl:2/3": elem2: {
+    kind:    "Deployment"
+    "@name": "elem2"
+}
+".jsonl:3/3": elem3: {
+    kind:    "Service"
+    "@name": "elem3"
+}
+-- services.jsonl --
+{
+    "kind": "Service",
+    "@name": "elem1"
+}
+{
+    "kind": "Deployment",
+    "@name": "elem2"
+}
+{
+    "kind": "Service",
+    "@name": "elem3"
+}
+-- cue.mod --
diff --git a/cmd/cue/cmd/testdata/script/export_list.txt b/cmd/cue/cmd/testdata/script/export_list.txt
new file mode 100644
index 0000000..f6244af
--- /dev/null
+++ b/cmd/cue/cmd/testdata/script/export_list.txt
@@ -0,0 +1,39 @@
+cue export -l "\(strings.ToLower(kind))" --list import/services.jsonl
+cmp stdout expect-stdout
+-- expect-stdout --
+{
+    "service": [
+        {
+            "name": "booster",
+            "kind": "Service"
+        },
+        {
+            "name": "supplement\nfoo",
+            "kind": "Service",
+            "json": "[1, 2]"
+        }
+    ],
+    "deployment": [
+        {
+            "name": "booster",
+            "kind": "Deployment",
+            "replicas": 1
+        }
+    ]
+}
+-- import/services.jsonl --
+{
+    "kind": "Service",
+    "name": "booster"
+}
+{
+    "kind": "Deployment",
+    "name": "booster",
+    "replicas": 1
+}
+{
+    "kind": "Service",
+    "name": "supplement\nfoo",
+    "json": "[1, 2]"
+}
+-- cue.mod --
diff --git a/cmd/cue/cmd/testdata/script/import_list.txt b/cmd/cue/cmd/testdata/script/import_list.txt
index 8985511..3a9cbb1 100644
--- a/cmd/cue/cmd/testdata/script/import_list.txt
+++ b/cmd/cue/cmd/testdata/script/import_list.txt
@@ -17,23 +17,6 @@
 	name:     "booster"
 	replicas: 1
 }]
--- import/services.cue --
-service: [{
-	kind: "Service"
-	name: "booster"
-}, {
-	kind: "Service"
-	name: """
-		supplement
-		foo
-		"""
-	json: "[1, 2]"
-}]
-deployment: [{
-	kind:     "Deployment"
-	name:     "booster"
-	replicas: 1
-}]
 -- import/services.jsonl --
 {
     "kind": "Service",
diff --git a/cmd/cue/cmd/testdata/script/import_path.txt b/cmd/cue/cmd/testdata/script/import_path.txt
index 90ddb12..b6715a6 100644
--- a/cmd/cue/cmd/testdata/script/import_path.txt
+++ b/cmd/cue/cmd/testdata/script/import_path.txt
@@ -18,23 +18,6 @@
 		"""
 	json: "[1, 2]"
 }
--- import/services.cue --
-service: [{
-	kind: "Service"
-	name: "booster"
-}, {
-	kind: "Service"
-	name: """
-		supplement
-		foo
-		"""
-	json: "[1, 2]"
-}]
-deployment: [{
-	kind:     "Deployment"
-	name:     "booster"
-	replicas: 1
-}]
 -- import/services.jsonl --
 {
     "kind": "Service",
diff --git a/cmd/cue/cmd/testdata/script/vet_path.txt b/cmd/cue/cmd/testdata/script/vet_path.txt
new file mode 100644
index 0000000..de79a96
--- /dev/null
+++ b/cmd/cue/cmd/testdata/script/vet_path.txt
@@ -0,0 +1,27 @@
+! cue vet -l 'strings.ToLower(kind)' -l name services.jsonl services.cue
+cmp stderr expect-stderr
+-- expect-stderr --
+deployment.Booster.name: invalid value "Booster" (excluded by !~"[A-Z]*"):
+    ./services.cue:1:29
+    ./services.jsonl:3:13
+service.booster.name: invalid value "booster" (excluded by !~"[A-Z]*"):
+    ./services.cue:2:26
+    ./services.jsonl:3:13
+-- services.cue --
+deployment: [string]: name: !~"[A-Z]*"
+service: [string]: name: !~"[A-Z]*"
+
+-- services.jsonl --
+{
+    "kind": "Service",
+    "name": "booster"
+}
+{
+    "kind": "Deployment",
+    "name": "Booster",
+    "replicas": 1
+}
+{
+    "kind": "Service",
+    "name": "supplement\nfoo",
+}
\ No newline at end of file
diff --git a/cmd/cue/cmd/vet.go b/cmd/cue/cmd/vet.go
index f0ea5e2..f45b123 100644
--- a/cmd/cue/cmd/vet.go
+++ b/cmd/cue/cmd/vet.go
@@ -71,6 +71,8 @@
 		RunE:  mkRunE(c, doVet),
 	}
 
+	addOrphanFlags(cmd.Flags())
+
 	cmd.Flags().BoolP(string(flagConcrete), "c", false,
 		"require the evaluation to be concrete")
 
diff --git a/cue/load/loader.go b/cue/load/loader.go
index 4cef6ed..7ac0d01 100644
--- a/cue/load/loader.go
+++ b/cue/load/loader.go
@@ -30,6 +30,7 @@
 	"cuelang.org/go/cue/errors"
 	"cuelang.org/go/cue/token"
 	"cuelang.org/go/internal/filetypes"
+	"golang.org/x/xerrors"
 )
 
 // Instances returns the instances named by the command line arguments 'args'.
@@ -184,7 +185,10 @@
 	pkg.Dir = cfg.Dir
 	rewriteFiles(pkg, pkg.Dir, true)
 	for _, err := range errors.Errors(fp.finalize()) { // ImportDir(&ctxt, dir, 0)
-		pkg.ReportError(err)
+		var x *NoFilesError
+		if len(pkg.OrphanedFiles) > 0 && !xerrors.As(err, &x) {
+			pkg.ReportError(err)
+		}
 	}
 	// TODO: Support module importing.
 	// if ModDirImportPath != nil {