1
0
mirror of https://github.com/golang/go synced 2024-11-24 06:40:17 -07:00

cmd/go: clarify error when package is removed in a module

If no module in the build list provides an imported package, we
try to upgrade to the "@latest" version. If there is a requirement on
a version of the module which is newer than the "@latest" version
(e.g., a prerelease or pseudoversion), we cannot upgrade further.

We previously reported "looping trying to add package" when we saw the
package in "@latest" but it was removed later. The meaning of this is
unclear for users, so with this change, we explain the package was
removed.

Fixes #30394

Change-Id: I1b7fec2c37e762fb600e66ee8a4df4aeaf13e67a
Reviewed-on: https://go-review.googlesource.com/c/go/+/169720
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
This commit is contained in:
Jay Conrod 2019-03-26 20:21:21 -04:00
parent d8f60eea64
commit ee780d4a78
6 changed files with 63 additions and 1 deletions

View File

@ -28,6 +28,10 @@ import (
type ImportMissingError struct { type ImportMissingError struct {
ImportPath string ImportPath string
Module module.Version Module module.Version
// newMissingVersion is set to a newer version of Module if one is present
// in the build list. When set, we can't automatically upgrade.
newMissingVersion string
} }
func (e *ImportMissingError) Error() string { func (e *ImportMissingError) Error() string {
@ -189,7 +193,18 @@ func Import(path string) (m module.Version, dir string, err error) {
} }
return module.Version{}, "", &ImportMissingError{ImportPath: path} return module.Version{}, "", &ImportMissingError{ImportPath: path}
} }
return m, "", &ImportMissingError{ImportPath: path, Module: m} newMissingVersion := ""
for _, bm := range buildList {
if bm.Path == m.Path && semver.Compare(bm.Version, m.Version) > 0 {
// This typically happens when a package is present at the "@latest"
// version (e.g., v1.0.0) of a module, but we have a newer version
// of the same module in the build list (e.g., v1.0.1-beta), and
// the package is not present there.
newMissingVersion = bm.Version
break
}
}
return m, "", &ImportMissingError{ImportPath: path, Module: m, newMissingVersion: newMissingVersion}
} }
// maybeInModule reports whether, syntactically, // maybeInModule reports whether, syntactically,

View File

@ -547,6 +547,9 @@ func (ld *loader) load(roots func() []string) {
} }
for _, pkg := range ld.pkgs { for _, pkg := range ld.pkgs {
if err, ok := pkg.err.(*ImportMissingError); ok && err.Module.Path != "" { if err, ok := pkg.err.(*ImportMissingError); ok && err.Module.Path != "" {
if err.newMissingVersion != "" {
base.Fatalf("go: %s: package provided by %s at latest version %s but not at required version %s", pkg.stackText(), err.Module.Path, err.Module.Version, err.newMissingVersion)
}
if added[pkg.path] { if added[pkg.path] {
base.Fatalf("go: %s: looping trying to add package", pkg.stackText()) base.Fatalf("go: %s: looping trying to add package", pkg.stackText())
} }

View File

@ -0,0 +1,11 @@
The deprecated package is present in this version (which is @latest) but
is deleted in a newer prerelease version.
-- .mod --
module example.com/missingpkg
-- .info --
{"Version":"v1.0.0"}
-- lib.go --
package lib
-- deprecated/deprecated.go --
package deprecated

View File

@ -0,0 +1,8 @@
The deprecated package is deleted in this version.
-- .mod --
module example.com/missingpkg
-- .info --
{"Version":"v1.0.1-beta"}
-- lib.go --
package lib

View File

@ -0,0 +1,13 @@
This module requires example.com/missingpkg at a prerelease version, which
is newer than @latest.
-- .mod --
module example.com/usemissingpre
require example.com/missingpkg v1.0.1-beta
-- .info --
{"Version":"v1.0.0"}
-- use.go --
package use
import _ "example.com/missingpkg"

View File

@ -0,0 +1,12 @@
env GO111MODULE=on
! go list use.go
stderr 'import "example.com/missingpkg/deprecated": package provided by example.com/missingpkg at latest version v1.0.0 but not at required version v1.0.1-beta'
-- use.go --
package use
import (
_ "example.com/missingpkg/deprecated"
_ "example.com/usemissingpre"
)