]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go/internal/test: add dep from test pkg build to real pkg build
authorIan Lance Taylor <iant@golang.org>
Thu, 18 Nov 2021 20:14:24 +0000 (12:14 -0800)
committerIan Lance Taylor <iant@golang.org>
Thu, 18 Nov 2021 22:40:42 +0000 (22:40 +0000)
If we have to build a test package, and if the full set of packages
being tested imports the regular package somewhere, then make building
the test package depend on building the regular package.  That way if
the regular package fails to build we only report the error once.

Fixes #44624

Change-Id: Ic7d66d8fec9c4688d369153a4b21194989f8def3
Reviewed-on: https://go-review.googlesource.com/c/go/+/365215
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
src/cmd/go/internal/test/test.go
src/cmd/go/testdata/script/build_single_error.txt [new file with mode: 0644]

index 73abca892758e9a94b9b8e9ccac4d73edc89453e..b7bbcb45136a7f4acf806296129b941f47d8cd75 100644 (file)
@@ -890,6 +890,17 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) {
                }
        }
 
+       // Collect all the packages imported by the packages being tested.
+       allImports := make(map[*load.Package]bool)
+       for _, p := range pkgs {
+               if p.Error != nil && p.Error.IsImportCycle {
+                       continue
+               }
+               for _, p1 := range p.Internal.Imports {
+                       allImports[p1] = true
+               }
+       }
+
        // Prepare build + run + print actions for all packages being tested.
        for _, p := range pkgs {
                // sync/atomic import is inserted by the cover tool. See #18486
@@ -897,7 +908,7 @@ func runTest(ctx context.Context, cmd *base.Command, args []string) {
                        ensureImport(p, "sync/atomic")
                }
 
-               buildTest, runTest, printTest, err := builderTest(&b, ctx, pkgOpts, p)
+               buildTest, runTest, printTest, err := builderTest(&b, ctx, pkgOpts, p, allImports[p])
                if err != nil {
                        str := err.Error()
                        str = strings.TrimPrefix(str, "\n")
@@ -964,7 +975,7 @@ var windowsBadWords = []string{
        "update",
 }
 
-func builderTest(b *work.Builder, ctx context.Context, pkgOpts load.PackageOpts, p *load.Package) (buildAction, runAction, printAction *work.Action, err error) {
+func builderTest(b *work.Builder, ctx context.Context, pkgOpts load.PackageOpts, p *load.Package, imported bool) (buildAction, runAction, printAction *work.Action, err error) {
        if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
                build := b.CompileAction(work.ModeBuild, work.ModeBuild, p)
                run := &work.Action{Mode: "test run", Package: p, Deps: []*work.Action{build}}
@@ -992,6 +1003,16 @@ func builderTest(b *work.Builder, ctx context.Context, pkgOpts load.PackageOpts,
                return nil, nil, nil, err
        }
 
+       // If imported is true then this package is imported by some
+       // package being tested. Make building the test version of the
+       // package depend on building the non-test version, so that we
+       // only report build errors once. Issue #44624.
+       if imported && ptest != p {
+               buildTest := b.CompileAction(work.ModeBuild, work.ModeBuild, ptest)
+               buildP := b.CompileAction(work.ModeBuild, work.ModeBuild, p)
+               buildTest.Deps = append(buildTest.Deps, buildP)
+       }
+
        // Use last element of import path, not package name.
        // They differ when package name is "main".
        // But if the import path is "command-line-arguments",
diff --git a/src/cmd/go/testdata/script/build_single_error.txt b/src/cmd/go/testdata/script/build_single_error.txt
new file mode 100644 (file)
index 0000000..241cdb9
--- /dev/null
@@ -0,0 +1,18 @@
+# go test ./... with a bad package should report the error once (#44624).
+! go test ./...
+stderr -count=1 undefined
+
+-- go.mod --
+module example.com
+
+go 1.18
+-- a/a.go --
+package a
+
+import "example.com/b"
+-- b/b.go --
+package b
+
+var X = Y
+-- b/b_test.go --
+package b