should I still declare GOPATH? - bash

I WAS reading Learning GO and suggest that needs to be declared on PATH
GOPATH="/home/user/go".
this is from author:
it’s a good idea to explicitly define GOPATH and to put the $GOPATH/bin directory in your executable path. Explicitly defining GOPATH makes it clear where your Go workspace is located and adding $GOPATH/bin to your executable path makes it easier to run third-party tools installed via go install.
when I run go env 1.18.1, is already declared, so why still suggesting declaring inside your path in .bashrc or .bash_profile
thanks

[S]hould I still declare GOPATH, GOROOT?
No and NO!
GOPATH defaults to $HOME/go which is fine and GOPATH based builds are deprecated since several years. Use modules.
GOROOT never was a thing for the enduser of Go. You have to set if you work on the Go compiler itself or install Go in unusual location (which no enduser should do).
Keep away from any resource wich promotes GOPATH or even advises to mess with GOROOT.

Related

Where does go download my dependencies if I do not specify GOPATH?

new go learner so this might be a trivial question. If I understand the documentation correctly, go had been using GOPATH in the beginning and every dependency and source code need to be in this GOPATH but after 1.1.1 GO switched gear to use Go Modules which is like other languages doing.
Now if I do not specify GOPATH at all in my bashrc/bash_profile or anywhere, I can now do go init mymod and write some code and simply run go build and it will download whatever depdendency package I am using without any problem. I have tried setting GOPATH and when GOPATH is set, the packages are downloaded to my GOPATH as expected, but without GOPATH, this still works. But I am not sure where the dependencies are downloaded.
Could you please explain to me what is happening here? Where the dependency pacakge are downloaded in this case?
Quoting from Command go: GOPATH environment variable:
If the environment variable is unset, GOPATH defaults to a subdirectory named "go" in the user's home directory ($HOME/go on Unix, %USERPROFILE%\go on Windows), unless that directory holds a Go distribution. Run "go env GOPATH" to see the current GOPATH.

Go Modules does not recognize files under GOPATH

I was trying to set up GO Modules in intellij and was trying import a package under GOPATH. When I use Go Modules, it doesnt seem to 'import' the packages from GOPATH. Any ideas on what I could be doing wrong?
Below is a screenshot. Left pic: GoModules, which doesnt recognize the package. Right Pic: Simple GO project, which recognized the packages.
I tried doing sync package, with no luck.
Go version - 1.12.3
.
The two supported modes ("GOPATH mode" and "module-aware mode") are mutually exclusive modes. This means you can't have both, you can't mix modules and GOPATH.
Quoting from Command go: GOPATH and Modules:
When using modules, GOPATH is no longer used for resolving imports. However, it is still used to store downloaded source code (in GOPATH/pkg/mod) and compiled commands (in GOPATH/bin).
And also Command go: Preliminary module support:
For more fine-grained control, the module support in Go 1.11 respects a temporary environment variable, GO111MODULE, which can be set to one of three string values: off, on, or auto (the default). If GO111MODULE=off, then the go command never uses the new module support. Instead it looks in vendor directories and GOPATH to find dependencies; we now refer to this as "GOPATH mode." If GO111MODULE=on, then the go command requires the use of modules, never consulting GOPATH. We refer to this as the command being module-aware or running in "module-aware mode". If GO111MODULE=auto or is unset, then the go command enables or disables module support based on the current directory. Module support is enabled only when the current directory is outside GOPATH/src and itself contains a go.mod file or is below a directory containing a go.mod file.
In module-aware mode, GOPATH no longer defines the meaning of imports during a build, but it still stores downloaded dependencies (in GOPATH/pkg/mod) and installed commands (in GOPATH/bin, unless GOBIN is set).
If you wish to use packages located on your disk, see How to use a module that is outside of "GOPATH" in another module?
I faced this problem, and I use this setting for each project, and it solved my problem.
But I'm still looking for a global GO module configuration.

Where does go put imports when using modules with no GOPATH set?

I'm toying around with converting a project at work to be a module. My understanding is it should make deploys much easier since $GOPATH won't have to be set up properly.
In my existing project I ran go mod init <project path>, and checked in go.mod and go.sum. As a test, I opened a new terminal, unset GOPATH, cloned my project into /tmp, go build, and everything worked great but it left me with questions. I expected my imports to be downloaded into a vendor folder but nothing.
Where does go modules put the packages it has to go get when no $GOPATH is set?
From the modules help:
When using modules, GOPATH is no longer used for resolving imports. However, it is still used to store downloaded source code (in GOPATH/pkg/mod) and compiled commands (in GOPATH/bin).
So in your case if GOPATH is unset it will use the default GOPATH ($HOME/go/) and thereby store the cached imports in: $HOME/go/pkg/mod

How to configure GOPATH?

I installed Goland as a Go IDE and it wants me to configure GOPATH. I'm new in this language so I don't know what to do. Here is the error message:
GOPATH was detected
We've detected some libraries from your GOPATH.
You may want to add extra libraries in GOPATH configuration.
Edit: Not a duplicate question, export GOROOT=""solved my problem. Thanks anyway.
You actually do not need to set the GOPATH environment variable; in Go 1.8 it's ~/go by default.
I suggest that you just update to latest stable Go (1.8) and use that convention; otherwise you'll need to set the GOPATH variable in your environment.
You need to set the GOPATH environment variable. How you do this varies depending on your operating system.
Here are examples of how to set the PATH environment variable, just modify the instructions to set GOPATH instead.
Also see How to Write Go Code for more details on setting up your workspace and setting GOPATH.
export GOROOT=""
solved the issue for some reason.

Can someone explain why GOPATH is convenient and how it should be used in general?

I am new to Go programming language and every tutorial starts off from setting GOPATH to current project folder.
Am I missing something? Is programmer really supposed to set GOPATH manually when he cd to his new Go project folder? I have read several FAQ entries about GOPATH but still couldn't wrap my head around it.
And why does GOROOT exist then? What's its purpose?
Are there any automatic tools which detects if current directory is root folder of Go project (for example by some hidden file) and changes GOPATH to this directory automatically?
Thank you, any advice really appriciated
ps. For example I develop completely disjoint Go projects A, B and C, should they live in single "workspace" environment? I guess not, but what I should do with GOPATH and GOROOT then?
The goal of the GOPATH is to centralize all packages into one common workspace. It is not really a new concept by itself (think of the Java Classpath for example), but Go's use is drastically simpler by not supporting packages versioning.
The Go programmer isn't supposed to set GOPATH manually when entering a new project folder. Each project folder is supposed to be a package by itself, and reside in the GOPATH along other packages, so GOPATH should be set only once. Tutorials begin by setting the GOPATH in order to isolate the tutorial workspace from anything else (or simply assuming that a user hasn't set the GOPATH, yet).
GOROOT is set to provide the standard packages to the Go programmer, you don't need to do anything with it. In short, there is a single rule for GOROOT: never, ever, touch it. Don't install anything in it, don't modify standard packages, etc.
I'm not aware of a tool to detect Go projects in the current directory, but it shouldn't be highly complex to create.
How you handle different projects is up to you. The Go way is to put every project as a package in the $GOPATH/src directory and do everything from there. As I don't really like it, I defined my GOPATH to be $HOME/.go. Then I put each project in a dedicated directory somewhere else (anywhere in my computer), and symlink the project directory into my $GOPATH/src dir. I can then use every Go toolchain command (e.g. go build myproject), use the project as package for another one, etc.
GOPATH allows you to collect dependency source code and the resulting compiled binaries in one place. This seems like a really attractive idea. However, I found myself working on several totally unrelated Go projects and an alternative approach suited me better.
This is a similar but different strategy to Elwinar's symlnks. I start a new project in an empty folder and create src. And I drop into the folder this shell script called env.sh:
if [ `type -p go` = "" ]; then
export PATH=$PATH:/usr/local/go/bin
fi
export GOPATH=$PWD
export PATH=$PATH:$PWD/bin
Each time I start work, I use
. env.sh
Note the dot and space - they matter.
Now, everything I do on this project is localised within this folder. It's possibly not the most widely-used strategy, but it works well for me.
And another thing: if your dependencies make use of environment variables for testing etc, you can put them in env.sh too. For example, Gorp has
export GORP_TEST_DSN=test/testuser/TestPasswd9
export GO_TEST_DSN=testuser:TestPasswd9#/test
Addendum
In the most recent Go versions, GOPATH is optional; if you don't set it, the default is $HOME/go. If you do set it and also want to use the new modules feature, set GO111MODULES=on also.
You don't need to set your GOPATH or GOROOT. GOPATH by default is under your user/home directory.
If no GOPATH is set, it is assumed to be $HOME/go on Unix systems and %USERPROFILE%\go on Windows. If you want to use a custom location as your workspace, you can set the GOPATH environment variable.
Go Modules
Now there's Go Modules support (since Go 1.11), so you don't have to use GOPATH anymore. For example, you can go to any directory on your system (outside of $GOPATH), and you can initialize a new Go module there, then you start working there. No GOPATH is needed.
You just need to do this once (while in a directory):
go mod init
$GOPATH: Go stores these files under it:
Source files ($GOPATH/src)
Compiled package files ($GOPATH/pkg)
Runnable files ($GOPATH/bin)
$GOROOT: Where the Go source code resides like Go Standard Library.
Also to run any go installed executable file from anywhere on your system, you might want to add $GOPATH/bin to your path environment variable like this:
export PATH=$PATH:$(go env GOPATH)/bin
More information check out this.

Resources