etcd-io/gofail

Failed to determine package path when source file is not inside GOPATH

disksing opened this issue · 2 comments

Now the package path is calculated based on the relative relationship between GOPATH and the directory where the file is located:

gofail/gofail.go

Lines 130 to 150 in 51ce9a7

pkgAbsDir := path.Dir(file)
pkg := path.Base(pkgAbsDir)
pkgDir := ""
for _, srcdir := range build.Default.SrcDirs() {
if strings.HasPrefix(pkgAbsDir, srcdir) {
pkgDir = strings.Replace(pkgAbsDir, srcdir, "", 1)
break
}
}
fppath := pkg
if pkgDir == "" {
fmt.Fprintf(
os.Stderr,
"missing package for %q; using %q as failpoint path\n",
pkgAbsDir,
pkg)
} else {
fppath = pkgDir[1:]
}
code.NewBinding(pkg, fppath, fps).Write(out)
out.Close()

With the go mod support after go1.11, source files can be outside of GOPATH. So when I run gofail, I can see the error: "missing package for %q; using %q as failpoint path".

I can think of several ways to get the package import path more accurately:

  1. Search parent directories for the go.mod file which contains the import path of the module.
  2. Use cmd.Exec to call go list to get the import path.
  3. Use reflect in generated foo.fail.go to determine import path.

I personally think that the third method is better as it relies less on the executing environment. It can be done by generating such code:

type __fp_foo struct{}
var __fp_fooBar *runtime.Failpoint = runtime.NewFailpoint(reflect.TypeOf(__fp_foo{}).PkgPath(), "fooBar")
ahrtr commented

I would like to resurrect the related PR #18. Please anyone feel free to work on it.

ahrtr commented

Resolved in #44, the package was eventually removed.