x/tools/cmd/gopls:返回已知包中新添加的模块

gijlo24d  于 2个月前  发布在  Go
关注(0)|答案(4)|浏览(29)

已知包(KnownPackages)是一个gopls命令,它返回一个工作区文件可以添加到其"import"语句的所有包的列表。
它目前被VSCode的"Add Import"功能使用。
然而,如果你刚刚在一个新模块上运行了一个"go get"命令,那么这个新模块的包将不会显示出来。这是因为它是一个"新添加的模块",意味着它记录在你的go.mod文件中,但你的Go文件中还没有导入这个模块中的任何包。这通常是你想要列出可用的包以将其添加到你的import语句的典型时间。
KnownPackages不返回新添加模块包的原因在于KnownPackages的实现做了两件事:

  1. 它考虑了在其会话中缓存的所有导入路径(显然这些路径还没有新添加的模块)
  2. 它通过GetAllCandidates函数随机搜索你所有的GOMODCACHE,但只限制自己在80毫秒内,并返回部分结果。这是因为搜索你所有的GOMODCACHE目录需要太长时间。因此,它是有成功和失败之分的,而且经常返回完全不相关的结果。

建议

我建议我们将上述实现更改为更可靠的内容,并解决上面提到的"新添加的模块"问题:
当客户端请求相对于某个文件的KnownPackages时,我们只需通过调用snapshot.GoModForFile获取属于该文件的go.mod,然后解析该文件以获取其依赖项。从那里开始,我们可以简单地遍历"require"语句,找到它们的位置并返回每个模块@版本中的有效包。
这实现了以下几点:

  1. 它只考虑你的新添加的模块并显示它的包。
  2. 它应该相当快,因为我们不需要运行任何"go list"或搜索所有的GOMODCACHE,而只是在你的工作区中查找go.mod文件的内容。另外值得注意的是,"go list"分析了你的导入路径(据我所知),这意味着它会跳过任何新添加的模块。
  3. 在你的go.mod文件中有Go1.17时,我们知道所有直接或间接的依赖关系是否都记录在那里,所以我们总是返回真正可以在你的模块中导入的每一个包。对于低于那个版本的版本,我们可以选择保留旧的行为或者应用新的行为,因为你通常不会导入你可能甚至不知道存在于你的传递依赖关系中的间接包。
    替代方案:
  4. 从根go.mod目录运行"go list"(不会捕获新添加的模块)
    边缘情况:
  5. 当然,这在GOPATH模式下是行不通的,但在那种情况下,我们可以默认采用旧的行为或者只显示标准库包。
  6. 在GOPATH/Module模式下,我们可以只显示标准库包。
bwleehnv

bwleehnv1#

https://golang.org/cl/351650提到了这个问题:internal/lsp/source: Deduce KnownPackages from the go.mod file

bis0qfac

bis0qfac2#

我使用的是gopls 0.8.1版本,list_known_packages返回的包列表不完整。将80毫秒修改为30秒后,将返回完整的包列表。

33qvvth1

33qvvth13#

任何回应?添加导入是一个非常有用的操作。

yv5phkfx

yv5phkfx4#

go list -f "{{.Name}};{{.ImportPath}}" all is incomplete in go mod, nearly two-thirds less.
go list -f "{{.Name}};{{.ImportPath}}" all
gopkgs -format '{{.Name}};{{.ImportPath}};{{.Dir}}' -workDir ./

相关问题