Skip to content

Commit 103fd0f

Browse files
matloobgopherbot
authored andcommitted
cmd/internal/pkgsite: improve godoc mode search in GOROOT
If a user starts go doc -http inside of GOROOT, we create three module getters when we only need one: We create a StdlibZip module getter which we're not going to use because we're using a local GOROOT, we create a gopackages module getter for the module determined as corresponding to the current directory, which is a stdlib module, and finally we create the NewGoPackagesStdlibModuleGetter, which is the main module getter for the standard library in that case. The StdlibZip module getter is not used when we're using a local GOROOT, so don't add it in that case. And if we detect that the module for a specified directory is std or cmd for the specified local GOROOT, skip adding it because it will be redundant with the module getter we create using NewGoPackagesStdlibModuleGetter specifically for the standard libarry. Removing the redundant module getter will prevent redundant search results returned by each of the gopackages module getters corresponding to the standard library. While we're here, if there's a VERSION file in GOROOT, set the version on the module metadata we return for the standard library to the stdlib.VersionForTag of that version, so we can report the version in the search results. Fixes golang/go#74459 Change-Id: If250f715b052f57f8668b02a57b4c96725be515a Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/687918 Reviewed-by: Jonathan Amsterdam <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> kokoro-CI: kokoro <[email protected]> Reviewed-by: Michael Matloob <[email protected]> Auto-Submit: Michael Matloob <[email protected]>
1 parent d4fd061 commit 103fd0f

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

cmd/internal/pkgsite/server.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func BuildServer(ctx context.Context, serverCfg ServerConfig) (*frontend.Server,
6969
}
7070
} else {
7171
var err error
72-
cfg.dirs, err = getModuleDirs(ctx, serverCfg.Paths, serverCfg.GoDocMode)
72+
cfg.dirs, err = getModuleDirs(ctx, serverCfg.Paths, serverCfg.GoRepoPath, serverCfg.GoDocMode)
7373
if err != nil {
7474
return nil, fmt.Errorf("searching modules: %v", err)
7575
}
@@ -122,7 +122,7 @@ func BuildServer(ctx context.Context, serverCfg ServerConfig) (*frontend.Server,
122122
//
123123
// An error is returned if any operations failed unexpectedly, or if no
124124
// requested directories contain any valid modules.
125-
func getModuleDirs(ctx context.Context, dirs []string, allowNoModules bool) (map[string][]frontend.LocalModule, error) {
125+
func getModuleDirs(ctx context.Context, dirs []string, goRepoPath string, allowNoModules bool) (map[string][]frontend.LocalModule, error) {
126126
dirModules := make(map[string][]frontend.LocalModule)
127127
for _, dir := range dirs {
128128
output, err := runGo(dir, "list", "-m", "-json")
@@ -136,6 +136,12 @@ func getModuleDirs(ctx context.Context, dirs []string, allowNoModules bool) (map
136136
if err := decoder.Decode(&m); err != nil {
137137
return nil, err
138138
}
139+
if allowNoModules && m.ModulePath == "std" && (m.Dir == filepath.Join(goRepoPath, "src") || m.Dir == filepath.Join(goRepoPath, "src", "cmd")) {
140+
// This module is in the stdlib in the GOROOT specified by goRepoPath. We will
141+
// already create a GoPackagesStdlibModuleGetter for that GOROOT, so don't
142+
// add a redundant module directory here.
143+
continue
144+
}
139145
if m.ModulePath != "command-line-arguments" {
140146
modules = append(modules, m)
141147
}
@@ -240,6 +246,7 @@ func buildGetters(ctx context.Context, cfg getterConfig) ([]fetch.ModuleGetter,
240246
getters = append(getters, g)
241247
}
242248

249+
var usingLocalStdlib bool
243250
if cfg.useLocalStdlib {
244251
goRepo := cfg.goRepoPath
245252
if goRepo == "" {
@@ -250,6 +257,7 @@ func buildGetters(ctx context.Context, cfg getterConfig) ([]fetch.ModuleGetter,
250257
if err != nil {
251258
log.Errorf(ctx, "loading packages from stdlib: %v", err)
252259
} else {
260+
usingLocalStdlib = true
253261
getters = append(getters, mg)
254262
}
255263
}
@@ -260,7 +268,9 @@ func buildGetters(ctx context.Context, cfg getterConfig) ([]fetch.ModuleGetter,
260268
getters = append(getters, fetch.NewProxyModuleGetter(cfg.proxy, source.NewClient(&http.Client{Timeout: time.Second})))
261269
}
262270

263-
getters = append(getters, fetch.NewStdlibZipModuleGetter())
271+
if !usingLocalStdlib {
272+
getters = append(getters, fetch.NewStdlibZipModuleGetter())
273+
}
264274

265275
return getters, nil
266276
}

internal/fetch/getters.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"go/doc"
1717
"go/parser"
1818
"go/token"
19+
goversion "go/version"
1920
"io"
2021
"io/fs"
2122
"os"
@@ -304,8 +305,10 @@ func NewGoPackagesStdlibModuleGetter(ctx context.Context, dir string) (*goPackag
304305
return nil, err
305306
}
306307

307-
stdmod := &packages.Module{Path: "std",
308-
Dir: filepath.Join(abs, "src"),
308+
stdmod := &packages.Module{
309+
Path: "std",
310+
Dir: filepath.Join(abs, "src"),
311+
Version: goVersion(abs),
309312
}
310313
modules := []*packages.Module{stdmod}
311314
for _, p := range pkgs {
@@ -320,6 +323,25 @@ func NewGoPackagesStdlibModuleGetter(ctx context.Context, dir string) (*goPackag
320323
}, nil
321324
}
322325

326+
// goVersion returns the go version of the go distribution at GOROOT, converted
327+
// into a semantic version that can be parsed by stdlib.TagForVersion; or LocalVersion,
328+
// if the version could not be determined. goVersion determines the version using
329+
// the VERSION file. Alternatively, it could run "go version" to get the version
330+
// in cases the VERSION file doesn't exist, but those versions likely wouldn't
331+
// be parsable by VersionForTag anyway.
332+
func goVersion(goroot string) string {
333+
b, err := os.ReadFile(filepath.Join(goroot, "VERSION"))
334+
if err != nil {
335+
return LocalVersion
336+
}
337+
b, _, _ = bytes.Cut(b, []byte("\n"))
338+
gov := strings.TrimSpace(string(b))
339+
if !goversion.IsValid(gov) {
340+
return LocalVersion
341+
}
342+
return stdlib.VersionForTag(gov)
343+
}
344+
323345
// findModule searches known modules for a module matching the provided path.
324346
func (g *goPackagesModuleGetter) findModule(path string) (*packages.Module, error) {
325347
i := sort.Search(len(g.modules), func(i int) bool {

0 commit comments

Comments
 (0)