Skip to content
This repository has been archived by the owner on Jul 15, 2023. It is now read-only.

Should Go tools be installed to a separate GOPATH from what user has set? #5

Closed
lukehoban opened this issue Nov 10, 2015 · 18 comments
Closed

Comments

@lukehoban
Copy link
Contributor

Currently, Go tools are located and acquired based on the currently active GOPATH. This has a few downsides:

  1. Go tools clutter up the users actual GOPATH even if they don't plan to use them outside of the editor
  2. For users with multiple workspaces, or with isolated GODEP setups per project, tools need to be downloaded into each of the workspaces

Instead, the plugin could automatically install these to it's own private GOPATH and use the binaries from that location. This could also allow the plugin to control versioning of these tools more precisely.

Additional feedback from offline discussion:

So if the plugin could grab them and everything just works out of the box with all these things installed, it actually might be pretty cool. It can also manage updates for those tools in a centralized place, rather than having them compiled at $GOPATH/bin of 10 different projects and eventually getting out of date independently.

Thoughts?

@newhook
Copy link
Contributor

newhook commented Nov 22, 2015

I prefer that they are installed to the current GOPATH.

I also prefer that that the tool executables are looked up from the PATH, not from GOROOT or GOPATH.

@AnthonyPoschen
Copy link

i wouldn't mind it in it's own private section as long as it is easy to navigate too / find from a options menu or a button in a dialog somewhere, in case you want to do something regarding the tools.

@ironcladlou
Copy link
Contributor

Here are what I see as some compelling benefits to installing the tooling to an isolated plugin GOPATH:

  1. Allows the user to keep an independent version of the tools in their global GOPATH
  2. Sidesteps issues with some tools requiring installation to $GOROOT/bin which isn't always user writable
  3. Opens the door for some useful configurations:
    1. Plugin-global specification of tool versions by Git tag
    2. Project-specific tool versions by Git Tag

The ability to pin a project's tools to a certain Git tag is useful for the case where you're trying to approximate a custom build environment locally in your IDE. For example, go vet produces different output across versions, and it's nice to be able to pin a project at a certain vet tag which is known to be compatible with the target build environment (like a CI system.)

One problem that may not be easily solved is gocode, which runs as a daemon that can't easily exist in parallel with other gocode daemons (if only there were Docker everywhere...)

FWIW, in GoTools, I use a precedence based lookup to find support binaries (GOPATH > PATH > GOROOT).

@lukehoban
Copy link
Contributor Author

@ironcladlou Thanks - this a good list of reasons to do this, and I'm increasingly inclined to think it's the right direction to go in the future.

Regarding lookup precedence, that same order is what is being used currently in vscode-go as well.

https://github.com/Microsoft/vscode-go/blob/master/src/goPath.ts#L12-L46

@peterbourgon
Copy link

Just a note from the peanut gallery: having multiple GOPATHs, per-project or otherwise, is nonstandard, and will become increasingly rare as GO15VENDOREXPERIMENT becomes the defacto standard for dependency management.

@ironcladlou
Copy link
Contributor

Just a note from the peanut gallery: having multiple GOPATHs, per-project or otherwise, is nonstandard,

I'm curious to understand this statement better. Multi-element GOPATH is explicitly supported as part of the handling of GOPATH since at least 1.4, and isolating project builds using project-scoped GOPATH is a totally idiomatic in the ecosystem.

and will become increasingly rare as GO15VENDOREXPERIMENT becomes the defacto standard for dependency management.

I admire your optimism... 😁

@peterbourgon
Copy link

Multi-element GOPATH is explicitly supported as part of the handling of GOPATH since at least 1.4

Yes, that's true. (Even before then, IIRC.) The intent was to allow a two-tier GOPATH hierarchy, e.g.

GOPATH=/path/to/global/gopath:/path/to/my/gopath

The go tooling, e.g. go get, would always write to the first path, which could be interpreted as "not my code", and you could keep your code in the second path, to allow a kind of simple hermetic separation. But not many folks ever used it. And it's much less important now that we have the vendor/ standard for third-party code.

isolating project builds using project-scoped GOPATH is a totally idiomatic in the ecosystem.

Sorry, that's not true. [edit: I guess I should be more precise and say I don't agree :)] — It's definitely possible, but repos and projects which represent their own GOPATH are and have always been nonidiomatic, as they're incompatible with go get. The only reason to do it (that I'm aware of) was to have explicit control of dependencies (and, I guess, for projects which are not pure Go) — but, again, the vendor/ standard obviates that need.

@mattetti
Copy link
Contributor

@ramya-rao-a can we please close this issue. Between Go not encouraging this approach and the support for vendoring, I think it's fine to close this old issue.

@ramya-rao-a
Copy link
Contributor

@lukehoban @ironcladlou Do you have any more thoughts on this thread? There is a PR open as well. I don't have much history here, so will leave it up to @lukehoban to take a call.

@lukehoban
Copy link
Contributor Author

I actually think the PR in #351 is a good solution to this which doesn't change the default experience but allows folks who do want to isolate their tools into a separate GOPATH to do that. I think this is orthogonal to multi-part GOPATH and vendoring concerns. This is just about where to store the binaries for the tools - and it's nice to have the option to place them somewhere outside of the active GOPATH.

@mattetti
Copy link
Contributor

As long as the default location doesn't change I am fine. Not understanding why doing a go get -u on a tool doesn't update the version used in VSCode is problematic.

@ramya-rao-a
Copy link
Contributor

Not understanding why doing a go get -u on a tool doesn't update the version used in VSCode is problematic

That's not true. go get -u on a tool does update the version used by VS Code as of now. Not after opting in for the feature in the PR though.

@mattetti
Copy link
Contributor

Sorry for the confusing message, that's exactly what I meant. Whoever will choose 2 go bin locations will find itself in this scenario

@ironcladlou
Copy link
Contributor

I personally still use separate GOPATHs per project (although thankfully no longer use multi-element GOPATH entries with the widespread adoption of 1.5+ vendoring), and so have a need (and already use) a "global" GOPATH that contains my tooling binaries. So, I handle tool updates manually.

The solution in #351 would work for me.

@ramya-rao-a
Copy link
Contributor

Ok then, I have pinged @samherrmann to resend the said PR after resolving merge conflicts. After that we should be good to go

@ramya-rao-a
Copy link
Contributor

PR is merged. This will be out in the next update. Thanks everyone!

@ramya-rao-a
Copy link
Contributor

I was testing this feature of using the env var as a separate location for the Go tools.

This doesn't work for gometalinter. As part of streamlining the go tools installation experience, with #735, gometalinter and the linters it uses will be installed when user clicks on "Install All" or the "Analysis Tools Missing" or via the "Go: Install Tools" command.

If gometalinter and its linters get installed in a separate location than the user's gopath, then when gometalinter is run , it won't be able to find all its linters.

@ramya-rao-a
Copy link
Contributor

Hello All,

The latest update (0.6.53) gives the user an option to install the go tools to an alternate location.

This is done via the new setting go.toolsGopath where you can provide the alternate location.

Remember to run Go: Install Tools after setting the above setting, so that the tools get installed to this location. After which, you can safely delete the ones from your GOPATH.

Note: dlv and gometalinter tools are exceptions to this rule. Reason being that gometalinter internally installs linters and expects them to be in the user's GOPATH. And that the debugger is not aware of any VS Code settings and so will not be able to find dlv from any location other than PATH or user's GOPATH

Please give it a try and comment here (or open a new issue) if you see any issues.

@vscodebot vscodebot bot locked and limited conversation to collaborators Jan 24, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants