Project Layout Question

163 views
Skip to first unread message

Boris Mühmer

unread,
Jun 11, 2019, 8:47:44 AM6/11/19
to golang-nuts
Hello Everyone,

my development environment is based on Linux and Windows, and I work with VS Code in both environments.

Before Go 1.12 I was a "fan" of https://github.com/golang-standards/project-layout to organize my projects.
With 1.12 I started to move my project bases out of "~/go/src/URI/USER/PROJECT" to a something like "REPOBASE/PROJECTS/PROJECT", and I wanted to establish "go.mod".
But several problems rised after this. Sometimes I just had problems to "go run" the program, other times VS Code showed several error messages.

Let's say I have the fantastic project "foo", which consists of several command line tools like "foo-server", "foo-client-admin", and "foo-client-user". Also there are several libraries like "foo-common", "foo-server", "foo-client".

With my pre-1.12 approach I would have done something like (just for the directories):

  - PROJECTS/foo
  - PROJECTS/foo/cmd/foo-server
  - PROJECTS/foo/cmd/foo-client-admin
  - PROJECTS/foo/cmd/foo-client-user
  - PROJECTS/foo/pkg/foo-common
  - PROJECTS/foo/pkg/foo-client
  - PROJECTS/foo/pkg/foo-server

"PROJECTS/foo" is also my "git root".


So, basically my questions is how should I organize a project to make the "go tools" and VS code happy?

For example, where should I do the "go mod init"?
Are library names with hyphens in there names a bad idea?
Is the project layout total rubbish?


Regards,
Boris

Ronny Bangsund

unread,
Jun 11, 2019, 1:38:58 PM6/11/19
to golang-nuts


On Tuesday, June 11, 2019 at 2:47:44 PM UTC+2, Boris Mühmer wrote:
Is the project layout total rubbish?

I'm not sure - all I know is that it's different from how I prefer it, and "pkg" is the one thing I frequently see people dislike ;)
If you want to share packages, parent them to the project directory. Anything you feel is too niche you can hide inside internal/. Binaries in cmd/ makes it nice and tidy, but you can get away with top-level main packages if there's only one command and it's really simple (few source files to clutter it up).

I might make a server cmd the same name as the project directory, and if possible, make it have CLI options to control itself (talk via local socket, gRPC, REST, whatever). Pleasing VS Code is mainly about configuring the build task(s). I like to have Release and Debug tasks, sometimes with tasks requiring other tasks (client-server projects, for instance).

So one of my web server app layouts might be something like this:
foo/
|--foo (binary)
|--auth/
|--<any number of content-specific package>
|--static/
    |--css/
    |--js/
    |--tpl/

While a tool with some less standard packages of utility content might look like this:
bar/
|--cmd/
|     |--binary1/ (and so on)
|--<misc. package directories>
|--internal/
    |--<various command-specific packages, for instance shared options and flags>

I try to give server/client parts of a multi-binary system somewhat useful names, even it it means a little "stutter". For instance, the server app might reside in "foo/cmd/foo", and the manager is in "foo/cmd/foomgr/". I don't really like hyphens and underscores in names, but I'm not sure if there's any technical reason you should use them. It might be a matter of taste. Some programs might have "foo" as the main command, and the other "foo-" commands are possible to run alone, but also hidden behind options in "foo".

I also decide from time to time that I hate everything about my project layouts and redo everything, so don't consider this advice, or even useful.

I haven't looked closely at the current state of modules to say anything about how it'll change up my standards, but it looks like we're expected to run module stuff out of the top-level directory. If not, aren't those parts better off breaking out into their own standalone projects? Running module setup in sub-directories with potentially different versions of external dependencies feels dirty.

David Riley

unread,
Jun 11, 2019, 5:47:17 PM6/11/19
to Ronny Bangsund, golang-nuts
On Jun 11, 2019, at 13:38, Ronny Bangsund <ronny.b...@gmail.com> wrote:



On Tuesday, June 11, 2019 at 2:47:44 PM UTC+2, Boris Mühmer wrote:
Is the project layout total rubbish?

I'm not sure - all I know is that it's different from how I prefer it, and "pkg" is the one thing I frequently see people dislike ;)
If you want to share packages, parent them to the project directory. Anything you feel is too niche you can hide inside internal/. Binaries in cmd/ makes it nice and tidy, but you can get away with top-level main packages if there's only one command and it's really simple (few source files to clutter it up).

This layout is, I feel, most useful for large projects which build many binaries and have many packages (which is what we use it for). In that context, it’s great.

I might make a server cmd the same name as the project directory, and if possible, make it have CLI options to control itself (talk via local socket, gRPC, REST, whatever). Pleasing VS Code is mainly about configuring the build task(s). I like to have Release and Debug tasks, sometimes with tasks requiring other tasks (client-server projects, for instance).

One thing I’ve found it doesn’t work especially nicely with is things that have files hardcoded to be in `pwd` (the common “task” utility is an example of this), because then you get your nice, tidy top level cluttered with dreck from your tools.

Also, `go test` runs its commands from the directory of the tested package, not the current working directory, but that gripe is better hashed out elsewhere.

I haven't looked closely at the current state of modules to say anything about how it'll change up my standards, but it looks like we're expected to run module stuff out of the top-level directory. If not, aren't those parts better off breaking out into their own standalone projects? Running module setup in sub-directories with potentially different versions of external dependencies feels dirty.

It works fine with modules, at least assuming your repo directory is one module! We haven’t tried it with sub-modules, mostly because that feels like madness.


- Dave

Boris Mühmer

unread,
Jun 13, 2019, 3:22:19 AM6/13/19
to David Riley, Ronny Bangsund, golang-nuts
Thanks for Your suggestions so far. I will have to do further tests to see what suits our team best.


Regards,
Boris

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/174A6172-8A4B-47F0-9C49-F54A7D1B17A8%40gmail.com.
For more options, visit https://groups.google.com/d/optout.

Randall O'Reilly

unread,
Jun 13, 2019, 5:04:02 AM6/13/19
to Boris Mühmer, David Riley, Ronny Bangsund, golang-nuts
In case it helps anyone else with this problem, there is an issue with the standard layout, and any project where all the code is in various subdirectories but there is no .go code at the top level: godoc.org won’t find it!

https://github.com/golang-standards/project-layout/issues/19
https://github.com/golang/gddo/issues/618

a good workaround is to create a doc.go file at the top level, which can be a handy place to put overall project docs I guess.

btw, a further advantage of moving all code (except doc.go) out of the top level is that it makes your github page look nicer, especially for being able to read the README file without having to scroll down too far. I’ve adopted the strategy of just having a “stutter” in repeating the name of the overall repository as the main package subdirectory in the repository (e.g., gi/gi) — the std go import prefix is the same, but you get the advantage of moving all the code out of the top level.

- Randy
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CALW2tjrL8bDJvqh3cZGMhK6GNoy7XNJhKFwmhFW9FJqH92KtqQ%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages