Do all Go projects need to live below GOPATH? [duplicate] - go

This question already has answers here:
Can someone explain why GOPATH is convenient and how it should be used in general?
(3 answers)
Closed 4 years ago.
I am starting with Go and trying to get my head around GOPATH (and probably GOBIN).
When trying to fetch external libraries via go get I get the error
go get: no install location for directory D:\Seafile\dev-perso\domotiqueNG\services\dispatcher-go\src\dispatcher-go outside GOPATH
This error is apparently solved by having a project structure below $GOPATH/src.
Does this mean that all my Go programs must live there? If GOPATH is d:\hello then the projects bonjour and aurvoir really need to be in
d:\hello\src\bonjour
d:\hello\src\aurevoir
only ?
In this is the case how can I
split, say, personal and professional projects when the personal must stay at d:\home and professional at x:\work ?
have multilanguage projects where d:\home\domotique\dispatch is in Go, d:\home\domotique\whatever is in Python, and I have several such combos in d:\home?

You can actually have Go projects outside of GOPATH. However, some tools do not work well or do not work at all in this kind of situation. For example, goimports, which formats your code and add missing imports, will not be able to find packages that are outside of GOPATH. You'll have to write the imports manually using a relative path: ./path/to/your/package.
how can I split, say, personal and professional projects when the personal must stay at d:\home and professional at x:\work ?
You actually can have multiple Go workspaces (https://github.com/golang/go/wiki/GOPATH). You just need to set GOPATH to the list of their location joined with the list separator of your OS. e.g. on Linux it would look like this:
GOPATH="/home/nobody/perso:/home/nobody/work"
Though, I'm not sure how go and other tools such as dependency managers handle multiple workspaces.

When using the GOPATH you can make subdirectories in the /src folder, for example, adding both home and work directories. In fact, the Go project has an example of how to organize code. While packages need to be in their own folders, a folder itself in the GOPATH is not automatically a package.
If you'd rather not work within the confines of the GOPATH, you can change it to the path you do want to work in, or set it to your home directory.

Related

how to manage GOPATH for multiple project directories

coming from a java and grails background, (and having written millions of lines of C 30 years ago), I cant see how go can be usable with a fixed gopath on windows.
installing go creates this structure
c:\users\me\go\scr
\pkg
\bin
As you will want to have many go projects it seems they have to be mixed together in the same src/kpg/bin dirs, polluting each other. e.g.
/src/project1/hello.go
/project2/hello.go
/pkg/xx
/bin/hello.exe
Which hello.go will hello.exe run?
Unless I am missing something fundamental, this seems crazy - all completely separate projects are expected to share the same package and bin dirs. It means you dont know which versions of which packages, and which exe files belong to which project, and there is presumably plenty of scope for conflicts. I would have expected a /src, /pkg and /bin for each separate go app (like java or grails or even C), and go path is completely redundant, it can be relative to the current project root (like in grails).
To make matters works, for work, we have to use a different directry, e.g.
d:\work\project3
\project4
\package5
\go_utility6
\go_utility7
So now we have a total of 6 separate directories where go progams live. It is not feasible to change the path every time you switch to working on a different project. I guess the other option is to add the 6 paths to the GOPATH. Presumably, all 7 go projects write to the same pkg and bin dir, which is going to be a disaster.
Is there a tenable solution to this situation (on windows at least)?
If we need to add a PATH to GOPATH for every project, what should the file structure be under each project?
E.g. uner xxx\go_utility6, which is a stand alone command line go app, what should the structure be? does there need to be a src dir in there somewhere? does this dir need gopath to point to it? does it need its own pkg, or should it use the c:\users\me\pkg dir?
UPDATE: When I posted this Go did not have modules support and we built and used a tool called vg. These days the recommended way to go is to use go modules.
I use vg for that, it takes care of keeping separate GOPATH paths per project and it switches automatically when you cd a project.
Your example "which hello.exe" should be used honestly makes not much sense. Two tools with the same name?
Even if both are, let's say, an api, your devops will be happier with more meaningful names.
The bin folder is used for 3rd party tools you install, you so not have to install your project binaries. Except they are tools, but then the name should be meaningful again.
You can get more information about the project structure here: https://golang.org/doc/code.html
Since go 1.8 supports a vendor folder below project folders, it is possible to break the original structure. (imho vendors were not maintainable before 1.8, yes that was crazy)
You might want to use a tool like direnv, which would support your desire to change GOPATH per project.
https://github.com/direnv/direnv
It also has some built in function for adding the current path to the GOPATH.
https://github.com/direnv/direnv/blob/master/stdlib.sh#L355:1
For example GoLang also supports handling multiple GOPATHs and per project GOPATHs. So direnv should also work properly.
In my company we have one go folder right next to our other projects.
Under go/src are our projects. No problem so far, since vendors are in the projects' vendor folders and committed.
The so far best dependency manager I would recommend for go is:
https://github.com/golang/dep
I hope that input helps.
With Go 1.11 Go Modules were introduced. You can use Go Modules to have Go projects outside the GOPATH directory.
Here is an example of how to configure a project using GoModules.

Golang package not found [duplicate]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I have a go project that is starting to become more complex, and want to lay the filesystem out in such a way to reduce pain.
Are there some good examples out there of what makes sense?
Update May 2013: the official documentation is in the section "Code organization"
Go code must be kept inside a workspace.
A workspace is a directory hierarchy with three directories at its root:
src contains Go source files organized into packages (one package per directory),
pkg contains package objects, and
bin contains executable commands.
The go tool builds source packages and installs the resulting binaries to the pkg and bin directories.
The src subdirectory typically contains multiple version control repositories (such as for Git or Mercurial) that track the development of one or more source packages.
bin/
streak # command executable
todo # command executable
pkg/
linux_amd64/
code.google.com/p/goauth2/
oauth.a # package object
github.com/nf/todo/
task.a # package object
src/
code.google.com/p/goauth2/
.hg/ # mercurial repository metadata
oauth/
oauth.go # package source
oauth_test.go # test source
Update July 2014: see "Structuring Applications in Go" from Ben Johnson
That article include tips like:
Separate your binary from your application
combining the main.go file and my application logic in the same package has two consequences:
It makes my application unusable as a library.
I can only have one application binary.
The best way I’ve found to fix this is to simply use a “cmd” directory in my project where each of its subdirectories is an application binary.
camlistore/
cmd/
camget/
main.go
cammount/
main.go
camput/
main.go
camtool/
main.go
Library driven development
Moving the main.go file out of your root allows you to build your application from the perspective of a library. Your application binary is simply a client of your application’s library.
Sometimes you might want users to interact in multiple ways so you create multiple binaries.
For example, if you had an “adder” package that that let users add numbers together, you may want to release a command line version as well as a web version.
You can easily do this by organizing your project like this:
adder/
adder.go
cmd/
adder/
main.go
adder-server/
main.go
Users can install your “adder” application binaries with “go get” using an ellipsis:
$ go get github.com/benbjohnson/adder/...
And voila, your user has “adder” and “adder-server” installed!
Don’t go crazy with subpackages
Usually my project’s types are all very related so it fits better from a usability and API standpoint.
These types can also take advantage of calling unexported between them which keeps the API small and clear.
Group related types and code together in each file. If your types and functions are well organized then I find that files tend to be between 200 and 500 SLOC. This might sound like a lot but I find it easy to navigate. 1000 SLOC is usually my upper limit for a single file.
Organize the most important type at the top of the file and add types in decreasing importance towards the bottom of the file.
Once your application starts getting above 10,000 SLOC you should seriously evaluate whether it can be broken into smaller projects.
Note: that last practice isn't always good:
Sorry I just cant agree with this practice.
Separating type to files helps code management, readability, maintenancability, testability.
It may also ensure single responsibility and the follow of open/closed principle…
The rule for not allowing circular dependency is to force we have a clear structure of the packages.
(Alternative February 2013, regarding src only)
You can find the classic layout illustrated in "GitHub Code Layout":
The app and both libraries live on Github, each in its own repository.
$GOPATH is the root of the project - each of your Github repos will be checked out several folders below $GOPATH.
Your code layout would look like this:
$GOPATH/
src/
github.com/
jmcvetta/
useless/
.git/
useless.go
useless_test.go
README.md
uselessd/
.git/
uselessd.go
uselessd_test.go
README.md
Each folder under src/github.com/jmcvetta/ is the root of a separate git checkout.
That attracted some criticisms though, in this reddit page:
I highly recommend not structuring the repo the way you have, it'll break "go get", which is one of the most useful things about Go.
It's far better to write your code for people who do know Go, since they're most likely to be the ones compiling it.
And for people who don't, they'll at least get a feel for the language.
Put the main package in the root of the repo.
Have the assets in a subdirectory (to keep things neat).
Keep the meat of the code in a subpackage (in case anyone wants to reuse it outside your binary).
Include a setup script in the root of the repo so it's easy to find.
It's still only a two step process to download, build, install, and setup.:
"go get <your repo path>": downloads and installs the go code, with a subdir for the assets
$GOPATH/<your repo path>/setup.sh: distributes the assets to the right place and installs the service
I assume that with 'project' you don't mean a Go package but a software you develop.
Otherwise you can get help here and here.
However it's not so much different to writing packages for Go: Use packages, create a folder for each package and combine those packages in your application.
To build yourself an opinion, you can look at trending Go repositories on github: https://github.com/trending/go. Notable examples are cayley
and zeus.
The most popular scheme is probably to have a main Go file and many modules and submodules in their own directories. In case you have many meta files (doc, license, templates, ...) you may want to put the source code into a subdirectory. That's what I did so far.
There is a recommended approach from the authors of Golang that defines how to layout your code to work best with the go tools and to support source control systems
You should probably also have a look into this repo. It shows a lot of ideas how to structure go applications: https://github.com/golang-standards/project-layout

Go - Do I have one workspace for all projects, or one workspace per project?

When using Go how are projects organized? I'm a bit confused on the workspaces part. I've had a read of the following: https://golang.org/doc/code.html#Workspaces ... and this part has thrown me off a little:
A typical workspace contains many source repositories containing many packages and commands. Most Go programmers keep all their Go source code and dependencies in a single workspace.
Does this mean that for each project I create it is a seperate workspace? For example if two projects use the same package, I would have two copies of that package on my computer.
Or, does it mean you have a main workspace and your projects share those packages?
Bit confused.
I personally like to have a different GOPATH per project. If you are fine using a tool to automate the process you can use vg which will take care of managing different GOPATHs for your projects.
The neat bit is that it integrates with most shells and auto-detect projects as you cd them.
So far, I use different workspaces either when I want to use a different version of Go or I want to separate my private work from the code the kids and I have fun with. Also if I want to play with some open source code but want a simple way of cleaning it all up later.
Something like
mk /tmp/tmpgo
cd /tmp/tmpgo
# Copy or edit a setenv file
. setenv # I use bash
The setenv file looks something like this.
export GOROOT=$HOME/go16
export GOPATH=$PWD
export GOBIN=$GOPATH/bin
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH
export PS1='\[\033[01;32m\]workspacenamehere\[\033[01;33m\] \W\[\033[00m\] '
This gives me a go workspace with its own bin, src, pkg subdirectories. I can go get anything I want. Later I can delete the whole temporary directory if I like. Getting things from repositories like github.com has a tendency to get many packages from other contributors, but because it puts them all into a clean src subdirectory, it's easy to use find and see what has been pulled down. And later it is even easier to remove everything from the hd again.
You have one workspace and projects share the packages.
It's there in the overview section:
Go programmers typically keep all their Go code in a single workspace.
Note that this differs from other programming environments in which every project has a separate workspace and workspaces are closely tied to version control repositories.
Edit: If you use vendoring, you can effectively get a separate workspace for each project. This brings things closer to how other programming languages work.

Whats a good best practice with Go workspaces?

I'm just getting into learning Go, and reading through existing code to learn "how others are doing it". In doing so, the use of a go "workspace", especially as it relates to a project's dependencies, seems to be all over the place.
What (or is there) a common best practice around using a single or multiple Go workspaces (i.e. definitions of $GOPATH) while working on various Go projects? Should I be expecting to have a single Go workspace that's sort of like a central repository of code for all my projects, or explicitly break it up and set up $GOPATH as I go to work on each of these projects (kind of like a python virtualenv)?
I think it's easier to have one $GOPATH per project, that way you can have different versions of the same package for different projects, and update the packages as needed.
With a central repository, it's difficult to update a package as you might break an unrelated project when doing so (if the package update has breaking changes or new bugs).
I used to use multiple GOPATHs -- dozens, in fact. Switching between projects and maintaining the dependencies was a lot harder, because pulling in a useful update in one workspace required that I do it in the others, and sometimes I'd forget, and scratch my head, wondering why that dependency works in one project but not another. Fiasco.
I now have just one GOPATH and I actually put all my dev projects - Go or not - within it. With one central workspace, I can still keep each project in its own git repository (src/<whatever>) and use git branching to manage dependencies when necessary (in practice, very seldom).
My recommendation: use just one workspace, or maybe two (like if you need to keep, for example, work and personal code more separate, though the recommended package path naming convention should do that for you).
If you just set GOPATH to $HOME/go or similar and start working, everything works out of the box and is really easy.
If you make lots of GOPATHs with lots of bin dirs for lots of projects with lots of common dependencies in various states of freshness you are, as should be quite obvious, making things harder on yourself. That's just more work.
If you find that, on occasion, you need to isolate some things, then you can make a separate GOPATH to handle that situation.
But in general, if you find yourself doing more work, it's often because you're choosing to make things harder.
I've got what must be approaching 100 projects I've accumulated in the last four years of go. I almost always work in GOPATH, which is $HOME/go on my computers.
Using one GOPATH across all of your projects is very handy, but I find this to only be the case for my own personal projects.
I use a separate GOPATH for each production system I maintain because I use git submodules in each GOPATH's directory tree in order to freeze dependencies.
So, something like:
~/code/my-project
- src
- github.com
+ dependency-one
+ dependency-two
- my-org
- my-project
* main.go
+ package-one
+ package-two
- pkg
- bin
By setting GOPATH to ~/code/my-project, then it uses the dependency-one and dependency-two git submodules within that project instead of using global dependencies.
Try envirius (universal virtual environments manager). It allows to compile any version of go and create any number of environments based on it. $GOPATH/$GOROOT are depend on each particular environment.
Moreover, it allows to create environments with mixed languages (for example, python & go in one environment).
At my company I created Virtualgo to make managing multiple GOPATHs super easy. A couple of advantages over handling it manually are:
Automatic switching to the correct GOPATH when you cd to a project.
It integrates well with vendoring tools
It also sets the new GOBIN in your path, so you can use the executables installed there.
It still has your original GOPATH as a backup. If a package is not found in the project specific workspace it will search the main GOPATH.
One workspace + godep is best as for me.
I follow KISS - one GOPATH, two go paths:
export GOPATH=$HOME/go:$HOME/development/go
That way third party stuff goes in a central place (package install uses the first path entry by default), and I can flexibly move my projects elsewhere, at the second path entry.
You might want to try the direnv package.
https://direnv.net/
Just use GoSwitch. Saves a heck of a lot of time and sanity.
Add the script to the root of each of your projects and source it.
It will make that project dir your gopath and also add/removes the exact bin folder of that project to path.
https://github.com/buffonomics/goswitch

go get with multiple projects in workspace

In Go, the workspace contains the src, pkg and bin directories. How do I create multiple projects in the workspace, each with its own src, pkg, bin directories, such that I can 'go get' packages into the pkg directory of a particular project.
You probably do not need that. Let's forget also the word "workspace" it's probably only confusing you.
If you set your GOPATH environment variable that that's all you actually need to have multiple projects independently sitting on you hard disk.
For example, having export GOPATH="$HOME", and performing
$ go get github.com/foo/bar
$ go get github.com/baz/qux
Your directory tree will be
$GOPATH/pkg...
compiled packages
$GOPATH/src/github.com/foo/bar
bar.go
$GOPATH/src/github.com/baz/qux
qux.go
More details here. Note that it does talk about workspaces, but I still consider that fact very unfortunate. The earlier versions of that doc did not use nor define the concept and they were useful anyway. That's IMO a proof of it (the workspace) being redundant.
go get is not intended to be used that way.
all go get packages land in $GOPATH/* as described here: http://golang.org/doc/code.html#remote and there is no concept of separate workspaces.
If you really want several "workspaces": Have several entries in GOPATH (separated by ":" on unix).
(But most just keep everything under one GOPATH).
Remember that go get fetches packages only into your first GOPATH entry.
The other entries can be used as "seperate workspaces".

Resources