Skip to content

Commit ef4d083

Browse files
hyangahgopherbot
authored andcommitted
gopls/internal/protocol/command: draft Packages/Modules API
This new Packages command provides information about go packages known to gopls. The Modules command reports modules known to gopls and found in the directory. For golang/go#59445 Change-Id: Ief0ac4984efb4a0e7f0fee8d8d55dae35eb00375 Reviewed-on: https://go-review.googlesource.com/c/tools/+/579438 LUCI-TryBot-Result: Go LUCI <[email protected]> Auto-Submit: Hyang-Ah Hana Kim <[email protected]> Reviewed-by: Ethan Reesor <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent d29feb5 commit ef4d083

File tree

5 files changed

+301
-0
lines changed

5 files changed

+301
-0
lines changed

gopls/doc/commands.md

+82
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,88 @@ Result:
515515
}
516516
```
517517

518+
<a id='gopls.modules'></a>
519+
## `gopls.modules`: **Return information about modules within a directory**
520+
521+
This command returns an empty result if there is no module,
522+
or if module mode is disabled.
523+
The result does not includes the modules that are not
524+
associated with any Views on the server yet.
525+
526+
Args:
527+
528+
```
529+
{
530+
// Dir is the directory in which to search for go.mod files.
531+
"Dir": string,
532+
// MaxDepth is the directory walk limit.
533+
// A value of 0 means inspect only Dir.
534+
// 1 means inspect its child directories too, and so on.
535+
// A negative value removes the limit.
536+
"MaxDepth": int,
537+
}
538+
```
539+
540+
Result:
541+
542+
```
543+
{
544+
"Modules": []{
545+
"Path": string,
546+
"Version": string,
547+
"GoMod": string,
548+
},
549+
}
550+
```
551+
552+
<a id='gopls.packages'></a>
553+
## `gopls.packages`: **Return information about packages**
554+
555+
This command returns an empty result if the specified files
556+
or directories are not associated with any Views on the
557+
server yet.
558+
559+
Args:
560+
561+
```
562+
{
563+
// Files is a list of files and directories whose associated
564+
// packages should be described by the result.
565+
//
566+
// In some cases, a file may belong to more than one package;
567+
// the result may describe any of them.
568+
"Files": []string,
569+
// Enumerate all packages under the directry loadable with
570+
// the ... pattern.
571+
// The search does not cross the module boundaries and
572+
// does not return packages that are not yet loaded.
573+
// (e.g. those excluded by the gopls directory filter setting,
574+
// or the go.work configuration)
575+
"Recursive": bool,
576+
// Mode controls the types of information returned for each package.
577+
"Mode": uint64,
578+
}
579+
```
580+
581+
Result:
582+
583+
```
584+
{
585+
// Packages is an unordered list of package metadata.
586+
"Packages": []{
587+
"Path": string,
588+
"ModulePath": string,
589+
"TestFiles": []{
590+
"URI": string,
591+
"Tests": { ... },
592+
},
593+
},
594+
// Modules maps module path to module metadata for
595+
// all the modules of the returned Packages.
596+
"Module": map[string]golang.org/x/tools/gopls/internal/protocol/command.Module,
597+
}
598+
```
599+
518600
<a id='gopls.regenerate_cgo'></a>
519601
## `gopls.regenerate_cgo`: **Regenerate cgo**
520602

gopls/internal/doc/api.json

+14
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,20 @@
10801080
"ArgDoc": "",
10811081
"ResultDoc": "{\n\t\"HeapAlloc\": uint64,\n\t\"HeapInUse\": uint64,\n\t\"TotalAlloc\": uint64,\n}"
10821082
},
1083+
{
1084+
"Command": "gopls.modules",
1085+
"Title": "Return information about modules within a directory",
1086+
"Doc": "This command returns an empty result if there is no module,\nor if module mode is disabled.\nThe result does not includes the modules that are not\nassociated with any Views on the server yet.",
1087+
"ArgDoc": "{\n\t// Dir is the directory in which to search for go.mod files.\n\t\"Dir\": string,\n\t// MaxDepth is the directory walk limit.\n\t// A value of 0 means inspect only Dir.\n\t// 1 means inspect its child directories too, and so on.\n\t// A negative value removes the limit.\n\t\"MaxDepth\": int,\n}",
1088+
"ResultDoc": "{\n\t\"Modules\": []{\n\t\t\"Path\": string,\n\t\t\"Version\": string,\n\t\t\"GoMod\": string,\n\t},\n}"
1089+
},
1090+
{
1091+
"Command": "gopls.packages",
1092+
"Title": "Return information about packages",
1093+
"Doc": "This command returns an empty result if the specified files\nor directories are not associated with any Views on the\nserver yet.",
1094+
"ArgDoc": "{\n\t// Files is a list of files and directories whose associated\n\t// packages should be described by the result.\n\t//\n\t// In some cases, a file may belong to more than one package;\n\t// the result may describe any of them.\n\t\"Files\": []string,\n\t// Enumerate all packages under the directry loadable with\n\t// the ... pattern.\n\t// The search does not cross the module boundaries and\n\t// does not return packages that are not yet loaded.\n\t// (e.g. those excluded by the gopls directory filter setting,\n\t// or the go.work configuration)\n\t\"Recursive\": bool,\n\t// Mode controls the types of information returned for each package.\n\t\"Mode\": uint64,\n}",
1095+
"ResultDoc": "{\n\t// Packages is an unordered list of package metadata.\n\t\"Packages\": []{\n\t\t\"Path\": string,\n\t\t\"ModulePath\": string,\n\t\t\"TestFiles\": []{\n\t\t\t\"URI\": string,\n\t\t\t\"Tests\": { ... },\n\t\t},\n\t},\n\t// Modules maps module path to module metadata for\n\t// all the modules of the returned Packages.\n\t\"Module\": map[string]golang.org/x/tools/gopls/internal/protocol/command.Module,\n}"
1096+
},
10831097
{
10841098
"Command": "gopls.regenerate_cgo",
10851099
"Title": "Regenerate cgo",

gopls/internal/protocol/command/command_gen.go

+40
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gopls/internal/protocol/command/interface.go

+157
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,21 @@ type Interface interface {
269269
//
270270
// This command is intended for use by gopls tests only.
271271
ScanImports(context.Context) error
272+
273+
// Packages: Return information about packages
274+
//
275+
// This command returns an empty result if the specified files
276+
// or directories are not associated with any Views on the
277+
// server yet.
278+
Packages(context.Context, PackagesArgs) (PackagesResult, error)
279+
280+
// Modules: Return information about modules within a directory
281+
//
282+
// This command returns an empty result if there is no module,
283+
// or if module mode is disabled.
284+
// The result does not includes the modules that are not
285+
// associated with any Views on the server yet.
286+
Modules(context.Context, ModulesArgs) (ModulesResult, error)
272287
}
273288

274289
type RunTestsArgs struct {
@@ -569,3 +584,145 @@ type View struct {
569584
Folder protocol.DocumentURI // workspace folder associated with the view
570585
EnvOverlay []string // environment variable overrides
571586
}
587+
588+
// PackagesArgs holds arguments for the Packages command.
589+
type PackagesArgs struct {
590+
// Files is a list of files and directories whose associated
591+
// packages should be described by the result.
592+
//
593+
// In some cases, a file may belong to more than one package;
594+
// the result may describe any of them.
595+
Files []protocol.DocumentURI
596+
597+
// Enumerate all packages under the directry loadable with
598+
// the ... pattern.
599+
// The search does not cross the module boundaries and
600+
// does not return packages that are not yet loaded.
601+
// (e.g. those excluded by the gopls directory filter setting,
602+
// or the go.work configuration)
603+
Recursive bool `json:"Recursive,omitempty"`
604+
605+
// Mode controls the types of information returned for each package.
606+
Mode PackagesMode
607+
}
608+
609+
// PackagesMode controls the details to include in PackagesResult.
610+
type PackagesMode uint64
611+
612+
const (
613+
// Populate the [TestFile.Tests] field in [Package] returned by the
614+
// Packages command.
615+
NeedTests PackagesMode = 1 << iota
616+
)
617+
618+
// PackagesResult is the result of the Packages command.
619+
type PackagesResult struct {
620+
// Packages is an unordered list of package metadata.
621+
Packages []Package
622+
623+
// Modules maps module path to module metadata for
624+
// all the modules of the returned Packages.
625+
Module map[string]Module
626+
}
627+
628+
// Package describes a Go package (not an empty parent).
629+
type Package struct {
630+
// Package path.
631+
Path string
632+
// Module path. Empty if the package doesn't
633+
// belong to any module.
634+
ModulePath string
635+
636+
// Note: the result does not include the directory name
637+
// of the package because mapping between a package and
638+
// a folder is not possible in certain build systems.
639+
// If directory info is needed, one can guess it
640+
// from the TestFile's file name.
641+
642+
// TestFiles contains the subset of the files of the package
643+
// whose name ends with "_test.go".
644+
// They are ordered deterministically as determined
645+
// by the underlying build system.
646+
TestFiles []TestFile
647+
}
648+
649+
type Module struct {
650+
Path string // module path
651+
Version string // module version if any.
652+
GoMod protocol.DocumentURI // path to the go.mod file.
653+
}
654+
655+
type TestFile struct {
656+
URI protocol.DocumentURI // a *_test.go file
657+
658+
// Tests is the list of tests in File, including subtests.
659+
//
660+
// The set of subtests is not exhaustive as in general they may be
661+
// dynamically generated, so it is impossible for static heuristics
662+
// to enumerate them.
663+
//
664+
// Tests are lexically ordered.
665+
// Since subtest names are prefixed by their top-level test names
666+
// each top-level test precedes its subtests.
667+
Tests []TestCase
668+
}
669+
670+
// TestCase represents a test case.
671+
// A test case can be a top-level Test/Fuzz/Benchmark/Example function,
672+
// as recognized by 'go list' or 'go test -list', or
673+
// a subtest within a top-level function.
674+
type TestCase struct {
675+
// Name is the complete name of the test (Test, Benchmark, Example, or Fuzz)
676+
// or the subtest as it appears in the output of go test -json.
677+
// The server may attempt to infer names of subtests by static
678+
// analysis; if so, it should aim to simulate the actual computed
679+
// name of the test, including any disambiguating suffix such as "#01".
680+
// To run only this test, clients need to compute the -run, -bench, -fuzz
681+
// flag values by first splitting the Name with “/” and
682+
// quoting each element with "^" + regexp.QuoteMeta(Name) + "$".
683+
// e.g. TestToplevel/Inner.Subtest → -run=^TestToplevel$/^Inner\.Subtest$
684+
Name string
685+
686+
// Loc is the filename and range enclosing this test function
687+
// or the subtest. This is used to place the gutter marker
688+
// and group tests based on location.
689+
// For subtests whose test names can be determined statically,
690+
// this can be either t.Run or the test data table
691+
// for table-driven setup.
692+
// Some testing frameworks allow to declare the actual test
693+
// logic in a different file. For example, one can define
694+
// a testify test suite in suite_test.go and use it from
695+
// main_test.go.
696+
/*
697+
-- main_test.go --
698+
...
699+
func TestFoo(t *testing.T) {
700+
suite.Run(t, new(MyTestSuite))
701+
}
702+
-- suite_test.go --
703+
type MyTestSuite struct {
704+
suite.Suite
705+
}
706+
func (suite *MyTestSuite) TestBar() { ... }
707+
*/
708+
// In this case, the testing framework creates "TestFoo/TestBar"
709+
// and the corresponding test case belongs to "main_test.go"
710+
// TestFile. However, the test case has "suite_test.go" as its
711+
// file location.
712+
Loc protocol.Location
713+
}
714+
715+
type ModulesArgs struct {
716+
// Dir is the directory in which to search for go.mod files.
717+
Dir protocol.DocumentURI
718+
719+
// MaxDepth is the directory walk limit.
720+
// A value of 0 means inspect only Dir.
721+
// 1 means inspect its child directories too, and so on.
722+
// A negative value removes the limit.
723+
MaxDepth int
724+
}
725+
726+
type ModulesResult struct {
727+
Modules []Module
728+
}

gopls/internal/server/command.go

+8
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ type commandHandler struct {
7171
params *protocol.ExecuteCommandParams
7272
}
7373

74+
func (h *commandHandler) Modules(context.Context, command.ModulesArgs) (command.ModulesResult, error) {
75+
panic("unimplemented")
76+
}
77+
78+
func (h *commandHandler) Packages(context.Context, command.PackagesArgs) (command.PackagesResult, error) {
79+
panic("unimplemented")
80+
}
81+
7482
func (h *commandHandler) MaybePromptForTelemetry(ctx context.Context) error {
7583
go h.s.maybePromptForTelemetry(ctx, true)
7684
return nil

0 commit comments

Comments
 (0)