What does the command do?
Here’s what the command’s documentation has to say about it:
Tidy makes sure go.mod matches the source code in the module. It adds any missing modules necessary to build the current module's packages and dependencies, and it removes unused modules that don't provide any relevant packages. It also adds any missing entries to go.sum and removes any unnecessary ones.
How does it work?
Let’s say you’re working on a simple web app and you’ve added module support with go mod init, but you haven’t explicitly added any dependencies, yet.
Given that, go.mod would likely look similar to the following:
module flash-messages-demo
go 1.20
Then, you update the import list in one of your app’s source files such that it looks like the following:
import (
"flag"
"fmt"
"html/template"
"log"
"net/http"
"os"
"github.com/gorilla/sessions"
"github.com/joho/godotenv"
"github.com/julienschmidt/httprouter"
"github.com/justinas/alice"
)
The packages at the top of the list, from the standard library, would be available. But the final four, external, modules would not be satisfied, resulting in a broken import error.
To satisfy them, you could jump to the terminal and run go get with the four package names, as in the following example:
go get github.com/gorilla/sessions \
github.com/joho/godotenv \
github.com/julienschmidt/httprouter \
github.com/justinas/alice
This would update go.mod and create go.sum. However, it also means you have to either:
- Type out the four packages at the end of
go get, potentially resulting in errors because you didn’t type the names correctly. - Copy-paste the package names from the import list to the terminal. This might still result in errors if you didn’t copy the full package name, and be annoying to boot.
Neither of these steps are required, though, thanks to go mod tidy.
It:
- Scans your app’s Go source files for package references
- Adds them to go.mod
- Creates go.sum (if not present) and adds the packages there as well
Using the four packages above as an example, you’d see the following printed to the terminal:
go: finding module for package github.com/gorilla/sessions
go: finding module for package github.com/julienschmidt/httprouter
go: finding module for package github.com/justinas/alice
go: finding module for package github.com/joho/godotenv
go: found github.com/gorilla/sessions in github.com/gorilla/sessions v1.2.2
go: found github.com/joho/godotenv in github.com/joho/godotenv v1.5.1
go: found github.com/julienschmidt/httprouter in github.com/julienschmidt/httprouter v1.3.0
go: found github.com/justinas/alice in github.com/justinas/alice v1.2.0
Then, if you looked in go.mod, it’d look similar to the following:
module flash-messages-demo
go 1.20
require (
github.com/gorilla/sessions v1.2.2
github.com/joho/godotenv v1.5.1
github.com/julienschmidt/httprouter v1.3.0
github.com/justinas/alice v1.2.0
)
require github.com/gorilla/securecookie v1.1.2 // indirect
And go.sum would look as follows:
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY=
github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/justinas/alice v1.2.0 h1:+MHSA/vccVCF4Uq37S42jwlkvI2Xzl7zTPCN5BnZNVo=
github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA=
Now, you won’t get any import errors when trying to lint or run the code.
That’s a quick introduction to go mod tidy
As someone not super-experienced with Go development and all the ins and outs of its tooling, there may be better approaches, as well as gotchas to using go mod tidy that I’m not aware of.
However, so far, I’ve found it to be a quick and handy way of ensuring that dependencies are added and removed when I update my Go source files. What about you? Do you make good use of it?