-
Notifications
You must be signed in to change notification settings - Fork 18.7k
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
short-term steps to improve using github.com/docker/docker for modules-based consumers (new tag? documentation? nested module?) #41503
Comments
One other comment is that after Go 1.16 ships, potentially the Also, here is what the go command (version 1.15.2) currently reports as the syntactically valid semver tags on this repo:
|
As of Go 1.16, it may be possible to add a (See golang/go#24031.) [Edit: oops, I should have refreshed the page before posting my comment, because I see that @thepudds gave the same suggestion above.] |
An incomplete summary of some related facts about this repo:
package client // import "github.com/docker/docker/client"
).v17.*.*-ce*
, which I suspect are all 3 years old or so at this point given they seem to be following "CalVer".v17.*
ones, none of the others are syntactically valid semver tags.0
(e.g.,03
for March), which are disallowed by semver. An example tag on this repo that is not a semver tag:v19.03.13
github.com/docker/docker@latest
resolves tov1.13.1
, which is a release that is over 3 years old from early 2017.Proposal
I think there are maybe 2-3 small near-term steps that could materially simplify importing docker for modules-based consumers, and I would like to focus this issue on discussing whether one or more short-term steps are feasible (whether from this list, or perhaps someone will suggest a better short-term step).
These near-term steps would not include adopting modules wholesale, which could be a separate discussion but which also could be made easier by adopting one or more of these near-term steps.
Suggestion 1: apply a v1.20.x tag or similar
Apply at least one syntactically valid semver release tag on a recent commit in moby/moby. This would materially improve things for modules-based consumers, even if this was done manually, and even if this was just done as a one time operation to start. A syntactically valid semver release tag would not include anything trailing hyphen such as
-foo
(which would make it a semver pre-release tag), and would not any leading0
in any of the version strings.For example, if you applied the tag v1.20.1903012 to the moby/moby commit that is currently tagged v19.03.12, then the go command would recognize v1.20.1903012 as a syntactically valid semver tag, and it would be considered greater than (more recent than) v1.13.1, which is ~3.5 years old at this point. In addition, all of the -ce tags (like v17.12.1-ce-rc2+incompatible) are semver pre-release tags, which the go command won't use by default when resolving
@latest
or when a client does an upgrade via something likego get -u ./...
.In other words, at that point,
go get github.com/docker/docker@latest
would resolve to v1.20.1903012 as the highest available syntactically valid non-prerelease tag.Of course, pick whatever commit makes the most sense, and once you see it work, you could choose to apply additional similar tags to other commits if that makes sense.
This would be a large step forward, and stop consumers from defaulting to the ~3.5 year old v1.13.1 release by default.
This would also be a step towards adopting modules for
github.com/docker/docker
, but it would be easier than fully adopting modules.Suggestion 2: document how to use a replace
If you don't want to do Suggestion 1, you could official document how to set a replace directive for modules-based consumers of docker/docker. For example, #39302 (comment) could be a starting point. If I search docs.docker.com, I do not see anything along those lines currently.
Suggestion 3: document how modules-consumers can use moby/moby/vendor.conf
Slightly more nuanced, but one of the challenges is moby/moby does not itself use modules, which the means dependency info in moby/moby/vendor.conf does not get used by module consumers, which in turn means sometimes people can do the right replace (e.g., following item 2) but still end up with a bad total set of versions if for example the
@latest
version of some dependency of moby/moby is in fact incompatible with the selected version of moby/moby. There is a solution for that documented here:https://github.com/golang/go/wiki/Modules#i-have-a-problem-with-a-complex-dependency-that-has-not-opted-in-to-modules-can-i-use-information-from-its-current-dependency-manager
It's a bit more nuanced, but you could document how to do that specifically with github.com/docker/docker as the non-module target, or maybe instead document a few lines of bash that do it automatically (or even create a small Go utility, though a handful of lines of bash might be easier).
Suggestion 4: consider one or more nested modules, such as docker/docker/client
You could partially adopt modules, for example starting with creating a go.mod at github.com/moby/moby/client/go.mod, the first line of which would read
module github.com/docker/docker/client
. You could then tag something likeclient/v0.1.0
orclient/v0.2020.9
(note the leadingclient/
on the git tag). When you have a nested module within a repo (that is, when you have a go.mod in a subdirectory of a repo), you use the directory name as part of the VCS tag, which means you would be sidestepping your CalVer history of the main repo.In other words, you would have more freedom about how you tag and version the nested
module github.com/docker/docker/client
because it would end up with its own "name space" from a VCS tag perspective as far as the go command was concerned.To start, you wouldn't need to create a go.mod at the root of the repo, and you wouldn't need to start using /v20 in your import paths.
This is my least favorite option because nested modules present their own challenges, but I at least wanted to mention it.
A few more details about "Suggestion 1: apply a v1.20.x tag or similar".
The
v17.*.*-ce*
semver pre-release tags will not be used by default, including because cmd/go prefers semver release tags over semver pre-release tags. For example, from cmd/go doc:https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them
Pre-release version definition: https://semver.org/#spec-item-9
However, one non-default scenario where the
v17.*.*-ce*
semver pre-release tags could appear is possibly as the explicitly named version in another dependency in the same build as someone who is importing the (new) release tag created in suggestion 1.For example, suppose in a single build module A is using the new release tag via
require github.com/docker/docker v1.20.1903012
, while module B in the same build hasrequire github.com/docker/docker v17.12.1-ce-rc2
in module B's go.mod. In that case, cmd/go's version selection will pick v17.12.1-ce-rc2 over v1.20.1903012 because v17.12.1-ce-rc2 has higher semver precedence. That would not be desirable, because it would be favoring a 3 year old version over a 2019 release.However, this is hopefully a fairly rare case -- those dozen or so v17.-ce pre-release tags are over three years old at this point, and won't be selected by default for new consumers, so it hopefully would be a relatively rare situation that an existing current user is using them in the same build as someone else who is using a more modern release tag.
Even if this does occur, it is still solvable with a
replace
in the top-level build, or by updating module B to not require a v17.*-c2 tag. Arguably, this no worse than the current situation.This is a longer, more complete version of my suggestions from a year or so ago in #39302 (comment), but #39302 is very wide ranging, and I felt it better to attempt to split out a separate issue focused on simpler and possibly more actionable steps.
CC @thaJeztah @cpuguy83 @rogpeppe @bcmills for any comments, corrections, or additional ideas.
The text was updated successfully, but these errors were encountered: