Skip to content

Commit 03cb455

Browse files
committed
internal/modindex: suppress missing modcacheindex message
There are workflows where there will be no module cache, and no place to put the index. Gopls should cope with this case silently. (If there is no index, then there will be no unimported completions found, but in these workflows, that seems to be ok.) Fixes: golang/go#75505 Change-Id: Ie71951cb31b79542ff1480965292ac9d72b93f45 Reviewed-on: https://go-review.googlesource.com/c/tools/+/733520 Reviewed-by: Madeline Kalil <mkalil@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
1 parent 15d13e8 commit 03cb455

File tree

4 files changed

+77
-5
lines changed

4 files changed

+77
-5
lines changed

gopls/internal/cache/imports.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,8 @@ func (s *modcacheState) refreshIndex() {
191191
if err != nil {
192192
if s.indexErr != nil {
193193
s.indexErr = err // prefer most recent error
194-
} else {
195-
// Keep using stale s.index (if any).
194+
} else if s.index != nil {
195+
// Keep using stale s.index.
196196
log.Printf("modcacheState.refreshIndex: %v", err)
197197
}
198198
} else {

gopls/internal/cache/snapshot.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -978,7 +978,7 @@ func (s *Snapshot) WorkspaceMetadata(ctx context.Context) ([]*metadata.Package,
978978
defer s.mu.Unlock()
979979

980980
meta := make([]*metadata.Package, 0, s.workspacePackages.Len())
981-
for id, _ := range s.workspacePackages.All() {
981+
for id := range s.workspacePackages.All() {
982982
meta = append(meta, s.meta.Packages[id])
983983
}
984984
return meta, nil

gopls/internal/test/integration/completion/completion_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
. "golang.org/x/tools/gopls/internal/test/integration"
2424
"golang.org/x/tools/gopls/internal/test/integration/fake"
2525
"golang.org/x/tools/gopls/internal/util/bug"
26+
"golang.org/x/tools/internal/modindex"
2627
"golang.org/x/tools/internal/testenv"
2728
)
2829

@@ -1624,3 +1625,69 @@ go 1.24.2
16241625
}
16251626
})
16261627
}
1628+
1629+
func TestModIndexDirEmpty(t *testing.T) {
1630+
// Test for issue #75505. Do not run this test in parallel.
1631+
// Test that if modindex.IndexDir is empty, we still get stdlib completions
1632+
// but not unimported completions from modules.
1633+
1634+
// Save/restore IndexDir, and set it to empty string.
1635+
// This simulates having no module cache.
1636+
old := modindex.IndexDir
1637+
modindex.IndexDir = ""
1638+
defer func() { modindex.IndexDir = old }()
1639+
// for the paranoid, with modindex.IndexDir = old here, the test fails
1640+
1641+
const mod = `
1642+
-- go.mod --
1643+
module mod.com
1644+
go 1.22
1645+
require example.com v1.2.3
1646+
-- main.go --
1647+
package main
1648+
func main() {
1649+
_ = fmt.P
1650+
_ = blah.N
1651+
}
1652+
-- main2.go --
1653+
package main
1654+
import "example.com/blah"
1655+
func _() {
1656+
_ = blah.Hello
1657+
}
1658+
`
1659+
WithOptions(
1660+
WriteGoSum("."),
1661+
ProxyFiles(proxy), // providing example.com through GOPROXY to the go command
1662+
Settings{"importsSource": settings.ImportsSourceGopls},
1663+
).Run(t, mod, func(t *testing.T, env *Env) {
1664+
// We need example.com in the module cache, but not
1665+
// otherwise available to the completion logic.
1666+
env.RemoveWorkspaceFile("main2.go")
1667+
env.RunGoCommand("mod", "tidy")
1668+
env.Await(env.DoneWithChangeWatchedFiles())
1669+
1670+
env.OpenFile("main.go")
1671+
env.Await(env.DoneWithOpen())
1672+
1673+
// 1. Check stdlib completion (should work)
1674+
loc := env.RegexpSearch("main.go", "fmt.P()")
1675+
completions := env.Completion(loc)
1676+
if len(completions.Items) == 0 {
1677+
t.Errorf("stdlib completion failed to find fmt.Print...")
1678+
}
1679+
1680+
// 2. Check unimported completion (should fail)
1681+
// We look for "blah.H" which is from example.com
1682+
loc = env.RegexpSearch("main.go", "blah.N()")
1683+
completions = env.Completion(loc)
1684+
1685+
// We expect NO unimported completions for blah.Name because modindex is disabled.
1686+
for _, item := range completions.Items {
1687+
// We shouldn't get candidate from example.com/blah.
1688+
if strings.Contains(item.Detail, "example.com/blah") {
1689+
t.Errorf("unexpected unimported completion for blah with empty IndexDir: %v", item)
1690+
}
1691+
}
1692+
})
1693+
}

internal/modindex/index.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"encoding/csv"
1111
"fmt"
1212
"io"
13-
"log"
1413
"os"
1514
"path/filepath"
1615
"strconv"
@@ -114,7 +113,7 @@ var IndexDir string = func() string {
114113
}
115114
dir = filepath.Join(dir, "goimports")
116115
if err := os.MkdirAll(dir, 0777); err != nil {
117-
log.Printf("failed to create modcache index dir: %v", err)
116+
dir = "" // #75505, people complain about the error message
118117
}
119118
return dir
120119
}()
@@ -127,6 +126,9 @@ func Read(gomodcache string) (*Index, error) {
127126
if err != nil {
128127
return nil, err
129128
}
129+
if IndexDir == "" {
130+
return nil, os.ErrNotExist
131+
}
130132

131133
// Read the "link" file for the specified gomodcache directory.
132134
// It names the payload file.
@@ -227,6 +229,9 @@ func readIndexFrom(gomodcache string, r io.Reader) (*Index, error) {
227229

228230
// write writes the index file and updates the index directory to refer to it.
229231
func write(gomodcache string, ix *Index) error {
232+
if IndexDir == "" {
233+
return os.ErrNotExist
234+
}
230235
// Write the index into a payload file with a fresh name.
231236
f, err := os.CreateTemp(IndexDir, fmt.Sprintf("index-%d-*", CurrentVersion))
232237
if err != nil {

0 commit comments

Comments
 (0)