Why does `go install` on a Github directory work but not file? - go

So if I have a go module on my local filesystem, I can install a binary by running go install cmd/main.go and it will create a binary called $GOPATH/main as expected. Basically it behave the same as go build but copying the binary to $GOPATH.
However, when I try to install the same module on stored on Github, it fails:
go install github.com/sanbornm/go-selfupdate/cmd/go-selfupdate/main.go
no required module provides package github.com/sanbornm/go-selfupdate/cmd/go-selfupdate/main.go; to add it:
go get github.com/sanbornm/go-selfupdate/cmd/go-selfupdate/main.go
Instead, I need to call go install on the directory for it to properly work:
go install github.com/sanbornm/go-selfupdate/cmd/go-selfupdate
How do I reconcile this behavior difference?

Related

Can 'go install' be made to work for executables with different names from the git repo?

Go has a nice feature where you can go install <x> and it will download, build and install a binary.
For example, on my local windows PC, go install github.com/goreleaser/goreleaser will find the latest release for goreleaser, download, build and install it to my local binaries path.
I am working on a project where we would like to enable go install, but encounter a problem if the github repo name does not match the executable name. The GitHub CLI itself runs into the exact same problem:
Example:
go install github.com/cli/cli#latest
go: downloading github.com/cli/cli v1.14.0
go: github.com/cli/cli#latest: module github.com/cli/cli#latest found (v1.14.0), but does not contain package github.com/cli/cli
Is there a way to resolve this?
Update: I worked out that I could directly reference the package via it's sub directory. In my particular instance this works: go install github.com/OctopusDeploy/cli/cmd/octopus#latest
This is a bit unpleasant, but works correctly. It doesn't work for the github CLI because their go.mod has a replace directive in it :-(
Question: Can this be made nicer? Is there a way to put some sort of alias or configuration file so that go install github.com/OctopusDeploy/cli#latest can be used instead of go install github.com/OctopusDeploy/cli/cmd/octopus#latest ?
Can this be made nicer? Is there a way to put some sort of alias or configuration file so that go install github.com/OctopusDeploy/cli#latest can be used instead of go install github.com/OctopusDeploy/cli/cmd/octopus#latest ?
No. Dead simple.

go install #latest found but does not contain package

I'm trying to install my package using go install but I get this error message when running the command go install github.com/JoaoDanielRufino/gcloc/cmd/gcloc#latest:
go install: github.com/JoaoDanielRufino/gcloc/cmd/gcloc#latest: module github.com/JoaoDanielRufino/gcloc#latest found (v1.0.0), but does not contain package github.com/JoaoDanielRufino/gcloc/cmd/gcloc
I want the executable name to be gcloc.
Here is the current source code: https://github.com/JoaoDanielRufino/gcloc
Note: I've already tried go clean -modcache but it didn't work
As the main function of this package isn't on its root, you should pass the directory of the main package on your command.
So, your command will be:
go install -v github.com/JoaoDanielRufino/gcloc/cmd#latest
I came across a similar issue when I was trying to use go install to install the cloudflare/cf-terraforming tool on my machine. The documentation for this tool is not clear on the installation and I had to dig around to get this to work
Basically #Jictyvoo answer above sums it up, if the path is pointing to anything other than directory where the main.go file is sitting I got the error
Command: go install github.com/cloudflare/cf-terraforming#latest v0.8.0#latest
go: github.com/cloudflare/cf-terraforming#latest: module
github.com/cloudflare/cf-terraforming#latest found (v0.8.0), but does not
contain package github.com/cloudflare/cf-terraforming
when I switched to the below it worked fine for me:
Command: go install -v github.com/cloudflare/cf-terraforming/cmd/cf-terraforming#latest
This worked for me after checking the repo and realising that the main.go file was sitting in the cmd/cf-terraforming subdirectory

How do I install a go module?

Usually, when i'm in a workspace, all I need to do is go install to install an executable into my pkg folder. However, let's say i'm creating a module outside of $GOPATH/src. I then have a folder called ModuleTest on my desktop that contains the go.mod file. How do I install the package I created so I can use it in other go programs.
I've tried running go get and go install while inside the ModuleTest folder but it doesn't install anything into $GOPATH/pkg or $GOPATH/bin.
EDIT: I guess what i'm asking is, how do I install a go module locally without first pushing it on github and then doing go get
Just use the replace keyword.
It will be something like this:
module github.com/a/b
replace github.com/foo/bar => /Users/YourName/Projects/bar
require (
github.com/foo/bar v1.0.0
)
For it to reflect in $GOPATH/bin you need to do go get -u ....... instead of go get ........
Hope it helps :)

go install not creating binary of a package while go get is able to

I am on go version go1.11.2 linux/amd64. When the package godog is installed using go get github.com/DATA-DOG/godog/, godog executable is created inside $GOPATH/bin/. All fine till now.
I am creating an application myApp that resides at $GOPATH/src/ in which under the folder vendor, godog package is added. When I try to create a binary out of vendor-ed package, an archive file is created inside $GOPATH/pkg/linux_amd64/myApp/vendor/github.com/DATA-DOG/ as godog.a
How can I create a binary in this scenario? I do not want to do go get again just for the binary.
go install does not automatically install apps in vendor folders, but you may specify a vendored path explicitly if you wish so. So simply run:
go install myApp/vendor/github.com/DATA-DOG/godog/cmd/godog

How to install "gotests" command?

I need to use the test driven development in Go using "gotests" command.
gotests -all *
This is not working. I did go get -u /github.com/cweill/gotests
and go install. But there is no binary created in $GOPATH/bin.
since there is NO main package, Use this command
$ go get github.com/cweill/gotests/...
this itself download all dependencies for the current package, and creates bin file, after downloading this package. see in $GOPATH/bin there will be a bin file named gotests
for more see HERE
The following worked for me with go v1.19.1
go install github.com/cweill/gotests/gotests#latest
Using go get to install things has been disabled since 1.18. See Deprecation of 'go get' for installing executables
go install github.com/rakyll/gotest
Source: https://github.com/rakyll/gotest

Resources