Skip to content

Commit

Permalink
gopls/internal/lsp/cache: isolate getWorkspaceInformation from Session
Browse files Browse the repository at this point in the history
getWorkspaceInformation will be a foundation of the zero-config gopls
algorithm, which we will want to be unit-testable. Therefore, separate
it from the session (it needs only a go command runner and file source).

While at it, separate workspace information from folder information.

For golang/go#57979

Change-Id: I79d6ad622dbd6f76afe979972a21b852f68ecf4d
Reviewed-on: https://go-review.googlesource.com/c/tools/+/538803
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: Alan Donovan <[email protected]>
Auto-Submit: Robert Findley <[email protected]>
Reviewed-by: Hyang-Ah Hana Kim <[email protected]>
  • Loading branch information
findleyr authored and gopherbot committed Nov 6, 2023
1 parent 4df4d8d commit 2ddaad7
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 25 deletions.
8 changes: 3 additions & 5 deletions gopls/internal/lsp/cache/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func (s *Session) createView(ctx context.Context, folder *Folder, seqID uint64)
index := atomic.AddInt64(&viewIndex, 1)

// Get immutable workspace information.
info, err := s.getWorkspaceInformation(ctx, folder.Dir, folder.Options)
info, err := getWorkspaceInformation(ctx, s.gocmdRunner, s, folder)
if err != nil {
return nil, nil, nil, err
}
Expand Down Expand Up @@ -419,7 +419,7 @@ func (s *Session) DidModifyFiles(ctx context.Context, changes []source.FileModif
// synchronously to change processing? Can we assume that the env did not
// change, and derive go.work using a combination of the configured
// GOWORK value and filesystem?
info, err := s.getWorkspaceInformation(ctx, view.folder.Dir, view.folder.Options)
info, err := getWorkspaceInformation(ctx, s.gocmdRunner, s, view.folder)
if err != nil {
// Catastrophic failure, equivalent to a failure of session
// initialization and therefore should almost never happen. One
Expand All @@ -430,9 +430,7 @@ func (s *Session) DidModifyFiles(ctx context.Context, changes []source.FileModif
// TODO(rfindley): consider surfacing this error more loudly. We
// could report a bug, but it's not really a bug.
event.Error(ctx, "fetching workspace information", err)
}

if info != view.workspaceInformation {
} else if *info != *view.workspaceInformation {
if err := s.updateViewLocked(ctx, view, view.folder); err != nil {
// More catastrophic failure. The view may or may not still exist.
// The best we can do is log and move on.
Expand Down
35 changes: 15 additions & 20 deletions gopls/internal/lsp/cache/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ type View struct {
// Workspace information. The fields below are immutable, and together with
// options define the build list. Any change to these fields results in a new
// View.
workspaceInformation // Go environment information
*workspaceInformation // Go environment information

importsState *importsState

Expand Down Expand Up @@ -122,9 +122,6 @@ type View struct {
//
// This type is compared to see if the View needs to be reconstructed.
type workspaceInformation struct {
// folder is the LSP workspace folder.
folder span.URI

// `go env` variables that need to be tracked by gopls.
goEnv

Expand Down Expand Up @@ -901,27 +898,25 @@ func (v *View) invalidateContent(ctx context.Context, changes map[span.URI]sourc
return v.snapshot, v.snapshot.Acquire()
}

func (s *Session) getWorkspaceInformation(ctx context.Context, folder span.URI, options *source.Options) (workspaceInformation, error) {
if err := checkPathCase(folder.Filename()); err != nil {
return workspaceInformation{}, fmt.Errorf("invalid workspace folder path: %w; check that the casing of the configured workspace folder path agrees with the casing reported by the operating system", err)
func getWorkspaceInformation(ctx context.Context, runner *gocommand.Runner, fs source.FileSource, folder *Folder) (*workspaceInformation, error) {
if err := checkPathCase(folder.Dir.Filename()); err != nil {
return nil, fmt.Errorf("invalid workspace folder path: %w; check that the casing of the configured workspace folder path agrees with the casing reported by the operating system", err)
}
info := new(workspaceInformation)
var err error
info := workspaceInformation{
folder: folder,
}
inv := gocommand.Invocation{
WorkingDir: folder.Filename(),
Env: options.EnvSlice(),
WorkingDir: folder.Dir.Filename(),
Env: folder.Options.EnvSlice(),
}
info.goversion, err = gocommand.GoVersion(ctx, inv, s.gocmdRunner)
info.goversion, err = gocommand.GoVersion(ctx, inv, runner)
if err != nil {
return info, err
}
info.goversionOutput, err = gocommand.GoVersionOutput(ctx, inv, s.gocmdRunner)
info.goversionOutput, err = gocommand.GoVersionOutput(ctx, inv, runner)
if err != nil {
return info, err
}
if err := info.load(ctx, folder.Filename(), options.EnvSlice(), s.gocmdRunner); err != nil {
if err := info.load(ctx, folder.Dir.Filename(), folder.Options.EnvSlice(), runner); err != nil {
return info, err
}
// The value of GOPACKAGESDRIVER is not returned through the go command.
Expand All @@ -933,15 +928,15 @@ func (s *Session) getWorkspaceInformation(ctx context.Context, folder span.URI,

// filterFunc is the path filter function for this workspace folder. Notably,
// it is relative to folder (which is specified by the user), not root.
filterFunc := pathExcludedByFilterFunc(folder.Filename(), info.gomodcache, options)
info.gomod, err = findWorkspaceModFile(ctx, folder, s, filterFunc)
filterFunc := pathExcludedByFilterFunc(folder.Dir.Filename(), info.gomodcache, folder.Options)
info.gomod, err = findWorkspaceModFile(ctx, folder.Dir, fs, filterFunc)
if err != nil {
return info, err
}

// Check if the workspace is within any GOPATH directory.
for _, gp := range filepath.SplitList(info.gopath) {
if source.InDir(filepath.Join(gp, "src"), folder.Filename()) {
if source.InDir(filepath.Join(gp, "src"), folder.Dir.Filename()) {
info.inGOPATH = true
break
}
Expand All @@ -955,10 +950,10 @@ func (s *Session) getWorkspaceInformation(ctx context.Context, folder span.URI,
//
// TODO(golang/go#57514): eliminate the expandWorkspaceToModule setting
// entirely.
if options.ExpandWorkspaceToModule && info.gomod != "" {
if folder.Options.ExpandWorkspaceToModule && info.gomod != "" {
info.goCommandDir = span.URIFromPath(filepath.Dir(info.gomod.Filename()))
} else {
info.goCommandDir = folder
info.goCommandDir = folder.Dir
}
return info, nil
}
Expand Down

0 comments on commit 2ddaad7

Please sign in to comment.