packageからfilepathを推測する方法あるいはその逆
packageからfilepathを推測する方法などをまとめておきたかった。
(ついでに個人的な信仰からホームディレクトリは~
になっている)
packageからfilepath
package main import ( "go/build" "os" "os/user" "path/filepath" "strings" "github.com/pkg/errors" ) func guessPath(pkgname string) (string, error) { ctxt := build.Default for _, srcdir := range ctxt.SrcDirs() { path := filepath.Join(srcdir, pkgname) if info, err := os.Stat(path); err == nil && info.IsDir() { u, err := user.Current() if err != nil { return "", err } return strings.Replace(path, u.HomeDir, "~", 1), nil } } return "", errors.Errorf("%q's physical address is not found", pkgname) }
filepathからpackage
package main import ( "go/build" "os/user" "path/filepath" "strings" "github.com/pkg/errors" ) func guessPkg(path string) (string, error) { if strings.HasPrefix(path, "~") { u, err := user.Current() if err != nil { return "", err } path = filepath.Join(u.HomeDir, path[1:]) } ctxt := build.Default path, err := filepath.Abs(path) if err != nil { return "", err } for _, srcdir := range ctxt.SrcDirs() { if strings.HasPrefix(path, srcdir) { pkgname := strings.TrimLeft(strings.Replace(path, srcdir, "", 1), "/") return pkgname, nil } } return "", errors.Errorf("%q is not subdir of srcdirs(%q)", path, build.Default.SrcDirs()) }
使った結果
GOPATHの方もGOROOTの方もOK
func main() { { pkg := "golang.org/x/tools/go/loader" fmt.Println(guessPath(pkg)) path, _ := guessPath(pkg) fmt.Println(guessPkg(path)) } fmt.Println("----------------------------------------") { pkg := "encoding/json" fmt.Println(guessPath(pkg)) path, _ := guessPath(pkg) fmt.Println(guessPkg(path)) } }
~/go/src/golang.org/x/tools/go/loader <nil> golang.org/x/tools/go/loader <nil> ---------------------------------------- /usr/lib/go/src/encoding/json <nil> encoding/json <nil>