cue/load: allow mixing anonymous packages in files mode

Also fixes a regression where multi-package errors
were gobbled.

A related but different issue is whether to allow a
directory with both files that have a package close
and ones that don't. The idea is to require an explicit
`package _` to indicate a package is anonymouse.

This change prepares for that in that it recognizes
`_` as an anonymous package.

Issue #190

Change-Id: Icc720cc033374b54731ed775a2075b8173479111
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/5240
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cmd/cue/cmd/testdata/script/load_pkg.txt b/cmd/cue/cmd/testdata/script/load_pkg.txt
new file mode 100644
index 0000000..8889087
--- /dev/null
+++ b/cmd/cue/cmd/testdata/script/load_pkg.txt
@@ -0,0 +1,45 @@
+# mixing two anonymous packages
+cue eval t.cue data.cue
+cmp stdout stdout-t
+
+# allow mixing named with anonymous package in files mode
+cue eval kube.cue data.cue
+cmp stdout stdout-files
+
+# allow mixing named with anonymous package in files mode
+cue eval kube.cue data.cue t.cue
+cmp stdout stdout-files
+
+# don't pick up the unnamed package in directory mode
+cue eval .
+cmp stdout stdout-pkg
+
+# don't allow mixing two differently named packages
+! cue eval kube.cue foo/kube2.cue
+
+-- data.cue --
+foo:3
+-- t.cue --
+package _
+
+foo: int
+bar: 3
+-- kube.cue --
+package kube
+
+foo: int
+bar: 3
+-- foo/kube2.cue --
+package kube2
+
+foo: int
+bar: 3
+-- stdout-t --
+foo: 3
+bar: 3
+-- stdout-files --
+foo: 3
+bar: 3
+-- stdout-pkg --
+foo: int
+bar: 3
diff --git a/cue/build/instance.go b/cue/build/instance.go
index 042ad58..8bb5b56 100644
--- a/cue/build/instance.go
+++ b/cue/build/instance.go
@@ -229,7 +229,7 @@
 		inst.Err = errors.Append(inst.Err, errors.Newf(pos, msg, args...))
 	})
 	_, pkg, pos := internal.PackageInfo(file)
-	if !inst.setPkg(pkg) && pkg != inst.PkgName {
+	if pkg != "" && pkg != "_" && !inst.setPkg(pkg) && pkg != inst.PkgName {
 		err := errors.Newf(pos,
 			"package name %q conflicts with previous package name %q",
 			pkg, inst.PkgName)
diff --git a/cue/load/errors.go b/cue/load/errors.go
index 926416b..2b0041c 100644
--- a/cue/load/errors.go
+++ b/cue/load/errors.go
@@ -150,7 +150,7 @@
 func (e *MultiplePackageError) Path() []string              { return nil }
 
 func (e *MultiplePackageError) Msg() (string, []interface{}) {
-	return "found packages %s (%s) and %s (%s) in %s", []interface{}{
+	return "found packages %q (%s) and %s (%s) in %q", []interface{}{
 		e.Packages[0],
 		e.Files[0],
 		e.Packages[1],
diff --git a/cue/load/import.go b/cue/load/import.go
index ab045ce..009041b 100644
--- a/cue/load/import.go
+++ b/cue/load/import.go
@@ -375,20 +375,22 @@
 		return false // don't mark as added
 	}
 
-	if p.PkgName == "" {
-		p.PkgName = pkg
-		fp.firstFile = base
-	} else if pkg != p.PkgName {
-		if fp.ignoreOther {
-			p.IgnoredCUEFiles = append(p.IgnoredCUEFiles, fullPath)
-			p.IgnoredFiles = append(p.IgnoredFiles, file)
-			return false
+	if pkg != "" && pkg != "_" {
+		if p.PkgName == "" {
+			p.PkgName = pkg
+			fp.firstFile = base
+		} else if pkg != p.PkgName {
+			if fp.ignoreOther {
+				p.IgnoredCUEFiles = append(p.IgnoredCUEFiles, fullPath)
+				p.IgnoredFiles = append(p.IgnoredFiles, file)
+				return false
+			}
+			return badFile(&MultiplePackageError{
+				Dir:      p.Dir,
+				Packages: []string{p.PkgName, pkg},
+				Files:    []string{fp.firstFile, base},
+			})
 		}
-		return badFile(&MultiplePackageError{
-			Dir:      p.Dir,
-			Packages: []string{p.PkgName, pkg},
-			Files:    []string{fp.firstFile, base},
-		})
 	}
 
 	isTest := strings.HasSuffix(base, "_test"+cueSuffix)
diff --git a/cue/load/loader.go b/cue/load/loader.go
index 74a9daa..16b7df9 100644
--- a/cue/load/loader.go
+++ b/cue/load/loader.go
@@ -185,7 +185,7 @@
 	rewriteFiles(pkg, pkg.Dir, true)
 	for _, err := range errors.Errors(fp.finalize()) { // ImportDir(&ctxt, dir, 0)
 		var x *NoFilesError
-		if len(pkg.OrphanedFiles) > 0 && !xerrors.As(err, &x) {
+		if len(pkg.OrphanedFiles) == 0 || !xerrors.As(err, &x) {
 			pkg.ReportError(err)
 		}
 	}