]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: add 'work' package pattern
authorMichael Matloob <matloob@golang.org>
Thu, 16 Jan 2025 22:05:02 +0000 (17:05 -0500)
committerMichael Matloob <matloob@golang.org>
Thu, 6 Mar 2025 19:14:22 +0000 (11:14 -0800)
The 'work' package pattern will resolve to the set of packages in the
work (formerly called main) modules. It's essentially 'all', but without
the dependencies. And the implementation is similar to that of 'all',
except that we don't expand to the dependencies.

Fixes #71294

Change-Id: I3d02beb74fa4e5c6de2290e24eedc51745d13080
Reviewed-on: https://go-review.googlesource.com/c/go/+/643235
Reviewed-by: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/go/internal/load/search.go
src/cmd/go/internal/modload/load.go
src/cmd/go/internal/search/search.go
src/cmd/go/testdata/script/build_perpkgflag.txt [new file with mode: 0644]
src/cmd/go/testdata/script/list_pattern_work.txt [new file with mode: 0644]

index 565996a21fa1147db603107bf7f5cfedb3ee7f2c..941cfb77a2ec082bf5005bae1b6d79221e1a9642 100644 (file)
@@ -8,6 +8,7 @@ import (
        "path/filepath"
        "strings"
 
+       "cmd/go/internal/modload"
        "cmd/go/internal/search"
        "cmd/internal/pkgpattern"
 )
@@ -45,11 +46,23 @@ func MatchPackage(pattern, cwd string) func(*Package) bool {
                        return matchPath(rel)
                }
        case pattern == "all":
+               // This is slightly inaccurate: it matches every package, which isn't the same
+               // as matching the "all" package pattern.
+               // TODO(matloob): Should we make this more accurate? Does anyone depend on this behavior?
                return func(p *Package) bool { return true }
        case pattern == "std":
                return func(p *Package) bool { return p.Standard }
        case pattern == "cmd":
                return func(p *Package) bool { return p.Standard && strings.HasPrefix(p.ImportPath, "cmd/") }
+       case pattern == "tool" && modload.Enabled():
+               return func(p *Package) bool {
+                       return modload.MainModules.Tools()[p.ImportPath]
+               }
+       case pattern == "work" && modload.Enabled():
+               return func(p *Package) bool {
+                       return p.Module != nil && modload.MainModules.Contains(p.Module.Path)
+               }
+
        default:
                matchPath := pkgpattern.MatchPattern(pattern)
                return func(p *Package) bool { return matchPath(p.ImportPath) }
index 1a3a4b5a694493c9ec780374b215706f008e76d3..67a41250675fe992686ca4c6d69e98878c78f7af 100644 (file)
@@ -323,6 +323,13 @@ func LoadPackages(ctx context.Context, opts PackageOpts, patterns ...string) (ma
                                }
                                matchPackages(ctx, m, opts.Tags, includeStd, mg.BuildList())
 
+                       case m.Pattern() == "work":
+                               matchModules := MainModules.Versions()
+                               if opts.MainModule != (module.Version{}) {
+                                       matchModules = []module.Version{opts.MainModule}
+                               }
+                               matchPackages(ctx, m, opts.Tags, omitStd, matchModules)
+
                        case m.Pattern() == "all":
                                if ld == nil {
                                        // The initial roots are the packages and tools in the main module.
index abc6b8b43c0f284da9e9d4d804303dbbfcad5470..0d83cbd47d3008305c83c9f6f9cada5823ba616c 100644 (file)
@@ -60,14 +60,14 @@ func (m *Match) IsLocal() bool {
 }
 
 // IsMeta reports whether the pattern is a “meta-package” keyword that represents
-// multiple packages, such as "std", "cmd", "tool", or "all".
+// multiple packages, such as "std", "cmd", "tool", "work", or "all".
 func (m *Match) IsMeta() bool {
        return IsMetaPackage(m.pattern)
 }
 
 // IsMetaPackage checks if name is a reserved package name that expands to multiple packages.
 func IsMetaPackage(name string) bool {
-       return name == "std" || name == "cmd" || name == "tool" || name == "all"
+       return name == "std" || name == "cmd" || name == "tool" || name == "work" || name == "all"
 }
 
 // A MatchError indicates an error that occurred while attempting to match a
diff --git a/src/cmd/go/testdata/script/build_perpkgflag.txt b/src/cmd/go/testdata/script/build_perpkgflag.txt
new file mode 100644 (file)
index 0000000..9a60756
--- /dev/null
@@ -0,0 +1,35 @@
+# Test the work and tool patterns in a per-package flag
+
+go build -n '-gcflags=work=-fakeflag' example.com/foo/a
+stderr 'compile.*-p example.com/foo/a.*-fakeflag'
+! stderr 'compile.*-p example.com/dep.*-fakeflag'
+
+go build -n '-gcflags=tool=-fakeflag' example.com/foo/a example.com/dep/tooldep
+! stderr 'compile.*-p example.com/foo/a.*-fakeflag'
+! stderr 'compile.*-p example.com/dep.*-fakeflag'
+stderr 'compile.*-p main.*-fakeflag.*main.go'
+
+-- go.mod --
+module example.com/foo
+
+go 1.24
+
+tool example.com/dep/tooldep
+
+require example.com/dep v1.0.0
+
+replace example.com/dep => ./dep
+-- a/a.go --
+package a
+
+import _ "example.com/dep"
+-- dep/go.mod --
+module example.com/dep
+
+go 1.24
+-- dep/dep.go --
+package dep
+-- dep/tooldep/main.go --
+package main
+
+import _ "example.com/dep"
diff --git a/src/cmd/go/testdata/script/list_pattern_work.txt b/src/cmd/go/testdata/script/list_pattern_work.txt
new file mode 100644 (file)
index 0000000..bb2911a
--- /dev/null
@@ -0,0 +1,79 @@
+cd m
+go list all
+stdout 'example.com/dep'
+stdout 'example.com/m/a'
+stdout 'example.com/m/b'
+go list work
+! stdout 'example.com/dep'
+stdout 'example.com/m/a'
+stdout 'example.com/m/b'
+
+cd ../n
+go list all
+stdout 'example.com/n/c'
+stdout 'example.com/n/d'
+stdout 'unsafe'
+go list work
+stdout 'example.com/n/c'
+stdout 'example.com/n/d'
+! stdout 'unsafe'
+
+cd ../w
+go list all
+stdout 'example.com/dep'
+stdout 'example.com/m/a'
+stdout 'example.com/m/b'
+stdout 'example.com/n/c'
+stdout 'example.com/n/d'
+stdout 'unsafe'
+go list work
+! stdout 'example.com/dep'
+stdout 'example.com/m/a'
+stdout 'example.com/m/b'
+stdout 'example.com/n/c'
+stdout 'example.com/n/d'
+! stdout 'unsafe'
+
+-- m/go.mod --
+module example.com/m
+
+go 1.24
+
+require example.com/dep v1.0.0
+replace example.com/dep v1.0.0 => ../dep
+-- m/a/a.go --
+package a
+-- m/b/b.go --
+package b
+
+import _ "example.com/dep"
+-- n/go.mod --
+module example.com/n
+
+go 1.24
+-- n/c/c.go --
+package c
+-- n/d/d.go --
+package d
+
+import _ "unsafe"
+-- w/go.work --
+go 1.24
+
+use (
+       ../m
+       ../n
+)
+-- dep/go.mod --
+module example.com/dep
+
+go 1.24
+-- dep/dep.go --
+package dep
+-- want_w_all.txt --
+example.com/dep
+example.com/work/a
+example.com/work/b
+-- want_w_all.txt --
+example.com/work/a
+example.com/work/b