Skip to content

proposal: cmd/go: notify about newer major versions #40323

Closed

Description

@zachgersh

Proposal: Major Module Version Alerts

This is a unification of two separate proposals (#38762 and #38502) that seek to alert users to the fact that a set of new major module versions may be available for inclusion in their project.

Problem

Semantic Import Versioning introduced the concept of a version suffix, which needs to be explicitly specified on your module path for major versions greater than 1. It is easy for users to consume a v0/v1 version of a module by default, even if they would be better served by selecting the most recent major version.

Discoverability is a key issue. The mechanisms for module authors to advertise recent major versions are inconsistent, and can be low-visibility (documentation? README.md?) or highly disruptive (printing deprecation warnings in init, broken builds to force an investigation).

Abstract

We propose a mechanism that notifies users of the latest major version of a module dependency when (a) that dependency is first added to the project; (b) they update to a newer minor or patch version; or (c) they list out dependencies that can be upgraded.

The proposed notification is informational; the user will have to decide the best course of action (stay with the v0/v1 version they fetched, or update their code to use a later version). We understand that automatic upgrades are not generally possible, as new major semantic versions are necessarily incompatible with previous ones.

Proposal

We propose notifying users of new major versions when:

  • They first add a requirement for an old major version of a module
  • They update a requirement for an old major version of a module
  • They list dependencies that can be updated

There are a few ways users add requirements to their modules:

  • By running go get github.com/user/repo
  • By adding a require github.com/user/repo line to their go.mod file manually
  • By adding an import line to a Go source file, and having goimports or gopls editor integration add the import line on save

For the latter two, the module isn't fetched until the go command is invoked within the module.

There are a few ways users update requirements:

  • By running go get [-u] github.com/user/repo
  • By running go get -u ./... from the module root

And there is one way users find out about available updates:

  • By running go list -m -u all

We propose to, in these cases, have the go tool print a note when a more recent major version of the module is available.

Examples

Consider a user fetching github.com/peterbourgon/ff with go get. We propose adding a notification to the output, alerting the user to a new major version:

$ go get github.com/peterbourgon/ff
go: finding github.com/pelletier/go-toml v1.6.0
go: finding gopkg.in/yaml.v2 v2.2.4
go: finding github.com/davecgh/go-spew v1.1.1
go: downloading github.com/peterbourgon/ff v1.7.0
go: extracting github.com/peterbourgon/ff v1.7.0
go: note: a more recent major version is available: github.com/peterbourgon/ff/v3 [v3.1.0]  👈

Consider a user listing all of the most recent versions of their dependencies. We propose printing the same note to standard error after any new minor or patch versions:

$ 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.6.0 [v1.7.0]
go: note: a more recent major version is available: github.com/peterbourgon/ff/v3 [v3.1.0] 👈

If the requirement is added to the go.mod file manually, the go tool would print the notification when it first fetches the new module, as part of a go build, go test, etc. run.

Integrations

pkg.go.dev

The Go package discovery website at pkg.go.dev shows modules and their versions. However, it obscures successive major versions when they exist, apparently treating major module versions as completely distinct. For example, the landing page for peterbourgon/ff shows v1.7.0 with a "Latest" bubble beside it. The versions tab does list other major versions, but under the heading "Other modules containing this package", which is confusing.
Instead, pkg.go.dev could feature a prominent indicator on the landing page for a v0/v1 module that there are two successive major versions (v2 and v3), to funnel the user toward the latter.

Editor integration (gopls, goimports)

Go text editor integrations typically include a feature that automatically adds import statements to source files based on the mentioned identifiers. Because of Semantic Import Versioning, this also gives those tools the responsibility of choosing the major version of the imported module. In the case where there is no suitable existing requirement in the project’s go.mod file, these editor integrations could alert the user to the availability of newer major module versions. How this works is outside the scope of this proposal.

Proposal Co-authors

Activity

  1. added this to the Proposal milestone on Jul 21, 2020
  2. bcmills commented on Jul 22, 2020

    @bcmills
    Contributor

    The main problem with “on first add” warnings is that users often don't have control over when things are added: it's easy for a tool to accidentally do the thing that triggers the warning (and then not log the warning, because the command completed successfully), and then the warning is buried ~forever. (Compare rust-lang/cargo#5560.)

    The editor integration seems more interesting, in that editors have the opportunity to surface low-priority information based on what the user is viewing rather than based on what they are doing.

  3. adg commented on Jul 22, 2020

    @adg
    Contributor

    it's easy for a tool to accidentally do the thing that triggers the warning (and then not log the warning, because the command completed successfully), and then the warning is buried ~forever

    Do you have a concrete example of this? I just use the go tool to manage my dependencies.

    It seems a bit cavalier to dismiss the utility of this proposal just because some people or tools might ignore the output.

  4. bcmills commented on Jul 23, 2020

    @bcmills
    Contributor

    Do you have a concrete example of this?

    Consider the following scenarios:

    • You run a command that produces a lot of output, such as go test all or go test -v ./..., then go back to editing your code (or go get a coffee or otherwise turn your attention from the go test command). By the time you look at the output (all tests passed!), the warning has scrolled well off the screen.

    • You receive a pull request from an external user who copied the change from a local patch, and didn't feel like rewriting their patch (or even mentioning the newer version) when they mailed you the change.

    • You added an import to a file, and now gopls is suggesting a change to your go.mod file to add the corresponding module (perhaps based on an internal, background go mod tidy run). You add it.

    In all of these cases, the warning appeared at some point but was either ignored or missed entirely.

    If it is important to surface out-of-date dependencies, I don't think a one-time warning is a good way to do that because it's so easy to miss the one time it appears. (Or, to put it another way: if it's unimportant enough that we shouldn't worry about the user missing the warning, then it's probably not important enough to emit the warning in the first place.)

  5. bcmills commented on Jul 23, 2020

    @bcmills
    Contributor
  6. peterbourgon commented on Jul 23, 2020

    @peterbourgon

    These proposals aren't intended to be perfect or exhaustive solutions to the complex problems they address — they're intended to be (substantial) improvements to the status quo. It is of course possible that a user could add a new module dependency to their project and then run the go tool in such a way that it would be easy to miss the messages we're proposing to add. YMMV, but I think it is much more likely, and far more common, that users add dependencies deliberately, and do pay attention to the results of the fetch.

  7. myitcv commented on Jul 23, 2020

    @myitcv
    Member

    YMMV, but I think it is much more likely, and far more common, that users add dependencies deliberately, and do pay attention to the results of the fetch.

    I commented over in #40357 (comment). I suspect in these days of gopls that the goimports-esque workflow is actually the most common.

    Hence:

    The editor integration seems more interesting, in that editors have the opportunity to surface low-priority information based on what the user is viewing rather than based on what they are doing.

    is I think the best way to surface this information.

    It seems a bit cavalier to dismiss the utility of this proposal just because some people or tools might ignore the output

    @adg - I don't think this is a fair or particularly charitable interpretation of @bcmills' response. @bcmills made an observation about the problems associated with “on first add” warnings, cited an example, and then went on to agree with the proposal in the context of surfacing this via editor integrations. I don't think I would characterise that as "dismiss(ing) the utility of this proposal".

    As some context, the golang-tools group has been discussing problems/solutions such as this since GopherCon 2018 (the group was largely established in the wake of the vgo release). I might well be biased, but based on previous experience the monthly calls are a good opportunity for discussion of these problems/solutions/options in the pre-proposal (design) phase.

  8. changed the title [-]Proposal: Major Module Version Alerts[/-] [+]proposal: cmd/go: notify about newer major versions[/+] on Jul 23, 2020
  9. jayconrod commented on Jul 23, 2020

    @jayconrod
    Contributor

    This overlaps a bit with #40357, but I assume if a module author explicitly deprecates a major version with a comment in go.mod, then the go command wouldn't also show this notice.

    I think some signal from the module author should be required to show a notice though, for two reasons:

    1. If a new major version is available, it doesn't necessarily mean the old major version is deprecated. Even if no new features are added, an old major version may still receive bug fixes and security updates. Users might still depend on features in the old version that were removed. Basically, migrating to a new major version isn't necessarily the right choice for users. While the messages proposed here don't suggest an action, I feel like they imply that.
    2. If we're telling users about a new major version, we should provide an action they can take to migrate. Because major versions are incompatible changes, there's nothing we can do automatically, yet. It would be better for the author to provide migration instructions in a deprecation notice. Or ideally, if migrations were automated (cmd/fix: automate migrations for simple deprecations #32816), we could tell people what command to run.
  10. peterbourgon commented on Jul 24, 2020

    @peterbourgon

    I think some signal from the module author should be required to show a notice

    The problem we're trying to solve is package consumers who intend to take the latest major version of a module, but select an old version due to unfamiliarity with the nuances of SIV. Making package authors opt-in to this notification wold subvert the intent and impact of the proposal.

    If a new major version is available, it doesn't necessarily mean the old major version is deprecated.

    The notification that a new major version is available is in no way a signal of deprecation of the current version. There is another proposal for authors who want to opt in to that stronger messaging.

    If we're telling users about a new major version, we should provide an action they can take to migrate.

    We initially had the notification include a command to make the upgrade, but went with this version in the end. Happy to switch back if that's the consensus.

  11. icholy commented on Jul 24, 2020

    @icholy
    Contributor

    If a new major version is available, it doesn't necessarily mean the old major version is deprecated.

    The problem is that they look like warnings and will create more and more noise as a project gets older. Instead of putting it on a separate line, it could just be combined with the existing output.

    $ 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.6.0 [v1.7.0] [latest v3.1.0]
    
  12. peterbourgon commented on Jul 24, 2020

    @peterbourgon

    The problem is that they look like warnings and will create more and more noise as a project gets older.

    We propose only a single line of output per dependency, specifically with a "note" or "notice" (read: not "warning") prefix, output only the first time the dependency is added to a project, and identifying only the most recent version of that dependency. I don't think this looks like a warning, nor does it create more noise over time.

    edit: Also, to me, putting the notification inline implies some level of compatibility between major versions that feels misleading.

    Instead of putting it on a separate line, it could just be combined with the existing output.

    By itself, this would be insufficiently obvious to solve the problem we're trying to solve with this proposal.

  13. icholy commented on Jul 24, 2020

    @icholy
    Contributor

    nor does it create more noise over time.

    Over time, as new major versions of your dependencies are released, more notices are printed.

  14. peterbourgon commented on Jul 24, 2020

    @peterbourgon

    Over time, as new major versions of your dependencies are released, more notices are printed.

    No, I don't think so. At least, the proposal doesn't intend so. Notices are only printed when a dependency is first added to a project at an older major version, or upgraded within an older major version tree. In other words, the trigger is not "a new major version of one of your dependencies is now available" but rather "you have added or upgraded a dependency to your project on a major version which is not the latest". And in all cases the notice only includes the most recent major version, not all major versions greater than the currently pinned major version.

  15. 81 remaining items

  16. gaby commented on May 8, 2024

    @gaby

    @rsc That doesnt help the Golang ecosystem at all. None of the tools take into account the "// Deprecated", a warning is not enough.

    Take into account dependabot, it doesn't notify about new major versions, it has no way of know either.

  17. KenjiTakahashi commented on May 8, 2024

    @KenjiTakahashi

    I have to agree with @billinghamj here.

    It is also worth noting that there are a number of projects already past-v1, which have moved on to the next major before the deprecation "feature" even existed.
    Expecting that all of them are now gonna go back and retrospectively mark earlier versions as deprecated is, frankly, wishful thinking.

    In general, basing discoverability solely on an explicit action from every (relevant) project maintainer is not very realistic.

  18. rsc commented on May 15, 2024

    @rsc
    Contributor

    The fundamental disagreement here is about whether the existence of v2 means that v1 should be implicitly considered deprecated and actively warned about. I wrote in the summary:

    There was also a long discussion about the meaning of the existence of a v2. Sometimes module authors create v2 and abandon v1. In that case, being warned about v2 could be helpful. But sometimes module authors create v2 and also keep maintaining v1. In that case, being warned about v1 is much less helpful. Therefore, the mere existence of v2 should not be taken as a reason to warn about use of v1. Some kind of explicit signal from module authors would be helpful here, like #40357, which at the time was also an active proposal.

    This remains true. Yes, some packages issue new major versions without marking old ones deprecated and should have done that. But others support both. We should encourage packages like stripe to mark old ones deprecated, and then tooling can do the right thing. (Or not. Maybe stripe supports the last 5 versions and they can mark the ones older than that deprecated. I don't know. But this gives them the ability to say exactly what should and should not be used.)

  19. zikaeroh commented on May 15, 2024

    @zikaeroh
    Contributor

    There was also a long discussion about the meaning of the existence of a v2. Sometimes module authors create v2 and abandon v1. In that case, being warned about v2 could be helpful. But sometimes module authors create v2 and also keep maintaining v1. In that case, being warned about v1 is much less helpful. Therefore, the mere existence of v2 should not be taken as a reason to warn about use of v1. Some kind of explicit signal from module authors would be helpful here, like #40357, which at the time was also an active proposal.

    Isn't this is self defeating? Anyone proactive enough to use a new "outdated" signal can already mark their old modules as deprecated today. Conversely, anyone who's already abandoning old versions will also not use a new explicit signal either, and it doesn't seem straightforward for those kinds of projects to resurrect old versions just to mark them as outdated/deprecated (find the last commit of a specific major version line, branch off, commit some new thing, publish again). So, even if modules could be marked as outdated, it doesn't seem to leave things better off.

  20. rsc commented on May 15, 2024

    @rsc
    Contributor

    No change in consensus, so declined.
    — rsc for the proposal review group

  21. moved this from Likely Decline to Declined in Proposalson May 15, 2024
  22. mitar commented on May 15, 2024

    @mitar
    Contributor

    The fundamental disagreement here is about whether the existence of v2 means that v1 should be implicitly considered deprecated and actively warned about.

    I think my proposal above with 11 upvotes goes away from this disagreement: we do not do such consideration and we do not do any warnings. There is just a simple tool which tells you that there are other higher versions available. It is on you (or your wrapper tools) to decide what to do about that then. I haven't seen any counter arguments against that?

  23. gaby commented on May 15, 2024

    @gaby

    @mitar Agree, and having a command like that would allow tools like dependabot, etc to alerts projects about new major versions. Most languages support this (Python for example is great at this), I don't understand why the Go team doesnt consider this.

    Should Go projects instead use plain semver for major releases instead of github.com/pkg/pkg/v2 ?

  24. Merovius commented on May 16, 2024

    @Merovius
    Contributor

    @mitar I'd suggest filing that as a new proposal, so it can be discussed on its own merits, instead of throwing together two different discussions.

  25. mitar commented on May 16, 2024

    @mitar
    Contributor

    Done: #67420

  26. locked and limited conversation to collaborators on May 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions