Description
Proposal: A Mechanism For Deprecating Modules
Authors: @peterbourgon, @adg
This proposal is a replacement for part of #38762. The other part is replaced by #40323.
Problem
Currently, there is no standard way for package authors to signal to consumers that a major version of a package is deprecated and no longer supported. Package consumers can easily inadvertently select an unmaintained major version (see #40323) and miss important new features or bug fixes.
Proposal
We propose adding a Deprecated:
comment for modules that is recognized by go tooling to flag that a module version as deprecated. This is parallel to the Deprecated:
comments that can be used to flag a package or identifier as deprecated.
When selecting a deprecated module version, the go tool will print a note to the user alerting them to the deprecation, and printing the deprecation text provided by the module author. Authors can use this notification to direct package consumers to more recent major versions, or an entirely new module that replaces the deprecated one.
As with package-level deprecation comments, module deprecation comments can span multiple lines.
Example
The author of module github.com/peterbourgon/ff
has released a new major version v2
(current version v2.0.1
), and wants to deprecate the old major version tree v1
(latest version v1.7.4
).
In the v1
branch, they add a module declaration to the go.mod
file, above the module declaration:
// Deprecated: The latest supported version is github.com/peterbourgon/ff/v2.
module github.com/peterbourgon/ff
They commit this change and tag it as a new patch release v1.7.5
.
There are several ways this deprecation message will or will not be displayed to package consumers.
If a consumer is fetching the module at major version v1
for the first time, the command succeeds but a deprecation warning is printed as part of go get's output:
$ go get gthub.com/peterbourgon/ff
go: deprecated: github.com/peterbourgon/ff v1.7.5 👈
go: deprecated: The latest supported version is github.com/peterbourgon/ff/v2. 👈
If a consumer is currently using the module at version e.g. v1.7.4
, no warnings will be printed when that module version is fetched. However, if the consumer tries to upgrade the dependency, they will see the deprecation warning. Notably, the upgrade will still succeed.
$ go get -u github.com/peterbourgon/ff
go: github.com/peterbourgon/ff upgrade => v1.7.5
go: deprecated: github.com/peterbourgon/ff v1.7.5 👈
go: deprecated: The latest supported version is github.com/peterbourgon/ff/v2. 👈
If a consumer is currently using the module at major version 1 (e.g. v1.7.4
), and runs a command that lists the latest version available in that major version tree (i.e. v1.7.5
), the warning is printed.
$ go list -m -u all
example.com/my-module
github.com/BurntSushi/toml v0.3.1
github.com/mitchellh/go-wordwrap v1.0.0
github.com/peterbourgon/ff v1.7.4 [v1.7.5]
go: deprecated: github.com/peterbourgon/ff v1.7.5 👈
go: deprecated: The latest supported version is github.com/peterbourgon/ff/v2. 👈
Integrations
pkg.go.dev
Module deprecation warnings should be prominently displayed on pkg.go.dev. It is worth exploring the linkification of module paths when displaying module deprecation notices.
Editor integration
If and when editors upgrade dependencies, these deprecation notices should be surfaced to the user as appropriate.