How can I install a package with go get? - go

I want to install packages from github to my $GOPATH, I have tried this:
go get github.com:capotej/groupcache-db-experiment.git
the repository is here.

Command go
Download and install packages and dependencies
Usage:
go get [-d] [-f] [-t] [-u] [-v] [-fix] [-insecure] [build flags] [packages]
Get downloads the packages named by the import paths, along with their
dependencies. It then installs the named packages, like 'go install'.
The -d flag instructs get to stop after downloading the packages; that
is, it instructs get not to install the packages.
The -f flag, valid only when -u is set, forces get -u not to verify
that each package has been checked out from the source control
repository implied by its import path. This can be useful if the
source is a local fork of the original.
The -fix flag instructs get to run the fix tool on the downloaded
packages before resolving dependencies or building the code.
The -insecure flag permits fetching from repositories and resolving
custom domains using insecure schemes such as HTTP. Use with caution.
The -t flag instructs get to also download the packages required to
build the tests for the specified packages.
The -u flag instructs get to use the network to update the named
packages and their dependencies. By default, get uses the network to
check out missing packages but does not use it to look for updates to
existing packages.
The -v flag enables verbose progress and debug output.
Get also accepts build flags to control the installation. See 'go help
build'.
When checking out a new package, get creates the target directory
GOPATH/src/. If the GOPATH contains multiple entries, get
uses the first one. For more details see: 'go help gopath'.
When checking out or updating a package, get looks for a branch or tag
that matches the locally installed version of Go. The most important
rule is that if the local installation is running version "go1", get
searches for a branch or tag named "go1". If no such version exists it
retrieves the default branch of the package.
When go get checks out or updates a Git repository, it also updates
any git submodules referenced by the repository.
Get never checks out or updates code stored in vendor directories.
For more about specifying packages, see 'go help packages'.
For more about how 'go get' finds source code to download, see 'go
help importpath'.
This text describes the behavior of get when using GOPATH to manage
source code and dependencies. If instead the go command is running in
module-aware mode, the details of get's flags and effects change, as
does 'go help get'. See 'go help modules' and 'go help module-get'.
See also: go build, go install, go clean.
For example, showing verbose output,
$ go get -v github.com/capotej/groupcache-db-experiment/...
github.com/capotej/groupcache-db-experiment (download)
github.com/golang/groupcache (download)
github.com/golang/protobuf (download)
github.com/capotej/groupcache-db-experiment/api
github.com/capotej/groupcache-db-experiment/client
github.com/capotej/groupcache-db-experiment/slowdb
github.com/golang/groupcache/consistenthash
github.com/golang/protobuf/proto
github.com/golang/groupcache/lru
github.com/capotej/groupcache-db-experiment/dbserver
github.com/capotej/groupcache-db-experiment/cli
github.com/golang/groupcache/singleflight
github.com/golang/groupcache/groupcachepb
github.com/golang/groupcache
github.com/capotej/groupcache-db-experiment/frontend
$

First, we need GOPATH
The $GOPATH is a folder (or set of folders) specified by its environment variable. We must notice that this is not the $GOROOT directory where Go is installed.
export GOPATH=$HOME/gocode
export PATH=$PATH:$GOPATH/bin
We used ~/gocode path in our computer to store the source of our application and its dependencies. The GOPATH directory will also store the binaries of their packages.
Then check Go env
You system must have $GOPATH and $GOROOT, below is my Env:
GOARCH="amd64"
GOBIN=""
GOCHAR="6"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/elpsstu/gocode"
GORACE=""
GOROOT="/home/pravin/go"
GOTOOLDIR="/home/pravin/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"
Now, you run download go package:
go get [-d] [-f] [-fix] [-t] [-u] [build flags] [packages]
Get downloads and installs the packages named by the import paths, along with their dependencies. For more details you can look here.

Note that since Go 1.17 installing packages with go get is deprecated:
Building and installing packages with get is deprecated. In a future release, the -d flag will be enabled by default, and go get will be only be used to adjust dependencies of the current module. To install a package using dependencies from the current module, use go install.
This "future release" is Go 1.18, as mentioned in the release notes:
go get no longer builds or installs packages in module-aware mode. go get is now dedicated to adjusting dependencies in go.mod. Effectively, the -d flag is always enabled.
(The -d flag instructs go get to only download packages and not install them.)
Use go install instead:
# Install the latest version of a program,
# ignoring go.mod in the current directory (if any).
$ go install golang.org/x/tools/gopls#latest
# Install a specific version of a program.
$ go install golang.org/x/tools/gopls#v0.6.4
# Install a program at the version selected by the module in the current directory.
$ go install golang.org/x/tools/gopls
# Install all programs in a directory.
$ go install ./cmd/...
The Go 1.18 release notes also mention that go get will work as before with GO111MODULE=off. However in 2022 you should definitely migrate to modules and use go install instead.

Run it from console
go mod download

Related

GoConvey: command not found : goconvey [duplicate]

I want to install packages from github to my $GOPATH, I have tried this:
go get github.com:capotej/groupcache-db-experiment.git
the repository is here.
Command go
Download and install packages and dependencies
Usage:
go get [-d] [-f] [-t] [-u] [-v] [-fix] [-insecure] [build flags] [packages]
Get downloads the packages named by the import paths, along with their
dependencies. It then installs the named packages, like 'go install'.
The -d flag instructs get to stop after downloading the packages; that
is, it instructs get not to install the packages.
The -f flag, valid only when -u is set, forces get -u not to verify
that each package has been checked out from the source control
repository implied by its import path. This can be useful if the
source is a local fork of the original.
The -fix flag instructs get to run the fix tool on the downloaded
packages before resolving dependencies or building the code.
The -insecure flag permits fetching from repositories and resolving
custom domains using insecure schemes such as HTTP. Use with caution.
The -t flag instructs get to also download the packages required to
build the tests for the specified packages.
The -u flag instructs get to use the network to update the named
packages and their dependencies. By default, get uses the network to
check out missing packages but does not use it to look for updates to
existing packages.
The -v flag enables verbose progress and debug output.
Get also accepts build flags to control the installation. See 'go help
build'.
When checking out a new package, get creates the target directory
GOPATH/src/. If the GOPATH contains multiple entries, get
uses the first one. For more details see: 'go help gopath'.
When checking out or updating a package, get looks for a branch or tag
that matches the locally installed version of Go. The most important
rule is that if the local installation is running version "go1", get
searches for a branch or tag named "go1". If no such version exists it
retrieves the default branch of the package.
When go get checks out or updates a Git repository, it also updates
any git submodules referenced by the repository.
Get never checks out or updates code stored in vendor directories.
For more about specifying packages, see 'go help packages'.
For more about how 'go get' finds source code to download, see 'go
help importpath'.
This text describes the behavior of get when using GOPATH to manage
source code and dependencies. If instead the go command is running in
module-aware mode, the details of get's flags and effects change, as
does 'go help get'. See 'go help modules' and 'go help module-get'.
See also: go build, go install, go clean.
For example, showing verbose output,
$ go get -v github.com/capotej/groupcache-db-experiment/...
github.com/capotej/groupcache-db-experiment (download)
github.com/golang/groupcache (download)
github.com/golang/protobuf (download)
github.com/capotej/groupcache-db-experiment/api
github.com/capotej/groupcache-db-experiment/client
github.com/capotej/groupcache-db-experiment/slowdb
github.com/golang/groupcache/consistenthash
github.com/golang/protobuf/proto
github.com/golang/groupcache/lru
github.com/capotej/groupcache-db-experiment/dbserver
github.com/capotej/groupcache-db-experiment/cli
github.com/golang/groupcache/singleflight
github.com/golang/groupcache/groupcachepb
github.com/golang/groupcache
github.com/capotej/groupcache-db-experiment/frontend
$
First, we need GOPATH
The $GOPATH is a folder (or set of folders) specified by its environment variable. We must notice that this is not the $GOROOT directory where Go is installed.
export GOPATH=$HOME/gocode
export PATH=$PATH:$GOPATH/bin
We used ~/gocode path in our computer to store the source of our application and its dependencies. The GOPATH directory will also store the binaries of their packages.
Then check Go env
You system must have $GOPATH and $GOROOT, below is my Env:
GOARCH="amd64"
GOBIN=""
GOCHAR="6"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/elpsstu/gocode"
GORACE=""
GOROOT="/home/pravin/go"
GOTOOLDIR="/home/pravin/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"
Now, you run download go package:
go get [-d] [-f] [-fix] [-t] [-u] [build flags] [packages]
Get downloads and installs the packages named by the import paths, along with their dependencies. For more details you can look here.
Note that since Go 1.17 installing packages with go get is deprecated:
Building and installing packages with get is deprecated. In a future release, the -d flag will be enabled by default, and go get will be only be used to adjust dependencies of the current module. To install a package using dependencies from the current module, use go install.
This "future release" is Go 1.18, as mentioned in the release notes:
go get no longer builds or installs packages in module-aware mode. go get is now dedicated to adjusting dependencies in go.mod. Effectively, the -d flag is always enabled.
(The -d flag instructs go get to only download packages and not install them.)
Use go install instead:
# Install the latest version of a program,
# ignoring go.mod in the current directory (if any).
$ go install golang.org/x/tools/gopls#latest
# Install a specific version of a program.
$ go install golang.org/x/tools/gopls#v0.6.4
# Install a program at the version selected by the module in the current directory.
$ go install golang.org/x/tools/gopls
# Install all programs in a directory.
$ go install ./cmd/...
The Go 1.18 release notes also mention that go get will work as before with GO111MODULE=off. However in 2022 you should definitely migrate to modules and use go install instead.
Run it from console
go mod download

Using -mod flag in go CLI

I was reading through godoc on how I can keep my dependencies up to date: https://golang.org/ref/mod#build-commands
It says that -mod=mod flag can be used to automatically update the go.mod file. But I am not able to use it.
This is the command that I tried:
% go get -mod=mod ./..
flag provided but not defined: -mod
usage: go get [-d] [-t] [-u] [-v] [-insecure] [build flags] [packages]
Run 'go help get' for details.
I am obviously missing something because I can't seem to get the flag to work.
Edit: It's a documentation error
After some experiments, it looks that only quite old versions of Go understand go get -mod=, in particular version 1.11. So the documentation is outdated and you could report it.
Officially recommended on Go version 1.14 or newer: to automatically update an existing go.mod file and to download dependencies, instead of doing go get -mod=mod ., simply run:
go get -d .
For the sake of the example being complete, you could now actually build everything and put binaries into $GOBIN (or $GOPATH/bin) with:
go install
If it still doesn't work, a couple of things to check:
Update go to the latest version
The online documentation that you are reading is always about the latest official version, while you might be using an older version. Check your version:
go version
With the current pace of Go development, most people are trying to update as soon as they can. Follow https://golang.org/doc/install
Docs for the older version
Apparently, there is no easy way to read older documentation online. Instead, I use godoc tool to do it locally:
go get -v golang.org/x/tools/cmd/godoc
godoc -http=127.0.0.1:6060
Leave the above command running, then in your browser go to http://127.0.0.1:6060/cmd/go/
This way I've checked for example what the old docs said about -mod flag.

How to `go install` to bin inside module dir?

For example, when I run this
GOOS="windows" GOARCH="386" go install ./something
The executable would be created at
$GOROOT/bin/$GOOS_$GOARCH/something.exe
I want the executable to be created at
path/to/my/module/bin/$GOOS_$GOARCH/something.exe
EDIT
To clarify, I ask the question in the context of cross compiled builds inside a module.
I get the desired result using this command inside my module. I'd like to avoid specifying the path.
GOOS="windows" GOARCH="386" go build -o ./bin/$GOOS_$GOARCH/something.exe ./something
So, is it possible to get the same with go install?
Setting GOBIN results in an error
GOBIN=$(pwd)/bin GOOS="windows" GOARCH="386" go install ./something
# go install: cannot install cross-compiled binaries when GOBIN is set
Don't use go install for cross compiling. Use go build with -o flag.
Here is some history regarding GOBIN, robpike posted an issue stating "I have $GOBIN set but the go tool is ignoring it when installing..."
This article mentions
"When cross compiling, you should use go build, not go install. This is the one of the few cases where go build is preferable to go install...
The reason for this is go install always caches compiled packages, .a files, into the pkg/ directory that matches the root of the source code...
This logic also holds true for the standard library, which lives in /usr/local/go/src, so will be compiled to /usr/local/go/pkg/$GOOS_$GOARCH. This is a problem, because when cross compiling the go tool needs to rebuild the standard library for your target, but the binary distribution expects that /usr/local/go is not writeable.
Using go build rather that go install is the solution here, because go build builds, then throws away most of the result (rather than caching it for later), leaving you with the final binary in the current directory, which is most likely writeable by you"

Go Install Binary name

go build allow to precise binary name with the -o command line option.
go install doesn't, but it deploy the binary and cache package compilation.
How to either change the binary name with go install? or cache compilation with go build?
A simple answer would be "use go install with correct package name", but please, where is the option I am missing?
You can use the -i flag to go build:
The -i flag installs the packages that are dependencies of the target.
go build -i -o binary packagename
When you type go help install you get
usage: go install [build flags] [packages]
Install compiles and installs the packages named by the import paths,
along with their dependencies.
For more about the build flags, see 'go help build'.
For more about specifying packages, see 'go help packages'.
See also: go build, go get, go clean.
The only build flags allowed are
-a
force rebuilding of packages that are already up-to-date.
-n
print the commands but do not run them.
-p n
the number of programs, such as build commands or
test binaries, that can be run in parallel.
The default is the number of CPUs available, except
on darwin/arm which defaults to 1.
-race
enable data race detection.
Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
-msan
enable interoperation with memory sanitizer.
Supported only on linux/amd64,
and only with Clang/LLVM as the host C compiler.
-v
print the names of packages as they are compiled.
-work
print the name of the temporary work directory and
do not delete it when exiting.
-x
print the commands.
-asmflags 'flag list'
arguments to pass on each go tool asm invocation.
-buildmode mode
build mode to use. See 'go help buildmode' for more.
-compiler name
name of compiler to use, as in runtime.Compiler (gccgo or gc).
-gccgoflags 'arg list'
arguments to pass on each gccgo compiler/linker invocation.
-gcflags 'arg list'
arguments to pass on each go tool compile invocation.
-installsuffix suffix
a suffix to use in the name of the package installation directory,
in order to keep output separate from default builds.
If using the -race flag, the install suffix is automatically set to race
or, if set explicitly, has _race appended to it. Likewise for the -msan
flag. Using a -buildmode option that requires non-default compile flags
has a similar effect.
-ldflags 'flag list'
arguments to pass on each go tool link invocation.
-linkshared
link against shared libraries previously created with
-buildmode=shared.
-pkgdir dir
install and load all packages from dir instead of the usual locations.
For example, when building with a non-standard configuration,
use -pkgdir to keep generated packages in a separate location.
-tags 'tag list'
a list of build tags to consider satisfied during the build.
For more information about build tags, see the description of
build constraints in the documentation for the go/build package.
-toolexec 'cmd args'
a program to use to invoke toolchain programs like vet and asm.
For example, instead of running asm, the go command will run
'cmd args /path/to/asm <arguments for asm>'.
Where -i and -o flags are no possible to install command and are available to build command only.
Now, The only option that I see to change the name of the Go install binary name is manually mv oldnamebinary newnamebinary. At least, this behaviour is in GO 1.6, maybe on coming releases can change.
we can run below commands to generate binary executable with the desired name and path:
optional if you want dep to be downloaded and installed
go install
to build the binary at path and name desired:
go build -o path/binary_name
example: go build -o ~/go/bin/mybinaryname
In GO 1.6+ you can rename your main file to whatever you want.
Example :
mv main.go myApp.go
Then just run go install myApp.go
Your myApp is ready to exec, and the location is in $GOROOT/bin

Golang equivalent of npm install -g

If I had a compiled Golang program that I wanted to install such that I could run it with a bash command from anywhere on my computer, how would I do that? For example, in nodejs
npm install -g express
Installs express such that I can run the command
express myapp
and express will generate a file directory for a node application called "myapp" in whatever my current directory is. Is there an equivalent command for go? I believe now with the "go install" command you have to be in the directory that contains the executable in order to run it
Thanks in advance!
Update: If you're using Go 1.16, this answer still works, but go install has changed and is now the recommended method for installing executable packages. See Karim's answer for an explanation: https://stackoverflow.com/a/68559728/10490740
Using Go >= 1.11, if your current directory is within a module-based project, or you've set GO111MODULE=on in your environment, go get will not install packages "globally". It will add them to your project's go.mod file instead.
As of Go 1.11.1, setting GO111MODULE=off works to circumvent this behavior:
GO111MODULE=off go get github.com/usr/repo
Basically, by disabling the module feature for this single command, it will install to GOPATH as expected.
Projects not using modules can still go get normally to install binaries to $GOPATH/bin.
There's a lengthy conversation and multiple issues logged about this change in behavior branching from here: golang/go - cmd/go: go get should not add a dependency to go.mod #27643.
Starting with Go >= 1.16 the recommended way to install an executable is to use
go install package#version
For example, go install github.com/fatih/gomodifytags#latest.
Executables (main packages) are installed to the directory named by the GOBIN environment variable, which defaults to $GOPATH/bin or $HOME/go/bin if the GOPATH environment variable is not set. You need to add this directory to your PATH variable to run executables globally. In my case, I've added this line to my ~/.zshrc file. (if you are using bash, add it to the ~/.bash_profile file):
export PATH="$HOME/go/bin:$PATH"
Go team published a blog post about this change, here's the explanation quote:
We used to recommend go get -u program to install an executable, but this use caused too much confusion with the meaning of go get for adding or changing module version requirements in go.mod.
Refer to go install documentation for more details
As far as I know, there is no direct equivalent to npm install -g. The closest equivalent would not be go install, but go get. From the help page (go help get):
usage: go get [-d] [-f] [-fix] [-insecure] [-t] [-u] [build flags] [packages]
Get downloads and installs the packages named by the import paths,
along with their dependencies.
By default, go get installs binaries to $GOPATH/bin, so the easiest way to make those binaries callable from everywhere is to add that directory to your $PATH.
For this, put the following line into your .bashrc (or .zshrc, depending on which shell you're using):
export PATH="$PATH:$GOPATH/bin"
Alternatively, you could also copy or link the executables to /usr/local/bin:
ln -s $GOPATH/bin/some-binary /usr/local/bin/some-binary
Short solution for Linux users:
Use the go get command as usual
Add the following lines to .bashrc:
# This is the default GOPATH, you should confirm with the 'go env' command
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
Restart terminal or source it. Installed binaries will be available globally.
For Go v1.8+
go install package_name#latest
Caveat: this answer is outdated following the 2020 deprecation of go get. The solution presented here won't work with newer Go runtime installs.
The closest analogue of this in Go would be go get. By default, it will fetch a Go package from a supplied repository URL, and requires a $GOPATH variable to be set in your shell so that Go knows where to store the packages (and subsequently where to find them when compiling code depending on go get-ted packages).
Example syntax:
$ go get github.com/user/repo
The behaviour supplied by npm's -g flag is default, and packages installed using go get are normally available globally.
See go get --help for more information about the command.
As mentioned by #helmbert, adding your $GOPATH to your $PATH is useful if you're installing standalone packages.
if you are using zsh :
first: install your package using :
go install package#version
then , you edit your .zshrc file
nano ~/.zshrc
Add this line to the end of .zshrc file :
export PATH="$HOME/go/bin:$PATH"
last but not least :
source ~/.zshrc
then open a new terminal and execute your command :)
TL;DR at the bottom. I'm going to walk you through how I came to this conclusion, and why the more obvious solutions don't work.
Upon seeing this question, I thought "If I could set root's GOPATH=/usr, it would install things in /usr/bin/ and /usr/src!"
So I tried the obvious thing:
Add GOPATH=/usr to root's .bashrc.
And it worked!
Sort of.
Not really.
Turns out, sudo doesn't execute root's .bashrc. For "security" or something like that.
Do env_set or something in /etc/sudoers
Turns out, /etc/sudoers can only remove environment variables. There's no env_set directive.
(As far as I can find)
Dig through man sudoers.
Where does sudo get it's default set of environment variables from?
Well, the first one in the list is /etc/environment, so that's the one I used.
sudo echo "GOPATH=/usr" >> /etc/environment
sudo go get <repo>
Binaries will be put in /usr/bin, and sources will be put in /usr/src.
Running go as non-root will use GOPATH the "normal" way.
If you don't have go installed, you may use the gobinaries. it builds an on-demand binary of the project from github repo.
The command to install the go package would be:
curl -sf https://gobinaries.com/rakyll/hey | sh

Resources