Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/go: add option to prevent 'go get -u' from updating certain dependencies #29968

Open
jayconrod opened this issue Jan 28, 2019 · 9 comments
Open
Labels
FeatureRequest GoCommand cmd/go modules NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@jayconrod
Copy link
Contributor

jayconrod commented Jan 28, 2019

We should provide a way for users to prevent go get -u from updating certain dependencies unless they're explicitly requested.

There are a number of reasons users may need to pin a module dependency to a lower version. For example:

  1. The dependency has a breaking change, which is allowed in v0 versions.
  2. There is a cyclic dependency involving the main module, and care must be taken to keep the cycle at specific versions. This is especially important when one module is a prefix of the other, and we want to avoid ambiguous imports as packages are moved between.
  3. The dependency adds many more transitive dependencies that are not needed which may need to be downloaded.
  4. The dependency has new functionality which is not used and adds significant overhead.

When a user has a dependency that requires special care to update, go get -u is not safe to use on its own. Instead, one needs to build a list of all requirements, exclude modules that shouldn't be updated, then pass that list to go get -u. This is cumbersome.

Some ideas for improvements:

  • An -except or -exclude flag, allowing users to specify modules that shouldn't be updated.
  • A comment or annotation in go.mod that tells go get -u not to update a module unless it's specifically named on the command line.

This is somewhat related to #28424.

@jayconrod jayconrod changed the title cmd/go: add option to prevent 'go get -u' cmd/go: add option to prevent 'go get -u' from updating certain dependencies Jan 28, 2019
@bcmills
Copy link
Contributor

bcmills commented Jan 30, 2019

The exclude directive in the go.mod file gets us partway there: if there is some regression, such as a large set of new dependencies or a significant performance degradation, then either the maintainers should fix that regression and issue a new release, or the users should fork the module to remove the unwanted bloat. Either way, the need to hold back should only persist for a release or two.

@bcmills
Copy link
Contributor

bcmills commented Jan 30, 2019

It may be that we should resolve the cyclic dependency problem in some other way, such as having go get -u detect the cycle and try to upgrade past it (#27899). In particular, we can't stop outside users of a given module from introducing newer requirements, so it seems fragile to rely on the version staying at some older release.

@bcmills
Copy link
Contributor

bcmills commented Jan 30, 2019

Finally, if there is a breaking change in a v0 version, then perhaps it's best to have a reminder to fix the call site. (As a workaround, you can always pass an explicit older version of a particular module to go get -u, and having that explicit in the update command is a good indicator of the Damocles' Sword of Incompatibility that is looming over your module...)

@jayconrod
Copy link
Contributor Author

I don't have a good sense of the severity or frequency of these issues. As you point out, there are alternatives for all of them, but I'm not sure how often they're going to come up or how annoying they're going to be.

Let's mark this as Unplanned and decide what to do after modules are on by default. I don't think this is a critical feature to have before then.

@jayconrod jayconrod added this to the Unplanned milestone Jan 30, 2019
@bcmills bcmills added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Mar 1, 2019
@bcmills
Copy link
Contributor

bcmills commented Oct 21, 2020

I think the best fit for this use-case is a special version query. upgrade already means “current selected version or higher”, and patch means “current selected version or higher but within the same minor version”; the logical progression of those is some third token (maybe current?) meaning “current selected version and no higher”.

@braydonk
Copy link

braydonk commented Jul 6, 2023

What are the chances that this might ever happen in some capacity? I'm in a scenario right now where I want to update all the dependencies in my go.mod except for one due to a breaking change that we are not yet ready to adopt. Effectively, I'd like to pin this dependency to the version we have now while still allowing everything else to update. I cannot find a way to properly accomplish that today.

@bcmills
Copy link
Contributor

bcmills commented Jul 11, 2023

@braydonk, today you can pass the version of the package or module that you want to keep to go get -u as an explicit argument, like:

go get -u ./... example.com/stuck@v0.5

@braydonk
Copy link

Ah cool, I wasn't able to find that anywhere when I was looking around documentation or even blog posts. Thank you for the trick!

@flimzy
Copy link
Contributor

flimzy commented Nov 23, 2023

I'd love to see this capability as well. On one codebase I'm working, we have 3 particular dependencies which introduce breaking changes, so cannot be updated. I'd love the option to do something like go get -pin example.com/foo@v0.5, which I magine might add a // pinned comment after the relevant line in go.mod, so that subsequent go get -u ./... executions just skip the pinned modules.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FeatureRequest GoCommand cmd/go modules NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants