What is the idea behind Go package naming convention? - go

I'm trying to understand the idea behind package naming convention in Go. Most packages are installed and imported as something like:
import "github.com/howeyc/fsnotify"
I get the idea that package names should be unique, but I don't see the point of using the website github.com. Why not just use author/package? Like:
import "howeyc/fsnotify"
That's not likely to ever collide. Or some other "shorter" strategy? Is it because it "just works" with go get? Or is there some other reason?

You can use howeyc/fsnotify if you want to. When github.com/howeyc/fsnotify is used it's understood that the package is hosted on Github. Other repositories work as well.
The reason is it makes it easier to locate and install dependencies with go get. Otherwise you'd have to satisfy the dependencies manually. And since forking repos is quite common in the open-source world, you may have a modified version from the same author. So it helps to distinguish what your project depends on.

Download and install packages and dependencies
Usage:
go get [-d] [-fix] [-u] [build flags] [packages]
Get downloads and installs the packages named by the import paths,
along with their dependencies.
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 most recent version of the package.
For more about specifying packages, see 'go help packages'.
For more about how 'go get' finds source code to download, see 'go help remote'.
The import path supports the go get command. Paths denoting remote repositories begin with the path to the code. Run the go help remote command for details.

Related

Issue in installing a go package

So,I recently started following a video tutorial and i am fairly new to golang and tried installing the forked version of bolt db using
$ go get go.etcd.io/bbolt/...
Note : I want to use this specific version
but i am getting an error which says
go: go.mod file not found in current directory or any parent directory.
'go get' is no longer supported outside a module.
To build and install a command, use 'go install' with a version,
like 'go install example.com/cmd#latest'
For more information, see https://golang.org/doc/go-get-install-deprecation
or run 'go help get' or 'go help install'
I read a few GitHub issues which say that go get is deprecated so how do I resolve this ?
I also tried few other things such as
go install go.etcd.io/bbolt/...
Go modules are today's standard. Especially if you are new to Go; do not spend time on material that do not use (and teach) them.
Run go mod init yourproject
in your project repository root directory. This will create go.mod file.
Once you have that you can either:
import go.etcd.io/bbolt in source code and then run go mod tidy. Go tool will find and add module to your dependencies (go.mod file). This is described in Getting started tutorial.
run go get go.etcd.io/bbolt directly, that will update dependencies too.
Using Go Modules series explains workflow in detail and will be helpful when converting commands from an outdated material.

Understanding go mod and cause of package is not in GOROOT

I'm trying to play around with the lightning network. I have cloned the repo, and on disk placed it here (I'm using windows):
C:\Users\hallibut\Documents\GitHub\lnd
I'd like to run any of the tests in itest, lets say testMultiHopPayments. The cli commands I'm using after I cd into the above location is:
go test itest -run testMultiHopPayments
However, I keep getting the error:
package itest is not in GOROOT (C:\Program Files\Go\src\itest)
I've read through the various posts on this error, but I'm still not quite sure why it happens, and it's likely because I don't fully understand the go module (I'm new to go). This article, was probably the best in helping me understand the structure and env variables:
https://golangbyexample.com/workspace-hello-world-golang/
My understanding from the various readings is that whatever directory the go.mod file is in, indicates the module level directory. Prior to version 1.13 there was a required directory and structure, but now that should not be an issue if you're using at least version 1.13 and modules. I'm using 1.17.1. This is somewhat of an assumption or inference, but I believe everything lower in the directory structure is part of a package to be installed as part of the module (and is defined by the package keyword). However, I don't understand why a package with source code within a subdirectory would be missing/throw the aforementioned error. I've also tried running:
go mod install github.com/lightningnetwork/lnd/lntest/itest
That doesn't seem to do anything/has not effect on the error. What am I not understanding about packages? Looking at the go.mod file I observe that itest is not specifically defined anywhere… Not sure if that's required. Also, I assume I've got to run some build process prior? I attempted this with:
go install -v ./...
If you're using VS Code and Go Modules, you need to "Open folder" and point to the cloned repo, to get around that error

Is it possible to update local packages without running go install?

I am trying to import a local file into my main.go file and this tutorial (and other similar tutorials) says to run go install <path> in order to import that path as a package. This seems like a slow way to develop local packages because you would have to run go install <path> every time you want to see the changes in your local package.
Is there a faster way to import/update local packages? I am using gomon to auto-reload my code after updating it, so ideally, my code would auto-reload after updating a local package.
You should use go modules. The tutorial you mentioned appears to be older than the modules feature. In short: you can import a package, run go build, and any imported external package will automatically be downloaded for you as needed, no need to do a go get. Start here:
https://blog.golang.org/using-go-modules
https://github.com/golang/go/wiki/Modules

How to download all the dependencies of fabric-sdk-go?

I used command "go get github.com/hyperledger/fabric-sdk-go" to download fabric-sdk-go and its dependencies. No error happened.
In the golang documentation( https://golang.org/cmd/go/#hdr-Download_and_install_packages_and_dependencies ), it said that "Get downloads the packages named by the import paths, along with their dependencies. It then installs the named packages, like 'go install'."
So I originally thought that all the dependencies of fabric-sdk-go would be downloaded recursively. But the fact proved that I was wrong.
When I ran command "go install ./..." under fabric-sdk-go directory, many errors "cannot find package" were displayed:
So my questions are:
Does "go get" download dependencies recursively or not?
How to download all the dependencies of fabric-sdk-go, instead of using "go get [a_dependency_package]" to download every single dependency one by one?
Thanks very much.
There is no entry point in the root of the project (i.e. no main method) so there is nowhere for the tool to start looking as it doesn't actually do recursive downloads. Instead it looks at the files in the directory you named in the URL and fetches import paths named in those files. For future reference this command will do what you want it to, go get github.com/hyperledger/fabric-sdk-go/... you can append the triple dot right to your go get command
Does "go get" download dependencies recursively or not?
Yes it does. No need to worry or doubt the documentation
How to download all the dependencies of fabric-sdk-go, instead of using "go get [a_dependency_package]" to download every single dependency one by one?
Just use go modules: export GO111MODULE=on and build your code.

Get missing imports in batches

When I clone a project written in golang, it is normal that a lot of imports like
'github.com/XXXX' are missing. Is there any way to get these imports in batches by a command? or I am suppose to get them one by one.
You should use go get to get "remote" packages. Quoting from Command go: Download and install packages and dependencies
Get downloads the packages named by the import paths, along with their dependencies. It then installs the named packages, like 'go install'.
You may use the -v flag in all of the following commands, and so you will see what go get is doing under the hood.
You may use the -d flag if you just want to download the packages but you do not want to install them.
The examples use the example remote package github.com/somebody/somepackage, but obviously it works for other packages hosted outside of github.com.
For more information, see the official doc: Command go, or type go help get.
To get a single package with all the dependencies of that package and install them, use
go get github.com/somebody/somepackage
To get a package with all its dependencies, and all other packages rooted at that path (along with their dependencies), and install all of them, use:
go get github.com/somebody/somepackage/...
Quoting from Command go:
An import path is a pattern if it includes one or more "..." wildcards, each of which can match any string, including the empty string and strings containing slashes. Such a pattern expands to all package directories found in the GOPATH trees with names matching the patterns.
To get a package with all its dependencies (and "subpackages") including dependencies of tests, and install all of them, use:
go get -t github.com/somebody/somepackage/...
To update a package you already have, use:
go get -u github.com/somebody/somepackage/...
To fetch dependencies of a package you already have (which is not necessarily from a remote location):
go get path/to/package/name/...
Or go to its folder and then you may use a relative path:
go get ./...
A lot of golang projects now use dependency management so you should look for that first. e.g a Glide.lock (glide) or Gopkg.lock (dep - the way people are moving now) file present in the root of the project.
https://github.com/golang/dep
https://golang.github.io/dep
if dep is used and you have it installed then dep ensure will set the dependencies up for you and make sure you get the versions the author intended
if a project is not using dependency management you can just get the packages with go get ./... but I don't think you will be guaranteed the correct versions (e.g if the author was pinned to a version tag for a dep)
If you run dep init it sets up dep on a project and will attempt to resolve the correct versions, however this doesnt always work if the stars dont align (e.g I have seen issues with dependencies using gopkg.in)
try using go get ./... in root of your project

Resources