rs, err := tidyRoots(ctx, ld.requirements, ld.pkgs)
if err != nil {
ld.errorf("go: %v\n", err)
- }
-
- if ld.requirements.pruning == pruned {
- // We continuously add tidy roots to ld.requirements during loading, so at
- // this point the tidy roots should be a subset of the roots of
- // ld.requirements, ensuring that no new dependencies are brought inside
- // the graph-pruning horizon.
- // If that is not the case, there is a bug in the loading loop above.
- for _, m := range rs.rootModules {
- if v, ok := ld.requirements.rootSelected(m.Path); !ok || v != m.Version {
- ld.errorf("go: internal error: a requirement on %v is needed but was not added during package loading\n", m)
- base.ExitIfErrors()
+ base.ExitIfErrors()
+ } else {
+ if ld.requirements.pruning == pruned {
+ // We continuously add tidy roots to ld.requirements during loading, so at
+ // this point the tidy roots should be a subset of the roots of
+ // ld.requirements, ensuring that no new dependencies are brought inside
+ // the graph-pruning horizon.
+ // If that is not the case, there is a bug in the loading loop above.
+ for _, m := range rs.rootModules {
+ if v, ok := ld.requirements.rootSelected(m.Path); !ok || v != m.Version {
+ ld.errorf("go: internal error: a requirement on %v is needed but was not added during package loading\n", m)
+ base.ExitIfErrors()
+ }
}
}
+ ld.requirements = rs
}
- ld.requirements = rs
}
// Report errors, if any.
return fmt.Sprintf("reading %s: %v\n\tserver response:%s%s", e.URL, e.Status, detailSep, e.Detail)
}
- if err := e.Err; err != nil {
- if pErr, ok := e.Err.(*fs.PathError); ok && strings.HasSuffix(e.URL, pErr.Path) {
- // Remove the redundant copy of the path.
- err = pErr.Err
+ if eErr := e.Err; eErr != nil {
+ if pErr, ok := e.Err.(*fs.PathError); ok {
+ if u, err := url.Parse(e.URL); err == nil {
+ if fp, err := urlToFilePath(u); err == nil && pErr.Path == fp {
+ // Remove the redundant copy of the path.
+ eErr = pErr.Err
+ }
+ }
}
- return fmt.Sprintf("reading %s: %v", e.URL, err)
+ return fmt.Sprintf("reading %s: %v", e.URL, eErr)
}
return fmt.Sprintf("reading %s: %v", e.URL, e.Status)
--- /dev/null
+# This test checks that "go mod tidy -e" do not panic when
+# using a file goproxy that is missing some modules.
+# Verifies golang.org/issue/51589
+
+# download the modules first
+env GO111MODULE=on
+env GOPATH=$WORK/gopath
+cd $WORK/x
+go mod tidy
+
+# Use download cache as file:/// proxy.
+[windows] env GOPROXY=file:///$WORK/gopath/pkg/mod/cache/download
+[!windows] env GOPROXY=file://$WORK/gopath/pkg/mod/cache/download
+rm $WORK/gopath/pkg/mod/cache/download/golang.org/x/text/
+go mod tidy -e
+stderr '^go: rsc.io/sampler@v1.3.0 requires\n\tgolang.org/x/text@.*: reading file://.*/pkg/mod/cache/download/golang.org/x/text/.*'
+! stderr 'signal SIGSEGV: segmentation violation'
+
+-- $WORK/x/go.mod --
+module example.com/mod
+
+go 1.17
+
+require rsc.io/quote v1.5.2
+
+require (
+ golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect
+ rsc.io/sampler v1.3.0 // indirect
+)
+
+-- $WORK/x/x.go --
+package mod
+
+import (
+ "fmt"
+
+ "rsc.io/quote"
+)
+
+func Echo() {
+ fmt.Println(quote.Hello())
+}
\ No newline at end of file