pikeman 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +21 -0
- data/CONTRIBUTING.md +15 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +36 -0
- data/LICENSE +27 -0
- data/LICENSE.txt +21 -0
- data/Makefile +39 -0
- data/README.md +85 -0
- data/Rakefile +10 -0
- data/VERSION +1 -0
- data/bin/console +14 -0
- data/bin/pikeman +15 -0
- data/bin/setup +8 -0
- data/golint/golint.go +213 -0
- data/golint/import.go +309 -0
- data/golint/version.go +3 -0
- data/lib/pikeman.rb +34 -0
- data/lib/pikeman/version.rb +3 -0
- data/lint.go +1708 -0
- data/lint_test.go +317 -0
- data/misc/emacs/golint.el +54 -0
- data/misc/vim/ftplugin/go/lint.vim +31 -0
- data/pikeman.gemspec +28 -0
- data/testdata/4.go +38 -0
- data/testdata/5_test.go +17 -0
- data/testdata/blank-import-lib.go +39 -0
- data/testdata/blank-import-lib_test.go +25 -0
- data/testdata/blank-import-main.go +14 -0
- data/testdata/broken.go +9 -0
- data/testdata/common-methods.go +16 -0
- data/testdata/const-block.go +36 -0
- data/testdata/context.go +24 -0
- data/testdata/contextkeytypes.go +38 -0
- data/testdata/else-multi.go +18 -0
- data/testdata/else.go +23 -0
- data/testdata/error-return.go +43 -0
- data/testdata/errorf.go +40 -0
- data/testdata/errors.go +38 -0
- data/testdata/iferr.go +101 -0
- data/testdata/import-dot.go +8 -0
- data/testdata/inc.go +14 -0
- data/testdata/names.go +116 -0
- data/testdata/pkg-caps.go +4 -0
- data/testdata/pkg-doc1.go +3 -0
- data/testdata/pkg-doc2.go +5 -0
- data/testdata/pkg-doc3.go +7 -0
- data/testdata/pkg-doc4.go +7 -0
- data/testdata/pkg-doc5.go +9 -0
- data/testdata/pkg-main.go +5 -0
- data/testdata/range.go +43 -0
- data/testdata/receiver-names.go +49 -0
- data/testdata/sort.go +20 -0
- data/testdata/stutter.go +25 -0
- data/testdata/time.go +13 -0
- data/testdata/unexp-return.go +46 -0
- data/testdata/var-decl.go +86 -0
- metadata +172 -0
data/testdata/5_test.go
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
// This file ends in _test.go, so we should not warn about doc comments.
|
2
|
+
// OK
|
3
|
+
|
4
|
+
package pkg
|
5
|
+
|
6
|
+
import "testing"
|
7
|
+
|
8
|
+
type H int
|
9
|
+
|
10
|
+
func TestSomething(t *testing.T) {
|
11
|
+
}
|
12
|
+
|
13
|
+
func TestSomething_suffix(t *testing.T) {
|
14
|
+
}
|
15
|
+
|
16
|
+
func ExampleBuffer_reader() {
|
17
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
// Test that blank imports in library packages are flagged.
|
2
|
+
|
3
|
+
// Package foo ...
|
4
|
+
package foo
|
5
|
+
|
6
|
+
// The instructions need to go before the imports below so they will not be
|
7
|
+
// mistaken for documentation.
|
8
|
+
|
9
|
+
/* MATCH /blank import/ */ import _ "encoding/json"
|
10
|
+
|
11
|
+
import (
|
12
|
+
"fmt"
|
13
|
+
|
14
|
+
/* MATCH /blank import/ */ _ "os"
|
15
|
+
|
16
|
+
/* MATCH /blank import/ */ _ "net/http"
|
17
|
+
_ "path"
|
18
|
+
)
|
19
|
+
|
20
|
+
import _ "encoding/base64" // Don't gripe about this
|
21
|
+
|
22
|
+
import (
|
23
|
+
// Don't gripe about these next two lines.
|
24
|
+
_ "compress/zlib"
|
25
|
+
_ "syscall"
|
26
|
+
|
27
|
+
/* MATCH /blank import/ */ _ "path/filepath"
|
28
|
+
)
|
29
|
+
|
30
|
+
import (
|
31
|
+
"go/ast"
|
32
|
+
_ "go/scanner" // Don't gripe about this or the following line.
|
33
|
+
_ "go/token"
|
34
|
+
)
|
35
|
+
|
36
|
+
var (
|
37
|
+
_ fmt.Stringer // for "fmt"
|
38
|
+
_ ast.Node // for "go/ast"
|
39
|
+
)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
// Test that blank imports in test packages are not flagged.
|
2
|
+
// OK
|
3
|
+
|
4
|
+
// Package foo ...
|
5
|
+
package foo
|
6
|
+
|
7
|
+
// These are essentially the same imports as in the "library" package, but
|
8
|
+
// these should not trigger the warning because this is a test.
|
9
|
+
|
10
|
+
import _ "encoding/json"
|
11
|
+
|
12
|
+
import (
|
13
|
+
"fmt"
|
14
|
+
"testing"
|
15
|
+
|
16
|
+
_ "os"
|
17
|
+
|
18
|
+
_ "net/http"
|
19
|
+
_ "path"
|
20
|
+
)
|
21
|
+
|
22
|
+
var (
|
23
|
+
_ fmt.Stringer // for "fmt"
|
24
|
+
_ testing.T // for "testing"
|
25
|
+
)
|
data/testdata/broken.go
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
// Test that we don't nag for comments on common methods.
|
2
|
+
// OK
|
3
|
+
|
4
|
+
// Package pkg ...
|
5
|
+
package pkg
|
6
|
+
|
7
|
+
import "net/http"
|
8
|
+
|
9
|
+
// T is ...
|
10
|
+
type T int
|
11
|
+
|
12
|
+
func (T) Error() string { return "" }
|
13
|
+
func (T) String() string { return "" }
|
14
|
+
func (T) ServeHTTP(w http.ResponseWriter, r *http.Request) {}
|
15
|
+
func (T) Read(p []byte) (n int, err error) { return 0, nil }
|
16
|
+
func (T) Write(p []byte) (n int, err error) { return 0, nil }
|
@@ -0,0 +1,36 @@
|
|
1
|
+
// Test for docs in const blocks
|
2
|
+
|
3
|
+
// Package foo ...
|
4
|
+
package foo
|
5
|
+
|
6
|
+
const (
|
7
|
+
// Prefix for something.
|
8
|
+
// MATCH /InlineWhatever.*form/
|
9
|
+
InlineWhatever = "blah"
|
10
|
+
|
11
|
+
Whatsit = "missing_comment" // MATCH /Whatsit.*should have comment.*block/
|
12
|
+
|
13
|
+
// We should only warn once per block for missing comments,
|
14
|
+
// but always complain about malformed comments.
|
15
|
+
|
16
|
+
WhosYourDaddy = "another_missing_one"
|
17
|
+
|
18
|
+
// Something
|
19
|
+
// MATCH /WhatDoesHeDo.*form/
|
20
|
+
WhatDoesHeDo = "it's not a tumor!"
|
21
|
+
)
|
22
|
+
|
23
|
+
// These shouldn't need doc comments.
|
24
|
+
const (
|
25
|
+
Alpha = "a"
|
26
|
+
Beta = "b"
|
27
|
+
Gamma = "g"
|
28
|
+
)
|
29
|
+
|
30
|
+
// The comment on the previous const block shouldn't flow through to here.
|
31
|
+
|
32
|
+
const UndocAgain = 6 // MATCH /UndocAgain.*should have comment/
|
33
|
+
|
34
|
+
const (
|
35
|
+
SomeUndocumented = 7 // MATCH /SomeUndocumented.*should have comment.*block/
|
36
|
+
)
|
data/testdata/context.go
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
// Test that context.Context is the first arg to a function.
|
2
|
+
|
3
|
+
// Package foo ...
|
4
|
+
package foo
|
5
|
+
|
6
|
+
import (
|
7
|
+
"context"
|
8
|
+
)
|
9
|
+
|
10
|
+
// A proper context.Context location
|
11
|
+
func x(ctx context.Context) { // ok
|
12
|
+
}
|
13
|
+
|
14
|
+
// A proper context.Context location
|
15
|
+
func x(ctx context.Context, s string) { // ok
|
16
|
+
}
|
17
|
+
|
18
|
+
// An invalid context.Context location
|
19
|
+
func y(s string, ctx context.Context) { // MATCH /context.Context should be the first parameter.*/
|
20
|
+
}
|
21
|
+
|
22
|
+
// An invalid context.Context location with more than 2 args
|
23
|
+
func y(s string, r int, ctx context.Context, x int) { // MATCH /context.Context should be the first parameter.*/
|
24
|
+
}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
// Package contextkeytypes verifies that correct types are used as keys in
|
2
|
+
// calls to context.WithValue.
|
3
|
+
package contextkeytypes
|
4
|
+
|
5
|
+
import (
|
6
|
+
"context"
|
7
|
+
"fmt"
|
8
|
+
)
|
9
|
+
|
10
|
+
type ctxKey struct{}
|
11
|
+
|
12
|
+
func contextKeyTypeTests() {
|
13
|
+
fmt.Println() // not in package context
|
14
|
+
context.TODO() // wrong function
|
15
|
+
c := context.Background() // wrong function
|
16
|
+
context.WithValue(c, "foo", "bar") // MATCH /should not use basic type( untyped|)? string as key in context.WithValue/
|
17
|
+
context.WithValue(c, true, "bar") // MATCH /should not use basic type( untyped|)? bool as key in context.WithValue/
|
18
|
+
context.WithValue(c, 1, "bar") // MATCH /should not use basic type( untyped|)? int as key in context.WithValue/
|
19
|
+
context.WithValue(c, int8(1), "bar") // MATCH /should not use basic type int8 as key in context.WithValue/
|
20
|
+
context.WithValue(c, int16(1), "bar") // MATCH /should not use basic type int16 as key in context.WithValue/
|
21
|
+
context.WithValue(c, int32(1), "bar") // MATCH /should not use basic type int32 as key in context.WithValue/
|
22
|
+
context.WithValue(c, rune(1), "bar") // MATCH /should not use basic type rune as key in context.WithValue/
|
23
|
+
context.WithValue(c, int64(1), "bar") // MATCH /should not use basic type int64 as key in context.WithValue/
|
24
|
+
context.WithValue(c, uint(1), "bar") // MATCH /should not use basic type uint as key in context.WithValue/
|
25
|
+
context.WithValue(c, uint8(1), "bar") // MATCH /should not use basic type uint8 as key in context.WithValue/
|
26
|
+
context.WithValue(c, byte(1), "bar") // MATCH /should not use basic type byte as key in context.WithValue/
|
27
|
+
context.WithValue(c, uint16(1), "bar") // MATCH /should not use basic type uint16 as key in context.WithValue/
|
28
|
+
context.WithValue(c, uint32(1), "bar") // MATCH /should not use basic type uint32 as key in context.WithValue/
|
29
|
+
context.WithValue(c, uint64(1), "bar") // MATCH /should not use basic type uint64 as key in context.WithValue/
|
30
|
+
context.WithValue(c, uintptr(1), "bar") // MATCH /should not use basic type uintptr as key in context.WithValue/
|
31
|
+
context.WithValue(c, float32(1.0), "bar") // MATCH /should not use basic type float32 as key in context.WithValue/
|
32
|
+
context.WithValue(c, float64(1.0), "bar") // MATCH /should not use basic type float64 as key in context.WithValue/
|
33
|
+
context.WithValue(c, complex64(1i), "bar") // MATCH /should not use basic type complex64 as key in context.WithValue/
|
34
|
+
context.WithValue(c, complex128(1i), "bar") // MATCH /should not use basic type complex128 as key in context.WithValue/
|
35
|
+
context.WithValue(c, ctxKey{}, "bar") // ok
|
36
|
+
context.WithValue(c, &ctxKey{}, "bar") // ok
|
37
|
+
context.WithValue(c, invalid{}, "bar") // ok
|
38
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
// Test of return+else warning; should not trigger on multi-branch if/else.
|
2
|
+
// OK
|
3
|
+
|
4
|
+
// Package pkg ...
|
5
|
+
package pkg
|
6
|
+
|
7
|
+
import "log"
|
8
|
+
|
9
|
+
func f(x int) bool {
|
10
|
+
if x == 0 {
|
11
|
+
log.Print("x is zero")
|
12
|
+
} else if x > 0 {
|
13
|
+
return true
|
14
|
+
} else {
|
15
|
+
log.Printf("non-positive x: %d", x)
|
16
|
+
}
|
17
|
+
return false
|
18
|
+
}
|
data/testdata/else.go
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
// Test of return+else warning.
|
2
|
+
|
3
|
+
// Package pkg ...
|
4
|
+
package pkg
|
5
|
+
|
6
|
+
import "log"
|
7
|
+
|
8
|
+
func f(x int) bool {
|
9
|
+
if x > 0 {
|
10
|
+
return true
|
11
|
+
} else { // MATCH /if.*return.*else.*outdent/
|
12
|
+
log.Printf("non-positive x: %d", x)
|
13
|
+
}
|
14
|
+
return false
|
15
|
+
}
|
16
|
+
|
17
|
+
func g(f func() bool) string {
|
18
|
+
if ok := f(); ok {
|
19
|
+
return "it's okay"
|
20
|
+
} else { // MATCH /if.*return.*else.*outdent.*short.*var.*declaration/
|
21
|
+
return "it's NOT okay!"
|
22
|
+
}
|
23
|
+
}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
// Test for returning errors.
|
2
|
+
|
3
|
+
// Package foo ...
|
4
|
+
package foo
|
5
|
+
|
6
|
+
// Returns nothing
|
7
|
+
func f() { // ok
|
8
|
+
}
|
9
|
+
|
10
|
+
// Check for a single error return
|
11
|
+
func g() error { // ok
|
12
|
+
return nil
|
13
|
+
}
|
14
|
+
|
15
|
+
// Check for a single other return type
|
16
|
+
func h() int { // ok
|
17
|
+
return 0
|
18
|
+
}
|
19
|
+
|
20
|
+
// Check for multiple return but error at end.
|
21
|
+
func i() (int, error) { // ok
|
22
|
+
return 0, nil
|
23
|
+
}
|
24
|
+
|
25
|
+
// Check for multiple return but error at end with named variables.
|
26
|
+
func j() (x int, err error) { // ok
|
27
|
+
return 0, nil
|
28
|
+
}
|
29
|
+
|
30
|
+
// Check for error in the wrong location on 2 types
|
31
|
+
func k() (error, int) { // MATCH /error should be the last type/
|
32
|
+
return nil, 0
|
33
|
+
}
|
34
|
+
|
35
|
+
// Check for error in the wrong location for > 2 types
|
36
|
+
func l() (int, error, int) { // MATCH /error should be the last type/
|
37
|
+
return 0, nil, 0
|
38
|
+
}
|
39
|
+
|
40
|
+
// Check for error in the wrong location with named variables.
|
41
|
+
func m() (x int, err error, y int) { // MATCH /error should be the last type/
|
42
|
+
return 0, nil, 0
|
43
|
+
}
|
data/testdata/errorf.go
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
// Test for not using fmt.Errorf or testing.Errorf.
|
2
|
+
|
3
|
+
// Package foo ...
|
4
|
+
package foo
|
5
|
+
|
6
|
+
import (
|
7
|
+
"errors"
|
8
|
+
"fmt"
|
9
|
+
"testing"
|
10
|
+
)
|
11
|
+
|
12
|
+
func f(x int) error {
|
13
|
+
if x > 10 {
|
14
|
+
return errors.New(fmt.Sprintf("something %d", x)) // MATCH /should replace.*errors\.New\(fmt\.Sprintf\(\.\.\.\)\).*fmt\.Errorf\(\.\.\.\)/ -> ` return fmt.Errorf("something %d", x)`
|
15
|
+
}
|
16
|
+
if x > 5 {
|
17
|
+
return errors.New(g("blah")) // ok
|
18
|
+
}
|
19
|
+
if x > 4 {
|
20
|
+
return errors.New("something else") // ok
|
21
|
+
}
|
22
|
+
return nil
|
23
|
+
}
|
24
|
+
|
25
|
+
// TestF is a dummy test
|
26
|
+
func TestF(t *testing.T) error {
|
27
|
+
x := 1
|
28
|
+
if x > 10 {
|
29
|
+
return t.Error(fmt.Sprintf("something %d", x)) // MATCH /should replace.*t\.Error\(fmt\.Sprintf\(\.\.\.\)\).*t\.Errorf\(\.\.\.\)/
|
30
|
+
}
|
31
|
+
if x > 5 {
|
32
|
+
return t.Error(g("blah")) // ok
|
33
|
+
}
|
34
|
+
if x > 4 {
|
35
|
+
return t.Error("something else") // ok
|
36
|
+
}
|
37
|
+
return nil
|
38
|
+
}
|
39
|
+
|
40
|
+
func g(s string) string { return "prefix: " + s }
|
data/testdata/errors.go
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
// Test for naming errors.
|
2
|
+
|
3
|
+
// Package foo ...
|
4
|
+
package foo
|
5
|
+
|
6
|
+
import (
|
7
|
+
"errors"
|
8
|
+
"fmt"
|
9
|
+
)
|
10
|
+
|
11
|
+
var unexp = errors.New("some unexported error") // MATCH /error var.*unexp.*errFoo/
|
12
|
+
|
13
|
+
// Exp ...
|
14
|
+
var Exp = errors.New("some exported error") // MATCH /error var.*Exp.*ErrFoo/
|
15
|
+
|
16
|
+
var (
|
17
|
+
e1 = fmt.Errorf("blah %d", 4) // MATCH /error var.*e1.*errFoo/
|
18
|
+
// E2 ...
|
19
|
+
E2 = fmt.Errorf("blah %d", 5) // MATCH /error var.*E2.*ErrFoo/
|
20
|
+
)
|
21
|
+
|
22
|
+
func f() {
|
23
|
+
var whatever = errors.New("ok") // ok
|
24
|
+
_ = whatever
|
25
|
+
}
|
26
|
+
|
27
|
+
// Check for the error strings themselves.
|
28
|
+
|
29
|
+
func g(x int) error {
|
30
|
+
var err error
|
31
|
+
err = fmt.Errorf("This %d is too low", x) // MATCH /error strings.*be capitalized/
|
32
|
+
err = fmt.Errorf("XML time") // ok
|
33
|
+
err = fmt.Errorf("newlines are fun\n") // MATCH /error strings.*end with punctuation/
|
34
|
+
err = fmt.Errorf("Newlines are really fun\n") // MATCH /error strings.+not be capitalized/
|
35
|
+
err = errors.New(`too much stuff.`) // MATCH /error strings.*end with punctuation/
|
36
|
+
err = errors.New("This %d is too low", x) // MATCH /error strings.*be capitalized/
|
37
|
+
return err
|
38
|
+
}
|
data/testdata/iferr.go
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
// Test of redundant if err != nil
|
2
|
+
|
3
|
+
// Package pkg ...
|
4
|
+
package pkg
|
5
|
+
|
6
|
+
func f() error {
|
7
|
+
if err := f(); err != nil {
|
8
|
+
g()
|
9
|
+
return err
|
10
|
+
}
|
11
|
+
return nil
|
12
|
+
}
|
13
|
+
|
14
|
+
func g() error {
|
15
|
+
if err := f(); err != nil { // MATCH /redundant/
|
16
|
+
return err
|
17
|
+
}
|
18
|
+
return nil
|
19
|
+
}
|
20
|
+
|
21
|
+
func h() error {
|
22
|
+
if err, x := f(), 1; err != nil {
|
23
|
+
return err
|
24
|
+
}
|
25
|
+
return nil
|
26
|
+
}
|
27
|
+
|
28
|
+
func i() error {
|
29
|
+
a := 1
|
30
|
+
if err := f(); err != nil {
|
31
|
+
a++
|
32
|
+
return err
|
33
|
+
}
|
34
|
+
return nil
|
35
|
+
}
|
36
|
+
|
37
|
+
func j() error {
|
38
|
+
var a error
|
39
|
+
if err := f(); err != nil {
|
40
|
+
return err
|
41
|
+
}
|
42
|
+
return a
|
43
|
+
}
|
44
|
+
|
45
|
+
func k() error {
|
46
|
+
if err := f(); err != nil {
|
47
|
+
// TODO: handle error better
|
48
|
+
return err
|
49
|
+
}
|
50
|
+
return nil
|
51
|
+
}
|
52
|
+
|
53
|
+
func l() (interface{}, error) {
|
54
|
+
if err := f(); err != nil {
|
55
|
+
return nil, err
|
56
|
+
}
|
57
|
+
if err := f(); err != nil {
|
58
|
+
return nil, err
|
59
|
+
}
|
60
|
+
if err := f(); err != nil {
|
61
|
+
return nil, err
|
62
|
+
}
|
63
|
+
// Phew, it worked
|
64
|
+
return nil
|
65
|
+
}
|
66
|
+
|
67
|
+
func m() error {
|
68
|
+
if err := f(); err != nil {
|
69
|
+
return err
|
70
|
+
}
|
71
|
+
if err := f(); err != nil {
|
72
|
+
return err
|
73
|
+
}
|
74
|
+
if err := f(); err != nil {
|
75
|
+
return err
|
76
|
+
}
|
77
|
+
// Phew, it worked again.
|
78
|
+
return nil
|
79
|
+
}
|
80
|
+
|
81
|
+
func multi() error {
|
82
|
+
a := 0
|
83
|
+
var err error
|
84
|
+
// unreachable code after return statements is intentional to check that it
|
85
|
+
// doesn't confuse the linter.
|
86
|
+
if true {
|
87
|
+
a++
|
88
|
+
if err := f(); err != nil { // MATCH /redundant/
|
89
|
+
return err
|
90
|
+
}
|
91
|
+
return nil
|
92
|
+
a++
|
93
|
+
} else {
|
94
|
+
a++
|
95
|
+
if err = f(); err != nil { // MATCH /redundant/
|
96
|
+
return err
|
97
|
+
}
|
98
|
+
return nil
|
99
|
+
a++
|
100
|
+
}
|
101
|
+
}
|