@@ -46,6 +46,19 @@ func (s workspaceSource) String() string {
46
46
}
47
47
}
48
48
49
+ // workspaceCommon holds immutable information about the workspace setup.
50
+ //
51
+ // TODO(rfindley): there is some redundancy here with workspaceInformation.
52
+ // Reconcile these two types.
53
+ type workspaceCommon struct {
54
+ root span.URI
55
+ excludePath func (string ) bool
56
+
57
+ // explicitGowork is, if non-empty, the URI for the explicit go.work file
58
+ // provided via the user's environment.
59
+ explicitGowork span.URI
60
+ }
61
+
49
62
// workspace tracks go.mod files in the workspace, along with the
50
63
// gopls.mod file, to provide support for multi-module workspaces.
51
64
//
@@ -58,8 +71,8 @@ func (s workspaceSource) String() string {
58
71
// This type is immutable (or rather, idempotent), so that it may be shared
59
72
// across multiple snapshots.
60
73
type workspace struct {
61
- root span. URI
62
- excludePath func ( string ) bool
74
+ workspaceCommon
75
+
63
76
moduleSource workspaceSource
64
77
65
78
// activeModFiles holds the active go.mod files.
@@ -98,17 +111,21 @@ type workspace struct {
98
111
//
99
112
// TODO(rfindley): newWorkspace should perhaps never fail, relying instead on
100
113
// the criticalError method to surface problems in the workspace.
101
- // TODO(rfindley): this function should accept the GOWORK value, if specified
102
- // by the user.
103
- func newWorkspace (ctx context.Context , root span.URI , fs source.FileSource , excludePath func (string ) bool , go111moduleOff , useWsModule bool ) (* workspace , error ) {
114
+ func newWorkspace (ctx context.Context , root , explicitGowork span.URI , fs source.FileSource , excludePath func (string ) bool , go111moduleOff , useWsModule bool ) (* workspace , error ) {
104
115
ws := & workspace {
105
- root : root ,
106
- excludePath : excludePath ,
116
+ workspaceCommon : workspaceCommon {
117
+ root : root ,
118
+ explicitGowork : explicitGowork ,
119
+ excludePath : excludePath ,
120
+ },
107
121
}
108
122
109
123
// The user may have a gopls.mod or go.work file that defines their
110
124
// workspace.
111
- if err := loadExplicitWorkspaceFile (ctx , ws , fs ); err == nil {
125
+ //
126
+ // TODO(rfindley): if GO111MODULE=off, this looks wrong, though there are
127
+ // probably other problems.
128
+ if err := ws .loadExplicitWorkspaceFile (ctx , fs ); err == nil {
112
129
return ws , nil
113
130
}
114
131
@@ -140,15 +157,15 @@ func newWorkspace(ctx context.Context, root span.URI, fs source.FileSource, excl
140
157
// loadExplicitWorkspaceFile loads workspace information from go.work or
141
158
// gopls.mod files, setting the active modules, mod file, and module source
142
159
// accordingly.
143
- func loadExplicitWorkspaceFile (ctx context.Context , ws * workspace , fs source.FileSource ) error {
160
+ func ( ws * workspace ) loadExplicitWorkspaceFile (ctx context.Context , fs source.FileSource ) error {
144
161
for _ , src := range []workspaceSource {goWorkWorkspace , goplsModWorkspace } {
145
- fh , err := fs .GetFile (ctx , uriForSource (ws .root , src ))
162
+ fh , err := fs .GetFile (ctx , uriForSource (ws .root , ws . explicitGowork , src ))
146
163
if err != nil {
147
164
return err
148
165
}
149
166
contents , err := fh .Read ()
150
167
if err != nil {
151
- continue
168
+ continue // TODO(rfindley): is it correct to proceed here?
152
169
}
153
170
var file * modfile.File
154
171
var activeModFiles map [span.URI ]struct {}
@@ -313,15 +330,14 @@ func (w *workspace) Clone(ctx context.Context, changes map[span.URI]*fileChange,
313
330
// Clone the workspace. This may be discarded if nothing changed.
314
331
changed := false
315
332
result := & workspace {
316
- root : w .root ,
317
- moduleSource : w .moduleSource ,
318
- knownModFiles : make (map [span.URI ]struct {}),
319
- activeModFiles : make (map [span.URI ]struct {}),
320
- workFile : w .workFile ,
321
- mod : w .mod ,
322
- sum : w .sum ,
323
- wsDirs : w .wsDirs ,
324
- excludePath : w .excludePath ,
333
+ workspaceCommon : w .workspaceCommon ,
334
+ moduleSource : w .moduleSource ,
335
+ knownModFiles : make (map [span.URI ]struct {}),
336
+ activeModFiles : make (map [span.URI ]struct {}),
337
+ workFile : w .workFile ,
338
+ mod : w .mod ,
339
+ sum : w .sum ,
340
+ wsDirs : w .wsDirs ,
325
341
}
326
342
for k , v := range w .knownModFiles {
327
343
result .knownModFiles [k ] = v
@@ -391,7 +407,7 @@ func handleWorkspaceFileChanges(ctx context.Context, ws *workspace, changes map[
391
407
// exists or walk the filesystem if it has been deleted.
392
408
// go.work should override the gopls.mod if both exist.
393
409
for _ , src := range []workspaceSource {goWorkWorkspace , goplsModWorkspace } {
394
- uri := uriForSource (ws .root , src )
410
+ uri := uriForSource (ws .root , ws . explicitGowork , src )
395
411
// File opens/closes are just no-ops.
396
412
change , ok := changes [uri ]
397
413
if ! ok {
@@ -460,12 +476,15 @@ func handleWorkspaceFileChanges(ctx context.Context, ws *workspace, changes map[
460
476
}
461
477
462
478
// goplsModURI returns the URI for the gopls.mod file contained in root.
463
- func uriForSource (root span.URI , src workspaceSource ) span.URI {
479
+ func uriForSource (root , explicitGowork span.URI , src workspaceSource ) span.URI {
464
480
var basename string
465
481
switch src {
466
482
case goplsModWorkspace :
467
483
basename = "gopls.mod"
468
484
case goWorkWorkspace :
485
+ if explicitGowork != "" {
486
+ return explicitGowork
487
+ }
469
488
basename = "go.work"
470
489
default :
471
490
return ""
0 commit comments