Using go.mod for local packages
Golang provides the tools which enable the users to manage the dependencies of a project using mod. This allows one to host the dependencies for each project individually but, more importantly, to select the version of that dependency they wish to use.
But the problem I faced these last two days was not that, but another. I wanted
to be able to host the code of my Go projects outside the src
folder inside
the $GOPATH
. Also, I wanted to be able to develop closed-source projects
without using the $gitserver/captainepoch/project
naming scheme.
To be able to do that, first of all you need to create a folder (with the
name of your liking because it will be the root package. For this example, my
main package will be called potato
:
$ go mod init potato
And you get a bare modules file:
module potato
go 1.15
Now, let’s create a config
local package. The point of this is to be able to
use it locally without getting it from any repo. Create a folder, a .go file,
and a go.mod file:
$ mkdir config && cd config
$ go init mod config
$ touch config.go
Inside the config.go
file:
package config
import "fmt"
func GetConfig() {
fmt.Println("GetConfig executed")
}
To be able to use this in the main package, you have to use the replace
directive:
module potato
go 1.15
replace potato/config => ./config
And the main.go
content:
package main
import (
"fmt"
"potato/config"
)
func main() {
fmt.Println("Potato is life")
config.GetConfig()
}
You should see your modules file already changed when adding this to your main
package. However, if you do not see anything, you have to run the tidy
command:
$ go mod tidy
If you need to use some local package inside another local package, you have to
use replace but using ..
: replace potato/utils => ../utils
which allows you
to use a local package inside the project’s root inside another local package.
Also, you have to add the replace
in the root modules file, so Go knows where
to look at to find that local package.
Be aware that this can cause circular dependencies which is not something good. So if you use this, use it with something you know will not create any circular dependency problem.
I know this is far from being orthodox but sometimes this hack helps more than other solutions.
If you have any questions, please reach me at my NixNet account captainepoch@nixnet.social (the mailist is WIP).
I want to thank jbauer and Tedster for the corrections of this post :).