-
Notifications
You must be signed in to change notification settings - Fork 5.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Best project structure when using go 1.11 mod #18
Comments
I've found that Go modules tend to not work all to well when it comes to the whole mono-repo approach that was encouraged by the use of For now I've just done as you have, and resorted to using |
@andrewpillar Thank you for the feedback. Yeah, I guess in the meantime I will keep doing the same and see which changes might come in the next version or revert back to just using GOPATH. |
Yeah, I think the approach I'll be taking for now is alternating between using |
I simply use the whole repository address in
Do you have a problem with this approach? |
@tiramiseb one problem I've encountered is that unless I put the For projects where I only have one
Consider the above project structure, if I made any changes to any packages I have in the top-level I hope I've explained this well enough, but the short of it is this: with Go modules I have ran into issues when taking a mono-repo approach in development. If I am missing something, or misunderstanding certain concepts then please do tell me. |
Indeed. I only have |
@tiramiseb I’m in the same boat, only a go.mod at the root, but I hit the same issue as @ypeckstadt if I moved my Did you (or anyone else) have a project structure that allowed for a single go.mod at repo root, but with all other code contained in subdirs? Or have I missed something here in structuring my code? Ideally, I’d like to end up with something similar to the standard structure many projects use with Gopkg.toml at the root, but basically all code inside |
This is exactly what I am doing : |
EDIT: Came back to this and noticed it had a lot of reactions! Here's a similar, simple project building binaries in and out of the root folder: https://github.com/alexeldeib/godemo I must be missing something -- I read that doc several times and haven't been able to figure out my issue. If for example I use this structure (example):
I can hit the imports successfully, but if I do e.g., I'm not sure this necessarily should work, but if not I'm unsure how I would go about this otherwise. Could you possibly share a an example project structure you use, with the application entrypoint in |
Have you put the complete package address in the go.mod header (and not only its name), as explained above? |
$DIR/go.mod:
$DIR/cmd/app/main.go:
and then Appreciate your advice! EDIT: If you're looking at this example, it should be |
The only difference I see is that I run |
D'oh. That was it. Thank you!! 😂 |
I like the idea of using Go, mostly for performance reasons (not the nicest or most succinct syntax tbh) but I find it strange that 4 years later there is only a rudimentary, barely working package/module system that doesn't scale at all well once you go beyond a single directory. Guess I check back in another year 😔 |
@dominictobias, can you explain it better please? |
As far as I can tell if I want to structure an application how I would in another language (lots of folders), I have to do this require/replace thing which causes the IDE/intellisense not to work properly and Go has no concept of local private packages, in fact I would just describe them as modules that make up an app, they're not intended to be separately published. I wish I could just structure an app how I pleased and do relative imports. Even if I want to put some cloud functions in folders for example gcloud can no longer find anything. Maybe it's my lack of experience but I find this stuff trivial with NPM for example. The google functions examples show things at one level deep but if I have 60 cloud functions that's 120 files with tests in one folder at minimum, plus shared utility code which could be dozens of files. I find whenever I give Go-a-go again I quickly hit this wall of googling how to structure more than a hello world. |
I think you need to understand how go mod works. |
Since I created this issue I really haven't run into any problems anymore while working with a project that has many folders and that follows the go-lang standard folder layout recommendations. |
Go does not support relative imports. https://stackoverflow.com/questions/38517593/relative-imports-in-go But, like others, I've had no problems structuring large applications with lots of directories. You need to give the module a name, and then use it with all imports. Example: https://github.com/simpleiot/simpleiot/blob/master/cmd/siot/main.go If you set up your editor to use use goimports, then the imports automatically get added/removed as needed, so it requires almost no effort to manage imports. Works pretty well for me. |
Thanks all, I'll give it another go! |
You can have a look into kubernetes project structure which is following a similar topology. Though it also needs require/replace in go.mod My idea of go-dev can be:
This has advantage that go mod/build layer can be reused to save overall build time. Also resulting app/run image can be based on alpine to have significantly less image size. |
if project use replace to import package in the same project, other who want to import the package will not found the package, because the path is ../package-name. |
Are there any examples without 'github.com/' and $GOPATH prefixes? |
@alexeldeib: shouldn't it be "package main", rather than "package app", in $DIR/cmd/app/main.go ? @tatarsky-v: the following works for me with go 1.13, in a random directory outside of GOPATH. I first did
(I chose different package name than the directory name just to demonstrate) If I Also, at the top level I can do The problem is, if I put public library code in a
... and I presume this means the users would have to import it the same way. If I want users to import Looking in Kubernetes source (which has a I did consider putting another |
@candlerb Executable commands must always use package main. (quoting https://golang.org/doc/code.html, under "Package names") Here's a demo project producing three binaries: https://github.com/alexeldeib/godemo |
Correct - I was referring to this comment of yours, second half, where you put your |
Yup, Note also that e.g. https://github.com/google/go-cloud Some go even flatter: |
Hi guys, on what condition we can close this issue? |
I think that to close this, a note should be added under the If I understand correctly, they are:
In short, Someone please correct me if I'm wrong. |
I had a quick look at this example and I see a set of apps under cmd. However these apps are pulling stuff from git hub (e.g. "github.com/simpleiot/simpleiot/api"). Suppose you want to change api and the app at the same time how do you do that without ongoing promotion of api to github? What if you don't want the code on github, just locally? |
Yes :) In
I put such lines at the end of the This is the main subject of this issue... |
The first thing you will run into when using go.mod, putting code outside GOPATH, and using the recommended folder structure is that your cmd/ does not have access to your internal or pkg folder. Therefore you are automatically required to resort to using the require/replace fix to actually get access to the code or actually split your code into actual modules and upload separately.
While the require/replace fix works and builds, your IDE will probably still have problems picking up the imports for good code navigation unless you manually update your go.mod file in the pkg or internal folder. (you cant use go build to update your go.mod/sum file as there is nothing to build in the folder) Of course, this is more of an IDE problem.
Would people still recommend this folder layout when using go modules, have multiple cmd applications, and especially when putting code outside the gopath? I am curious as I see more and more people starting to use modules and putting their code in a GOPATH-less environment and this is for sure bound to create problems and confusion when using modules as it requires "some" custom setup. Of course, nothing major once you figure it out.
Come to think of it, this is more of a general issue with go mod. You will run into this issue from the moment you put your main.go file in a subfolder and not the root.
The text was updated successfully, but these errors were encountered: