Add showimp to commands.

This commit is contained in:
Kyle 2015-09-22 11:25:54 -07:00
parent 27819dbf0e
commit 4b3f1037b3
3 changed files with 140 additions and 0 deletions

21
cmd/showimp/README.md Normal file
View File

@ -0,0 +1,21 @@
# showimp
## show imports
This will run over a source tree and print any imports that are not in
the standard library or inside the project.
```
kyle@nocturne:~/src/github.com/kisom/cryptutils$ showimp
External imports:
code.google.com/p/go.crypto/bcrypt
code.google.com/p/go.crypto/nacl/box
code.google.com/p/go.crypto/nacl/secretbox
code.google.com/p/go.crypto/scrypt
code.google.com/p/rsc/qr
github.com/agl/ed25519
github.com/conformal/yubikey
github.com/gokyle/readpass
github.com/gokyle/twofactor
github.com/gorilla/mux
```

110
cmd/showimp/main.go Normal file
View File

@ -0,0 +1,110 @@
// showimp is a utility for displaying the imports in a package.
package main
import (
"flag"
"fmt"
"go/parser"
"go/token"
"os"
"path/filepath"
"regexp"
"sort"
"strings"
"github.com/kisom/goutils/die"
"github.com/kisom/goutils/logging"
)
var (
gopath string
project string
)
var (
stdLibRegexp = regexp.MustCompile(`^\w+(/\w+)*$`)
sourceRegexp = regexp.MustCompile(`^[^.].*\.go$`)
log = logging.Init()
)
func init() {
gopath = os.Getenv("GOPATH")
if gopath == "" {
fmt.Fprintf(os.Stderr, "GOPATH isn't set, can't proceed.")
os.Exit(1)
}
gopath += "/src/"
wd, err := os.Getwd()
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to establish working directory: %v", err)
os.Exit(1)
}
if !strings.HasPrefix(wd, gopath) {
fmt.Fprintf(os.Stderr, "Can't determine my location in the GOPATH.\n")
fmt.Fprintf(os.Stderr, "Working directory is %s\n", wd)
fmt.Fprintf(os.Stderr, "Go source path is %s\n", gopath)
os.Exit(1)
}
project = wd[len(gopath):]
}
var (
imports = map[string]bool{}
fset = &token.FileSet{}
)
func walkFile(path string, info os.FileInfo, err error) error {
if !sourceRegexp.MatchString(path) {
return nil
}
log.Debug(path)
f, err := parser.ParseFile(fset, path, nil, parser.ImportsOnly)
if err != nil {
return err
}
for _, importSpec := range f.Imports {
importPath := strings.Trim(importSpec.Path.Value, `"`)
if stdLibRegexp.MatchString(importPath) {
log.Debug("standard lib:", importPath)
continue
} else if strings.HasPrefix(importPath, project) {
log.Debug("internal import:", importPath)
continue
} else if strings.HasPrefix(importPath, "golang.org/") {
log.Debug("extended lib:", importPath)
continue
}
log.Debug("import:", importPath)
imports[importPath] = true
}
return nil
}
func main() {
verbose := flag.Bool("v", false, "log debugging information")
flag.Parse()
if *verbose {
log.SetLevel(logging.LevelDebug)
}
err := filepath.Walk(".", walkFile)
die.If(err)
fmt.Println("External imports:")
importList := make([]string, 0, len(imports))
for imp := range imports {
importList = append(importList, imp)
}
sort.Strings(importList)
for _, imp := range importList {
fmt.Println("\t", imp)
}
}

View File

@ -45,3 +45,12 @@ func Err(exit int, err error, format string, a ...interface{}) {
fmt.Fprintf(os.Stderr, format, a...) fmt.Fprintf(os.Stderr, format, a...)
os.Exit(exit) os.Exit(exit)
} }
// CheckFatal calls Err if err isn't nil.
func CheckFatal(err error, format string, a ...interface{}) {
if err == nil {
return
}
Err(ExitFailure, err, format, a...)
}