aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2010-12-14 17:09:24 -0800
committerRob Pike <r@golang.org>2010-12-14 17:09:24 -0800
commit670e77b54d800f4636bfbb9af4516660cea2fe6c (patch)
tree2851784d9d50b4c467d733d32df4a0032c5b674f
parent5742ded3ad6496de67a80b3745dce29cd5bd5b09 (diff)
downloadgo-670e77b54d800f4636bfbb9af4516660cea2fe6c.tar.gz
go-670e77b54d800f4636bfbb9af4516660cea2fe6c.zip
govet: allow directories as arguments, process recursively.
R=gri CC=golang-dev https://golang.org/cl/3652041
-rw-r--r--src/cmd/govet/doc.go1
-rw-r--r--src/cmd/govet/govet.go43
2 files changed, 40 insertions, 4 deletions
diff --git a/src/cmd/govet/doc.go b/src/cmd/govet/doc.go
index fd66d3c0b0..5a2489fca7 100644
--- a/src/cmd/govet/doc.go
+++ b/src/cmd/govet/doc.go
@@ -19,6 +19,7 @@ complains about arguments that look like format descriptor strings.
Usage:
govet [flag] [file.go ...]
+ govet [flag] [directory ...] # Scan all .go files under directory, recursively
The flags are:
-v
diff --git a/src/cmd/govet/govet.go b/src/cmd/govet/govet.go
index b49e32e12c..1d775ff28c 100644
--- a/src/cmd/govet/govet.go
+++ b/src/cmd/govet/govet.go
@@ -15,6 +15,7 @@ import (
"go/parser"
"go/token"
"os"
+ "path"
"strconv"
"strings"
)
@@ -73,8 +74,13 @@ func main() {
if flag.NArg() == 0 {
doFile("stdin", os.Stdin)
} else {
- for _, arg := range flag.Args() {
- doFile(arg, nil)
+ for _, name := range flag.Args() {
+ // Is it a directory?
+ if fi, err := os.Stat(name); err == nil && fi.IsDirectory() {
+ walkDir(name)
+ } else {
+ doFile(name, nil)
+ }
}
}
os.Exit(exitCode)
@@ -83,7 +89,6 @@ func main() {
// doFile analyzes one file. If the reader is nil, the source code is read from the
// named file.
func doFile(name string, reader io.Reader) {
- // TODO: process directories?
fs := token.NewFileSet()
parsedFile, err := parser.ParseFile(fs, name, reader, 0)
if err != nil {
@@ -94,6 +99,36 @@ func doFile(name string, reader io.Reader) {
file.checkFile(name, parsedFile)
}
+// Visitor for path.Walk - trivial. Just calls doFile on each file.
+// TODO: if govet becomes richer, might want to process
+// a directory (package) at a time.
+type V struct{}
+
+func (v V) VisitDir(path string, f *os.FileInfo) bool {
+ return true
+}
+
+func (v V) VisitFile(path string, f *os.FileInfo) {
+ if strings.HasSuffix(path, ".go") {
+ doFile(path, nil)
+ }
+}
+
+// walkDir recursively walks the tree looking for .go files.
+func walkDir(root string) {
+ errors := make(chan os.Error)
+ done := make(chan bool)
+ go func() {
+ for e := range errors {
+ error("walk error: %s", e)
+ }
+ done <- true
+ }()
+ path.Walk(root, V{}, errors)
+ close(errors)
+ <-done
+}
+
// error formats the error to standard error, adding program
// identification and a newline
func error(format string, args ...interface{}) {
@@ -143,7 +178,7 @@ func (f *File) Warnf(pos token.Pos, format string, args ...interface{}) {
// checkFile checks all the top-level declarations in a file.
func (f *File) checkFile(name string, file *ast.File) {
- Println("Checking", name)
+ Println("Checking file", name)
ast.Walk(f, file)
}