Setting `GOPATH` for each vscode project - go

Setting the GOPATH variable global as an enviroment variable works fine with Visual Studio Code.
But setting a project specific variable globally doesn't seem very nice to me. Consider you have multiple Go projects, you would have to change this variable each time you, compile, debug, ... etc. a project.
Is there a possibility to set the GOPATH variable as a project variable in Visual Studio Code? Ether in settings.json or launch.json?

(Q2 2018:
Note that with the vgo project, GOPATH might end up being deprecated in favor of a project-based workflow. That would avoid the manual project-based GOPATH I was proposing below, two years ago)
With Go 1.11 (August 2018), GOPATH can be optional, with modules.
It is more and more supported with VSCode:
vscode-go/issue 1532
"Go modules support in Visual Studio Code"
In addition to vendor folder, you still can have one GOPATH per project.
See "GOPATH from go.inferGopath setting":
GOPATH from go.inferGopath setting
Setting go.inferGopath overrides all of the above.
If go.inferGopath is set to true, the extension will try to infer the GOPATH from the path of the workspace i.e. the directory opened in vscode. It searches upwards in the path for the src directory, and sets GOPATH to one level above that.
For example, if your project looks like /aaa/bbb/ccc/src/..., then opening the directory /aaa/bbb/ccc/src (or anything below that) will cause the extension to search upwards, find the src component in the path, and set the GOPATH to one level above that i.e. GOPATH=/aaa/bbb/ccc.
This setting is useful when you are working on different Go projects which have different GOPATHs. Instead of setting the GOPATH in the workspace settings of each project or setting all the paths as ;/: separated string, you can just set go.inferGopath to true and the extension uses the right GOPATH automatically.
GOPATH for installing the Go tools using go.toolsGopath
By default, all the dependent Go tools are used from the GOPATH derived from the above logic.
If they are available on your PATH, the PATH is used to locate the Go tools.
If the Go tools are not in your path, you might end up with the same Go tools installed in each of your GOPATHs.
To prevent the Go tools from cluttering your GOPATH, use the go.toolsGopath setting to provide a separate location for the Go tools.
The first time you set go.toolsGopath, you will have to run Go: Install Tools command so that the Go tools get installed in the provided location.

set workspace settings, in windows:
goto settings: ctrl+,
set workspace setting:
{
"go.gopath": "d:\\gopath;E:\\src"
}
use ; for multiple path
restart visual studio code to take effect.

The GOPATH is your workspace and it's divided in
GOPATH/
|- bin/
|- pkg/
|- src/ <--- your projects are saved here
|- .../my_project1
|- .../my_project2
With this separation, your don't need to set a new GOPATH for each project. I recommend you read How to Write Go Code

Go 1.5 added the vendor directory that allows a per-project dependency management.
If there is a source directory d/vendor, then, when compiling a source file within the subtree rooted at d, import "p" is interpreted as import "d/vendor/p" if that path names a directory containing at least one file with a name ending in “.go”.
source
This feature has been enabled by default with Go 1.6:
Go 1.5 introduced experimental support for a “vendor” directory that was enabled by an environment variable. In Go 1.6, the feature is now enabled by default.
source
Even with the 1.6 version, depending on the tools you use, you might need to set the GO15VENDOREXPERIMENT environment variable to 1 (export GO15VENDOREXPERIMENT=1 on unix-based OS)

If your VSCode project directory is organized,
go to Settings
either search "Infer Gopath" or find this entry under Extensions/Go
check the box
Then VSCode infers GOPATH from your workspace root, which solves my problem immediately. I believe this is explained in other answers. I am posting this just to give a shorter version.

Related

Building go/src packages from golang/go Github Repository

Asking to see what the appropriate workaround is for building individual go packages from the go/std library when working on a github repo fork. The issue encountered is summarized by the following error when building for example the src/go/parser package.
parser.go 21:2 use of internal package go/internal/typeparams is not allowed
Of course the project import paths all reference GOROOT library paths
usr/local/go
And I am typically working on projects from my own directory where my go path is set.
/Users/andewx/github/go/src/github.com/andewx/my_go_extension_project
The crux of the issue is that the clone/fork project uses standard library import paths and I would like to be able to work on my repo from my own GOPATH. But internal packages can't be imported in this case because the import directives will always point to my GOROOT.
The only two options I can think of is:
Extending my personal go project by initiating the repo inside of my /usr/local/go and working on the packages from there.
Changing my GOROOT to point to my current project and including current go binary go fmt and toolchains in my project
Ideally I can just leave everything as far as directory structure is concerned as is and I can redirect the standard import path for go standard library to my current project for this project only...
Any ideas from the community for solution #3 is what I'm looking for.
Extending my personal go project by initiating the repo inside of my /usr/local/go and working on the packages from there.
Changing my GOROOT to point to my current project and including current go binary go fmt and toolchains in my project
If you are trying to work on the go compiler and extend it I actually found that changing your GOROOT to point to your workspace and then copying over the binaries and tools you need as a suitable fix and it doesn't create any additional issues.
Export your environment variable export GOROOT="/my/go/project"
Find out where your go tools are located with go env GOTOOLDIR copy this directory structure into your project folder.
Copy go bin cp /usr/local/bin/* ${GOROOT}"/bin" copy in your go binary
Copy toolscp /usr/local/go/pkg/tool/linux_amd64/* ${GOROOT}/pkg/tool/linux_amd64
Now your project should be able to run the copied binaries with your project directories temporarily set as the GOROOT.

What does Enable Go modules integration do in Intellij IDE

Not having previous knowledge about creating a project from zero within terminal, I've created a folder, cd into of it then run go mod init my_project_name which created a go.mod file for me, then I've created main.go file which built just ok.
Then I created a folder and add a go file inside with package name (being same with directory) and create a struct inside of it. Next I tried to import that package in main package but when I try to build on terminal it gave me this error
go: cannot determine module path for source directory /Users/berkcan/workspace/go/my_project_name (outside GOPATH, module path must be specified)
After googling and not being able to find a solution to my problem, I've imported project to beloved Intellij IDE and I enabled Go modules integration then everything worked flawlessly. First I thought IDE doing some magic inside while building project but even when I try go build command in terminal, it built. But I cant see difference in project structure or a new line in go.mod file.
So what happened, what did Intellij IDE did when I ticked go module integration box and what I can do enable it on terminal without Intellij IDE ?
here is the photo of option in IDE when ticked
IntelliJ IDEA plus Go plugin or GoLand under the hood has two modes to get the information about your packages (simplified):
GOPATH. IDEA scans your $GOPATH directory to build internal indexes of your packages and provides code completion, resolving, etc.
Go Modules. IDEA executes go list -m -json to resolve your dependencies and scans your $GOPATH/pkg/mod directory (default value of GOMODCACHE) for the packages. If they don't exist, IDEA executes go mod download. After these operations, the IDE provides all built-in features like code completion, navigation and so on.
Both modes don't change your Go or environment variables as well as behavior in the terminal. When you check Enable Go Modules integration option in the settings, the IDE just switches the mode from scan $GOPATH to execute go list and resolve your dependencies from the Go Modules cache.
To summarize, IntelliJ IDEA doesn't do any magic. I suppose it relates to your custom Go environment variables inside the terminal, especially GO111MODULE and if you didn't pass these variables to the GUI apps (e.g. you have specified it in .zshrc file and run the IDE via Desktop entry instead of the terminal), IntelliJ IDEA doesn't inherit them. You can compare go env output inside your local terminal and built-in inside the IDE (View | Tool Windows | Terminal) and find differences.

Go extension for Visual Studio Code add a go folder in my GOPATH or the current folder that i open

I am using VScode with the go extension so I created a new folder in my repo folder called go-workspace and change the GOPATH environment variable to that folder (C:\Users\username\Documents\Repo) but when I check the GOPATH detected by VScode using the GO: Current GoPath and the command returns C:\Users\username\Documents\Repo\go-workspace\go. I tried changing the folder but it keeps adding \go to the root folder, I also tried to create a new folder in a different path but it is still not working.
I don't know how you changed the GOPATH environment variable from the question yet. VSCode currently picks up the environment variables from either
Login shell (~/.profile, ~/.bash_profile, ... see your shell manual) if launched from the system default launcher, or
Inherit the environment from the terminal you invoke the VS Code application (code) even when you open a new vscode window from another vscode window,
(warning: the behavior I described above may change over time :-( )
and VS Code Go extension uses the environment variables VSCode picked up. So, please check if vscode itself picked up your setup.
The last resort is "go.gopath" as you figured out already.
Ive fixed it by adding "go.gopath" in my settings.json in VScode
"go.gopath":"path/to/prefered/gopath"

How can make my GoLand to detect dependency packages under $GOPATH/pkg/mod?

I'm trying through kubebuilder tutorial, and just imported existing project to GoLand.
Workthrough with kubebuilder auto-generated scaffold codes, and auto-downloaded pkgs with go mod for me. I had no problem when I was working with commandline environment, but turns out, after opening the project with GoLand, IDE is failing to resolve imported package names, which means it is failing to detect - or link - packages installed by go mod.
I enabled go mod(with vendoring) and dep both from IDE preferences, set GOPATH and Go runtime properly, but the error keeps to appear.
I don't know why I'm getting this error, and how to solve it.
+) Working Directory is $GOPATH/src/example, all the logics and settings are placed in the directory. Installed dependencies are placed under $GOPATH/pkg/mod.
I enabled go mod(with vendoring) and dep both from IDE preferences, set GOPATH and GOROOT properly, but the error keeps to appear.
Let's assume that you have the following setup on your machine:
Go is installed under /usr/lib/go
GOPATH is set to /home/florin/go
the KubeBuilder project named demobuilder is created under /home/florin/projects/demobuilder. I recommend this as opposed to using GOPATH, as you do, for Go Modules projects because they behave in a different way while in GOPATH.
First, make sure that you have GoLand 2019.3.1 or newer.
Then, after creating the demobuilder project, start GoLand, then click on the Open Project button.
When the project is opened, if you have not configured yet, the IDE will ask you for the Go SDK configuration, aka GOROOT. It will be a yellow bar at the top of the editor. Click on the link on the right side to configure it. You can select the local installation and point it to /usr/local/go. If you don't have Go installed, you can also download it in a directory of your choice.
Then, the IDE should automatically notice that the project is a Go Modules based project and enable the support for them. If it's not, then go to Settings/Preferences | Go | Go Modules and enable that. DO NOT enable both Go Modules and dep support at the same time. If you did that, disable the dep integration and try again.
You can see all of these in the help page.
Is Go modules integration enabled via File | Settings | Languages & Frameworks | Go | Go Modules

How to install golang tools globally and then use them in multiple projects in different GOPATH?

Most of the golang tools like golint, gopkgs etc are installed like libraries with go get for instance, go get -v github.com/golang/lint/golint or go get -v github.com/tpng/gopkgs. I wonder why these are not just binaries that run through the source code, like go fmt, for example?
Since I work on multiple Go projects at the same time, I prefer having different GOPATH for different projects and so I am having to install these tools into every single project so that I can lint or have auto completions.
Am I doing something wrong or is there a way to install these tools globally and then just use them in multiple projects? How do people handling multiple projects manage this?
EDIT:
I am not asking about vendoring of libraries or about projects using different versions of Go at the same time. My question is about having to install tools like lint and gopkgs into every GOPATH, why they were designed to be treated like libraries instead of being provided as a global binary like go fmt which then could've been used in multiple projects, just like we use go fmt
so I am having to install these tools into every single project so that I can lint or have auto completions.
No you don't: see how Visual Studio Code does it through its Microsoft vscode-go plugin (since its 0.6.53 version, January 2017).
New setting go.toolsGopath, for providing an alternate location to install all the Go tools that the extension depends on, if you don't want them cluttering your GOPATH.
See PR 351 and PR 737
The tools installed in that one common `` folder are:
'gocode': 'github.com/nsf/gocode',
'gopkgs': 'github.com/tpng/gopkgs',
'go-outline': 'github.com/ramya-rao-a/go-outline',
'go-symbols': 'github.com/acroca/go-symbols',
'guru': 'golang.org/x/tools/cmd/guru',
'gorename': 'golang.org/x/tools/cmd/gorename',
'gomodifytags': 'github.com/fatih/gomodifytags',
'impl': 'github.com/josharian/impl'
(and a few others, around godoc, goimports or goreturns, dlv, ...),
That means your GOPATH is composed of:
your project-specific workspace folder
a global go.toolsGopath workspace folder dedicated to tools used by all projects.
The tools are installed/updated in the bin/ subfolder of that latter workspace.
You can do that manually too (without Visual Studio Code): simply set GOPATH to that global tools folder whenever you want to install/update the tools.
Then reset GOPATH to my/project/dedicated/workspace;/tools/workspace, and add both bin/ subfolders to your $PATH/%PATH%.
The OP Nithin adds in the comments:
these tools can be compiled to binaries and if those binaries are available in $PATH, most editors, as far as I tested (based on your post), both vscode and atom (go-plus) will work and wont go get them again.
It is easier to update if they are treated like libraries. (I mean go get)

Resources