cmd/cue/cmd: fix regression that allowed space-separated fields again

Change-Id: I99e9343c2b227c77a525224c2adc875b4c7e3607
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/5643
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cmd/cue/cmd/common.go b/cmd/cue/cmd/common.go
index 4edfe36..15ea9dd 100644
--- a/cmd/cue/cmd/common.go
+++ b/cmd/cue/cmd/common.go
@@ -47,13 +47,12 @@
 
 var defaultConfig = config{
 	loadCfg: &load.Config{
-		Context: build.NewContext(
-			build.ParseFile(func(name string, src interface{}) (*ast.File, error) {
-				return parser.ParseFile(name, src,
-					parser.FromVersion(syntaxVersion),
-					parser.ParseComments,
-				)
-			})),
+		ParseFile: func(name string, src interface{}) (*ast.File, error) {
+			return parser.ParseFile(name, src,
+				parser.FromVersion(syntaxVersion),
+				parser.ParseComments,
+			)
+		},
 	},
 }
 
diff --git a/cmd/cue/cmd/script_test.go b/cmd/cue/cmd/script_test.go
index 736271b..c48d7e0 100644
--- a/cmd/cue/cmd/script_test.go
+++ b/cmd/cue/cmd/script_test.go
@@ -23,7 +23,8 @@
 // even if still valid in backwards compatibility mode.
 func TestLatest(t *testing.T) {
 	filepath.Walk("testdata/script", func(fullpath string, info os.FileInfo, err error) error {
-		if !strings.HasSuffix(fullpath, ".txt") {
+		if !strings.HasSuffix(fullpath, ".txt") ||
+			strings.HasPrefix(filepath.Base(fullpath), "legacy") {
 			return nil
 		}
 
diff --git a/cmd/cue/cmd/testdata/script/legacy.txt b/cmd/cue/cmd/testdata/script/legacy.txt
new file mode 100644
index 0000000..1b92cc3
--- /dev/null
+++ b/cmd/cue/cmd/testdata/script/legacy.txt
@@ -0,0 +1,22 @@
+! cue eval foo.cue
+cmp stderr expect-stderr
+
+! cue export foo.cue
+cmp stderr expect-stderr
+
+cue fmt foo.cue
+cmp foo.cue foo-new.cue
+
+-- expect-stderr --
+space-separated labels deprecated as of v0.0.13: try running `cue fmt` on the file to upgrade.:
+    ./foo.cue:1:3
+old-style comprehensions deprecated as of v0.0.11: try running `cue fmt` on the file to upgrade.:
+    ./foo.cue:2:8
+-- foo.cue --
+a b: 2
+"x": 3 for x in a
+-- foo-new.cue --
+a: b: 2
+for x in a {
+	"x": 3
+}
\ No newline at end of file
diff --git a/cue/load/config.go b/cue/load/config.go
index 95d883e..cdea276 100644
--- a/cue/load/config.go
+++ b/cue/load/config.go
@@ -23,6 +23,7 @@
 	"strings"
 
 	"cuelang.org/go/cue"
+	"cuelang.org/go/cue/ast"
 	"cuelang.org/go/cue/build"
 	"cuelang.org/go/cue/errors"
 	"cuelang.org/go/cue/token"
@@ -175,6 +176,19 @@
 	// This is mostly used for bootstrapping.
 	StdRoot string
 
+	// ParseFile is called to read and parse each file when preparing a
+	// package's syntax tree. It must be safe to call ParseFile simultaneously
+	// from multiple goroutines. If ParseFile is nil, the loader will uses
+	// parser.ParseFile.
+	//
+	// ParseFile should parse the source from src and use filename only for
+	// recording position information.
+	//
+	// An application may supply a custom implementation of ParseFile to change
+	// the effective file contents or the behavior of the parser, or to modify
+	// the syntax tree.
+	ParseFile func(name string, src interface{}) (*ast.File, error)
+
 	// Overlay provides a mapping of absolute file paths to file contents.
 	// If the file  with the given path already exists, the parser will use the
 	// alternative file contents provided by the map.
diff --git a/cue/load/loader.go b/cue/load/loader.go
index 3e3c789..d62a2bb 100644
--- a/cue/load/loader.go
+++ b/cue/load/loader.go
@@ -176,7 +176,10 @@
 
 func (l *loader) addFiles(dir string, p *build.Instance) {
 	for _, f := range p.BuildFiles {
-		d := encoding.NewDecoder(f, &encoding.Config{Stdin: l.cfg.stdin()})
+		d := encoding.NewDecoder(f, &encoding.Config{
+			Stdin:     l.cfg.stdin(),
+			ParseFile: l.cfg.ParseFile,
+		})
 		for ; !d.Done(); d.Next() {
 			_ = p.AddSyntax(d.File())
 		}
diff --git a/internal/encoding/encoding.go b/internal/encoding/encoding.go
index 6618a02..0a0b07c 100644
--- a/internal/encoding/encoding.go
+++ b/internal/encoding/encoding.go
@@ -134,6 +134,7 @@
 	EscapeHTML bool
 	ProtoPath  []string
 	Format     []format.Option
+	ParseFile  func(name string, src interface{}) (*ast.File, error)
 }
 
 // NewDecoder returns a stream of non-rooted data expressions. The encoding
@@ -190,7 +191,11 @@
 	path := f.Filename
 	switch f.Encoding {
 	case build.CUE:
-		i.file, i.err = parser.ParseFile(path, r, parser.ParseComments)
+		if cfg.ParseFile == nil {
+			i.file, i.err = parser.ParseFile(path, r, parser.ParseComments)
+		} else {
+			i.file, i.err = cfg.ParseFile(path, r)
+		}
 		i.validate(i.file, f)
 	case build.JSON, build.JSONL:
 		i.next = json.NewDecoder(nil, path, r).Extract