aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/golang.org/x/mod
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2021-03-12 19:44:12 -0800
committerIan Lance Taylor <iant@golang.org>2021-03-15 14:52:55 -0700
commit3a5bcac339c5b166bc1a51c38226a8dc5e6484ca (patch)
tree0049b97ee92ee092025a5691336112654a21be94 /libgo/go/golang.org/x/mod
parent7b843d4716698957606c05219a66d3fc4b44ba83 (diff)
downloadgcc-3a5bcac339c5b166bc1a51c38226a8dc5e6484ca.zip
gcc-3a5bcac339c5b166bc1a51c38226a8dc5e6484ca.tar.gz
gcc-3a5bcac339c5b166bc1a51c38226a8dc5e6484ca.tar.bz2
libgo: update to Go 1.16.2 release
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/301459
Diffstat (limited to 'libgo/go/golang.org/x/mod')
-rw-r--r--libgo/go/golang.org/x/mod/modfile/rule.go167
-rw-r--r--libgo/go/golang.org/x/mod/module/module.go40
2 files changed, 152 insertions, 55 deletions
diff --git a/libgo/go/golang.org/x/mod/modfile/rule.go b/libgo/go/golang.org/x/mod/modfile/rule.go
index c6a189d..f8c9384 100644
--- a/libgo/go/golang.org/x/mod/modfile/rule.go
+++ b/libgo/go/golang.org/x/mod/modfile/rule.go
@@ -125,6 +125,12 @@ func (f *File) AddComment(text string) {
type VersionFixer func(path, version string) (string, error)
+// errDontFix is returned by a VersionFixer to indicate the version should be
+// left alone, even if it's not canonical.
+var dontFixRetract VersionFixer = func(_, vers string) (string, error) {
+ return vers, nil
+}
+
// Parse parses the data, reported in errors as being from file,
// into a File struct. It applies fix, if non-nil, to canonicalize all module versions found.
func Parse(file string, data []byte, fix VersionFixer) (*File, error) {
@@ -142,7 +148,7 @@ func ParseLax(file string, data []byte, fix VersionFixer) (*File, error) {
return parseToFile(file, data, fix, false)
}
-func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (*File, error) {
+func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (parsed *File, err error) {
fs, err := parse(file, data)
if err != nil {
return nil, err
@@ -150,8 +156,18 @@ func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (*File
f := &File{
Syntax: fs,
}
-
var errs ErrorList
+
+ // fix versions in retract directives after the file is parsed.
+ // We need the module path to fix versions, and it might be at the end.
+ defer func() {
+ oldLen := len(errs)
+ f.fixRetract(fix, &errs)
+ if len(errs) > oldLen {
+ parsed, err = nil, errs
+ }
+ }()
+
for _, x := range fs.Stmt {
switch x := x.(type) {
case *Line:
@@ -370,7 +386,7 @@ func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, a
case "retract":
rationale := parseRetractRationale(block, line)
- vi, err := parseVersionInterval(verb, &args, fix)
+ vi, err := parseVersionInterval(verb, "", &args, dontFixRetract)
if err != nil {
if strict {
wrapError(err)
@@ -397,6 +413,47 @@ func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, a
}
}
+// fixRetract applies fix to each retract directive in f, appending any errors
+// to errs.
+//
+// Most versions are fixed as we parse the file, but for retract directives,
+// the relevant module path is the one specified with the module directive,
+// and that might appear at the end of the file (or not at all).
+func (f *File) fixRetract(fix VersionFixer, errs *ErrorList) {
+ if fix == nil {
+ return
+ }
+ path := ""
+ if f.Module != nil {
+ path = f.Module.Mod.Path
+ }
+ var r *Retract
+ wrapError := func(err error) {
+ *errs = append(*errs, Error{
+ Filename: f.Syntax.Name,
+ Pos: r.Syntax.Start,
+ Err: err,
+ })
+ }
+
+ for _, r = range f.Retract {
+ if path == "" {
+ wrapError(errors.New("no module directive found, so retract cannot be used"))
+ return // only print the first one of these
+ }
+
+ args := r.Syntax.Token
+ if args[0] == "retract" {
+ args = args[1:]
+ }
+ vi, err := parseVersionInterval("retract", path, &args, fix)
+ if err != nil {
+ wrapError(err)
+ }
+ r.VersionInterval = vi
+ }
+}
+
// isIndirect reports whether line has a "// indirect" comment,
// meaning it is in go.mod only for its effect on indirect dependencies,
// so that it can be dropped entirely once the effective version of the
@@ -491,13 +548,13 @@ func AutoQuote(s string) string {
return s
}
-func parseVersionInterval(verb string, args *[]string, fix VersionFixer) (VersionInterval, error) {
+func parseVersionInterval(verb string, path string, args *[]string, fix VersionFixer) (VersionInterval, error) {
toks := *args
if len(toks) == 0 || toks[0] == "(" {
return VersionInterval{}, fmt.Errorf("expected '[' or version")
}
if toks[0] != "[" {
- v, err := parseVersion(verb, "", &toks[0], fix)
+ v, err := parseVersion(verb, path, &toks[0], fix)
if err != nil {
return VersionInterval{}, err
}
@@ -509,7 +566,7 @@ func parseVersionInterval(verb string, args *[]string, fix VersionFixer) (Versio
if len(toks) == 0 {
return VersionInterval{}, fmt.Errorf("expected version after '['")
}
- low, err := parseVersion(verb, "", &toks[0], fix)
+ low, err := parseVersion(verb, path, &toks[0], fix)
if err != nil {
return VersionInterval{}, err
}
@@ -523,7 +580,7 @@ func parseVersionInterval(verb string, args *[]string, fix VersionFixer) (Versio
if len(toks) == 0 {
return VersionInterval{}, fmt.Errorf("expected version after ','")
}
- high, err := parseVersion(verb, "", &toks[0], fix)
+ high, err := parseVersion(verb, path, &toks[0], fix)
if err != nil {
return VersionInterval{}, err
}
@@ -631,8 +688,7 @@ func parseVersion(verb string, path string, s *string, fix VersionFixer) (string
}
}
if fix != nil {
- var err error
- t, err = fix(path, t)
+ fixed, err := fix(path, t)
if err != nil {
if err, ok := err.(*module.ModuleError); ok {
return "", &Error{
@@ -643,19 +699,23 @@ func parseVersion(verb string, path string, s *string, fix VersionFixer) (string
}
return "", err
}
+ t = fixed
+ } else {
+ cv := module.CanonicalVersion(t)
+ if cv == "" {
+ return "", &Error{
+ Verb: verb,
+ ModPath: path,
+ Err: &module.InvalidVersionError{
+ Version: t,
+ Err: errors.New("must be of the form v1.2.3"),
+ },
+ }
+ }
+ t = cv
}
- if v := module.CanonicalVersion(t); v != "" {
- *s = v
- return *s, nil
- }
- return "", &Error{
- Verb: verb,
- ModPath: path,
- Err: &module.InvalidVersionError{
- Version: t,
- Err: errors.New("must be of the form v1.2.3"),
- },
- }
+ *s = t
+ return *s, nil
}
func modulePathMajor(path string) (string, error) {
@@ -835,11 +895,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 +973,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 +1141,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
}
diff --git a/libgo/go/golang.org/x/mod/module/module.go b/libgo/go/golang.org/x/mod/module/module.go
index c1c5263..272baee 100644
--- a/libgo/go/golang.org/x/mod/module/module.go
+++ b/libgo/go/golang.org/x/mod/module/module.go
@@ -270,7 +270,7 @@ func fileNameOK(r rune) bool {
// CheckPath checks that a module path is valid.
// A valid module path is a valid import path, as checked by CheckImportPath,
-// with two additional constraints.
+// with three additional constraints.
// First, the leading path element (up to the first slash, if any),
// by convention a domain name, must contain only lower-case ASCII letters,
// ASCII digits, dots (U+002E), and dashes (U+002D);
@@ -280,8 +280,9 @@ func fileNameOK(r rune) bool {
// and must not contain any dots. For paths beginning with "gopkg.in/",
// this second requirement is replaced by a requirement that the path
// follow the gopkg.in server's conventions.
+// Third, no path element may begin with a dot.
func CheckPath(path string) error {
- if err := checkPath(path, false); err != nil {
+ if err := checkPath(path, modulePath); err != nil {
return fmt.Errorf("malformed module path %q: %v", path, err)
}
i := strings.Index(path, "/")
@@ -315,7 +316,7 @@ func CheckPath(path string) error {
//
// A valid path element is a non-empty string made up of
// ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~.
-// It must not begin or end with a dot (U+002E), nor contain two dots in a row.
+// It must not end with a dot (U+002E), nor contain two dots in a row.
//
// The element prefix up to the first dot must not be a reserved file name
// on Windows, regardless of case (CON, com1, NuL, and so on). The element
@@ -326,19 +327,29 @@ func CheckPath(path string) error {
// top-level package documentation for additional information about
// subtleties of Unicode.
func CheckImportPath(path string) error {
- if err := checkPath(path, false); err != nil {
+ if err := checkPath(path, importPath); err != nil {
return fmt.Errorf("malformed import path %q: %v", path, err)
}
return nil
}
+// pathKind indicates what kind of path we're checking. Module paths,
+// import paths, and file paths have different restrictions.
+type pathKind int
+
+const (
+ modulePath pathKind = iota
+ importPath
+ filePath
+)
+
// checkPath checks that a general path is valid.
// It returns an error describing why but not mentioning path.
// Because these checks apply to both module paths and import paths,
// the caller is expected to add the "malformed ___ path %q: " prefix.
// fileName indicates whether the final element of the path is a file name
// (as opposed to a directory name).
-func checkPath(path string, fileName bool) error {
+func checkPath(path string, kind pathKind) error {
if !utf8.ValidString(path) {
return fmt.Errorf("invalid UTF-8")
}
@@ -357,35 +368,34 @@ func checkPath(path string, fileName bool) error {
elemStart := 0
for i, r := range path {
if r == '/' {
- if err := checkElem(path[elemStart:i], fileName); err != nil {
+ if err := checkElem(path[elemStart:i], kind); err != nil {
return err
}
elemStart = i + 1
}
}
- if err := checkElem(path[elemStart:], fileName); err != nil {
+ if err := checkElem(path[elemStart:], kind); err != nil {
return err
}
return nil
}
// checkElem checks whether an individual path element is valid.
-// fileName indicates whether the element is a file name (not a directory name).
-func checkElem(elem string, fileName bool) error {
+func checkElem(elem string, kind pathKind) error {
if elem == "" {
return fmt.Errorf("empty path element")
}
if strings.Count(elem, ".") == len(elem) {
return fmt.Errorf("invalid path element %q", elem)
}
- if elem[0] == '.' && !fileName {
+ if elem[0] == '.' && kind == modulePath {
return fmt.Errorf("leading dot in path element")
}
if elem[len(elem)-1] == '.' {
return fmt.Errorf("trailing dot in path element")
}
charOK := pathOK
- if fileName {
+ if kind == filePath {
charOK = fileNameOK
}
for _, r := range elem {
@@ -406,7 +416,7 @@ func checkElem(elem string, fileName bool) error {
}
}
- if fileName {
+ if kind == filePath {
// don't check for Windows short-names in file names. They're
// only an issue for import paths.
return nil
@@ -444,7 +454,7 @@ func checkElem(elem string, fileName bool) error {
// top-level package documentation for additional information about
// subtleties of Unicode.
func CheckFilePath(path string) error {
- if err := checkPath(path, true); err != nil {
+ if err := checkPath(path, filePath); err != nil {
return fmt.Errorf("malformed file path %q: %v", path, err)
}
return nil
@@ -647,7 +657,7 @@ func EscapePath(path string) (escaped string, err error) {
// Versions are allowed to be in non-semver form but must be valid file names
// and not contain exclamation marks.
func EscapeVersion(v string) (escaped string, err error) {
- if err := checkElem(v, true); err != nil || strings.Contains(v, "!") {
+ if err := checkElem(v, filePath); err != nil || strings.Contains(v, "!") {
return "", &InvalidVersionError{
Version: v,
Err: fmt.Errorf("disallowed version string"),
@@ -706,7 +716,7 @@ func UnescapeVersion(escaped string) (v string, err error) {
if !ok {
return "", fmt.Errorf("invalid escaped version %q", escaped)
}
- if err := checkElem(v, true); err != nil {
+ if err := checkElem(v, filePath); err != nil {
return "", fmt.Errorf("invalid escaped version %q: %v", v, err)
}
return v, nil