Emacs, scripting and anything text oriented.

Cleaning up ${GOPATH}/pkg/

Kaushal Modi

Use go clean -modcache to clean up all the old auto-downloaded Go modules in ${GOPATH}/pkg/. That’s all you need to know. Rest of the post gives just the history of how I got there.

As I mentioned in the post description above, the solution to clean up the auto-populated ${GOPATH}/pkg/ is to run go clean -modcache. While the solution is simple, it wasn’t easy for me to discover, and so I am writing this short piece to make it a bit more discoverable for others like me.

The $GOPATH directory #

The GOPATH environment variable lists places to look for Go code.

If you haven’t set this variable and if the ${HOME}/go/ directory isn’t used to contain the Go distribution, $GOPATH defaults to that path.

When you run go get to install any Go package,

  • ${GOPATH}/pkg/ gets populated with all the Go module dependencies,
  • .. and all package’s executables if any get installed to ${GOPATH}/bin/.

I think that if the user has set the $GOMODCACHE environment variable, that directory would get populated with Go module downloads instead. But for my use, I am sticking with only the $GOPATH for simplicity.

To confirm the value of GOPATH used by Go, see go env | rg GOPATH.

The disk space issue #

I have been happily installing and building Go apps like Hugo using go get or go build, and all these installations would end up in the $GOPATH. But over time, I noticed that the disk space used by ${GOPATH}/pkg/ just kept on creeping up.

Today I happened to notice that this directory was taking up roughly 4 GB of my disk space! I started analyzing why it was taking up so much space using my favorite tool for this purpose – ncdu.

Here’s a snapshot showing disk usage by one of the sub-directories under ${GOPATH}/pkg/, which shows the problem — Over time, I had accumulated multiple versions of multiple packages!

Figure 1: Snapshot of ncdu showing disk usage for a ${GOPATH}/pkg/ directory

Figure 1: Snapshot of ncdu showing disk usage for a ${GOPATH}/pkg/ directory

Write-protected ${GOPATH}/pkg/ #

I identified the problem. And I knew that I just needed to delete all the old packages.

        But Go wouldn’t allow deleting those pkg/ directories!

I had been searching a solution to this on and off, but didn’t have much success, mainly attributed to the short and generic name of the “Go” language, and the fact that I didn’t know what the ${GOPATH}/pkg/ directory was called.

Cleaning up “modcache” #

Today, I finally had success when I searched for this magic phrase: golang “cannot remove” “pkg/mod” .. and Golang Issues # 27161 was the first search result!

The solution was so simple, but so difficult to look for ..

go clean -modcache
Code Snippet 1: Command to delete contents in ${GOPATH}/pkg/ or the Go modcache

From that issue, I also learned that the ${GOPATH}/pkg/ directory is the default “modcache” or the cache directory for holding all the installed Go modules.

Wrapping up #

Knowing that the stuff I was trying to delete is called modcache, this of course works ..

go help clean | rg modcache -A 2
Code Snippet 2: Getting help with cleaning up the modcache from go help

The issue referenced above gets resolved when a -modcacherw switch gets added to the go build command. I see that switch when I run go help build. But that switch is not available for go get? .. because I don’t see it when I run go help get.

I don’t understand why Go decided to make this so complicated by taking away the write access from the user who installed the Go package!

        At least go clean -modcache accomplishes what I want .. sigh

References #