130 lines
2.5 KiB
Go
130 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"go/build"
|
|
"io"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
func main() {
|
|
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
|
|
binDirs := []string{}
|
|
srcDirs := []string{}
|
|
|
|
for _, path := range filepath.SplitList(os.Getenv("GOPATH")) {
|
|
binDirs = append(binDirs, filepath.Join(path, "bin"))
|
|
srcDirs = append(srcDirs, filepath.Join(path, "src"))
|
|
}
|
|
|
|
files := []string{}
|
|
|
|
for _, binDir := range binDirs {
|
|
fi, err := os.Stat(binDir)
|
|
if err != nil {
|
|
log.Printf("%+v", err)
|
|
continue
|
|
}
|
|
if !fi.IsDir() {
|
|
log.Printf("%s is not a directory!", binDir)
|
|
continue
|
|
}
|
|
dirInfo, err := ioutil.ReadDir(binDir)
|
|
if err != nil {
|
|
log.Printf("%+v", err)
|
|
continue
|
|
}
|
|
for _, di := range dirInfo {
|
|
files = append(files, filepath.Join(binDir, di.Name()))
|
|
}
|
|
}
|
|
|
|
execs := map[string]bool{}
|
|
execNames := []string{}
|
|
buf := &bytes.Buffer{}
|
|
for _, name := range files {
|
|
buf.Reset()
|
|
if !exists(name) {
|
|
log.Fatal("this should never happen: file we just found isn't there now")
|
|
}
|
|
if fi, err := os.Stat(name); fi.IsDir() {
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
continue
|
|
}
|
|
fi, err := os.Open(name)
|
|
defer fi.Close()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
lr := &io.LimitedReader{
|
|
R: fi,
|
|
N: 2,
|
|
}
|
|
_, err = io.Copy(buf, lr)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
execPatterns := [][]byte{
|
|
{0x7f, 0x45},
|
|
{0xcf, 0xfa},
|
|
}
|
|
for _, b := range execPatterns {
|
|
if bytes.Equal(buf.Bytes(), b) {
|
|
_, en := filepath.Split(name)
|
|
if _, ok := execs[en]; !ok {
|
|
execs[en] = true
|
|
execNames = append(execNames, en)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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)
|
|
p := filepath.Join(srcDir, pkg.ImportPath)
|
|
if _, ok := execs[en]; ok {
|
|
fmt.Printf("%-30s%s\n", en, p)
|
|
}
|
|
return nil
|
|
},
|
|
)
|
|
}
|
|
}
|
|
|
|
// Exists emits true if path exists, false otherwise
|
|
func exists(path string) bool {
|
|
if _, err := os.Stat(path); err != nil {
|
|
return false
|
|
} else if os.IsNotExist(err) {
|
|
return false
|
|
}
|
|
return true
|
|
}
|