x/tools/gopls: 当不是可获取的时,工作区忽略供应商目录

icnyk63a  于 5个月前  发布在  Go
关注(0)|答案(4)|浏览(58)

gopls版本

Build info
----------
golang.org/x/tools/gopls v0.8.3
    golang.org/x/tools/gopls@v0.8.3 h1:Mxm94ix8oSARQ6svioO6SxKEYWT/VCP54/448LOHzrk=
    github.com/BurntSushi/toml@v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU=
    github.com/google/go-cmp@v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
    github.com/sergi/go-diff@v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
    golang.org/x/exp/typeparams@v0.0.0-20220218215828-6cf2b201936e h1:qyrTQ++p1afMkO4DPEeLGq/3oTsdlvdH4vqZUBWzUKM=
    golang.org/x/mod@v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
    golang.org/x/sync@v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
    golang.org/x/sys@v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c=
    golang.org/x/text@v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
    golang.org/x/tools@v0.1.11-0.20220407163324-91bcfb1bdf9c h1:rYiuK/jn6TCxjAq1hQ6MR6pgOeP3A5gIHDxgrQ8Vbys=
    golang.org/x/vuln@v0.0.0-20220324005316-18fd808f5c7f h1:9dMzk88fnONra7zrEalqkRMGa9jMGf9B5mdzhYVyI28=
    golang.org/x/xerrors@v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
    honnef.co/go/tools@v0.3.0 h1:2LdYUZ7CIxnYgskbUZfY7FPggmqnh6shBqfWa8Tn3XU=
    mvdan.cc/gofumpt@v0.3.0 h1:kTojdZo9AcEYbQYhGuLf/zszYthRdhDNDUi2JKTxas4=
    mvdan.cc/xurls/v2@v2.4.0 h1:tzxjVAj+wSBmDcF6zBB7/myTy3gX9xvi8Tyr28AuQgc=
go: go1.18

go环境

GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/rh/.cache/go-build"
GOENV="/home/rh/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/rh/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/rh/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/rh/sdk/go1.18"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/rh/sdk/go1.18/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16.15"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1617301297=/tmp/go-build -gno-record-gcc-switches"

你做了什么?

我们的项目结构如下:

src/services/api/
  cmd/
    api/
      main.go
  [other pakcages ...]
  vendor/
    somepackage/
      ...
    modules.txt
  go.mod
go.work

我们在vendor/目录下有一些包,它们无法通过go-get获取,因此我们也在go.mod中手动管理它们。当api项目文件位于根目录时,这对gopls来说完全没有问题。但是在使用工作区时,gopls不会在vendor目录中查找导入的包并尝试go-get它们,对于某些包这是不可能的。这导致了一个BrokenImport错误,尽管go build运行时没有任何问题。

你的预期结果是什么?

在我看来,当Go工具链允许描述的过程时,gopls也应该能够接受仅位于vendor/目录中的无法通过go-get获取的包。

你看到的是什么?

gopls忽略了位于modules vendor/目录中的包,并尝试go-get它们。这失败了,导致了一个BrokenImport错误,尽管go build运行时没有任何问题。

编辑器和设置

我尝试了以下项目设置,希望能解决这个问题。

{
  "gopls": {
    "build.experimentalWorkspaceModule": true,
    "build.expandWorkspaceToModule": true
  }
}

日志

  • 以下日志并非来自上述项目,因为我不希望泄露关于我们项目的任何信息。但是我在一个测试项目中重现了这个问题,显示了完全相同的行为。*
6za6bjd0

6za6bjd01#

一般来说,当你在一个工作区中组合两个模块时,提供它们导入的包的选定版本可能高于在各个单独模块中选定的版本。(工作区中的一个模块可以升级另一个模块中以较低版本打包的无关紧要的依赖项,在这种情况下,正确版本的包根本不会在任何供应商目录中找到。)

svujldwt

svujldwt2#

这是当前工作区设计中的预期内容,不可更改。
不幸的是,依赖私有仓库的工作区需要能够将这些仓库获取到模块缓存中。

fruv7luv

fruv7luv3#

同意将来自工作区多个模块的供应商信息结合起来是不可行的。
然而,有趣的是,当工作区中只有一个模块时,我发现 go list 似乎可以正常工作(我认为),但 gopls 无法正常运行。
以下是一个让我感到困惑的情况。

--- go.work ---
go 1.18

use ./proj

--- proj/go.mod --
module proj

go 1.18

require golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3

require golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect

-- proj/main.go --
package main

import _ "golang.org/x/mod/modfile"

func main() {}

根据上述内容,从 proj 目录运行 GOWORK=off go mod vendor

go.work
proj/
   go.mod
   go.sum
   main.go
   vendor/
      ...

然后,

$ export GOMODCACHE=`$(mktemp -d)`
$ export GOPROXY=off
$ go list -f "{{.Dir}}" golang.org/x/mod/modfile
/tmp/repro/proj/vendor/golang.org/x/mod/modfile
$ cd proj; go list -f "{{.Dir}}" golang.org/x/mod/modfile
/tmp/repro/proj/vendor/golang.org/x/mod/modfile

另一方面, gopls 无法找到依赖项。

could not import golang.org/x/mod/modfile (no required module provides package "golang.org/x/mod/modfile") compiler [BrokenImport]

我无法解释 go 和 gopls 的行为差异。
@findleyr

tkclm6bt

tkclm6bt4#

重新开放以调查我们是否可以从gopls中部分缓解这个问题。

相关问题