In a multi-module repository, should a module name (set via the go.mod module
directive) follow the conventions of package naming?
E.g. module github.com/org-name/repo-name/path/to/module-dir
I understand that, whatever the module is named, the packages within the module refer to each other using the module name as prefix. But, from outside the module, there seems to problems if the module name is set to something other than the <host><path-within-repo>
pattern. get
-ing a package included in the module then gives messages about unrecognized import path
.
Is there any cause to name a module differently than <host><path-within-repo>
?
There isn't any hard requirement for referencing modules, although it always good practice to use the domain/repo pattern. So, if you want to reference other modules locally that are not in the GOPATH, you can use the replace
directive.
https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive
replace also can be used to inform the go tooling of the relative or absolute on->disk location of modules in a multi-module project, such as:
replace example.com/project/foo => ../foo
Let's say we have the following structure:
├── .gitingore
├── pkg1
│ ├── go.mod
│ └── main.go
└── pkg2
├── go.mod
└── utils.go
pkg1/main.go
package main
import (
"fmt"
"local/pkg2"
)
func main() {
fmt.Println(pkg2.Add(1, 2))
}
pkg1/go.mod
module local/pkg1
go 1.12
require local/pkg2 v0.0.0
replace local/pkg2 => ../pkg2
pkg2/utils.go
package pkg2
func Add(a, b int) int {
return a + b
}
pkg2/go.mod
module local/pkg2
go 1.12
Running:
cd pkg1
go run main.go
You get:
3
If you want to be able to go get
a module, it should follow the <host>/repo/path/within/repo
pattern.
However, I would suggest stepping back and asking if you really do want a multi-module repo. It adds substantial complexity, it is hard to get right, and usually means more work on an on-going basis.
Russ Cox commented in #26664:
For all but power users, you probably want to adopt the usual convention that one repo = one module. It's important for long-term evolution of code storage options that a repo can contain multiple modules, but it's almost certainly not something you want to do by default.
For more details, see "Organize local code in packages using Go modules".