refactor: use exclude directives instead of replace directives for pinning #8056
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
The 'replace' directive is very heavy-handed: it replaces nodes in the dependency graph with different source code. That distorts their apparent transitive dependencies, and makes a module that uses 'exclude' directives much more difficult for downstream consumers to use even if they aren't using the parts of the module that depend on the replaced versions.
In contrast, the 'exclude' directive knocks out specific version requirements from the module graph without otherwise affecting the dependencies of any remaining module in the graph.
'exclude' directives also make it clearer why particular pins are necessary: normally only the 'require' directive is needed to select desired versions (since they are not upgraded implicitly), so having 'exclude' blocks for specific conflicting requirements more clearly shows which of the transitive dependencies are believed to be spurious.
(See https://go.dev/ref/mod#go-mod-file-exclude.)
Follow-up Work
In the long term, the code should be updated to work with dependencies selected using only
require
directives, which respect the requirements of dependencies, rather than pinning versions below those requirements.Testing
The following is a diff of
go list -m all
before and after this change.Note that the former
replace
targets are now the MVS-selected versions.One additional module is now visible in the module graph (
github.com/docker/spdystream
), but it has no effect on the resulting artifacts because it does not provide any transitively-imported package.