diff options
| author | Carlos Martín Nieto <[email protected]> | 2014-12-09 00:47:41 +0100 |
|---|---|---|
| committer | Carlos Martín Nieto <[email protected]> | 2014-12-09 00:47:41 +0100 |
| commit | 7762e1a3a963d3e00c4709b284d30ff843ea30ff (patch) | |
| tree | 72a2f736bc7aaf291a41fb82668793dffe219c13 /script/check-MakeGitError-thread-lock.go | |
| parent | 520a0425c736c7d584d21d073b08a8735dd2464f (diff) | |
| parent | 57095bafe72ffd80d22469215db026be3c5d4242 (diff) | |
Merge pull request #138 from sqs/check-MakeGitError-thread-lock
Add script for checking thread locks in funcs that call MakeGitError
Diffstat (limited to 'script/check-MakeGitError-thread-lock.go')
| -rw-r--r-- | script/check-MakeGitError-thread-lock.go | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/script/check-MakeGitError-thread-lock.go b/script/check-MakeGitError-thread-lock.go new file mode 100644 index 0000000..f6b01b3 --- /dev/null +++ b/script/check-MakeGitError-thread-lock.go @@ -0,0 +1,71 @@ +package main + +import ( + "bytes" + "fmt" + "go/ast" + "go/build" + "go/parser" + "go/printer" + "go/token" + "log" + "os" + "path/filepath" + "strings" +) + +var ( + fset = token.NewFileSet() +) + +func main() { + log.SetFlags(0) + + bpkg, err := build.ImportDir(".", 0) + if err != nil { + log.Fatal(err) + } + + pkgs, err := parser.ParseDir(fset, bpkg.Dir, func(fi os.FileInfo) bool { return filepath.Ext(fi.Name()) == ".go" }, 0) + if err != nil { + log.Fatal(err) + } + + for _, pkg := range pkgs { + if err := checkPkg(pkg); err != nil { + log.Fatal(err) + } + } + if len(pkgs) == 0 { + log.Fatal("No packages to check.") + } +} + +var ignoreViolationsInFunc = map[string]bool{ + "MakeGitError": true, + "MakeGitError2": true, +} + +func checkPkg(pkg *ast.Package) error { + var violations []string + ast.Inspect(pkg, func(node ast.Node) bool { + switch node := node.(type) { + case *ast.FuncDecl: + var b bytes.Buffer + if err := printer.Fprint(&b, fset, node); err != nil { + log.Fatal(err) + } + src := b.String() + + if strings.Contains(src, "MakeGitError") && !strings.Contains(src, "runtime.LockOSThread()") && !strings.Contains(src, "defer runtime.UnlockOSThread()") && !ignoreViolationsInFunc[node.Name.Name] { + pos := fset.Position(node.Pos()) + violations = append(violations, fmt.Sprintf("%s at %s:%d", node.Name.Name, pos.Filename, pos.Line)) + } + } + return true + }) + if len(violations) > 0 { + return fmt.Errorf("%d non-thread-locked calls to MakeGitError found. To fix, add the following to each func below that calls MakeGitError, before the cgo call that might produce the error:\n\n\truntime.LockOSThread()\n\tdefer runtime.UnlockOSThread()\n\n%s", len(violations), strings.Join(violations, "\n")) + } + return nil +} |
