Go Modules and How to Migrate

I have just ported one of my internal modules to use Go Modules instead of dep and I ran into a interesting problem and some pleasant surprises I will like to share with you!

If you have a project running another dependency manager e.g. dep it is possible to make an automatic migration to go modules by doing the following:

$ cd $GOPATH/vcs/organization/project
$ export GO111MODULES=on    # To use modules on projects within your $GOPATH
$ go mod init

After this it is possible to use go module commands in your coding workflow such as go mod tidy which will tidy-up in your dependencies based on your code.

Gotcha with Module Name and Internal Packages


When doing this automatic migration $ go mod init will call your module the path from $GOPATH e.g. bitbucket.org/organization/project.
However, when I did this automatic migration I did it on a clean clone of the project.
But I did not place the project within the correct path and my module name was set to module project.
When doing go build it will invoke go get  to get the internal dependencies placed within internal/ which fails with the following errors:

go: missing Mercurial command. See https://golang.org/s/gogetcmd
go: missing Mercurial command. See https://golang.org/s/gogetcmd
go: missing Mercurial command. See https://golang.org/s/gogetcmd
go: missing Mercurial command. See https://golang.org/s/gogetcmd
go: missing Mercurial command. See https://golang.org/s/gogetcmd

After a good amount of googling on the issue I found this: https://github.com/golang/go/issues/27224#issuecomment-416000753
So the fix is to manipulate go.mod from module project to module bitbucket.org/organization/project and everything started working correctly.

No more $GOPATH!

Now you can move your project to where ever you want on your machine and still go build, test, and run as you normally do!
E.g. try and move your project to /dev/project and execute a go build
This is such a nice change I cant even find the words to describe it!

Vendoring

It was purposed to totally remove vendoring (you may know it as the vendor directory) in go modules and I actaully thought it would get removed. But the community had good reasons and it was decided to keep it!
You can read more here: https://github.com/golang/go/wiki/Modules#how-do-i-use-vendoring-with-modules-is-vendoring-going-away

If you like vendoring (and not just ignore it in your .gitignore) you can keep using it by doing:

go mod vendor

This will create a vendor directory including all your dependencies.

Conclusion

In conclusion I ran into a gotcha, because of a human mistake, but overall I really enjoy modules and I think the go team have done a fantastic job especially with the migration from prior dependency managers such as dep:  https://github.com/golang/go/wiki/Modules#automatic-migration-from-prior-dependency-managers
I will definitely port more projects to go modules in the future and most importantly no more $GOPATH!