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: go get -u=patch with argument bumps minor version #26812

Closed
mfridman opened this issue Aug 5, 2018 · 6 comments
Closed

cmd/go: go get -u=patch with argument bumps minor version #26812

mfridman opened this issue Aug 5, 2018 · 6 comments
Labels
early-in-cycle A change that should be done early in the 3 month dev cycle. FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@mfridman
Copy link

mfridman commented Aug 5, 2018

What version of Go are you using (go version)?

go version devel +5a720d229d Sat Aug 4 16:37:47 2018 +0000 darwin/amd64

Does this issue reproduce with the latest release?

N/A, building from source

What did you do?

Repro provided.

$ git clone git@github.com:mfridman/srfax.git
$ cd srfax

$ cat go.mod 
module github.com/mfridman/srfax

require (
	github.com/mitchellh/mapstructure v0.0.0-20180715050151-f15292f7a699
	github.com/pkg/errors v0.6.0
)


$ go get -u=patch
$ git diff
# no changes

$ go get -u=patch github.com/pkg/errors
$ git diff
-       github.com/pkg/errors v0.6.0
+       github.com/pkg/errors v0.8.0

Based on the docs, I was expecting pkg/errors to remain on v0.6.0, but instead it got bumped to v0.8.0. Running go get -u=patch (without arg) did not update the patch version.

The -u=patch flag (not -u patch) instructs get to update dependencies to use newer patch releases when available

I would only ever expect the minor version to be bumped when running go get -u or go get -u github.com/pkg/errors.

Likewise I would expect -u=patch with or without an arg to operate in the same way.

@gopherbot, please add label modules

@FiloSottile FiloSottile added this to the Go1.11 milestone Aug 6, 2018
@FiloSottile FiloSottile added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Aug 6, 2018
@rsc
Copy link
Contributor

rsc commented Aug 9, 2018

The documentation explains this:

The first step is to resolve which dependencies to add.

For each named package or package pattern, get must decide which version of
the corresponding module to use. By default, get chooses the latest tagged
release version, such as v0.4.5 or v1.2.3. If there are no tagged release
versions, get chooses the latest tagged prerelease version, such as
v0.0.1-pre1. If there are no tagged versions at all, get chooses the latest
known commit.

This default version selection can be overridden by adding an @version
suffix to the package argument, as in 'go get golang.org/x/text@v0.3.0'.
For modules stored in source control repositories, the version suffix can
also be a commit hash, branch identifier, or other syntax known to the
source control system, as in 'go get golang.org/x/text@master'.
The version suffix @latest explicitly requests the default behavior
described above.

If a module under consideration is already a dependency of the current
development module, then get will update the required version.
Specifying a version earlier than the current required version is valid and
downgrades the dependency. The version suffix @none indicates that the
dependency should be removed entirely.

Although get defaults to using the latest version of the module containing
a named package, it does not use the latest version of that module's
dependencies. Instead it prefers to use the specific dependency versions
requested by that module. For example, if the latest A requires module
B v1.2.3, while B v1.2.4 and v1.3.1 are also available, then 'go get A'
will use the latest A but then use B v1.2.3, as requested by A. (If there
are competing requirements for a particular module, then 'go get' resolves
those requirements by taking the maximum requested version.)

The -u flag instructs get to update dependencies to use newer minor or
patch releases when available. Continuing the previous example,
'go get -u A' will use the latest A with B v1.3.1 (not B v1.2.3).

The -u=patch flag (not -u patch) instructs get to update dependencies
to use newer patch releases when available. Continuing the previous example,
'go get -u=patch A' will use the latest A with B v1.2.4 (not B v1.2.3).

By saying github.com/pkg/errors on the command line you are implicitly saying github.com/pkg/errors@latest. The -u=patch applies to dependencies of the listed packages/modules, not to those packages/modules themselves.

Maybe we can revisit semantics for Go 1.12 but these are the Go 1.11 semantics.

@rsc rsc modified the milestones: Go1.11, Go1.12 Aug 9, 2018
@rsc rsc added the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label Aug 9, 2018
@gopherbot gopherbot removed the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Aug 9, 2018
@stevenh
Copy link
Contributor

stevenh commented Oct 19, 2018

I would agree with the original poster, that this behaviour is very confusing, even reading the docs several times its wasn't clear and caused much hair pulling and time wasted.

I believe the reason for this is that it states dependencies and if you running go -u get <package> in your repo <package> is a dependency.

The use case IMO for running go get -u=patch <package> is to update just <package> and its dependencies using the patch strategy.

With the current design there is no easy way to update a specific package and its dependencies using the patch strategy. The only option is to manually visit to the repo site look for the version and issue the manual go get -u=patch <package>@vX.Y.Z which is a royal PITA.

@bcmills
Copy link
Contributor

bcmills commented Nov 13, 2018

go get -u=patch some/binary@latest has a pretty clear use-case: you want to build and install the latest version of some/binary@latest, using the patch releases of its dependencies. After #24250 is addressed, that may well be the best default for installing tools from outside of a module. On the other hand, outside of a module, some/binary and some/binary@latest resolve to the same version anyway: perhaps we should only implicitly add @latest to new dependencies rather than existing ones, uniformly.

There is also a bit of a skew between the old and new go get behaviors without -u: in GOPATH mode, go get foo for some package foo already in GOPATH/src does not upgrade the version, but in module mode it implicitly upgrades to @latest.

That provides an opportunity for a nice symmetry: if the @latest version is necessary to upgrade the named package to the latest version, then we could add a similar version @patch, with the meaning “the latest patch release of the minor version already in the module graph”.

I don't think we'll get to this for 1.12, but I'd like to at least make a decision on it early in 1.13

@bcmills bcmills modified the milestones: Go1.12, Go1.13 Nov 13, 2018
@rsc rsc added early-in-cycle A change that should be done early in the 3 month dev cycle. and removed modules labels Nov 20, 2018
@rsc
Copy link
Contributor

rsc commented Jan 17, 2019

Per (brief) discussion above and more in person, I think we should change this. If we introduce go get x@patch, then that can mean "the latest patch version of a module x already in use" (an error if x is not already a depended-upon module). Then we can define that -u=patch changes the default version suffix from @latest to @patch.

@bcmills bcmills added the NeedsFix The path to resolution is known, but the work has not been done. label Jan 24, 2019
@gopherbot gopherbot removed the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label Jan 24, 2019
@bcmills bcmills self-assigned this Jan 24, 2019
@bcmills
Copy link
Contributor

bcmills commented Mar 15, 2019

[@patch] can mean "the latest patch version of a module x already in use" (an error if x is not already a depended-upon module). Then we can define that -u=patch changes the default version suffix from @latest to @patch.

If @patch is an error if the module is not already in use, then go get -m -u=patch some/new/module would be an error. I would argue that the user's clear intent in that case is to “install some/new/module and patch all of its dependencies”.

That suggests that @patch should decay to @latest if an explicitly-requested module is not already present in the build graph.

@gopherbot
Copy link

Change https://golang.org/cl/167747 mentions this issue: cmd/go/internal/modget: support the suffix '@patch' in 'go get'

@golang golang locked and limited conversation to collaborators Mar 31, 2020
@rsc rsc unassigned bcmills Jun 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
early-in-cycle A change that should be done early in the 3 month dev cycle. FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

6 participants