Error with Go modules build using /cmd structure
Asked Answered
S

3

13

I'm new to go modules, and am taking them for a spin in a new project which I'm trying to model after the structure described here

Here is an example of my directory structure:

.
├── cmd
│   └── app_name
│       └── main.go
├── go.mod
├── go.sum
├── internal
│   └── bot
│       └── bot.go
└── pkg
    ├── website_name
    │   ├── client.go
    │   ├── client.options.go
    │   ├── server.go
    │   └── server.options.go
    └── lib
        └── lib.go
  1. Is this idiomatically correct? I know there's not a whole lot of consensus out there, but I'd like to follow best practices.
  2. When I run go build I get 'unexpected module path "github.com/ragurney/app_name/cmd/app_name"', but when I run go build ./... it works. Why?

When I move main.go to the top level everything works as expected. Should I just not use the /cmd pattern with modules?

Spitsbergen answered 2/11, 2018 at 16:32 Comment(3)
What is the module line in your go.mod? It sounds like it's referring to cmd/app_name which would be incorrect - it should point at the directory where it is located.Crymotherapy
It was pointing to cmd/app_name specifically: module github.com/ragurney/app_name/cmd/app_name. So instead it should be: github.com/ragurney/app_name? Doing that causes a similar error: "cannot find module providing package github.com/ragurney/app_name"Spitsbergen
Yes, it should be github.com/ragurney/app_name if that's the root (where the go.mod file is). Do you have multiple go.mod files in your repo by chance?Crymotherapy
L
15

To answer your first question, its completely opinionated and whatever you like best that is also easy to understand for others you should go with (I think it's fine).

To answer your second question the reason go build ./... works as opposed to go build from the root directory is because ./... starts in the current directory (the root) and searches for all program entry-points and builds them. When you move main.go to the root directory, with this new information, go build working then makes sense, as its only looking in the current directory.

You can explicitly say go build ./cmd/app_name which would also work.

Your application structure works perfectly fine with modules, as I use something very similar to it (https://www.ardanlabs.com/blog/2017/02/package-oriented-design.html) and modules work very well for me.

Loyal answered 2/11, 2018 at 16:59 Comment(6)
Thanks for the detailed response, also for the link that's a pretty helpful resource! Just to confirm, it's fine if I keep this structure, and then I'd init with go mod init github.com/ragurney/app_name? Then whenever I want to generate the binary, run go build cmd/app_name/main.go?Spitsbergen
Yes that's perfectly valid!Loyal
As the answer says, you would go build ./cmd/app_name. You build a package, not a file, and it's important to root it in CWD (otherwise go thinks you're giving a package name, not a path).Crymotherapy
Gotcha, thanks for all the help everyone and for putting up with my noobish questions. Learned some new things today :DSpitsbergen
"...it's important to root it in CWD..." @Crymotherapy can you point me to a link that describes that / elaborate a little more? I've done go mod init github.com/ragurney/app_name which seems to be working fine, although my cwd is something along the lines of /Users/rygurney/Code/OtherDir/app_nameSpitsbergen
go help build would explain what I was talking about in my comment, but it's nothing to do with modules, it's just how the build command works.Crymotherapy
S
0

from what i can tell there is nothing wrong with your project structure. What has worked for me is to run the go build/run command from the project root

eg. go run github.com/username/project/cmd/somecommand

go build -o somebinary github.com/username/project/cmd/somecommand

Subfloor answered 2/11, 2018 at 16:59 Comment(0)
R
0

I prefer to add the specific file to build, there are some projects with more than one executable

go build -o app ./cmd/server/main.go

Ratchford answered 27/9, 2022 at 19:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.