aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/vendor/golang.org/x/mod/modfile/rule.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/vendor/golang.org/x/mod/modfile/rule.go')
-rw-r--r--src/cmd/vendor/golang.org/x/mod/modfile/rule.go65
1 files changed, 46 insertions, 19 deletions
diff --git a/src/cmd/vendor/golang.org/x/mod/modfile/rule.go b/src/cmd/vendor/golang.org/x/mod/modfile/rule.go
index c6a189dbe0..8fcf96b713 100644
--- a/src/cmd/vendor/golang.org/x/mod/modfile/rule.go
+++ b/src/cmd/vendor/golang.org/x/mod/modfile/rule.go
@@ -835,11 +835,8 @@ func (f *File) DropRequire(path string) error {
// AddExclude adds a exclude statement to the mod file. Errors if the provided
// version is not a canonical version string
func (f *File) AddExclude(path, vers string) error {
- if !isCanonicalVersion(vers) {
- return &module.InvalidVersionError{
- Version: vers,
- Err: errors.New("must be of the form v1.2.3"),
- }
+ if err := checkCanonicalVersion(path, vers); err != nil {
+ return err
}
var hint *Line
@@ -916,17 +913,15 @@ func (f *File) DropReplace(oldPath, oldVers string) error {
// AddRetract adds a retract statement to the mod file. Errors if the provided
// version interval does not consist of canonical version strings
func (f *File) AddRetract(vi VersionInterval, rationale string) error {
- if !isCanonicalVersion(vi.High) {
- return &module.InvalidVersionError{
- Version: vi.High,
- Err: errors.New("must be of the form v1.2.3"),
- }
+ var path string
+ if f.Module != nil {
+ path = f.Module.Mod.Path
}
- if !isCanonicalVersion(vi.Low) {
- return &module.InvalidVersionError{
- Version: vi.Low,
- Err: errors.New("must be of the form v1.2.3"),
- }
+ if err := checkCanonicalVersion(path, vi.High); err != nil {
+ return err
+ }
+ if err := checkCanonicalVersion(path, vi.Low); err != nil {
+ return err
}
r := &Retract{
@@ -1086,8 +1081,40 @@ func lineRetractLess(li, lj *Line) bool {
return semver.Compare(vii.High, vij.High) > 0
}
-// isCanonicalVersion tests if the provided version string represents a valid
-// canonical version.
-func isCanonicalVersion(vers string) bool {
- return vers != "" && semver.Canonical(vers) == vers
+// checkCanonicalVersion returns a non-nil error if vers is not a canonical
+// version string or does not match the major version of path.
+//
+// If path is non-empty, the error text suggests a format with a major version
+// corresponding to the path.
+func checkCanonicalVersion(path, vers string) error {
+ _, pathMajor, pathMajorOk := module.SplitPathVersion(path)
+
+ if vers == "" || vers != module.CanonicalVersion(vers) {
+ if pathMajor == "" {
+ return &module.InvalidVersionError{
+ Version: vers,
+ Err: fmt.Errorf("must be of the form v1.2.3"),
+ }
+ }
+ return &module.InvalidVersionError{
+ Version: vers,
+ Err: fmt.Errorf("must be of the form %s.2.3", module.PathMajorPrefix(pathMajor)),
+ }
+ }
+
+ if pathMajorOk {
+ if err := module.CheckPathMajor(vers, pathMajor); err != nil {
+ if pathMajor == "" {
+ // In this context, the user probably wrote "v2.3.4" when they meant
+ // "v2.3.4+incompatible". Suggest that instead of "v0 or v1".
+ return &module.InvalidVersionError{
+ Version: vers,
+ Err: fmt.Errorf("should be %s+incompatible (or module %s/%v)", vers, path, semver.Major(vers)),
+ }
+ }
+ return err
+ }
+ }
+
+ return nil
}