if !filepath.IsAbs(dir) {
dir = filepath.Join(ModRoot(), dir)
}
+ // Ensure that the replacement directory actually exists:
+ // dirInModule does not report errors for missing modules,
+ // so if we don't report the error now, later failures will be
+ // very mysterious.
+ if _, err := os.Stat(dir); err != nil {
+ if os.IsNotExist(err) {
+ // Semantically the module version itself “exists” — we just don't
+ // have its source code. Remove the equivalence to os.ErrNotExist,
+ // and make the message more concise while we're at it.
+ err = fmt.Errorf("replacement directory %s does not exist", r.Path)
+ } else {
+ err = fmt.Errorf("replacement directory %s: %w", r.Path, err)
+ }
+ return dir, true, module.VersionError(mod, err)
+ }
return dir, true, nil
}
mod = r
cd fail
! go list all
stdout 'localhost.fail'
-stderr '^can.t load package: m.go:3:8: module w@latest found \(v0.0.0-00010101000000-000000000000, replaced by ../w\), but does not contain package w$'
+stderr '^can''t load package: m.go:4:2: module w@latest found \(v0.0.0-00010101000000-000000000000, replaced by ../w\), but does not contain package w$'
+stderr '^can''t load package: m.go:5:2: nonexist@v0.1.0: replacement directory ../nonexist does not exist$'
-- go.mod --
module example.com/m
-- fail/m.go --
package main
-import _ "w"
+import (
+ _ "w"
+ _ "nonexist"
+)
func main() {}
replace w => ../w
+replace nonexist v0.1.0 => ../nonexist