From 94c04cfc5fc3108584512cd27eaa936771648281 Mon Sep 17 00:00:00 2001 From: Iwasaki Yudai Date: Wed, 6 Feb 2019 13:15:45 -0800 Subject: [PATCH] Fix errors in non-moduled dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What's Observed =============== Bingo returns errors when I open files in the $GOPATH/pkg/mod directory (on Emacs with lsp-mode). For example, textDocument/hover requests fail with the following error message: ``` --> request #165: textDocument/hover: {"textDocument":{"uri":"file:///home/yudai/gopath/pkg/mod/k8s.io/kubernetes@v1.13.3/pkg/kubelet/pod/pod_manager.go"},"position":{"line":131,"character":0}} <-- error #165: textDocument/hover: {"code":0,"message":"go [list -f {{context.GOARCH}} {{context.Compiler}} -- unsafe]: exit status 1: go: creating new go.mod: module k8s.io/kubernetes\ngo: copying requirements from ../../../Godeps/Godeps.json\ngo: open /home/yudai/gopath/pkg/mod/k8s.io/kubernetes@v1.13.3/go.mod: permission denied\n","data":null} ``` Root Cause ========== The command `go [list -f {{context.GOARCH}} {{context.Compiler}} -- unsafe` is executed by `GetSizesGolist()` in golang.org/x/tools: https://github.com/golang/tools/blob/79186431cf2917562ba2e632326924b5594ce114/go/internal/packagesdriver/sizes.go#L81 The `go list` command actually fails alone if you run it on the directory of a non-moduled (no go.mod) dependency package. ``` $ echo $GO111MODULE on $ pwd /home/yudai/gopath/pkg/mod/k8s.io/kubernetes@v1.13.3 $ go list -f '{{context.GOARCH}} {{context.Compiler}}' -- unsafe go: creating new go.mod: module k8s.io/kubernetes go: copying requirements from Godeps/Godeps.json go: open /home/yudai/gopath/pkg/mod/k8s.io/kubernetes@v1.13.3/go.mod: permission denied ``` It seems `go list ` tries to create `go.md` when `GO111MODULE` is on even if you are in `pkg/mod`. However since directories in `pkg/mod` are read only, the command always fails. I’m not sure if this behavior itself is correct (`go list` should not try to convert packages to modules in `pkg/mod` even when MODULE is on?), but anyway it won’t work in `pkg/mod` now. 
This `GetSizesGoList()` is called from `packages.Load()` and it’s originated from `*View.parse()` in `cache/view.go`. We currently set `path` to `v.Config.Dir`, that makes the `go list` command run in `path` and causes the error above. Fix === We don’t need to set `v.Config.Dir`. The go command will be run in the current working directory and that just works. --- langserver/internal/cache/view.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/langserver/internal/cache/view.go b/langserver/internal/cache/view.go index 8de8226..6451113 100644 --- a/langserver/internal/cache/view.go +++ b/langserver/internal/cache/view.go @@ -9,7 +9,6 @@ import ( "go/ast" "go/parser" "go/token" - "path/filepath" "sync" "github.com/saibing/bingo/langserver/internal/source" @@ -83,7 +82,6 @@ func (v *View) parse(uri source.URI) error { return err } - v.Config.Dir = filepath.Dir(path) v.Config.ParseFile = v.parseFile pkgs, err := packages.Load(v.Config, fmt.Sprintf("file=%s", path)) if len(pkgs) == 0 {