diff --git a/main.go b/main.go index 5590f35..c8cf9b7 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,7 @@ package main import ( "bytes" "fmt" + "go/build" "io" "io/ioutil" "log" @@ -14,12 +15,14 @@ import ( func main() { log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) binDirs := []string{} + srcDirs := []string{} for _, env := range os.Environ() { if strings.HasPrefix(env, "GOPATH=") { i := strings.Index(env, "=") paths := filepath.SplitList(env[i+1:]) for _, path := range paths { binDirs = append(binDirs, filepath.Join(path, "bin")) + srcDirs = append(srcDirs, filepath.Join(path, "src")) } } } @@ -46,7 +49,8 @@ func main() { } } - execs := []string{} + execs := map[string][]string{} + execNames := []string{} buf := &bytes.Buffer{} for _, name := range files { buf.Reset() @@ -78,16 +82,55 @@ func main() { } for _, b := range execPatterns { if bytes.Equal(buf.Bytes(), b) { - execs = append(execs, name) + _, en := filepath.Split(name) + if _, ok := execs[en]; !ok { + execs[en] = []string{} + execNames = append(execNames, en) + } } } } - for _, exec := range execs { - fmt.Println(exec) + for _, srcDir := range srcDirs { + filepath.Walk( + srcDir, + func(path string, info os.FileInfo, err error) error { + if !info.IsDir() { + return nil + } + if strings.HasSuffix(path, ".git") || + strings.HasSuffix(path, ".hg") { + return filepath.SkipDir + } + potentialPackage := strings.TrimPrefix(path, srcDir+"/") + + pkg, err := build.Import(potentialPackage, srcDir, 0) + if err != nil { + return nil + } + if pkg.Name != "main" { + return nil + } + _, en := filepath.Split(pkg.ImportPath) + if _, ok := execs[en]; ok { + execs[en] = append(execs[en], pkg.ImportPath) + } + return nil + }, + ) + } + + for _, name := range execNames { + if len(execs[name]) > 0 { + fmt.Println(name) + for _, potential := range execs[name] { + fmt.Printf("\t%s\n", potential) + } + } } } +// Exists emits true if path exists, false otherwise func exists(path string) bool { if _, err := os.Stat(path); err != nil { return false