Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

golang modules can not update single dependency to my .mod file

Tags:

module

go

I want to update a single dependency in my modules repo.

I've looked through lots of documentation and the JustForFunc videos and it seems like the way to do this is go into the .mod file and update from "1.0.0" to "1.2.0" and run go build.

This works, but then I see my entire go.mod file changed in many places, including those that are not indirects. Some of these changed versions are major version changes for dependencies used in other places in my project. My obvious fear is this will cause a breaking change when I want these versions to remain the same.

I'm using modules and working outside my GOPATH if that matters.

Is there a way to minimize my .mod file changes?

like image 604
bravinator932421 Avatar asked Dec 06 '18 15:12

bravinator932421


2 Answers

tl;dr pass -mod=readonly to go commands to prevent it from automatically updating dependencies to the latest minor/patch releases.

Per the Go wiki:

To upgrade or downgrade to a more specific version, 'go get' allows version selection to be overridden by adding an @version suffix or "module query" to the package argument, such as go get github.com/gorilla/[email protected], go get foo@e3702bed2, or go get foo@'

And from the same wiki:

The go tooling provides a fair amount of flexibility to adjust or disable these default behaviors, including via -mod=readonly, -mod=vendor, GOFLAGS, GOPROXY=off, GOPROXY=file:///filesystem/path, go mod vendor, and go mod download.

The details on these options are spread throughout the official documentation. One community attempt at a consolidated overview of knobs related to these behaviors is here, which includes links to the official documentation for more information.

like image 50
Adrian Avatar answered Oct 18 '22 05:10

Adrian


The go command updates the go.mod file to ensure consistency. If you go get example.com/[email protected] and it changes many other requirements in your go.mod file, that implies that example.com/m v1.2.0 transitively depends on versions of those other modules that are higher than what you have specified.

You can use go mod graph and the digraph tool to see how those transitive requirements arise.

You can take a few steps to avoid unexpected changes — especially breaking changes — when you need to update a single dependency:

  1. Periodically upgrade your dependencies (go get -u ./... from the root of your module) to stay near the latest release of each, re-running your tests after each upgrade. If that pulls in a breaking change, you can always back out the upgrade for the time being — but then you'll know that it is coming and have adequate time to plan to work around it. (Don't let unplanned technical debt accumulate over the long term.)

  2. Before you add a dependency, take a look at its release history and issue tracker to see how often it breaks: that will help you estimate the work required to stay up-to-date with the most recent version of that dependency. (Avoid taking on dependencies that make too many breaking changes.)

  3. If you need to stay at a specific version of that dependency, pass that version explicitly to go get when you upgrade. As of Go 1.16, go get -u will avoid upgrading modules whose versions are specified on the command line; if those versions are incompatible, it will give an error indicating which of the (two or more) named versions are mutually incompatible.

like image 25
bcmills Avatar answered Oct 18 '22 05:10

bcmills