Features Tutorials

Working with Go Modules – Dependency management

In this second article from our series on Go Modules, we’ll cover how to manage project dependencies:.

This series of articles is broken down into the following sections:

We looked at how to get started with a simple application that has an external dependency in the previous article. Now let’s check out how we can change the version of that dependency, remove it from our source code, and, finally, use the vendoring mode to move our dependencies to the vendor folder.

Changing the version of a dependency

Changing the version of a dependency is a fairly straightforward task.
Navigate to the go.mod file of the project, locate your dependency and replace the version that’s present in the file with the one that you need to upgrade or downgrade to.

The caveat here is that if you want to upgrade to a major version, then you’ll have to change the import path as well, e.g., to migrate from github.com/dlsniper/demo at v1.6.5 to v2.3.4, you’ll need to change the file from require github.com/dlsniper/demo v1.6.5 to require github.com/dlsniper/demo/v2 v2.3.4. We’ll cover this in more detail in a separate article about versioning and migrating to a new major version.

For our example code, let’s migrate from github.com/gorilla/mux v1.7.4, which was the one that was fetched automatically when we originally wrote it, to v1.7.2. To finish the migration, switch to the main file and use the Sync packages of project to download the new version. If the version of the dependency is already in the Go Modules cache, the Sync… operation won’t be needed.

After this, you should now see that the new version is reflected in the list of dependencies for the project.

Using Go Modules - 07 - changing go modules dependency version

Using the vendoring mode

The vendor folder appeared in Go 1.5 and is a popular way to ship the code along with all the dependencies needed to compile it.

Using the vendor mode with Go Modules is straightforward, even if the project was not initially created with it in mind.

We’ll need to enable this manually by going to Settings/Preferences | Go | Go Modules (vgo) and tick the vendoring mode checkbox.

This will result in a vendor folder being created and all our current dependencies being placed there.

Using Go Modules - 08 - vendor dependencies

If we want to add a new dependency, like the popular logging library https://github.com/sirupsen/logrus, then the steps are still the same.

Using the code below, we need to run the Sync packages of project action again and see how the new dependencies are added to our vendor folder.

package main

import (
	"net/http"
	"os"
	"time"

	"github.com/gorilla/mux"
	log "github.com/sirupsen/logrus"
)

func main() {
	log.SetFormatter(&log.JSONFormatter{})
	log.SetOutput(os.Stdout)

	mtx := mux.NewRouter()
	mtx.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		log.WithField("user-agent", r.UserAgent()).Info("accessed home page")
		_, _ = w.Write([]byte("Hello World!"))
	})

	srv := &http.Server{
		Handler:      mtx,
		Addr:         "127.0.0.1:8000",
		WriteTimeout: 10 * time.Second,
		ReadTimeout:  10 * time.Second,
	}

	log.Fatal(srv.ListenAndServe())
}

Using Go Modules - 09 - adding a dependency when vendoring

Tip: Using vendoring mode on new projects is straightforward as well. We just need to tick the vendoring mode checkbox when the project is created, and that’s it.

Tidying up the modules in a project

During the normal usage of modules, some modules that you don’t need may show up in the dependencies list, or you may need to add missing parts of the libraries you import.

So, how do you tidy up the environment? Go offers the go mod tidy command, which will take care of this. It will ensure that the missing modules are added to go.sum and the ones that are no longer used are removed.

It will also clean up the go.sum file so that it refers only to the versions currently being used.

Using Go Modules - 10 - running go mod tidy - optimized

Visualizing the dependencies of a Go project

As projects become more complex, one way to keep track of this complexity is to visualize the dependencies used.

In GoLand you can do this by using the Show Diagram feature, Ctrl+Alt+Shift+U on Windows/Linux or Cmd+Opt+Shift+U on macOS. Navigate to any go.mod file in the project and invoke the feature via the dedicated shortcut or Find Action, Ctrl+Shift+A on Windows/Linux or Cmd+Shift+A on macOS, or Search Everywhere, Shift+Shift.

In the example below, we’ll use Delve, the Go debugger, as an example of this feature in a medium complexity project.

Using Go Modules - 14 - Using Diagrams to see golang dependencies of a project

This concludes our second post for today. In it, we have learned how to change the version of a project dependency and how to use the vendoring mode. In the next blog post, we’ll see how we can increase our project’s major version and what needs to be done to do this correctly.

Until then, if we are looking forward to your feedback. As usual, you can write to us in the comments section below, on our issue tracker, or by tweet to our Twitter account.

image description