Skip to content

Commit c0cf190

Browse files
committed
cmd/go: do context propagation for tracing downloads
This change does context propagation (and only context propagation) necessary to add context to modfetch.Download and pkg.LoadImport. This was done by adding context to their callers, and then adding context to all call-sites, and then repeating adding context to callers of those enclosing functions and their callers until none were left. In some cases the call graph expansion was pruned by using context.TODOs. The next CL will add a span to Download. I kept it out of this change to avoid making it any larger (and harder to review) than it needs to be. Updates #38714 Change-Id: I5bf2d599aafef67334c384dfccd5e255198c85b4 Reviewed-on: https://go-review.googlesource.com/c/go/+/248327 Run-TryBot: Michael Matloob <matloob@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
1 parent 797124f commit c0cf190

25 files changed

+131
-113
lines changed

src/cmd/go/internal/get/get.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,9 @@ func download(arg string, parent *load.Package, stk *load.ImportStack, mode int)
246246
load1 := func(path string, mode int) *load.Package {
247247
if parent == nil {
248248
mode := 0 // don't do module or vendor resolution
249-
return load.LoadImport(path, base.Cwd, nil, stk, nil, mode)
249+
return load.LoadImport(context.TODO(), path, base.Cwd, nil, stk, nil, mode)
250250
}
251-
return load.LoadImport(path, parent.Dir, parent, stk, nil, mode|load.ResolveModule)
251+
return load.LoadImport(context.TODO(), path, parent.Dir, parent, stk, nil, mode|load.ResolveModule)
252252
}
253253

254254
p := load1(arg, mode)

src/cmd/go/internal/list/list.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"cmd/go/internal/cache"
2121
"cmd/go/internal/cfg"
2222
"cmd/go/internal/load"
23+
"cmd/go/internal/modinfo"
2324
"cmd/go/internal/modload"
2425
"cmd/go/internal/str"
2526
"cmd/go/internal/work"
@@ -349,7 +350,7 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
349350
fm := template.FuncMap{
350351
"join": strings.Join,
351352
"context": context,
352-
"module": modload.ModuleInfo,
353+
"module": func(path string) *modinfo.ModulePublic { return modload.ModuleInfo(ctx, path) },
353354
}
354355
tmpl, err := template.New("main").Funcs(fm).Parse(*listFmt)
355356
if err != nil {
@@ -389,7 +390,7 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
389390
base.Fatalf("go list -m: not using modules")
390391
}
391392

392-
modload.InitMod() // Parses go.mod and sets cfg.BuildMod.
393+
modload.InitMod(ctx) // Parses go.mod and sets cfg.BuildMod.
393394
if cfg.BuildMod == "vendor" {
394395
const actionDisabledFormat = "go list -m: can't %s using the vendor directory\n\t(Use -mod=mod or -mod=readonly to bypass.)"
395396

src/cmd/go/internal/load/pkg.go

+20-20
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ var (
4242
ModBinDir func() string // return effective bin directory
4343
ModLookup func(parentPath string, parentIsStd bool, path string) (dir, realPath string, err error) // lookup effective meaning of import
4444
ModPackageModuleInfo func(path string) *modinfo.ModulePublic // return module info for Package struct
45-
ModImportPaths func(args []string) []*search.Match // expand import paths
45+
ModImportPaths func(ctx context.Context, args []string) []*search.Match // expand import paths
4646
ModPackageBuildInfo func(main string, deps []string) string // return module info to embed in binary
4747
ModInfoProg func(info string, isgccgo bool) []byte // wrap module info in .go code for binary
48-
ModImportFromFiles func([]string) // update go.mod to add modules for imports in these files
48+
ModImportFromFiles func(context.Context, []string) // update go.mod to add modules for imports in these files
4949
ModDirImportPath func(string) string // return effective import path for directory
5050
)
5151

@@ -553,7 +553,7 @@ func ReloadPackageNoFlags(arg string, stk *ImportStack) *Package {
553553
})
554554
packageDataCache.Delete(p.ImportPath)
555555
}
556-
return LoadImport(arg, base.Cwd, nil, stk, nil, 0)
556+
return LoadImport(context.TODO(), arg, base.Cwd, nil, stk, nil, 0)
557557
}
558558

559559
// dirToImportPath returns the pseudo-import path we use for a package
@@ -605,11 +605,11 @@ const (
605605
// LoadImport does not set tool flags and should only be used by
606606
// this package, as part of a bigger load operation, and by GOPATH-based "go get".
607607
// TODO(rsc): When GOPATH-based "go get" is removed, unexport this function.
608-
func LoadImport(path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
609-
return loadImport(nil, path, srcDir, parent, stk, importPos, mode)
608+
func LoadImport(ctx context.Context, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
609+
return loadImport(ctx, nil, path, srcDir, parent, stk, importPos, mode)
610610
}
611611

612-
func loadImport(pre *preload, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
612+
func loadImport(ctx context.Context, pre *preload, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
613613
if path == "" {
614614
panic("LoadImport called with empty package path")
615615
}
@@ -657,7 +657,7 @@ func loadImport(pre *preload, path, srcDir string, parent *Package, stk *ImportS
657657
// Load package.
658658
// loadPackageData may return bp != nil even if an error occurs,
659659
// in order to return partial information.
660-
p.load(path, stk, importPos, bp, err)
660+
p.load(ctx, path, stk, importPos, bp, err)
661661

662662
if !cfg.ModulesEnabled && path != cleanImport(path) {
663663
p.Error = &PackageError{
@@ -1591,7 +1591,7 @@ func (p *Package) DefaultExecName() string {
15911591
// load populates p using information from bp, err, which should
15921592
// be the result of calling build.Context.Import.
15931593
// stk contains the import stack, not including path itself.
1594-
func (p *Package) load(path string, stk *ImportStack, importPos []token.Position, bp *build.Package, err error) {
1594+
func (p *Package) load(ctx context.Context, path string, stk *ImportStack, importPos []token.Position, bp *build.Package, err error) {
15951595
p.copyBuild(bp)
15961596

15971597
// The localPrefix is the path we interpret ./ imports relative to.
@@ -1800,7 +1800,7 @@ func (p *Package) load(path string, stk *ImportStack, importPos []token.Position
18001800
if path == "C" {
18011801
continue
18021802
}
1803-
p1 := LoadImport(path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], ResolveImport)
1803+
p1 := LoadImport(ctx, path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], ResolveImport)
18041804

18051805
path = p1.ImportPath
18061806
importPaths[i] = path
@@ -2073,7 +2073,7 @@ func PackageList(roots []*Package) []*Package {
20732073
// TestPackageList returns the list of packages in the dag rooted at roots
20742074
// as visited in a depth-first post-order traversal, including the test
20752075
// imports of the roots. This ignores errors in test packages.
2076-
func TestPackageList(roots []*Package) []*Package {
2076+
func TestPackageList(ctx context.Context, roots []*Package) []*Package {
20772077
seen := map[*Package]bool{}
20782078
all := []*Package{}
20792079
var walk func(*Package)
@@ -2089,7 +2089,7 @@ func TestPackageList(roots []*Package) []*Package {
20892089
}
20902090
walkTest := func(root *Package, path string) {
20912091
var stk ImportStack
2092-
p1 := LoadImport(path, root.Dir, root, &stk, root.Internal.Build.TestImportPos[path], ResolveImport)
2092+
p1 := LoadImport(ctx, path, root.Dir, root, &stk, root.Internal.Build.TestImportPos[path], ResolveImport)
20932093
if p1.Error == nil {
20942094
walk(p1)
20952095
}
@@ -2112,7 +2112,7 @@ func TestPackageList(roots []*Package) []*Package {
21122112
// TODO(jayconrod): delete this function and set flags automatically
21132113
// in LoadImport instead.
21142114
func LoadImportWithFlags(path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
2115-
p := LoadImport(path, srcDir, parent, stk, importPos, mode)
2115+
p := LoadImport(context.TODO(), path, srcDir, parent, stk, importPos, mode)
21162116
setToolFlags(p)
21172117
return p
21182118
}
@@ -2153,12 +2153,12 @@ func PackagesAndErrors(ctx context.Context, patterns []string) []*Package {
21532153
// We need to test whether the path is an actual Go file and not a
21542154
// package path or pattern ending in '.go' (see golang.org/issue/34653).
21552155
if fi, err := os.Stat(p); err == nil && !fi.IsDir() {
2156-
return []*Package{GoFilesPackage(patterns)}
2156+
return []*Package{GoFilesPackage(ctx, patterns)}
21572157
}
21582158
}
21592159
}
21602160

2161-
matches := ImportPaths(patterns)
2161+
matches := ImportPaths(ctx, patterns)
21622162
var (
21632163
pkgs []*Package
21642164
stk ImportStack
@@ -2174,7 +2174,7 @@ func PackagesAndErrors(ctx context.Context, patterns []string) []*Package {
21742174
if pkg == "" {
21752175
panic(fmt.Sprintf("ImportPaths returned empty package for pattern %s", m.Pattern()))
21762176
}
2177-
p := loadImport(pre, pkg, base.Cwd, nil, &stk, nil, 0)
2177+
p := loadImport(ctx, pre, pkg, base.Cwd, nil, &stk, nil, 0)
21782178
p.Match = append(p.Match, m.Pattern())
21792179
p.Internal.CmdlinePkg = true
21802180
if m.IsLiteral() {
@@ -2228,9 +2228,9 @@ func setToolFlags(pkgs ...*Package) {
22282228
}
22292229
}
22302230

2231-
func ImportPaths(args []string) []*search.Match {
2231+
func ImportPaths(ctx context.Context, args []string) []*search.Match {
22322232
if ModInit(); cfg.ModulesEnabled {
2233-
return ModImportPaths(args)
2233+
return ModImportPaths(ctx, args)
22342234
}
22352235
return search.ImportPaths(args)
22362236
}
@@ -2281,7 +2281,7 @@ func PackagesForBuild(ctx context.Context, args []string) []*Package {
22812281
// GoFilesPackage creates a package for building a collection of Go files
22822282
// (typically named on the command line). The target is named p.a for
22832283
// package p or named after the first Go file for package main.
2284-
func GoFilesPackage(gofiles []string) *Package {
2284+
func GoFilesPackage(ctx context.Context, gofiles []string) *Package {
22852285
ModInit()
22862286

22872287
for _, f := range gofiles {
@@ -2329,7 +2329,7 @@ func GoFilesPackage(gofiles []string) *Package {
23292329
ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
23302330

23312331
if cfg.ModulesEnabled {
2332-
ModImportFromFiles(gofiles)
2332+
ModImportFromFiles(ctx, gofiles)
23332333
}
23342334

23352335
var err error
@@ -2345,7 +2345,7 @@ func GoFilesPackage(gofiles []string) *Package {
23452345
pkg := new(Package)
23462346
pkg.Internal.Local = true
23472347
pkg.Internal.CmdlineFiles = true
2348-
pkg.load("command-line-arguments", &stk, nil, bp, err)
2348+
pkg.load(ctx, "command-line-arguments", &stk, nil, bp, err)
23492349
pkg.Internal.LocalPrefix = dirToImportPath(dir)
23502350
pkg.ImportPath = "command-line-arguments"
23512351
pkg.Target = ""

src/cmd/go/internal/load/test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func TestPackagesAndErrors(ctx context.Context, p *Package, cover *TestCover) (p
108108
stk.Push(p.ImportPath + " (test)")
109109
rawTestImports := str.StringList(p.TestImports)
110110
for i, path := range p.TestImports {
111-
p1 := loadImport(pre, path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], ResolveImport)
111+
p1 := loadImport(ctx, pre, path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], ResolveImport)
112112
if str.Contains(p1.Deps, p.ImportPath) || p1.ImportPath == p.ImportPath {
113113
// Same error that loadPackage returns (via reusePackage) in pkg.go.
114114
// Can't change that code, because that code is only for loading the
@@ -127,7 +127,7 @@ func TestPackagesAndErrors(ctx context.Context, p *Package, cover *TestCover) (p
127127
pxtestNeedsPtest := false
128128
rawXTestImports := str.StringList(p.XTestImports)
129129
for i, path := range p.XTestImports {
130-
p1 := loadImport(pre, path, p.Dir, p, &stk, p.Internal.Build.XTestImportPos[path], ResolveImport)
130+
p1 := loadImport(ctx, pre, path, p.Dir, p, &stk, p.Internal.Build.XTestImportPos[path], ResolveImport)
131131
if p1.ImportPath == p.ImportPath {
132132
pxtestNeedsPtest = true
133133
} else {
@@ -244,7 +244,7 @@ func TestPackagesAndErrors(ctx context.Context, p *Package, cover *TestCover) (p
244244
if dep == ptest.ImportPath {
245245
pmain.Internal.Imports = append(pmain.Internal.Imports, ptest)
246246
} else {
247-
p1 := loadImport(pre, dep, "", nil, &stk, nil, 0)
247+
p1 := loadImport(ctx, pre, dep, "", nil, &stk, nil, 0)
248248
pmain.Internal.Imports = append(pmain.Internal.Imports, p1)
249249
}
250250
}

src/cmd/go/internal/modcmd/download.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
9090
if len(args) == 0 {
9191
args = []string{"all"}
9292
} else if modload.HasModRoot() {
93-
modload.InitMod() // to fill Target
93+
modload.InitMod(ctx) // to fill Target
9494
targetAtLatest := modload.Target.Path + "@latest"
9595
targetAtUpgrade := modload.Target.Path + "@upgrade"
9696
targetAtPatch := modload.Target.Path + "@patch"
@@ -126,7 +126,7 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) {
126126
return
127127
}
128128
m.Sum = modfetch.Sum(mod)
129-
m.Dir, err = modfetch.Download(mod)
129+
m.Dir, err = modfetch.Download(ctx, mod)
130130
if err != nil {
131131
m.Error = err.Error()
132132
return

src/cmd/go/internal/modcmd/init.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,6 @@ func runInit(ctx context.Context, cmd *base.Command, args []string) {
5151
if strings.Contains(modload.CmdModModule, "@") {
5252
base.Fatalf("go mod init: module path must not contain '@'")
5353
}
54-
modload.InitMod() // does all the hard work
54+
modload.InitMod(ctx) // does all the hard work
5555
modload.WriteGoMod()
5656
}

src/cmd/go/internal/modcmd/tidy.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func runTidy(ctx context.Context, cmd *base.Command, args []string) {
4040
base.Fatalf("go mod tidy: no arguments allowed")
4141
}
4242

43-
modload.LoadALL()
43+
modload.LoadALL(ctx)
4444
modload.TidyBuildList()
4545
modload.TrimGoSum()
4646
modload.WriteGoMod()

src/cmd/go/internal/modcmd/vendor.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func runVendor(ctx context.Context, cmd *base.Command, args []string) {
4848
if len(args) != 0 {
4949
base.Fatalf("go mod vendor: vendor takes no arguments")
5050
}
51-
pkgs := modload.LoadVendor()
51+
pkgs := modload.LoadVendor(ctx)
5252

5353
vdir := filepath.Join(modload.ModRoot(), "vendor")
5454
if err := os.RemoveAll(vdir); err != nil {

src/cmd/go/internal/modcmd/why.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func runWhy(ctx context.Context, cmd *base.Command, args []string) {
7676
}
7777
mods := modload.ListModules(ctx, args, listU, listVersions)
7878
byModule := make(map[module.Version][]string)
79-
for _, path := range loadALL() {
79+
for _, path := range loadALL(ctx) {
8080
m := modload.PackageModule(path)
8181
if m.Path != "" {
8282
byModule[m] = append(byModule[m], path)
@@ -105,8 +105,8 @@ func runWhy(ctx context.Context, cmd *base.Command, args []string) {
105105
sep = "\n"
106106
}
107107
} else {
108-
matches := modload.ImportPaths(args) // resolve to packages
109-
loadALL() // rebuild graph, from main module (not from named packages)
108+
matches := modload.ImportPaths(ctx, args) // resolve to packages
109+
loadALL(ctx) // rebuild graph, from main module (not from named packages)
110110
sep := ""
111111
for _, m := range matches {
112112
for _, path := range m.Pkgs {

src/cmd/go/internal/modconv/convert_test.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package modconv
66

77
import (
88
"bytes"
9+
"context"
910
"fmt"
1011
"internal/testenv"
1112
"io/ioutil"
@@ -146,6 +147,8 @@ func TestConvertLegacyConfig(t *testing.T) {
146147
},
147148
}
148149

150+
ctx := context.Background()
151+
149152
for _, tt := range tests {
150153
t.Run(strings.ReplaceAll(tt.path, "/", "_")+"_"+tt.vers, func(t *testing.T) {
151154
f, err := modfile.Parse("golden", []byte(tt.gomod), nil)
@@ -157,7 +160,7 @@ func TestConvertLegacyConfig(t *testing.T) {
157160
t.Fatal(err)
158161
}
159162

160-
dir, err := modfetch.Download(module.Version{Path: tt.path, Version: tt.vers})
163+
dir, err := modfetch.Download(ctx, module.Version{Path: tt.path, Version: tt.vers})
161164
if err != nil {
162165
t.Fatal(err)
163166
}

src/cmd/go/internal/modfetch/fetch.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package modfetch
77
import (
88
"archive/zip"
99
"bytes"
10+
"context"
1011
"errors"
1112
"fmt"
1213
"io"
@@ -34,7 +35,7 @@ var downloadCache par.Cache
3435
// Download downloads the specific module version to the
3536
// local download cache and returns the name of the directory
3637
// corresponding to the root of the module's file tree.
37-
func Download(mod module.Version) (dir string, err error) {
38+
func Download(ctx context.Context, mod module.Version) (dir string, err error) {
3839
if cfg.GOMODCACHE == "" {
3940
// modload.Init exits if GOPATH[0] is empty, and cfg.GOMODCACHE
4041
// is set to GOPATH[0]/pkg/mod if GOMODCACHE is empty, so this should never happen.

0 commit comments

Comments
 (0)