├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── aligncheck ├── aligncheck.go └── aligncheck_test.go ├── checkers └── checkers.go ├── dupl ├── dupl.go └── dupl_test.go ├── errcheck ├── errcheck.go └── errcheck_test.go ├── gofmt ├── gofmt.go └── gofmt_test.go ├── golint ├── golint.go └── golint_test.go ├── gometalinter ├── _vendored │ ├── .gitignore │ ├── manifest │ └── src │ │ ├── github.com │ │ ├── alecthomas │ │ │ ├── gometalinter │ │ │ │ ├── COPYING │ │ │ │ ├── aggregate.go │ │ │ │ ├── checkstyle.go │ │ │ │ ├── main.go │ │ │ │ ├── regressiontests │ │ │ │ │ └── support.go │ │ │ │ └── vendor │ │ │ │ │ └── src │ │ │ │ │ ├── github.com │ │ │ │ │ ├── HewlettPackard │ │ │ │ │ │ └── gas │ │ │ │ │ │ │ ├── core │ │ │ │ │ │ │ ├── analyzer.go │ │ │ │ │ │ │ ├── helpers.go │ │ │ │ │ │ │ ├── issue.go │ │ │ │ │ │ │ └── select.go │ │ │ │ │ │ │ ├── filelist.go │ │ │ │ │ │ │ ├── main.go │ │ │ │ │ │ │ ├── output │ │ │ │ │ │ │ └── formatter.go │ │ │ │ │ │ │ ├── rulelist.go │ │ │ │ │ │ │ ├── rules │ │ │ │ │ │ │ ├── bind.go │ │ │ │ │ │ │ ├── errors.go │ │ │ │ │ │ │ ├── fileperms.go │ │ │ │ │ │ │ ├── hardcoded_credentials.go │ │ │ │ │ │ │ ├── httpoxy.go │ │ │ │ │ │ │ ├── rand.go │ │ │ │ │ │ │ ├── rsa.go │ │ │ │ │ │ │ ├── sql.go │ │ │ │ │ │ │ ├── subproc.go │ │ │ │ │ │ │ ├── tempfiles.go │ │ │ │ │ │ │ ├── templates.go │ │ │ │ │ │ │ ├── tls.go │ │ │ │ │ │ │ ├── unsafe.go │ │ │ │ │ │ │ └── weakcrypto.go │ │ │ │ │ │ │ └── tools.go │ │ │ │ │ ├── alecthomas │ │ │ │ │ │ └── gocyclo │ │ │ │ │ │ │ └── gocyclo.go │ │ │ │ │ ├── client9 │ │ │ │ │ │ └── misspell │ │ │ │ │ │ │ ├── case.go │ │ │ │ │ │ │ ├── cmd │ │ │ │ │ │ │ └── misspell │ │ │ │ │ │ │ │ └── main.go │ │ │ │ │ │ │ ├── mime.go │ │ │ │ │ │ │ ├── notwords.go │ │ │ │ │ │ │ ├── replace.go │ │ │ │ │ │ │ ├── stringreplacer │ │ │ │ │ │ │ └── replace.go │ │ │ │ │ │ │ ├── url.go │ │ │ │ │ │ │ └── words.go │ │ │ │ │ ├── golang │ │ │ │ │ │ └── lint │ │ │ │ │ │ │ ├── golint │ │ │ │ │ │ │ ├── golint.go │ │ │ │ │ │ │ └── import.go │ │ │ │ │ │ │ └── lint.go │ │ │ │ │ ├── gordonklaus │ │ │ │ │ │ └── ineffassign │ │ │ │ │ │ │ └── ineffassign.go │ │ │ │ │ ├── jgautheron │ │ │ │ │ │ └── goconst │ │ │ │ │ │ │ ├── cmd │ │ │ │ │ │ │ └── goconst │ │ │ │ │ │ │ │ └── main.go │ │ │ │ │ │ │ ├── parser.go │ │ │ │ │ │ │ └── visitor.go │ │ │ │ │ ├── kisielk │ │ │ │ │ │ ├── errcheck │ │ │ │ │ │ │ ├── internal │ │ │ │ │ │ │ │ └── errcheck │ │ │ │ │ │ │ │ │ └── errcheck.go │ │ │ │ │ │ │ └── main.go │ │ │ │ │ │ └── gotool │ │ │ │ │ │ │ ├── go13.go │ │ │ │ │ │ │ ├── go14-15.go │ │ │ │ │ │ │ ├── go16.go │ │ │ │ │ │ │ ├── match.go │ │ │ │ │ │ │ └── tool.go │ │ │ │ │ ├── mdempsky │ │ │ │ │ │ └── unconvert │ │ │ │ │ │ │ └── unconvert.go │ │ │ │ │ ├── mibk │ │ │ │ │ │ └── dupl │ │ │ │ │ │ │ ├── job │ │ │ │ │ │ │ ├── buildtree.go │ │ │ │ │ │ │ └── parse.go │ │ │ │ │ │ │ ├── main.go │ │ │ │ │ │ │ ├── output │ │ │ │ │ │ │ ├── html.go │ │ │ │ │ │ │ ├── plumbing.go │ │ │ │ │ │ │ └── text.go │ │ │ │ │ │ │ ├── suffixtree │ │ │ │ │ │ │ ├── dupl.go │ │ │ │ │ │ │ └── suffixtree.go │ │ │ │ │ │ │ └── syntax │ │ │ │ │ │ │ ├── golang │ │ │ │ │ │ │ └── golang.go │ │ │ │ │ │ │ └── syntax.go │ │ │ │ │ ├── mvdan │ │ │ │ │ │ └── interfacer │ │ │ │ │ │ │ ├── cache.go │ │ │ │ │ │ │ ├── check.go │ │ │ │ │ │ │ ├── cmd │ │ │ │ │ │ │ └── interfacer │ │ │ │ │ │ │ │ └── main.go │ │ │ │ │ │ │ ├── generate │ │ │ │ │ │ │ └── std │ │ │ │ │ │ │ │ └── main.go │ │ │ │ │ │ │ ├── internal │ │ │ │ │ │ │ └── util │ │ │ │ │ │ │ │ └── util.go │ │ │ │ │ │ │ ├── std.go │ │ │ │ │ │ │ └── types.go │ │ │ │ │ ├── opennota │ │ │ │ │ │ └── check │ │ │ │ │ │ │ └── cmd │ │ │ │ │ │ │ ├── aligncheck │ │ │ │ │ │ │ └── aligncheck.go │ │ │ │ │ │ │ ├── structcheck │ │ │ │ │ │ │ └── structcheck.go │ │ │ │ │ │ │ └── varcheck │ │ │ │ │ │ │ └── varcheck.go │ │ │ │ │ ├── tsenart │ │ │ │ │ │ └── deadcode │ │ │ │ │ │ │ └── deadcode.go │ │ │ │ │ └── walle │ │ │ │ │ │ └── lll │ │ │ │ │ │ ├── cmd │ │ │ │ │ │ └── lll │ │ │ │ │ │ │ └── main.go │ │ │ │ │ │ ├── lll.go │ │ │ │ │ │ └── vendor │ │ │ │ │ │ └── github.com │ │ │ │ │ │ └── alexflint │ │ │ │ │ │ └── go-arg │ │ │ │ │ │ ├── doc.go │ │ │ │ │ │ ├── parse.go │ │ │ │ │ │ ├── scalar.go │ │ │ │ │ │ └── usage.go │ │ │ │ │ ├── golang.org │ │ │ │ │ └── x │ │ │ │ │ │ ├── text │ │ │ │ │ │ ├── internal │ │ │ │ │ │ │ ├── gen │ │ │ │ │ │ │ │ ├── code.go │ │ │ │ │ │ │ │ └── gen.go │ │ │ │ │ │ │ ├── triegen │ │ │ │ │ │ │ │ ├── compact.go │ │ │ │ │ │ │ │ ├── print.go │ │ │ │ │ │ │ │ └── triegen.go │ │ │ │ │ │ │ └── ucd │ │ │ │ │ │ │ │ └── ucd.go │ │ │ │ │ │ ├── transform │ │ │ │ │ │ │ └── transform.go │ │ │ │ │ │ ├── unicode │ │ │ │ │ │ │ └── cldr │ │ │ │ │ │ │ │ ├── base.go │ │ │ │ │ │ │ │ ├── cldr.go │ │ │ │ │ │ │ │ ├── collate.go │ │ │ │ │ │ │ │ ├── decode.go │ │ │ │ │ │ │ │ ├── makexml.go │ │ │ │ │ │ │ │ ├── resolve.go │ │ │ │ │ │ │ │ ├── slice.go │ │ │ │ │ │ │ │ └── xml.go │ │ │ │ │ │ └── width │ │ │ │ │ │ │ ├── gen.go │ │ │ │ │ │ │ ├── gen_common.go │ │ │ │ │ │ │ ├── gen_trieval.go │ │ │ │ │ │ │ ├── kind_string.go │ │ │ │ │ │ │ ├── tables.go │ │ │ │ │ │ │ ├── transform.go │ │ │ │ │ │ │ ├── trieval.go │ │ │ │ │ │ │ └── width.go │ │ │ │ │ │ └── tools │ │ │ │ │ │ ├── cmd │ │ │ │ │ │ ├── goimports │ │ │ │ │ │ │ ├── doc.go │ │ │ │ │ │ │ └── goimports.go │ │ │ │ │ │ └── gotype │ │ │ │ │ │ │ ├── doc.go │ │ │ │ │ │ │ └── gotype.go │ │ │ │ │ │ ├── container │ │ │ │ │ │ └── intsets │ │ │ │ │ │ │ ├── popcnt_amd64.go │ │ │ │ │ │ │ ├── popcnt_amd64.s │ │ │ │ │ │ │ ├── popcnt_gccgo.go │ │ │ │ │ │ │ ├── popcnt_gccgo_c.c │ │ │ │ │ │ │ ├── popcnt_generic.go │ │ │ │ │ │ │ ├── sparse.go │ │ │ │ │ │ │ └── util.go │ │ │ │ │ │ ├── go │ │ │ │ │ │ ├── ast │ │ │ │ │ │ │ └── astutil │ │ │ │ │ │ │ │ ├── enclosing.go │ │ │ │ │ │ │ │ ├── imports.go │ │ │ │ │ │ │ │ └── util.go │ │ │ │ │ │ ├── buildutil │ │ │ │ │ │ │ ├── allpackages.go │ │ │ │ │ │ │ ├── fakecontext.go │ │ │ │ │ │ │ ├── overlay.go │ │ │ │ │ │ │ ├── tags.go │ │ │ │ │ │ │ └── util.go │ │ │ │ │ │ ├── gcimporter15 │ │ │ │ │ │ │ ├── bexport.go │ │ │ │ │ │ │ ├── bimport.go │ │ │ │ │ │ │ ├── exportdata.go │ │ │ │ │ │ │ ├── gcimporter.go │ │ │ │ │ │ │ ├── setname15.go │ │ │ │ │ │ │ └── setname16.go │ │ │ │ │ │ ├── loader │ │ │ │ │ │ │ ├── cgo.go │ │ │ │ │ │ │ ├── cgo_pkgconfig.go │ │ │ │ │ │ │ ├── doc.go │ │ │ │ │ │ │ ├── go16.go │ │ │ │ │ │ │ ├── loader.go │ │ │ │ │ │ │ └── util.go │ │ │ │ │ │ ├── ssa │ │ │ │ │ │ │ ├── blockopt.go │ │ │ │ │ │ │ ├── builder.go │ │ │ │ │ │ │ ├── const.go │ │ │ │ │ │ │ ├── const15.go │ │ │ │ │ │ │ ├── create.go │ │ │ │ │ │ │ ├── doc.go │ │ │ │ │ │ │ ├── dom.go │ │ │ │ │ │ │ ├── emit.go │ │ │ │ │ │ │ ├── func.go │ │ │ │ │ │ │ ├── interp │ │ │ │ │ │ │ │ ├── external.go │ │ │ │ │ │ │ │ ├── external_darwin.go │ │ │ │ │ │ │ │ ├── external_freebsd.go │ │ │ │ │ │ │ │ ├── external_plan9.go │ │ │ │ │ │ │ │ ├── external_unix.go │ │ │ │ │ │ │ │ ├── external_windows.go │ │ │ │ │ │ │ │ ├── interp.go │ │ │ │ │ │ │ │ ├── map.go │ │ │ │ │ │ │ │ ├── ops.go │ │ │ │ │ │ │ │ ├── reflect.go │ │ │ │ │ │ │ │ └── value.go │ │ │ │ │ │ │ ├── lift.go │ │ │ │ │ │ │ ├── lvalue.go │ │ │ │ │ │ │ ├── methods.go │ │ │ │ │ │ │ ├── mode.go │ │ │ │ │ │ │ ├── print.go │ │ │ │ │ │ │ ├── sanity.go │ │ │ │ │ │ │ ├── source.go │ │ │ │ │ │ │ ├── ssa.go │ │ │ │ │ │ │ ├── ssautil │ │ │ │ │ │ │ │ ├── load.go │ │ │ │ │ │ │ │ ├── switch.go │ │ │ │ │ │ │ │ └── visit.go │ │ │ │ │ │ │ ├── testmain.go │ │ │ │ │ │ │ ├── util.go │ │ │ │ │ │ │ └── wrappers.go │ │ │ │ │ │ └── types │ │ │ │ │ │ │ └── typeutil │ │ │ │ │ │ │ ├── imports.go │ │ │ │ │ │ │ ├── map.go │ │ │ │ │ │ │ ├── methodsetcache.go │ │ │ │ │ │ │ └── ui.go │ │ │ │ │ │ └── imports │ │ │ │ │ │ ├── fastwalk.go │ │ │ │ │ │ ├── fastwalk_dirent_fileno.go │ │ │ │ │ │ ├── fastwalk_dirent_ino.go │ │ │ │ │ │ ├── fastwalk_portable.go │ │ │ │ │ │ ├── fastwalk_unix.go │ │ │ │ │ │ ├── fix.go │ │ │ │ │ │ ├── imports.go │ │ │ │ │ │ ├── mkindex.go │ │ │ │ │ │ ├── mkstdlib.go │ │ │ │ │ │ ├── sortimports.go │ │ │ │ │ │ └── zstdlib.go │ │ │ │ │ └── honnef.co │ │ │ │ │ └── go │ │ │ │ │ ├── lint │ │ │ │ │ ├── lint.go │ │ │ │ │ ├── lint16.go │ │ │ │ │ ├── lintutil │ │ │ │ │ │ └── util.go │ │ │ │ │ └── testutil │ │ │ │ │ │ └── util.go │ │ │ │ │ ├── simple │ │ │ │ │ ├── cmd │ │ │ │ │ │ └── gosimple │ │ │ │ │ │ │ └── gosimple.go │ │ │ │ │ ├── lint.go │ │ │ │ │ ├── lint17.go │ │ │ │ │ └── lint18.go │ │ │ │ │ ├── staticcheck │ │ │ │ │ ├── cmd │ │ │ │ │ │ └── staticcheck │ │ │ │ │ │ │ └── staticcheck.go │ │ │ │ │ └── lint.go │ │ │ │ │ └── unused │ │ │ │ │ ├── cmd │ │ │ │ │ └── unused │ │ │ │ │ │ └── main.go │ │ │ │ │ └── unused.go │ │ │ ├── template │ │ │ │ ├── LICENSE │ │ │ │ ├── doc.go │ │ │ │ ├── exec.go │ │ │ │ ├── funcs.go │ │ │ │ ├── helper.go │ │ │ │ ├── parse │ │ │ │ │ ├── lex.go │ │ │ │ │ ├── node.go │ │ │ │ │ └── parse.go │ │ │ │ └── template.go │ │ │ └── units │ │ │ │ ├── COPYING │ │ │ │ ├── bytes.go │ │ │ │ ├── doc.go │ │ │ │ ├── si.go │ │ │ │ └── util.go │ │ ├── google │ │ │ └── shlex │ │ │ │ ├── COPYING │ │ │ │ └── shlex.go │ │ └── stretchr │ │ │ └── testify │ │ │ ├── assert │ │ │ ├── LICENCE.txt │ │ │ ├── LICENSE │ │ │ ├── assertion_forward.go │ │ │ ├── assertions.go │ │ │ ├── doc.go │ │ │ ├── errors.go │ │ │ ├── forward_assertions.go │ │ │ └── http_assertions.go │ │ │ └── vendor │ │ │ └── github.com │ │ │ ├── davecgh │ │ │ └── go-spew │ │ │ │ └── spew │ │ │ │ ├── LICENCE.txt │ │ │ │ ├── LICENSE │ │ │ │ ├── bypass.go │ │ │ │ ├── bypasssafe.go │ │ │ │ ├── common.go │ │ │ │ ├── config.go │ │ │ │ ├── doc.go │ │ │ │ ├── dump.go │ │ │ │ ├── format.go │ │ │ │ └── spew.go │ │ │ └── pmezard │ │ │ └── go-difflib │ │ │ └── difflib │ │ │ ├── LICENCE.txt │ │ │ ├── LICENSE │ │ │ └── difflib.go │ │ └── gopkg.in │ │ └── alecthomas │ │ └── kingpin.v2 │ │ ├── COPYING │ │ ├── actions.go │ │ ├── app.go │ │ ├── args.go │ │ ├── cmd.go │ │ ├── cmd │ │ └── genvalues │ │ │ └── main.go │ │ ├── completions.go │ │ ├── doc.go │ │ ├── envar.go │ │ ├── flags.go │ │ ├── global.go │ │ ├── guesswidth.go │ │ ├── guesswidth_unix.go │ │ ├── model.go │ │ ├── parser.go │ │ ├── parsers.go │ │ ├── templates.go │ │ ├── usage.go │ │ ├── values.go │ │ └── values_generated.go ├── metalinter.go └── metalinter_test.go ├── gosimple ├── gosimple.go └── gosimple_test.go ├── gostaticcheck ├── gostaticcheck.go └── gostaticcheck_test.go ├── govet ├── govet.go └── govet_test.go ├── lint.go ├── lint_test.go ├── skip.go ├── structcheck ├── structcheck.go └── structcheck_test.go ├── testcovered.sh ├── testutil └── testutil.go ├── unused.go └── varcheck ├── varcheck.go └── varcheck_test.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | 26 | *.swp 27 | 28 | .idea 29 | *.iml 30 | 31 | out 32 | .DS_Store 33 | 34 | .ruby-version 35 | *.coverprofile 36 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.6 4 | env: 5 | global: 6 | - PATH=$HOME/gopath/bin:$PATH 7 | - secure: rJu5iwvxj/IxwSWAiB2qrAX9+Rytd4xsQFwNJlnlXBPD03T2BzaPIegUZfMVX8nYtNdmpIhAufKEDRVCmzGNWSYXe426AyReShYjZ30IROG7Ym4eB+dYZLhGi24208yt6eoq64ha25s+zNrPGRusQ0/AfLTog0Yaxp0sFLJRBGhXPG8e+10fN8w3ClnA4Xx9Hk7YWz57qyRJkPbcZw4XyybO55XlfXTrwa+JopXCO35LfzjMS5c3/ZWRR6LpLsYYo/2OTMKz6FLZRYBc0QSpgkV5P+WMpBu9MG502Ots2sDeP23oeHfEZJNHv7qCQbrrZsM/iz+2F7bOhSRzbCQr7AgeKYW+h4gRWkW5riiZ/dAQ1zmBfv4XbAxzxS1QVCvd1LtqLZBjKVXY2DbL40fjcqvzh335k0bIhRr0wGi+DOjT+6/QcxFZfPFwYbjc7Mlpbj1LPpUBasvCld8XA7kExeGsE6xdLJNcBv95fjhKas45i0H/ZTRXjtohlb169rwvQ2fInDKgLDe9l+ceWQxPSvp5svbYKqYKulPnTIDMfckoZdV2RRGl2As+X2Uy07u8SsrLEr0W71yH9go/0nKkYubrSWYQ41yVjyUDqdbS7ul7w+OeC0z0+r1PucvsdzCfHe2/idgl6zZXlHqkR/1/HJWyU9hrve8yXpKkv7iHTnw= 8 | 9 | install: 10 | - go get golang.org/x/tools/cover github.com/mattn/goveralls github.com/modocache/gover 11 | - go get -t ./... 12 | 13 | script: 14 | - ./testcovered.sh 15 | - goveralls -coverprofile=gover.coverprofile -service=travis-ci -repotoken $COVERALLS_TOKEN 16 | -------------------------------------------------------------------------------- /aligncheck/aligncheck.go: -------------------------------------------------------------------------------- 1 | // Package aligncheck provides lint integration for the aligncheck linter 2 | package aligncheck 3 | 4 | import "github.com/surullabs/lint/checkers" 5 | 6 | // Check runs the aligncheck linter (https://github.com/opennota/check) 7 | type Check struct { 8 | } 9 | 10 | // Check runs aligncheck and returns any errors found. 11 | func (c Check) Check(pkgs ...string) error { 12 | return checkers.Lint("aligncheck", 13 | "github.com/opennota/check", 14 | "github.com/opennota/check/cmd/aligncheck", pkgs) 15 | } 16 | -------------------------------------------------------------------------------- /aligncheck/aligncheck_test.go: -------------------------------------------------------------------------------- 1 | package aligncheck_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/surullabs/lint/aligncheck" 7 | "github.com/surullabs/lint/testutil" 8 | ) 9 | 10 | func TestAligncheck(t *testing.T) { 11 | testutil.Test(t, "alignchecktest", []testutil.StaticCheckTest{ 12 | { 13 | Checker: aligncheck.Check{}, 14 | Content: []byte(`package alignchecktest 15 | // TestFunc is a test function 16 | func TestFunc() { 17 | } 18 | `), 19 | Validate: testutil.NoError, 20 | }, 21 | { 22 | Checker: aligncheck.Check{}, 23 | Content: []byte(`package alignchecktest 24 | sfsff 25 | 26 | func TestFunc() { 27 | } 28 | `), 29 | Validate: testutil.Contains("expected declaration, found 'IDENT' sfsff"), 30 | }, 31 | { 32 | Checker: aligncheck.Check{}, 33 | Content: []byte(`package alignchecktest 34 | 35 | type s struct { 36 | b bool 37 | a string 38 | c int32 39 | } 40 | `), 41 | Validate: testutil.HasSuffix("struct s could have size 24 (currently 32)"), 42 | }, 43 | { 44 | Checker: aligncheck.Check{}, 45 | Content: []byte(`package alignchecktest 46 | 47 | type s struct { 48 | b bool 49 | a string 50 | c int32 51 | } 52 | `), 53 | Validate: testutil.SkippedErrors(`struct s could have size 24 \(currently 32\)`), 54 | }, 55 | }, 56 | ) 57 | } 58 | -------------------------------------------------------------------------------- /dupl/dupl.go: -------------------------------------------------------------------------------- 1 | package dupl 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "os/exec" 7 | 8 | "strconv" 9 | 10 | "regexp" 11 | "strings" 12 | 13 | "github.com/surullabs/lint" 14 | "github.com/surullabs/lint/checkers" 15 | ) 16 | 17 | // Check is implements lint.Checker for gofmt. 18 | type Check struct { 19 | Threshold int 20 | } 21 | 22 | var ( 23 | foundRE = regexp.MustCompile(`found [0-9]+ clones:`) 24 | finalRE = regexp.MustCompile(`Found total [0-9]+ clone groups.`) 25 | ) 26 | 27 | type skipFunc func(str string) bool 28 | 29 | func (s skipFunc) Skip(str string) bool { return s(str) } 30 | 31 | // SkipTwo implements Skipper and skips all duplicates having just two instances. 32 | var SkipTwo = skipFunc(func(str string) bool { 33 | return strings.HasPrefix(str, "dupl.Check: found 2 clones:") || 34 | strings.HasPrefix(str, "found 2 clones:") 35 | }) 36 | 37 | // Skip returns a Skipper which ignores the dup whose first instance ends with suffix. 38 | // 39 | // c = lint.Skip(c, Skip("lint.go:1,12")) 40 | func Skip(suffix string) lint.Skipper { 41 | return skipFunc(func(str string) bool { 42 | if !strings.Contains(str, "dupl") { 43 | return false 44 | } 45 | lines := strings.Split(str, "\n") 46 | return len(lines) > 1 && strings.HasSuffix(lines[1], suffix) 47 | }) 48 | } 49 | 50 | // Check runs 51 | // dupl 52 | // 53 | // for all files in pkgs. 54 | func (c Check) Check(pkgs ...string) error { 55 | files, err := checkers.GoFiles(pkgs...) 56 | if err != nil { 57 | return err 58 | } 59 | bin, err := checkers.InstallMissing("dupl", "github.com/mibk/dupl", "github.com/mibk/dupl") 60 | if err != nil { 61 | return err 62 | } 63 | t := c.Threshold 64 | if t == 0 { 65 | t = 15 66 | } 67 | args := append([]string{"-t", strconv.Itoa(t)}, files...) 68 | data, err := exec.Command(bin, args...).CombinedOutput() 69 | if err != nil { 70 | return fmt.Errorf("dupl failed: %v: %s", err, string(data)) 71 | } 72 | data = bytes.TrimSpace(data) 73 | loc := finalRE.FindIndex(data) 74 | if loc == nil { 75 | return fmt.Errorf("unexpected output: couldn't find final clone group line: %v", string(data)) 76 | } 77 | if loc[0] == 0 { 78 | return nil 79 | } 80 | data = data[0:loc[0]] 81 | indices := foundRE.FindAllIndex(data, -1) 82 | if indices == nil { 83 | return fmt.Errorf("%s", string(data)) 84 | } 85 | indices = append(indices, []int{len(data), len(data)}) 86 | p := -1 87 | var errs []string 88 | for _, l := range indices { 89 | if p >= 0 { 90 | errs = append(errs, string(data[p:l[0]])) 91 | } 92 | p = l[0] 93 | } 94 | return checkers.Error(errs...) 95 | } 96 | -------------------------------------------------------------------------------- /dupl/dupl_test.go: -------------------------------------------------------------------------------- 1 | package dupl_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/surullabs/lint/dupl" 7 | "github.com/surullabs/lint/testutil" 8 | ) 9 | 10 | func TestDupl(t *testing.T) { 11 | testutil.Test(t, "dupltest", []testutil.StaticCheckTest{ 12 | { 13 | Checker: dupl.Check{}, 14 | Validate: testutil.NoError, 15 | Content: []byte(`package dupltest 16 | 17 | import ( 18 | "fmt" 19 | ) 20 | 21 | func TestFunc() { 22 | fmt.Println("This is a file with no duplicates") 23 | } 24 | `), 25 | }, 26 | { 27 | Checker: dupl.Check{}, 28 | Validate: testutil.MatchesRegexp("found 2 clones:"), 29 | Content: []byte(`package dupltest 30 | 31 | import ( 32 | "fmt" 33 | ) 34 | 35 | func TestFunc() { 36 | fmt.Println("This is a duplicate string") 37 | fmt.Println("This is a duplicate string") 38 | } 39 | 40 | func TestFunc2() { 41 | fmt.Println("This is a duplicate string") 42 | fmt.Println("This is a duplicate string") 43 | } 44 | `), 45 | }, 46 | { 47 | Checker: dupl.Check{}, 48 | Content: []byte(`package dupltest 49 | 50 | blah`), 51 | Validate: testutil.Contains("expected declaration, found 'IDENT' blah"), 52 | }, 53 | }) 54 | } 55 | 56 | const expectedUnformatted = `File not formatted: diff GOFMT_TMP_FOLDER 57 | --- GOFMT_TMP_FOLDER 58 | +++ GOFMT_TMP_FOLDER 59 | @@ -5,10 +5,10 @@ 60 | ) 61 | 62 | func TestFunc() { 63 | - fmt.Println("This is a poorly formatted file") 64 | + fmt.Println("This is a poorly formatted file") 65 | } 66 | 67 | type A struct { 68 | - A string 69 | - Long string 70 | + A string 71 | + Long string 72 | }` 73 | 74 | func TestSkipTwo(t *testing.T) { 75 | testutil.TestSkips(t, []testutil.SkipTest{ 76 | {S: dupl.SkipTwo, Line: "some line", Skip: false}, 77 | {S: dupl.SkipTwo, Line: "found 2 clones: here", Skip: true}, 78 | {S: dupl.SkipTwo, Line: "checker: found 2 clones: here", Skip: false}, 79 | {S: dupl.SkipTwo, Line: "dupl.Check: found 2 clones: here", Skip: true}, 80 | }) 81 | } 82 | 83 | func TestSkip(t *testing.T) { 84 | testutil.TestSkips(t, []testutil.SkipTest{ 85 | {S: dupl.Skip("lint.go:1,12"), Line: "some line", Skip: false}, 86 | {S: dupl.Skip("lint.go:1,12"), Line: "lint.go:1,12", Skip: false}, 87 | {S: dupl.Skip("lint.go:1,12"), Line: "dupl.Check: found 2 clones: here\nlint.go:1,12", Skip: true}, 88 | }) 89 | } 90 | -------------------------------------------------------------------------------- /errcheck/errcheck.go: -------------------------------------------------------------------------------- 1 | // Package errcheck provides lint integration for the errcheck linter 2 | package errcheck 3 | 4 | import "github.com/surullabs/lint/checkers" 5 | 6 | // Check runs the errcheck linter (https://github.com/kisielk/errcheck) 7 | type Check struct { 8 | // Blank enables checking for assignments to the blank identifier 9 | Blank bool 10 | // Asserts enables checking for ignored type assertion results 11 | Assert bool 12 | // Tags is a list of space separated build tags 13 | Tags string 14 | } 15 | 16 | // Check runs errcheck and returns any errors found. 17 | func (c Check) Check(pkgs ...string) error { 18 | return checkers.Lint("errcheck", "", "github.com/kisielk/errcheck", pkgs, c.Args()...) 19 | } 20 | 21 | // Args returns command line arguments used for errcheck 22 | func (c Check) Args() []string { 23 | var args []string 24 | if c.Blank { 25 | args = append(args, "-blank") 26 | } 27 | if c.Assert { 28 | args = append(args, "-asserts") 29 | } 30 | if c.Tags != "" { 31 | args = append(args, "-tags", c.Tags) 32 | } 33 | return args 34 | } 35 | -------------------------------------------------------------------------------- /errcheck/errcheck_test.go: -------------------------------------------------------------------------------- 1 | package errcheck_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/surullabs/lint/errcheck" 7 | "github.com/surullabs/lint/testutil" 8 | ) 9 | 10 | func TestGoErrCheck(t *testing.T) { 11 | testutil.Test(t, "errchecktest", []testutil.StaticCheckTest{ 12 | { 13 | Checker: errcheck.Check{}, 14 | Content: []byte(`package errchecktest 15 | // TestFunc is a test function 16 | func TestFunc() { 17 | } 18 | `), 19 | Validate: testutil.NoError, 20 | }, 21 | { 22 | Checker: errcheck.Check{}, 23 | Content: []byte(`package errchecktest 24 | sfsff 25 | 26 | func TestFunc() { 27 | } 28 | `), 29 | Validate: testutil.Contains("expected declaration, found 'IDENT' sfsff"), 30 | }, 31 | { 32 | Checker: errcheck.Check{}, 33 | Content: []byte(`package errchecktest 34 | import ( 35 | "os" 36 | ) 37 | 38 | func TestFunc() { 39 | f, _ := os.Open("somefile") 40 | f.Close() 41 | } 42 | `), 43 | Validate: testutil.HasSuffix("f.Close()"), 44 | }, 45 | { 46 | Checker: errcheck.Check{}, 47 | Content: []byte(`package errchecktest 48 | import ( 49 | "os" 50 | ) 51 | 52 | func TestFunc() { 53 | f, _ := os.Open("somefile") 54 | f.Close() 55 | } 56 | `), 57 | Validate: testutil.SkippedErrors(`f\.Close`), 58 | }, 59 | { 60 | Checker: errcheck.Check{Assert: true}, 61 | Content: []byte(`package errchecktest 62 | 63 | func TestFunc() { 64 | var i interface{} = 1 65 | _ = i.(int) 66 | } 67 | `), 68 | Validate: testutil.Contains("_ = i.(int)"), 69 | }, 70 | }, 71 | ) 72 | } 73 | 74 | func TestGoErrCheckMultiFile(t *testing.T) { 75 | test := testutil.StaticCheckMultiFileTest{ 76 | Contents: [][]byte{ 77 | []byte(`package errchecktest 78 | 79 | func main() { 80 | f() 81 | } 82 | `), 83 | []byte(`// +build tag 84 | 85 | package errchecktest 86 | 87 | import "errors" 88 | 89 | func f() error { 90 | return errors.New("Returning error") 91 | } 92 | `), 93 | }, 94 | Checker: errcheck.Check{Tags: "tag"}, 95 | Validate: testutil.HasSuffix("f()"), 96 | } 97 | 98 | if err := test.Test("errchecktest"); err != nil { 99 | t.Error("Check", err) 100 | } 101 | } 102 | 103 | func TestArgs(t *testing.T) { 104 | testutil.TestArgs(t, []testutil.ArgTest{ 105 | {A: errcheck.Check{}, Expected: nil}, 106 | {A: errcheck.Check{Blank: true}, Expected: []string{"-blank"}}, 107 | {A: errcheck.Check{Assert: true}, Expected: []string{"-asserts"}}, 108 | {A: errcheck.Check{Tags: "test"}, Expected: []string{"-tags", "test"}}, 109 | {A: errcheck.Check{Blank: true, Assert: true}, Expected: []string{"-blank", "-asserts"}}, 110 | }) 111 | } 112 | -------------------------------------------------------------------------------- /gofmt/gofmt.go: -------------------------------------------------------------------------------- 1 | package gofmt 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "os/exec" 7 | 8 | "github.com/surullabs/lint/checkers" 9 | ) 10 | 11 | // Check is implements lint.Checker for gofmt. 12 | type Check struct { 13 | } 14 | 15 | // Check runs 16 | // gofmt -d 17 | // 18 | // for all files in pkgs. 19 | func (Check) Check(pkgs ...string) error { 20 | var errs = []string{} 21 | 22 | files, err := checkers.GoFiles(pkgs...) 23 | if err != nil { 24 | return err 25 | } 26 | 27 | for _, f := range files { 28 | data, err := exec.Command("gofmt", "-d", f).CombinedOutput() 29 | if err != nil { 30 | return fmt.Errorf("%v: %s", err, string(data)) 31 | } 32 | 33 | str := bytes.TrimSpace(data) 34 | if len(str) > 0 { 35 | errs = append(errs, fmt.Sprintf("File not formatted: %s", string(str))) 36 | } 37 | } 38 | 39 | return checkers.Error(errs...) 40 | } 41 | -------------------------------------------------------------------------------- /gofmt/gofmt_test.go: -------------------------------------------------------------------------------- 1 | package gofmt_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/surullabs/lint/gofmt" 7 | "github.com/surullabs/lint/testutil" 8 | ) 9 | 10 | func TestGoFmt(t *testing.T) { 11 | testutil.Test(t, "gofmttest", []testutil.StaticCheckTest{ 12 | { 13 | Checker: gofmt.Check{}, 14 | Content: []byte(`package gofmttest 15 | 16 | import ( 17 | "fmt" 18 | ) 19 | 20 | func TestFunc() { 21 | fmt.Println("This is a properly formatted file") 22 | } 23 | `), 24 | Validate: testutil.NoError, 25 | }, 26 | { 27 | Checker: gofmt.Check{}, 28 | Content: []byte(`package gofmttest 29 | 30 | import ( 31 | "fmt" 32 | ) 33 | 34 | func TestFunc() { 35 | fmt.Println("This is a poorly formatted file") 36 | } 37 | 38 | type A struct { 39 | A string 40 | Long string 41 | } 42 | `), 43 | Validate: testutil.MatchesRegexp("^File not formatted.*gofmttest/file.go"), 44 | }, 45 | { 46 | Checker: gofmt.Check{}, 47 | Content: []byte(`package gofmttest 48 | 49 | blah`), 50 | Validate: testutil.Contains("expected declaration, found 'IDENT' blah"), 51 | }, 52 | }) 53 | } 54 | 55 | const expectedUnformatted = `File not formatted: diff GOFMT_TMP_FOLDER 56 | --- GOFMT_TMP_FOLDER 57 | +++ GOFMT_TMP_FOLDER 58 | @@ -5,10 +5,10 @@ 59 | ) 60 | 61 | func TestFunc() { 62 | - fmt.Println("This is a poorly formatted file") 63 | + fmt.Println("This is a poorly formatted file") 64 | } 65 | 66 | type A struct { 67 | - A string 68 | - Long string 69 | + A string 70 | + Long string 71 | }` 72 | -------------------------------------------------------------------------------- /golint/golint.go: -------------------------------------------------------------------------------- 1 | package golint 2 | 3 | import "github.com/surullabs/lint/checkers" 4 | 5 | // Check implements a golint Checker 6 | type Check struct { 7 | } 8 | 9 | // Check implements lint.Checker for golint. 10 | func (Check) Check(pkgs ...string) error { 11 | return checkers.Lint("golint", "", "github.com/golang/lint/golint", pkgs) 12 | } 13 | -------------------------------------------------------------------------------- /golint/golint_test.go: -------------------------------------------------------------------------------- 1 | package golint_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/surullabs/lint/golint" 7 | "github.com/surullabs/lint/testutil" 8 | ) 9 | 10 | func TestGolint(t *testing.T) { 11 | testutil.Test(t, "golinttest", []testutil.StaticCheckTest{ 12 | { 13 | Checker: golint.Check{}, 14 | Content: []byte(`package golinttest 15 | import ( 16 | "fmt" 17 | ) 18 | 19 | // TestFunc is a test function 20 | func TestFunc() { 21 | fmt.Println("This is a properly formatted file") 22 | } 23 | `), 24 | Validate: testutil.NoError, 25 | }, 26 | { 27 | Checker: golint.Check{}, 28 | Content: []byte(`package golinttest 29 | 30 | import ( 31 | "fmt" 32 | ) 33 | sfsff 34 | 35 | func TestFunc() { 36 | fmt.Println("undocumented") 37 | } 38 | `), 39 | Validate: testutil.HasSuffix("expected declaration, found 'IDENT' sfsff"), 40 | }, 41 | { 42 | Checker: golint.Check{}, 43 | Content: []byte(`package golinttest 44 | import ( 45 | "fmt" 46 | ) 47 | 48 | func TestFunc() { 49 | fmt.Println("This is a properly formatted file") 50 | } 51 | `), 52 | Validate: testutil.HasSuffix( 53 | "file.go:6:1: exported function TestFunc should have comment or be unexported"), 54 | }, 55 | { 56 | Checker: golint.Check{}, 57 | Content: []byte(`package golinttest 58 | import ( 59 | "fmt" 60 | ) 61 | 62 | func TestFunc() { 63 | } 64 | `), 65 | Validate: testutil.SkippedErrors( 66 | `exported function TestFunc should have comment or be unexported`), 67 | }, 68 | }, 69 | ) 70 | } 71 | -------------------------------------------------------------------------------- /gometalinter/_vendored/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | pkg/ 3 | -------------------------------------------------------------------------------- /gometalinter/_vendored/manifest: -------------------------------------------------------------------------------- 1 | { 2 | "version": 0, 3 | "dependencies": [ 4 | { 5 | "importpath": "github.com/alecthomas/gometalinter", 6 | "repository": "https://github.com/alecthomas/gometalinter", 7 | "vcs": "git", 8 | "revision": "25d9c68acf628a968b546c186283c79783d601d3", 9 | "branch": "master", 10 | "notests": true 11 | }, 12 | { 13 | "importpath": "github.com/alecthomas/template", 14 | "repository": "https://github.com/alecthomas/template", 15 | "vcs": "git", 16 | "revision": "a0175ee3bccc567396460bf5acd36800cb10c49c", 17 | "branch": "master", 18 | "notests": true 19 | }, 20 | { 21 | "importpath": "github.com/alecthomas/units", 22 | "repository": "https://github.com/alecthomas/units", 23 | "vcs": "git", 24 | "revision": "2efee857e7cfd4f3d0138cc3cbb1b4966962b93a", 25 | "branch": "master", 26 | "notests": true 27 | }, 28 | { 29 | "importpath": "github.com/google/shlex", 30 | "repository": "https://github.com/google/shlex", 31 | "vcs": "git", 32 | "revision": "6f45313302b9c56850fc17f99e40caebce98c716", 33 | "branch": "master", 34 | "notests": true 35 | }, 36 | { 37 | "importpath": "github.com/stretchr/testify/assert", 38 | "repository": "https://github.com/stretchr/testify", 39 | "vcs": "git", 40 | "revision": "976c720a22c8eb4eb6a0b4348ad85ad12491a506", 41 | "branch": "master", 42 | "path": "/assert", 43 | "notests": true 44 | }, 45 | { 46 | "importpath": "github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew", 47 | "repository": "https://github.com/stretchr/testify", 48 | "vcs": "git", 49 | "revision": "976c720a22c8eb4eb6a0b4348ad85ad12491a506", 50 | "branch": "master", 51 | "path": "vendor/github.com/davecgh/go-spew/spew", 52 | "notests": true 53 | }, 54 | { 55 | "importpath": "github.com/stretchr/testify/vendor/github.com/pmezard/go-difflib/difflib", 56 | "repository": "https://github.com/stretchr/testify", 57 | "vcs": "git", 58 | "revision": "976c720a22c8eb4eb6a0b4348ad85ad12491a506", 59 | "branch": "master", 60 | "path": "vendor/github.com/pmezard/go-difflib/difflib", 61 | "notests": true 62 | }, 63 | { 64 | "importpath": "gopkg.in/alecthomas/kingpin.v2", 65 | "repository": "https://gopkg.in/alecthomas/kingpin.v2", 66 | "vcs": "git", 67 | "revision": "e9044be3ab2a8e11d4e1f418d12f0790d57e8d70", 68 | "branch": "master", 69 | "notests": true 70 | } 71 | ] 72 | } -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (C) 2012 Alec Thomas 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/aggregate.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "sort" 5 | "strings" 6 | ) 7 | 8 | type ( 9 | issueKey struct { 10 | path string 11 | line, col int 12 | message string 13 | } 14 | 15 | multiIssue struct { 16 | *Issue 17 | linterNames []string 18 | } 19 | ) 20 | 21 | func aggregateIssues(issues chan *Issue) chan *Issue { 22 | out := make(chan *Issue, 1000000) 23 | issueMap := make(map[issueKey]*multiIssue) 24 | go func() { 25 | for issue := range issues { 26 | key := issueKey{ 27 | path: issue.Path, 28 | line: issue.Line, 29 | col: issue.Col, 30 | message: issue.Message, 31 | } 32 | if existing, ok := issueMap[key]; ok { 33 | existing.linterNames = append(existing.linterNames, issue.Linter.Name) 34 | } else { 35 | issueMap[key] = &multiIssue{ 36 | Issue: issue, 37 | linterNames: []string{issue.Linter.Name}, 38 | } 39 | } 40 | } 41 | for _, multi := range issueMap { 42 | issue := multi.Issue 43 | sort.Strings(multi.linterNames) 44 | issue.Linter.Name = strings.Join(multi.linterNames, ", ") 45 | out <- issue 46 | } 47 | close(out) 48 | }() 49 | return out 50 | } 51 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/checkstyle.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/xml" 5 | "fmt" 6 | 7 | kingpin "gopkg.in/alecthomas/kingpin.v2" 8 | ) 9 | 10 | type checkstyleOutput struct { 11 | XMLName xml.Name `xml:"checkstyle"` 12 | Version string `xml:"version,attr"` 13 | Files []*checkstyleFile `xml:"file"` 14 | } 15 | 16 | type checkstyleFile struct { 17 | Name string `xml:"name,attr"` 18 | Errors []*checkstyleError `xml:"error"` 19 | } 20 | 21 | type checkstyleError struct { 22 | Column int `xml:"column,attr"` 23 | Line int `xml:"line,attr"` 24 | Message string `xml:"message,attr"` 25 | Severity string `xml:"severity,attr"` 26 | Source string `xml:"source,attr"` 27 | } 28 | 29 | func outputToCheckstyle(issues chan *Issue) int { 30 | var lastFile *checkstyleFile 31 | out := checkstyleOutput{ 32 | Version: "5.0", 33 | } 34 | status := 0 35 | for issue := range issues { 36 | if lastFile != nil && lastFile.Name != issue.Path { 37 | out.Files = append(out.Files, lastFile) 38 | lastFile = nil 39 | } 40 | if lastFile == nil { 41 | lastFile = &checkstyleFile{ 42 | Name: issue.Path, 43 | } 44 | } 45 | lastFile.Errors = append(lastFile.Errors, &checkstyleError{ 46 | Column: issue.Col, 47 | Line: issue.Line, 48 | Message: issue.Message, 49 | Severity: string(issue.Severity), 50 | Source: issue.Linter.Name, 51 | }) 52 | status = 1 53 | } 54 | if lastFile != nil { 55 | out.Files = append(out.Files, lastFile) 56 | } 57 | d, err := xml.Marshal(&out) 58 | kingpin.FatalIfError(err, "") 59 | fmt.Printf("%s%s\n", xml.Header, d) 60 | return status 61 | } 62 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/regressiontests/support.go: -------------------------------------------------------------------------------- 1 | package regressiontests 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | "os/exec" 9 | "path/filepath" 10 | "sort" 11 | "strings" 12 | "testing" 13 | 14 | "github.com/stretchr/testify/assert" 15 | ) 16 | 17 | type Issue struct { 18 | Linter string `json:"linter"` 19 | Severity string `json:"severity"` 20 | Path string `json:"path"` 21 | Line int `json:"line"` 22 | Col int `json:"col"` 23 | Message string `json:"message"` 24 | } 25 | 26 | func (i *Issue) String() string { 27 | col := "" 28 | if i.Col != 0 { 29 | col = fmt.Sprintf("%d", i.Col) 30 | } 31 | return fmt.Sprintf("%s:%d:%s:%s: %s (%s)", strings.TrimSpace(i.Path), i.Line, col, i.Severity, strings.TrimSpace(i.Message), i.Linter) 32 | } 33 | 34 | type Issues []Issue 35 | 36 | func (e Issues) Len() int { return len(e) } 37 | func (e Issues) Swap(i, j int) { e[i], e[j] = e[j], e[i] } 38 | func (e Issues) Less(i, j int) bool { return e[i].String() < e[j].String() } 39 | 40 | // ExpectIssues runs gometalinter and expects it to generate exactly the 41 | // issues provided. 42 | func ExpectIssues(t *testing.T, linter string, source string, expected Issues, extraFlags ...string) { 43 | // Write source to temporary directory. 44 | dir, err := ioutil.TempDir(".", "gometalinter-") 45 | if !assert.NoError(t, err) { 46 | return 47 | } 48 | defer os.RemoveAll(dir) 49 | w, err := os.Create(filepath.Join(dir, "test.go")) 50 | if !assert.NoError(t, err) { 51 | return 52 | } 53 | defer os.Remove(w.Name()) 54 | _, err = w.WriteString(source) 55 | _ = w.Close() 56 | if !assert.NoError(t, err) { 57 | return 58 | } 59 | 60 | // Run gometalinter. 61 | args := []string{"go", "run", "../main.go", "../checkstyle.go", "../aggregate.go", "--disable-all", "--enable", linter, "--json", dir} 62 | args = append(args, extraFlags...) 63 | cmd := exec.Command(args[0], args[1:]...) 64 | if !assert.NoError(t, err) { 65 | return 66 | } 67 | output, _ := cmd.Output() 68 | var actual Issues 69 | err = json.Unmarshal(output, &actual) 70 | if !assert.NoError(t, err) { 71 | return 72 | } 73 | 74 | // Remove output from other linters. 75 | actualForLinter := Issues{} 76 | for _, issue := range actual { 77 | if issue.Linter == linter || linter == "" { 78 | // Normalise path. 79 | issue.Path = "test.go" 80 | issue.Message = strings.Replace(issue.Message, w.Name(), "test.go", -1) 81 | issue.Message = strings.Replace(issue.Message, dir, "", -1) 82 | actualForLinter = append(actualForLinter, issue) 83 | } 84 | } 85 | sort.Sort(expected) 86 | sort.Sort(actualForLinter) 87 | 88 | assert.Equal(t, expected, actualForLinter) 89 | } 90 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/core/helpers.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package core 16 | 17 | import ( 18 | "fmt" 19 | "go/ast" 20 | "go/token" 21 | "reflect" 22 | "regexp" 23 | "strconv" 24 | "strings" 25 | ) 26 | 27 | // helpfull "canned" matching routines ---------------------------------------- 28 | 29 | func selectName(n ast.Node, s reflect.Type) (string, bool) { 30 | t := reflect.TypeOf(&ast.SelectorExpr{}) 31 | if node, ok := SimpleSelect(n, s, t).(*ast.SelectorExpr); ok { 32 | t = reflect.TypeOf(&ast.Ident{}) 33 | if ident, ok := SimpleSelect(node.X, t).(*ast.Ident); ok { 34 | return strings.Join([]string{ident.Name, node.Sel.Name}, "."), ok 35 | } 36 | } 37 | return "", false 38 | } 39 | 40 | func MatchCall(n ast.Node, r *regexp.Regexp) *ast.CallExpr { 41 | t := reflect.TypeOf(&ast.CallExpr{}) 42 | if name, ok := selectName(n, t); ok && r.MatchString(name) { 43 | return n.(*ast.CallExpr) 44 | } 45 | return nil 46 | } 47 | 48 | func MatchCompLit(n ast.Node, r *regexp.Regexp) *ast.CompositeLit { 49 | t := reflect.TypeOf(&ast.CompositeLit{}) 50 | if name, ok := selectName(n, t); ok && r.MatchString(name) { 51 | return n.(*ast.CompositeLit) 52 | } 53 | return nil 54 | } 55 | 56 | func GetInt(n ast.Node) (int64, error) { 57 | if node, ok := n.(*ast.BasicLit); ok && node.Kind == token.INT { 58 | return strconv.ParseInt(node.Value, 0, 64) 59 | } 60 | return 0, fmt.Errorf("Unexpected AST node type: %T", n) 61 | } 62 | 63 | func GetFloat(n ast.Node) (float64, error) { 64 | if node, ok := n.(*ast.BasicLit); ok && node.Kind == token.FLOAT { 65 | return strconv.ParseFloat(node.Value, 64) 66 | } 67 | return 0.0, fmt.Errorf("Unexpected AST node type: %T", n) 68 | } 69 | 70 | func GetChar(n ast.Node) (byte, error) { 71 | if node, ok := n.(*ast.BasicLit); ok && node.Kind == token.CHAR { 72 | return node.Value[0], nil 73 | } 74 | return 0, fmt.Errorf("Unexpected AST node type: %T", n) 75 | } 76 | 77 | func GetString(n ast.Node) (string, error) { 78 | if node, ok := n.(*ast.BasicLit); ok && node.Kind == token.STRING { 79 | return strconv.Unquote(node.Value) 80 | } 81 | return "", fmt.Errorf("Unexpected AST node type: %T", n) 82 | } 83 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/core/issue.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | package core 15 | 16 | import ( 17 | "encoding/json" 18 | "fmt" 19 | "go/ast" 20 | "os" 21 | ) 22 | 23 | type Score int 24 | 25 | const ( 26 | Low Score = iota 27 | Medium 28 | High 29 | ) 30 | 31 | type Issue struct { 32 | Severity Score `json:"severity"` 33 | Confidence Score `json:"confidence"` 34 | What string `json:"details"` 35 | File string `json:"file"` 36 | Code string `json:"code"` 37 | Line int `json:"line"` 38 | } 39 | 40 | type MetaData struct { 41 | Severity Score 42 | Confidence Score 43 | What string 44 | } 45 | 46 | func (c Score) MarshalJSON() ([]byte, error) { 47 | return json.Marshal(c.String()) 48 | } 49 | 50 | func (c Score) String() string { 51 | switch c { 52 | case High: 53 | return "HIGH" 54 | case Medium: 55 | return "MEDIUM" 56 | case Low: 57 | return "LOW" 58 | } 59 | return "UNDEFINED" 60 | } 61 | 62 | func codeSnippet(file *os.File, start int64, end int64, n ast.Node) (string, error) { 63 | if n == nil { 64 | return "", fmt.Errorf("Invalid AST node provided") 65 | } 66 | 67 | size := (int)(end - start) // Go bug, os.File.Read should return int64 ... 68 | file.Seek(start, 0) 69 | 70 | buf := make([]byte, size) 71 | if nread, err := file.Read(buf); err != nil || nread != size { 72 | return "", fmt.Errorf("Unable to read code") 73 | } 74 | return string(buf), nil 75 | } 76 | 77 | func NewIssue(ctx *Context, node ast.Node, desc string, severity Score, confidence Score) *Issue { 78 | var code string 79 | fobj := ctx.FileSet.File(node.Pos()) 80 | name := fobj.Name() 81 | line := fobj.Line(node.Pos()) 82 | 83 | if file, err := os.Open(fobj.Name()); err == nil { 84 | defer file.Close() 85 | s := (int64)(fobj.Position(node.Pos()).Offset) // Go bug, should be int64 86 | e := (int64)(fobj.Position(node.End()).Offset) // Go bug, should be int64 87 | code, err = codeSnippet(file, s, e, node) 88 | if err != nil { 89 | code = err.Error() 90 | } 91 | } 92 | 93 | return &Issue{ 94 | File: name, 95 | Line: line, 96 | What: desc, 97 | Confidence: confidence, 98 | Severity: severity, 99 | Code: code, 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/filelist.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import ( 18 | "os" 19 | "path" 20 | "path/filepath" 21 | "strings" 22 | ) 23 | 24 | type filelist []string 25 | 26 | func (f *filelist) String() string { 27 | return strings.Join([]string(*f), ", ") 28 | } 29 | 30 | func (f *filelist) Set(val string) error { 31 | *f = append(*f, val) 32 | return nil 33 | } 34 | 35 | func (f *filelist) Contains(pathname string) bool { 36 | 37 | // Ignore dot files 38 | _, filename := filepath.Split(pathname) 39 | if strings.HasPrefix(filename, ".") { 40 | return true 41 | } 42 | 43 | cwd, _ := os.Getwd() 44 | abs, _ := filepath.Abs(pathname) 45 | 46 | for _, pattern := range *f { 47 | 48 | // Also check working directory 49 | rel := path.Join(cwd, pattern) 50 | 51 | // Match pattern directly 52 | if matched, _ := filepath.Match(pattern, pathname); matched { 53 | return true 54 | } 55 | // Also check pattern relative to working directory 56 | if matched, _ := filepath.Match(rel, pathname); matched { 57 | return true 58 | } 59 | 60 | // Finally try absolute path 61 | st, e := os.Stat(rel) 62 | if os.IsExist(e) && st.IsDir() && strings.HasPrefix(abs, rel) { 63 | return true 64 | } 65 | 66 | } 67 | return false 68 | } 69 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/output/formatter.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package output 16 | 17 | import ( 18 | "encoding/csv" 19 | "encoding/json" 20 | "io" 21 | "strconv" 22 | "text/template" 23 | 24 | gas "github.com/HewlettPackard/gas/core" 25 | ) 26 | 27 | // The output format for reported issues 28 | type ReportFormat int 29 | 30 | const ( 31 | ReportText ReportFormat = iota // Plain text format 32 | ReportJSON // Json format 33 | ReportCSV // CSV format 34 | ) 35 | 36 | var text = `Results: 37 | {{ range $index, $issue := .Issues }} 38 | [{{ $issue.File }}:{{ $issue.Line }}] - {{ $issue.What }} (Confidence: {{ $issue.Confidence}}, Severity: {{ $issue.Severity }}) 39 | > {{ $issue.Code }} 40 | 41 | {{ end }} 42 | Summary: 43 | Files: {{.Stats.NumFiles}} 44 | Lines: {{.Stats.NumLines}} 45 | Nosec: {{.Stats.NumNosec}} 46 | Issues: {{.Stats.NumFound}} 47 | 48 | ` 49 | 50 | func CreateReport(w io.Writer, format string, data *gas.Analyzer) error { 51 | var err error 52 | switch format { 53 | case "json": 54 | err = reportJSON(w, data) 55 | case "csv": 56 | err = reportCSV(w, data) 57 | case "text": 58 | err = reportFromTemplate(w, text, data) 59 | default: 60 | err = reportFromTemplate(w, text, data) 61 | } 62 | return err 63 | } 64 | 65 | func reportJSON(w io.Writer, data *gas.Analyzer) error { 66 | raw, err := json.MarshalIndent(data, "", "\t") 67 | if err != nil { 68 | panic(err) 69 | } 70 | 71 | _, err = w.Write(raw) 72 | if err != nil { 73 | panic(err) 74 | } 75 | return err 76 | } 77 | 78 | func reportCSV(w io.Writer, data *gas.Analyzer) error { 79 | out := csv.NewWriter(w) 80 | defer out.Flush() 81 | for _, issue := range data.Issues { 82 | err := out.Write([]string{ 83 | issue.File, 84 | strconv.Itoa(issue.Line), 85 | issue.What, 86 | issue.Severity.String(), 87 | issue.Confidence.String(), 88 | issue.Code, 89 | }) 90 | if err != nil { 91 | return err 92 | } 93 | } 94 | return nil 95 | } 96 | 97 | func reportFromTemplate(w io.Writer, reportTemplate string, data *gas.Analyzer) error { 98 | t, e := template.New("gas").Parse(reportTemplate) 99 | if e != nil { 100 | return e 101 | } 102 | 103 | return t.Execute(w, data) 104 | } 105 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/rulelist.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import ( 18 | "fmt" 19 | "go/ast" 20 | "strings" 21 | 22 | gas "github.com/HewlettPackard/gas/core" 23 | "github.com/HewlettPackard/gas/rules" 24 | ) 25 | 26 | type ruleMaker func() (gas.Rule, ast.Node) 27 | type ruleConfig struct { 28 | enabled bool 29 | constructors []ruleMaker 30 | } 31 | 32 | type rulelist struct { 33 | rules map[string]*ruleConfig 34 | overwritten bool 35 | } 36 | 37 | func newRulelist() rulelist { 38 | var rs rulelist 39 | rs.rules = make(map[string]*ruleConfig) 40 | rs.overwritten = false 41 | rs.register("sql", rules.NewSqlStrConcat, rules.NewSqlStrFormat) 42 | rs.register("crypto", rules.NewImportsWeakCryptography, rules.NewUsesWeakCryptography) 43 | rs.register("hardcoded", rules.NewHardcodedCredentials) 44 | rs.register("perms", rules.NewMkdirPerms, rules.NewChmodPerms) 45 | rs.register("tempfile", rules.NewBadTempFile) 46 | rs.register("tls_good", rules.NewModernTlsCheck) 47 | rs.register("tls_ok", rules.NewIntermediateTlsCheck) 48 | rs.register("tls_old", rules.NewCompatTlsCheck) 49 | rs.register("bind", rules.NewBindsToAllNetworkInterfaces) 50 | rs.register("unsafe", rules.NewUsingUnsafe) 51 | rs.register("rsa", rules.NewWeakKeyStrength) 52 | rs.register("templates", rules.NewTemplateCheck) 53 | rs.register("exec", rules.NewSubproc) 54 | rs.register("errors", rules.NewNoErrorCheck) 55 | rs.register("httpoxy", rules.NewHttpoxyTest) 56 | rs.register("rand", rules.NewWeakRandCheck) 57 | return rs 58 | } 59 | 60 | func (r *rulelist) register(name string, cons ...ruleMaker) { 61 | r.rules[name] = &ruleConfig{false, cons} 62 | } 63 | 64 | func (r *rulelist) useDefaults() { 65 | for k := range r.rules { 66 | r.rules[k].enabled = true 67 | } 68 | } 69 | 70 | func (r *rulelist) list() []string { 71 | i := 0 72 | keys := make([]string, len(r.rules)) 73 | for k := range r.rules { 74 | keys[i] = k 75 | i++ 76 | } 77 | return keys 78 | } 79 | 80 | func (r *rulelist) apply(g *gas.Analyzer) { 81 | for _, v := range r.rules { 82 | if v.enabled { 83 | for _, ctor := range v.constructors { 84 | g.AddRule(ctor()) 85 | } 86 | } 87 | } 88 | } 89 | 90 | func (r *rulelist) String() string { 91 | return strings.Join(r.list(), ", ") 92 | } 93 | 94 | func (r *rulelist) Set(opt string) error { 95 | r.overwritten = true 96 | if x, ok := r.rules[opt]; ok { 97 | x.enabled = true 98 | return nil 99 | } 100 | return fmt.Errorf("Valid rules are: %s", r) 101 | } 102 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/rules/bind.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package rules 16 | 17 | import ( 18 | gas "github.com/HewlettPackard/gas/core" 19 | "go/ast" 20 | "regexp" 21 | ) 22 | 23 | // Looks for net.Listen("0.0.0.0") or net.Listen(":8080") 24 | type BindsToAllNetworkInterfaces struct { 25 | gas.MetaData 26 | call *regexp.Regexp 27 | pattern *regexp.Regexp 28 | } 29 | 30 | func (r *BindsToAllNetworkInterfaces) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) { 31 | if node := gas.MatchCall(n, r.call); node != nil { 32 | if arg, err := gas.GetString(node.Args[1]); err == nil { 33 | if r.pattern.MatchString(arg) { 34 | return gas.NewIssue(c, n, r.What, r.Severity, r.Confidence), nil 35 | } 36 | } 37 | } 38 | return 39 | } 40 | 41 | func NewBindsToAllNetworkInterfaces() (r gas.Rule, n ast.Node) { 42 | r = &BindsToAllNetworkInterfaces{ 43 | call: regexp.MustCompile(`^net\.Listen$`), 44 | pattern: regexp.MustCompile(`^(0.0.0.0|:).*$`), 45 | MetaData: gas.MetaData{ 46 | Severity: gas.Medium, 47 | Confidence: gas.High, 48 | What: "Binds to all network interfaces", 49 | }, 50 | } 51 | n = (*ast.CallExpr)(nil) 52 | return 53 | } 54 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/rules/errors.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package rules 16 | 17 | import ( 18 | "go/ast" 19 | "go/types" 20 | "reflect" 21 | 22 | gas "github.com/HewlettPackard/gas/core" 23 | ) 24 | 25 | type NoErrorCheck struct { 26 | gas.MetaData 27 | } 28 | 29 | func (r *NoErrorCheck) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) { 30 | if node, ok := n.(*ast.AssignStmt); ok { 31 | sel := reflect.TypeOf(&ast.CallExpr{}) 32 | if call, ok := gas.SimpleSelect(node.Rhs[0], sel).(*ast.CallExpr); ok { 33 | if t := c.Info.Types[call].Type; t != nil { 34 | if typeVal, typeErr := t.(*types.Tuple); typeErr { 35 | for i := 0; i < typeVal.Len(); i++ { 36 | if typeVal.At(i).Type().String() == "error" { // TODO(tkelsey): is there a better way? 37 | if id, ok := node.Lhs[i].(*ast.Ident); ok && id.Name == "_" { 38 | return gas.NewIssue(c, n, r.What, r.Severity, r.Confidence), nil 39 | } 40 | } 41 | } 42 | } else if t.String() == "error" { // TODO(tkelsey): is there a better way? 43 | if id, ok := node.Lhs[0].(*ast.Ident); ok && id.Name == "_" { 44 | return gas.NewIssue(c, n, r.What, r.Severity, r.Confidence), nil 45 | } 46 | } 47 | } 48 | } 49 | } 50 | return nil, nil 51 | } 52 | 53 | func NewNoErrorCheck() (r gas.Rule, n ast.Node) { 54 | r = &NoErrorCheck{ 55 | MetaData: gas.MetaData{ 56 | Severity: gas.Low, 57 | Confidence: gas.High, 58 | What: "Errors unhandled.", 59 | }, 60 | } 61 | n = (*ast.AssignStmt)(nil) 62 | return 63 | } 64 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/rules/fileperms.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package rules 16 | 17 | import ( 18 | "fmt" 19 | gas "github.com/HewlettPackard/gas/core" 20 | "go/ast" 21 | "regexp" 22 | ) 23 | 24 | type FilePermissions struct { 25 | gas.MetaData 26 | pattern *regexp.Regexp 27 | mode int64 28 | } 29 | 30 | func (r *FilePermissions) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) { 31 | if node := gas.MatchCall(n, r.pattern); node != nil { 32 | if val, err := gas.GetInt(node.Args[1]); err == nil && val > r.mode { 33 | return gas.NewIssue(c, n, r.What, r.Severity, r.Confidence), nil 34 | } 35 | } 36 | return nil, nil 37 | } 38 | 39 | func NewChmodPerms() (r gas.Rule, n ast.Node) { 40 | mode := 0600 41 | r = &FilePermissions{ 42 | pattern: regexp.MustCompile(`^os\.Chmod$`), 43 | mode: (int64)(mode), 44 | MetaData: gas.MetaData{ 45 | Severity: gas.Medium, 46 | Confidence: gas.High, 47 | What: fmt.Sprintf("Expect chmod permissions to be %#o or less", mode), 48 | }, 49 | } 50 | n = (*ast.CallExpr)(nil) 51 | return 52 | } 53 | 54 | func NewMkdirPerms() (r gas.Rule, n ast.Node) { 55 | mode := 0700 56 | r = &FilePermissions{ 57 | pattern: regexp.MustCompile(`^(os\.Mkdir|os\.MkdirAll)$`), 58 | mode: (int64)(mode), 59 | MetaData: gas.MetaData{ 60 | Severity: gas.Medium, 61 | Confidence: gas.High, 62 | What: fmt.Sprintf("Expect directory permissions to be %#o or less", mode), 63 | }, 64 | } 65 | n = (*ast.CallExpr)(nil) 66 | return 67 | } 68 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/rules/hardcoded_credentials.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package rules 16 | 17 | import ( 18 | "go/ast" 19 | "regexp" 20 | 21 | gas "github.com/HewlettPackard/gas/core" 22 | ) 23 | 24 | type CredsAssign struct { 25 | gas.MetaData 26 | pattern *regexp.Regexp 27 | } 28 | 29 | func (r *CredsAssign) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) { 30 | if node, ok := n.(*ast.AssignStmt); ok { 31 | for _, i := range node.Lhs { 32 | if ident, ok := i.(*ast.Ident); ok { 33 | if r.pattern.MatchString(ident.Name) { 34 | for _, e := range node.Rhs { 35 | if _, ok := e.(*ast.BasicLit); ok { 36 | return gas.NewIssue(c, n, r.What, r.Severity, r.Confidence), nil 37 | } 38 | } 39 | } 40 | } 41 | } 42 | } 43 | return 44 | } 45 | 46 | func NewHardcodedCredentials() (r gas.Rule, n ast.Node) { 47 | r = &CredsAssign{ 48 | pattern: regexp.MustCompile(`(?i)passwd|pass|password|pwd|secret|token`), 49 | MetaData: gas.MetaData{ 50 | What: "Potential hardcoded credentials", 51 | Confidence: gas.Low, 52 | Severity: gas.High, 53 | }, 54 | } 55 | n = (*ast.AssignStmt)(nil) 56 | return 57 | } 58 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/rules/httpoxy.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package rules 16 | 17 | import ( 18 | "go/ast" 19 | "regexp" 20 | 21 | gas "github.com/HewlettPackard/gas/core" 22 | ) 23 | 24 | // Looks for "import net/http/cgi" 25 | type HttpoxyTest struct { 26 | gas.MetaData 27 | pattern *regexp.Regexp 28 | } 29 | 30 | func (r *HttpoxyTest) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) { 31 | if node, ok := n.(*ast.ImportSpec); ok { 32 | if r.pattern.MatchString(node.Path.Value) { 33 | return gas.NewIssue(c, n, r.What, r.Severity, r.Confidence), nil 34 | } 35 | } 36 | return 37 | } 38 | 39 | func NewHttpoxyTest() (r gas.Rule, n ast.Node) { 40 | r = &HttpoxyTest{ 41 | MetaData: gas.MetaData{ 42 | Severity: gas.High, 43 | Confidence: gas.Low, 44 | What: "Go code running under CGI is vulnerable to Httpoxy attack. (CVE-2016-5386)", 45 | }, 46 | pattern: regexp.MustCompile(`^"net/http/cgi"$`), 47 | } 48 | n = (*ast.ImportSpec)(nil) 49 | return 50 | } 51 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/rules/rand.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package rules 16 | 17 | import ( 18 | "go/ast" 19 | "regexp" 20 | 21 | gas "github.com/HewlettPackard/gas/core" 22 | ) 23 | 24 | type WeakRand struct { 25 | gas.MetaData 26 | pattern *regexp.Regexp 27 | packageName string 28 | packagePath string 29 | } 30 | 31 | func (w *WeakRand) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) { 32 | if call := gas.MatchCall(n, w.pattern); call != nil { 33 | for _, pkg := range c.Pkg.Imports() { 34 | if pkg.Name() == w.packageName && pkg.Path() == w.packagePath { 35 | return gas.NewIssue(c, n, w.What, w.Severity, w.Confidence), nil 36 | } 37 | } 38 | } 39 | return nil, nil 40 | } 41 | 42 | func NewWeakRandCheck() (r gas.Rule, n ast.Node) { 43 | r = &WeakRand{ 44 | pattern: regexp.MustCompile(`^rand\.Read$`), 45 | packageName: "rand", 46 | packagePath: "math/rand", 47 | MetaData: gas.MetaData{ 48 | Severity: gas.High, 49 | Confidence: gas.Medium, 50 | What: "Use of weak random number generator (math/rand instead of crypto/rand)", 51 | }, 52 | } 53 | n = (*ast.CallExpr)(nil) 54 | return 55 | } 56 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/rules/rsa.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package rules 16 | 17 | import ( 18 | "fmt" 19 | "go/ast" 20 | "regexp" 21 | 22 | gas "github.com/HewlettPackard/gas/core" 23 | ) 24 | 25 | type WeakKeyStrength struct { 26 | gas.MetaData 27 | pattern *regexp.Regexp 28 | bits int 29 | } 30 | 31 | func (w *WeakKeyStrength) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) { 32 | if node := gas.MatchCall(n, w.pattern); node != nil { 33 | if bits, err := gas.GetInt(node.Args[1]); err == nil && bits < (int64)(w.bits) { 34 | return gas.NewIssue(c, n, w.What, w.Severity, w.Confidence), nil 35 | } 36 | } 37 | return nil, nil 38 | } 39 | 40 | func NewWeakKeyStrength() (r gas.Rule, n ast.Node) { 41 | bits := 2048 42 | r = &WeakKeyStrength{ 43 | pattern: regexp.MustCompile(`^rsa\.GenerateKey$`), 44 | bits: bits, 45 | MetaData: gas.MetaData{ 46 | Severity: gas.Medium, 47 | Confidence: gas.High, 48 | What: fmt.Sprintf("RSA keys should be at least %d bits", bits), 49 | }, 50 | } 51 | n = (*ast.CallExpr)(nil) 52 | return 53 | } 54 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/rules/sql.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package rules 16 | 17 | import ( 18 | "go/ast" 19 | "regexp" 20 | 21 | gas "github.com/HewlettPackard/gas/core" 22 | ) 23 | 24 | type SqlStatement struct { 25 | gas.MetaData 26 | pattern *regexp.Regexp 27 | } 28 | 29 | type SqlStrConcat struct { 30 | SqlStatement 31 | } 32 | 33 | // see if we can figgure out what it is 34 | func (s *SqlStrConcat) checkObject(n *ast.Ident) bool { 35 | if n.Obj != nil { 36 | return (n.Obj.Kind != ast.Var || n.Obj.Kind != ast.Fun) 37 | } 38 | return false 39 | } 40 | 41 | // Look for "SELECT * FROM table WHERE " + " ' OR 1=1" 42 | func (s *SqlStrConcat) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) { 43 | if node, ok := n.(*ast.BinaryExpr); ok { 44 | if start, ok := node.X.(*ast.BasicLit); ok { 45 | if str, _ := gas.GetString(start); s.pattern.MatchString(str) { 46 | if _, ok := node.Y.(*ast.BasicLit); ok { 47 | return nil, nil // string cat OK 48 | } 49 | if second, ok := node.Y.(*ast.Ident); ok && s.checkObject(second) { 50 | return nil, nil 51 | } 52 | return gas.NewIssue(c, n, s.What, s.Severity, s.Confidence), nil 53 | } 54 | } 55 | } 56 | return nil, nil 57 | } 58 | 59 | func NewSqlStrConcat() (r gas.Rule, n ast.Node) { 60 | r = &SqlStrConcat{ 61 | SqlStatement: SqlStatement{ 62 | pattern: regexp.MustCompile(`(?)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE) `), 63 | MetaData: gas.MetaData{ 64 | Severity: gas.Medium, 65 | Confidence: gas.High, 66 | What: "SQL string concatenation", 67 | }, 68 | }, 69 | } 70 | n = (*ast.BinaryExpr)(nil) 71 | return 72 | } 73 | 74 | type SqlStrFormat struct { 75 | SqlStatement 76 | call *regexp.Regexp 77 | } 78 | 79 | // Looks for "fmt.Sprintf("SELECT * FROM foo where '%s', userInput)" 80 | func (s *SqlStrFormat) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) { 81 | if node := gas.MatchCall(n, s.call); node != nil { 82 | if arg, _ := gas.GetString(node.Args[0]); s.pattern.MatchString(arg) { 83 | return gas.NewIssue(c, n, s.What, s.Severity, s.Confidence), nil 84 | } 85 | } 86 | return nil, nil 87 | } 88 | 89 | func NewSqlStrFormat() (r gas.Rule, n ast.Node) { 90 | r = &SqlStrFormat{ 91 | call: regexp.MustCompile(`^fmt\.Sprintf$`), 92 | SqlStatement: SqlStatement{ 93 | pattern: regexp.MustCompile("(?)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE) "), 94 | MetaData: gas.MetaData{ 95 | Severity: gas.Medium, 96 | Confidence: gas.High, 97 | What: "SQL string formatting", 98 | }, 99 | }, 100 | } 101 | n = (*ast.CallExpr)(nil) 102 | return 103 | } 104 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/rules/subproc.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package rules 16 | 17 | import ( 18 | gas "github.com/HewlettPackard/gas/core" 19 | "go/ast" 20 | "regexp" 21 | "strings" 22 | ) 23 | 24 | type Subprocess struct { 25 | pattern *regexp.Regexp 26 | } 27 | 28 | func (r *Subprocess) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) { 29 | if node := gas.MatchCall(n, r.pattern); node != nil { 30 | // call with variable command or arguments 31 | for _, arg := range node.Args { 32 | if _, test := arg.(*ast.BasicLit); !test { 33 | // TODO: try to resolve the symbol ... 34 | what := "Subprocess launching with variable." 35 | return gas.NewIssue(c, n, what, gas.High, gas.High), nil 36 | } 37 | } 38 | 39 | // call with partially qualified command 40 | if str, err := gas.GetString(node.Args[0]); err == nil { 41 | if !strings.HasPrefix(str, "/") { 42 | what := "Subprocess launching with partial path." 43 | return gas.NewIssue(c, n, what, gas.Medium, gas.High), nil 44 | } 45 | } 46 | 47 | what := "Subprocess launching should be audited." 48 | return gas.NewIssue(c, n, what, gas.Low, gas.High), nil 49 | } 50 | return nil, nil 51 | } 52 | 53 | func NewSubproc() (r gas.Rule, n ast.Node) { 54 | r = &Subprocess{ 55 | pattern: regexp.MustCompile(`^exec.Command$`), 56 | } 57 | n = (*ast.CallExpr)(nil) 58 | return 59 | } 60 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/rules/tempfiles.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package rules 16 | 17 | import ( 18 | gas "github.com/HewlettPackard/gas/core" 19 | "go/ast" 20 | "regexp" 21 | ) 22 | 23 | type BadTempFile struct { 24 | gas.MetaData 25 | args *regexp.Regexp 26 | call *regexp.Regexp 27 | } 28 | 29 | func (t *BadTempFile) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) { 30 | if node := gas.MatchCall(n, t.call); node != nil { 31 | if arg, _ := gas.GetString(node.Args[0]); t.args.MatchString(arg) { 32 | return gas.NewIssue(c, n, t.What, t.Severity, t.Confidence), nil 33 | } 34 | } 35 | return nil, nil 36 | } 37 | 38 | func NewBadTempFile() (r gas.Rule, n ast.Node) { 39 | r = &BadTempFile{ 40 | call: regexp.MustCompile(`ioutil\.WriteFile|os\.Create`), 41 | args: regexp.MustCompile(`^/tmp/.*$|^/var/tmp/.*$`), 42 | MetaData: gas.MetaData{ 43 | Severity: gas.Medium, 44 | Confidence: gas.High, 45 | What: "File creation in shared tmp directory without using ioutil.Tempfile", 46 | }, 47 | } 48 | n = (*ast.CallExpr)(nil) 49 | return 50 | } 51 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/rules/templates.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package rules 16 | 17 | import ( 18 | gas "github.com/HewlettPackard/gas/core" 19 | "go/ast" 20 | "regexp" 21 | ) 22 | 23 | type TemplateCheck struct { 24 | gas.MetaData 25 | call *regexp.Regexp 26 | } 27 | 28 | func (t *TemplateCheck) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) { 29 | if node := gas.MatchCall(n, t.call); node != nil { 30 | for _, arg := range node.Args { 31 | if _, ok := arg.(*ast.BasicLit); !ok { // basic lits are safe 32 | return gas.NewIssue(c, n, t.What, t.Severity, t.Confidence), nil 33 | } 34 | } 35 | } 36 | return nil, nil 37 | } 38 | 39 | func NewTemplateCheck() (r gas.Rule, n ast.Node) { 40 | r = &TemplateCheck{ 41 | call: regexp.MustCompile(`^template\.(HTML|JS|URL)$`), 42 | MetaData: gas.MetaData{ 43 | Severity: gas.Medium, 44 | Confidence: gas.Low, 45 | What: "this method will not auto-escape HTML. Verify data is well formed.", 46 | }, 47 | } 48 | n = (*ast.CallExpr)(nil) 49 | return 50 | } 51 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/rules/unsafe.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package rules 16 | 17 | import ( 18 | gas "github.com/HewlettPackard/gas/core" 19 | "go/ast" 20 | "regexp" 21 | ) 22 | 23 | type UsingUnsafe struct { 24 | gas.MetaData 25 | pattern *regexp.Regexp 26 | } 27 | 28 | func (r *UsingUnsafe) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) { 29 | if node := gas.MatchCall(n, r.pattern); node != nil { 30 | return gas.NewIssue(c, n, r.What, r.Severity, r.Confidence), nil 31 | } 32 | return nil, nil 33 | } 34 | 35 | func NewUsingUnsafe() (r gas.Rule, n ast.Node) { 36 | r = &UsingUnsafe{ 37 | pattern: regexp.MustCompile(`unsafe.*`), 38 | MetaData: gas.MetaData{ 39 | What: "Use of unsafe calls should be audited", 40 | Severity: gas.Low, 41 | Confidence: gas.High, 42 | }, 43 | } 44 | n = (*ast.CallExpr)(nil) 45 | return 46 | } 47 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/rules/weakcrypto.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package rules 16 | 17 | import ( 18 | gas "github.com/HewlettPackard/gas/core" 19 | "go/ast" 20 | "reflect" 21 | "regexp" 22 | ) 23 | 24 | type ImportsWeakCryptography struct { 25 | gas.MetaData 26 | pattern *regexp.Regexp 27 | } 28 | 29 | func (r *ImportsWeakCryptography) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) { 30 | a := reflect.TypeOf(&ast.ImportSpec{}) 31 | b := reflect.TypeOf(&ast.BasicLit{}) 32 | if node := gas.SimpleSelect(n, a, b); node != nil { 33 | if str, _ := gas.GetString(node); r.pattern.MatchString(str) { 34 | return gas.NewIssue(c, n, r.What, r.Severity, r.Confidence), nil 35 | } 36 | } 37 | return 38 | } 39 | 40 | // Imports crypto/md5, crypto/des crypto/rc4 41 | func NewImportsWeakCryptography() (r gas.Rule, n ast.Node) { 42 | r = &ImportsWeakCryptography{ 43 | pattern: regexp.MustCompile(`crypto/md5|crypto/des|crypto/rc4`), 44 | MetaData: gas.MetaData{ 45 | Severity: gas.Medium, 46 | Confidence: gas.High, 47 | What: "Import of weak cryptographic primitive", 48 | }, 49 | } 50 | n = (*ast.ImportSpec)(nil) 51 | return 52 | } 53 | 54 | type UsesWeakCryptography struct { 55 | gas.MetaData 56 | pattern *regexp.Regexp 57 | } 58 | 59 | func (r *UsesWeakCryptography) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) { 60 | if node := gas.MatchCall(n, r.pattern); node != nil { 61 | return gas.NewIssue(c, n, r.What, r.Severity, r.Confidence), nil 62 | } 63 | return nil, nil 64 | } 65 | 66 | // Uses des.* md5.* or rc4.* 67 | func NewUsesWeakCryptography() (r gas.Rule, n ast.Node) { 68 | r = &UsesWeakCryptography{ 69 | pattern: regexp.MustCompile(`des\.NewCipher|des\.NewTripleDESCipher|md5\.New|md5\.Sum|rc4\.NewCipher`), 70 | MetaData: gas.MetaData{ 71 | Severity: gas.Medium, 72 | Confidence: gas.High, 73 | What: "Use of weak cryptographic primitive", 74 | }, 75 | } 76 | n = (*ast.CallExpr)(nil) 77 | return 78 | } 79 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/HewlettPackard/gas/tools.go: -------------------------------------------------------------------------------- 1 | // (c) Copyright 2016 Hewlett Packard Enterprise Development LP 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import ( 18 | "fmt" 19 | "go/ast" 20 | "go/parser" 21 | "go/token" 22 | "os" 23 | "strings" 24 | ) 25 | 26 | type command func(args ...string) 27 | type utilities struct { 28 | commands map[string]command 29 | call []string 30 | } 31 | 32 | // Custom commands / utilities to run instead of default analyzer 33 | func newUtils() *utilities { 34 | utils := make(map[string]command) 35 | utils["dump"] = dumpAst 36 | return &utilities{utils, make([]string, 0)} 37 | } 38 | 39 | func (u *utilities) String() string { 40 | i := 0 41 | keys := make([]string, len(u.commands)) 42 | for k := range u.commands { 43 | keys[i] = k 44 | i++ 45 | } 46 | return strings.Join(keys, ", ") 47 | } 48 | 49 | func (u *utilities) Set(opt string) error { 50 | if _, ok := u.commands[opt]; !ok { 51 | return fmt.Errorf("valid tools are: %s", u.String()) 52 | 53 | } 54 | u.call = append(u.call, opt) 55 | return nil 56 | } 57 | 58 | func (u *utilities) run(args ...string) { 59 | for _, util := range u.call { 60 | if cmd, ok := u.commands[util]; ok { 61 | cmd(args...) 62 | } 63 | } 64 | } 65 | 66 | func dumpAst(files ...string) { 67 | for _, arg := range files { 68 | // Ensure file exists and not a directory 69 | st, e := os.Stat(arg) 70 | if e != nil { 71 | fmt.Fprintf(os.Stderr, "Skipping: %s - %s\n", arg, e) 72 | continue 73 | } 74 | if st.IsDir() { 75 | fmt.Fprintf(os.Stderr, "Skipping: %s - directory\n", arg) 76 | continue 77 | } 78 | 79 | // Create the AST by parsing src. 80 | fset := token.NewFileSet() // positions are relative to fset 81 | f, err := parser.ParseFile(fset, arg, nil, 0) 82 | if err != nil { 83 | fmt.Fprintf(os.Stderr, "Unable to parse file %s\n", err) 84 | continue 85 | } 86 | 87 | // Print the AST. 88 | ast.Print(fset, f) 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/client9/misspell/case.go: -------------------------------------------------------------------------------- 1 | package misspell 2 | 3 | import ( 4 | "strings" 5 | "unicode" 6 | ) 7 | 8 | // WordCase is an enum of various word casing styles 9 | type WordCase int 10 | 11 | // Various WordCase types.. likely to be not correct 12 | const ( 13 | AllLower WordCase = iota 14 | AllUpper 15 | Title 16 | Mixed 17 | Camel 18 | ) 19 | 20 | // CaseStyle returns what case style a word is in 21 | func CaseStyle(word string) WordCase { 22 | hasTitle := false 23 | upperCount := 0 24 | lowerCount := 0 25 | runeCount := 0 26 | 27 | // this iterates over RUNES not BYTES 28 | for _, r := range word { 29 | // ASCII apostrophe doesn't count 30 | // want words like "don't" to have 31 | // upper case forms when adding to dictionary 32 | if r == 0x0027 { 33 | continue 34 | } 35 | runeCount++ 36 | if unicode.IsLower(r) { 37 | lowerCount++ 38 | continue 39 | } 40 | if unicode.IsUpper(r) { 41 | if runeCount == 1 { 42 | hasTitle = true 43 | } 44 | upperCount++ 45 | continue 46 | } 47 | 48 | //??? 49 | } 50 | 51 | switch { 52 | case runeCount == lowerCount: 53 | return AllLower 54 | case runeCount == upperCount: 55 | return AllUpper 56 | case hasTitle && runeCount-1 == lowerCount: 57 | return Title 58 | default: 59 | return Mixed 60 | } 61 | } 62 | 63 | // CaseVariations returns 64 | // If AllUpper or First-Letter-Only is upcased: add the all upper case version 65 | // If AllLower, add the original, the title and upcase forms 66 | // If Mixed, return the original, and the all upcase form 67 | // 68 | func CaseVariations(word string, style WordCase) []string { 69 | switch style { 70 | case AllLower: 71 | return []string{word, strings.ToUpper(word[0:1]) + word[1:], strings.ToUpper(word)} 72 | case AllUpper: 73 | return []string{strings.ToUpper(word)} 74 | default: 75 | return []string{word, strings.ToUpper(word)} 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/client9/misspell/notwords.go: -------------------------------------------------------------------------------- 1 | package misspell 2 | 3 | import ( 4 | "bytes" 5 | "regexp" 6 | "strings" 7 | ) 8 | 9 | var reEmail = regexp.MustCompile(`[a-zA-Z0-9_.%+-]+@[a-zA-Z0-9-.]+\.[a-zA-Z]{2,6}[^a-zA-Z]`) 10 | var reHost = regexp.MustCompile(`[a-zA-Z0-9-.]+\.[a-zA-Z]+`) 11 | 12 | // RemovePath attempts to strip away embedded file system paths, e.g. 13 | // /foo/bar or /static/myimg.png 14 | // 15 | // TODO: windows style 16 | // 17 | func RemovePath(s string) string { 18 | out := bytes.Buffer{} 19 | var idx int 20 | for len(s) > 0 { 21 | if idx = strings.IndexByte(s, '/'); idx == -1 { 22 | out.WriteString(s) 23 | break 24 | } 25 | 26 | if idx > 0 { 27 | idx-- 28 | } 29 | 30 | var chclass string 31 | switch s[idx] { 32 | case '/', ' ', '\n', '\t', '\r': 33 | chclass = " \n\r\t" 34 | case '[': 35 | chclass = "]\n" 36 | case '(': 37 | chclass = ")\n" 38 | default: 39 | out.WriteString(s[:idx+2]) 40 | s = s[idx+2:] 41 | continue 42 | } 43 | 44 | endx := strings.IndexAny(s[idx+1:], chclass) 45 | if endx != -1 { 46 | out.WriteString(s[:idx+1]) 47 | out.Write(bytes.Repeat([]byte{' '}, endx)) 48 | s = s[idx+endx+1:] 49 | } else { 50 | out.WriteString(s) 51 | break 52 | } 53 | } 54 | return out.String() 55 | } 56 | 57 | // replaceWithBlanks returns a string with the same number of spaces as the input 58 | func replaceWithBlanks(s string) string { 59 | return strings.Repeat(" ", len(s)) 60 | } 61 | 62 | // RemoveEmail remove email-like strings, e.g. "nickg+junk@xfoobar.com", "nickg@xyz.abc123.biz" 63 | func RemoveEmail(s string) string { 64 | return reEmail.ReplaceAllStringFunc(s, replaceWithBlanks) 65 | } 66 | 67 | // RemoveHost removes host-like strings "foobar.com" "abc123.fo1231.biz" 68 | func RemoveHost(s string) string { 69 | return reHost.ReplaceAllStringFunc(s, replaceWithBlanks) 70 | } 71 | 72 | // RemoveNotWords blanks out all the not words 73 | func RemoveNotWords(s string) string { 74 | // do most selective/specific first 75 | return RemoveHost(RemoveEmail(RemovePath(StripURL(s)))) 76 | } 77 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/client9/misspell/url.go: -------------------------------------------------------------------------------- 1 | package misspell 2 | 3 | import ( 4 | "regexp" 5 | ) 6 | 7 | // Regexp for URL https://mathiasbynens.be/demo/url-regex 8 | // 9 | // original @imme_emosol (54 chars) has trouble with dashes in hostname 10 | // @(https?|ftp)://(-\.)?([^\s/?\.#-]+\.?)+(/[^\s]*)?$@iS 11 | var reURL = regexp.MustCompile(`(?i)(https?|ftp)://(-\.)?([^\s/?\.#]+\.?)+(/[^\s]*)?`) 12 | 13 | // StripURL attemps to replace URLs with blank spaces, e.g. 14 | // "xxx http://foo.com/ yyy -> "xxx yyyy" 15 | func StripURL(s string) string { 16 | return reURL.ReplaceAllStringFunc(s, replaceWithBlanks) 17 | } 18 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/kisielk/gotool/go13.go: -------------------------------------------------------------------------------- 1 | // +build !go1.4 2 | 3 | package gotool 4 | 5 | import ( 6 | "go/build" 7 | "path/filepath" 8 | "runtime" 9 | ) 10 | 11 | var gorootSrc = filepath.Join(runtime.GOROOT(), "src", "pkg") 12 | 13 | func shouldIgnoreImport(p *build.Package) bool { 14 | return true 15 | } 16 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/kisielk/gotool/go14-15.go: -------------------------------------------------------------------------------- 1 | // +build go1.4,!go1.6 2 | 3 | package gotool 4 | 5 | import ( 6 | "go/build" 7 | "path/filepath" 8 | "runtime" 9 | ) 10 | 11 | var gorootSrc = filepath.Join(runtime.GOROOT(), "src") 12 | 13 | func shouldIgnoreImport(p *build.Package) bool { 14 | return true 15 | } 16 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/kisielk/gotool/go16.go: -------------------------------------------------------------------------------- 1 | // +build go1.6 2 | 3 | package gotool 4 | 5 | import ( 6 | "go/build" 7 | "path/filepath" 8 | "runtime" 9 | ) 10 | 11 | var gorootSrc = filepath.Join(runtime.GOROOT(), "src") 12 | 13 | func shouldIgnoreImport(p *build.Package) bool { 14 | return p == nil || len(p.InvalidGoFiles) == 0 15 | } 16 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/kisielk/gotool/tool.go: -------------------------------------------------------------------------------- 1 | // Package gotool contains utility functions used to implement the standard 2 | // "cmd/go" tool, provided as a convenience to developers who want to write 3 | // tools with similar semantics. 4 | package gotool 5 | 6 | import "go/build" 7 | 8 | // Export functions here to make it easier to keep the implementations up to date with upstream. 9 | 10 | // DefaultContext is the default context that uses build.Default. 11 | var DefaultContext = Context{ 12 | BuildContext: build.Default, 13 | } 14 | 15 | // A Context specifies the supporting context. 16 | type Context struct { 17 | // BuildContext is the build.Context that is used when computing import paths. 18 | BuildContext build.Context 19 | } 20 | 21 | // ImportPaths returns the import paths to use for the given command line. 22 | // 23 | // The path "all" is expanded to all packages in $GOPATH and $GOROOT. 24 | // The path "std" is expanded to all packages in the Go standard library. 25 | // The path "cmd" is expanded to all Go standard commands. 26 | // The string "..." is treated as a wildcard within a path. 27 | // When matching recursively, directories are ignored if they are prefixed with 28 | // a dot or an underscore (such as ".foo" or "_foo"), or are named "testdata". 29 | // Relative import paths are not converted to full import paths. 30 | // If args is empty, a single element "." is returned. 31 | func (c *Context) ImportPaths(args []string) []string { 32 | return c.importPaths(args) 33 | } 34 | 35 | // ImportPaths returns the import paths to use for the given command line 36 | // using default context. 37 | // 38 | // The path "all" is expanded to all packages in $GOPATH and $GOROOT. 39 | // The path "std" is expanded to all packages in the Go standard library. 40 | // The path "cmd" is expanded to all Go standard commands. 41 | // The string "..." is treated as a wildcard within a path. 42 | // When matching recursively, directories are ignored if they are prefixed with 43 | // a dot or an underscore (such as ".foo" or "_foo"), or are named "testdata". 44 | // Relative import paths are not converted to full import paths. 45 | // If args is empty, a single element "." is returned. 46 | func ImportPaths(args []string) []string { 47 | return DefaultContext.importPaths(args) 48 | } 49 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/mibk/dupl/job/buildtree.go: -------------------------------------------------------------------------------- 1 | package job 2 | 3 | import ( 4 | "github.com/mibk/dupl/suffixtree" 5 | "github.com/mibk/dupl/syntax" 6 | ) 7 | 8 | func BuildTree(schan chan []*syntax.Node) (t *suffixtree.STree, d *[]*syntax.Node, done chan bool) { 9 | t = suffixtree.New() 10 | data := make([]*syntax.Node, 0, 100) 11 | done = make(chan bool) 12 | go func() { 13 | for seq := range schan { 14 | data = append(data, seq...) 15 | for _, node := range seq { 16 | t.Update(node) 17 | } 18 | } 19 | done <- true 20 | }() 21 | return t, &data, done 22 | } 23 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/mibk/dupl/job/parse.go: -------------------------------------------------------------------------------- 1 | package job 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/mibk/dupl/syntax" 7 | "github.com/mibk/dupl/syntax/golang" 8 | ) 9 | 10 | func Parse(fchan chan string) chan []*syntax.Node { 11 | 12 | // parse AST 13 | achan := make(chan *syntax.Node) 14 | go func() { 15 | for file := range fchan { 16 | ast, err := golang.Parse(file) 17 | if err != nil { 18 | log.Println(err) 19 | continue 20 | } 21 | achan <- ast 22 | } 23 | close(achan) 24 | }() 25 | 26 | // serialize 27 | schan := make(chan []*syntax.Node) 28 | go func() { 29 | for ast := range achan { 30 | seq := syntax.Serialize(ast) 31 | schan <- seq 32 | } 33 | close(schan) 34 | }() 35 | return schan 36 | } 37 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/mibk/dupl/output/html.go: -------------------------------------------------------------------------------- 1 | package output 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io" 7 | "regexp" 8 | "sort" 9 | 10 | "github.com/mibk/dupl/syntax" 11 | ) 12 | 13 | type HTMLPrinter struct { 14 | iota int 15 | *TextPrinter 16 | } 17 | 18 | func NewHTMLPrinter(w io.Writer, fr FileReader) *HTMLPrinter { 19 | fmt.Fprint(w, ` 20 | 21 | Duplicates 22 | 29 | `) 30 | return &HTMLPrinter{ 31 | TextPrinter: NewTextPrinter(w, fr), 32 | } 33 | } 34 | 35 | func (p *HTMLPrinter) Print(dups [][]*syntax.Node) error { 36 | p.iota++ 37 | fmt.Fprintf(p.writer, "

#%d found %d clones

\n", p.iota, len(dups)) 38 | 39 | clones := make([]clone, len(dups)) 40 | for i, dup := range dups { 41 | cnt := len(dup) 42 | if cnt == 0 { 43 | panic("zero length dup") 44 | } 45 | nstart := dup[0] 46 | nend := dup[cnt-1] 47 | 48 | file, err := p.freader.ReadFile(nstart.Filename) 49 | if err != nil { 50 | return err 51 | } 52 | 53 | lineStart, _ := blockLines(file, nstart.Pos, nend.End) 54 | cl := clone{filename: nstart.Filename, lineStart: lineStart} 55 | start := findLineBeg(file, nstart.Pos) 56 | content := append(toWhitespace(file[start:nstart.Pos]), file[nstart.Pos:nend.End]...) 57 | cl.fragment = deindent(content) 58 | clones[i] = cl 59 | } 60 | 61 | sort.Sort(byNameAndLine(clones)) 62 | for _, cl := range clones { 63 | fmt.Fprintf(p.writer, "

%s:%d

\n
%s
\n", cl.filename, cl.lineStart, cl.fragment) 64 | } 65 | return nil 66 | } 67 | 68 | func (*HTMLPrinter) Finish() {} 69 | 70 | func findLineBeg(file []byte, index int) int { 71 | for i := index; i >= 0; i-- { 72 | if file[i] == '\n' { 73 | return i + 1 74 | } 75 | } 76 | return 0 77 | } 78 | 79 | func toWhitespace(str []byte) []byte { 80 | var out []byte 81 | for _, c := range bytes.Runes(str) { 82 | if c == '\t' { 83 | out = append(out, '\t') 84 | } else { 85 | out = append(out, ' ') 86 | } 87 | } 88 | return out 89 | } 90 | 91 | func deindent(block []byte) []byte { 92 | const maxVal = 99 93 | min := maxVal 94 | re := regexp.MustCompile(`(^|\n)(\t*)\S`) 95 | for _, line := range re.FindAllSubmatch(block, -1) { 96 | indent := line[2] 97 | if len(indent) < min { 98 | min = len(indent) 99 | } 100 | } 101 | if min == 0 || min == maxVal { 102 | return block 103 | } 104 | block = block[min:] 105 | Loop: 106 | for i := 0; i < len(block); i++ { 107 | if block[i] == '\n' && i != len(block)-1 { 108 | for j := 0; j < min; j++ { 109 | if block[i+j+1] != '\t' { 110 | continue Loop 111 | } 112 | } 113 | block = append(block[:i+1], block[i+1+min:]...) 114 | } 115 | } 116 | return block 117 | } 118 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/mibk/dupl/output/plumbing.go: -------------------------------------------------------------------------------- 1 | package output 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "sort" 7 | 8 | "github.com/mibk/dupl/syntax" 9 | ) 10 | 11 | type PlumbingPrinter struct { 12 | *TextPrinter 13 | } 14 | 15 | func NewPlumbingPrinter(w io.Writer, fr FileReader) *PlumbingPrinter { 16 | return &PlumbingPrinter{NewTextPrinter(w, fr)} 17 | } 18 | 19 | func (p *PlumbingPrinter) Print(dups [][]*syntax.Node) error { 20 | clones, err := p.prepareClonesInfo(dups) 21 | if err != nil { 22 | return err 23 | } 24 | sort.Sort(byNameAndLine(clones)) 25 | for i, cl := range clones { 26 | nextCl := clones[(i+1)%len(clones)] 27 | fmt.Fprintf(p.writer, "%s:%d-%d: duplicate of %s:%d-%d\n", cl.filename, cl.lineStart, cl.lineEnd, 28 | nextCl.filename, nextCl.lineStart, nextCl.lineEnd) 29 | } 30 | return nil 31 | } 32 | 33 | func (p *PlumbingPrinter) Finish() {} 34 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/mibk/dupl/output/text.go: -------------------------------------------------------------------------------- 1 | package output 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "sort" 7 | 8 | "github.com/mibk/dupl/syntax" 9 | ) 10 | 11 | type FileReader interface { 12 | ReadFile(filename string) ([]byte, error) 13 | } 14 | 15 | type Printer interface { 16 | Print(dups [][]*syntax.Node) error 17 | Finish() 18 | } 19 | 20 | type TextPrinter struct { 21 | writer io.Writer 22 | freader FileReader 23 | cnt int 24 | } 25 | 26 | func NewTextPrinter(w io.Writer, fr FileReader) *TextPrinter { 27 | return &TextPrinter{ 28 | writer: w, 29 | freader: fr, 30 | } 31 | } 32 | 33 | func (p *TextPrinter) Print(dups [][]*syntax.Node) error { 34 | p.cnt++ 35 | fmt.Fprintf(p.writer, "found %d clones:\n", len(dups)) 36 | clones, err := p.prepareClonesInfo(dups) 37 | if err != nil { 38 | return err 39 | } 40 | sort.Sort(byNameAndLine(clones)) 41 | for _, cl := range clones { 42 | fmt.Fprintf(p.writer, " %s:%d,%d\n", cl.filename, cl.lineStart, cl.lineEnd) 43 | } 44 | return nil 45 | } 46 | 47 | func (p *TextPrinter) prepareClonesInfo(dups [][]*syntax.Node) ([]clone, error) { 48 | clones := make([]clone, len(dups)) 49 | for i, dup := range dups { 50 | cnt := len(dup) 51 | if cnt == 0 { 52 | panic("zero length dup") 53 | } 54 | nstart := dup[0] 55 | nend := dup[cnt-1] 56 | 57 | file, err := p.freader.ReadFile(nstart.Filename) 58 | if err != nil { 59 | return nil, err 60 | } 61 | 62 | cl := clone{filename: nstart.Filename} 63 | cl.lineStart, cl.lineEnd = blockLines(file, nstart.Pos, nend.End) 64 | clones[i] = cl 65 | } 66 | return clones, nil 67 | } 68 | 69 | func (p *TextPrinter) Finish() { 70 | fmt.Fprintf(p.writer, "\nFound total %d clone groups.\n", p.cnt) 71 | } 72 | 73 | func blockLines(file []byte, from, to int) (int, int) { 74 | line := 1 75 | lineStart, lineEnd := 0, 0 76 | for offset, b := range file { 77 | if b == '\n' { 78 | line++ 79 | } 80 | if offset == from { 81 | lineStart = line 82 | } 83 | if offset == to-1 { 84 | lineEnd = line 85 | break 86 | } 87 | } 88 | return lineStart, lineEnd 89 | } 90 | 91 | type clone struct { 92 | filename string 93 | lineStart int 94 | lineEnd int 95 | fragment []byte 96 | } 97 | 98 | type byNameAndLine []clone 99 | 100 | func (c byNameAndLine) Len() int { return len(c) } 101 | 102 | func (c byNameAndLine) Swap(i, j int) { c[i], c[j] = c[j], c[i] } 103 | 104 | func (c byNameAndLine) Less(i, j int) bool { 105 | if c[i].filename == c[j].filename { 106 | return c[i].lineStart < c[j].lineStart 107 | } 108 | return c[i].filename < c[j].filename 109 | } 110 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/mibk/dupl/suffixtree/dupl.go: -------------------------------------------------------------------------------- 1 | package suffixtree 2 | 3 | import "sort" 4 | 5 | type Match struct { 6 | Ps []Pos 7 | Len Pos 8 | } 9 | 10 | type posList struct { 11 | positions []Pos 12 | } 13 | 14 | func newPosList() *posList { 15 | return &posList{make([]Pos, 0)} 16 | } 17 | 18 | func (p *posList) append(p2 *posList) { 19 | p.positions = append(p.positions, p2.positions...) 20 | } 21 | 22 | func (p *posList) add(pos Pos) { 23 | p.positions = append(p.positions, pos) 24 | } 25 | 26 | type contextList struct { 27 | lists map[int]*posList 28 | } 29 | 30 | func newContextList() *contextList { 31 | return &contextList{make(map[int]*posList)} 32 | } 33 | 34 | func (c *contextList) getAll() []Pos { 35 | keys := make([]int, 0, len(c.lists)) 36 | for k := range c.lists { 37 | keys = append(keys, k) 38 | } 39 | sort.Ints(keys) 40 | var ps []Pos 41 | for _, k := range keys { 42 | ps = append(ps, c.lists[k].positions...) 43 | } 44 | return ps 45 | } 46 | 47 | func (c *contextList) append(c2 *contextList) { 48 | for lc, pl := range c2.lists { 49 | if _, ok := c.lists[lc]; ok { 50 | c.lists[lc].append(pl) 51 | } else { 52 | c.lists[lc] = pl 53 | } 54 | } 55 | } 56 | 57 | // FindDuplOver find pairs of maximal duplicities over a threshold 58 | // length. 59 | func (t *STree) FindDuplOver(threshold int) <-chan Match { 60 | auxTran := newTran(0, 0, t.root) 61 | ch := make(chan Match) 62 | go func() { 63 | walkTrans(auxTran, 0, threshold, ch) 64 | close(ch) 65 | }() 66 | return ch 67 | } 68 | 69 | func walkTrans(parent *tran, length, threshold int, ch chan<- Match) *contextList { 70 | s := parent.state 71 | 72 | cl := newContextList() 73 | 74 | if len(s.trans) == 0 { 75 | pl := newPosList() 76 | start := parent.end + 1 - Pos(length) 77 | pl.add(start) 78 | ch := 0 79 | if start > 0 { 80 | ch = s.tree.data[start-1].Val() 81 | } 82 | cl.lists[ch] = pl 83 | return cl 84 | } 85 | 86 | for _, t := range s.trans { 87 | ln := length + t.len() 88 | cl2 := walkTrans(t, ln, threshold, ch) 89 | if ln >= threshold { 90 | cl.append(cl2) 91 | } 92 | } 93 | if length >= threshold && len(cl.lists) > 1 { 94 | m := Match{cl.getAll(), Pos(length)} 95 | ch <- m 96 | } 97 | return cl 98 | } 99 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/mvdan/interfacer/cache.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015, Daniel Martí 2 | // See LICENSE for licensing information 3 | 4 | package interfacer 5 | 6 | import ( 7 | "go/types" 8 | 9 | "golang.org/x/tools/go/loader" 10 | 11 | "github.com/mvdan/interfacer/internal/util" 12 | ) 13 | 14 | //go:generate sh -c "go list std | go run generate/std/main.go -o std.go" 15 | //go:generate gofmt -w -s std.go 16 | 17 | type cache struct { 18 | loader.Config 19 | 20 | cur pkgCache 21 | 22 | grabbed map[string]pkgCache 23 | } 24 | 25 | type pkgCache struct { 26 | exp, unexp typeSet 27 | } 28 | 29 | type typeSet struct { 30 | ifaces map[string]string 31 | funcs map[string]string 32 | } 33 | 34 | func newCache() *cache { 35 | c := &cache{ 36 | grabbed: make(map[string]pkgCache), 37 | } 38 | c.AllowErrors = true 39 | c.TypeChecker.Error = func(e error) {} 40 | c.TypeChecker.DisableUnusedImportCheck = true 41 | c.TypeCheckFuncBodies = func(path string) bool { 42 | _, e := stdPkgs[path] 43 | return !e 44 | } 45 | return c 46 | } 47 | 48 | func (c *cache) funcOf(t string) string { 49 | if s := stdFuncs[t]; s != "" { 50 | return s 51 | } 52 | if s := c.cur.exp.funcs[t]; s != "" { 53 | return s 54 | } 55 | return c.cur.unexp.funcs[t] 56 | } 57 | 58 | func (c *cache) ifaceOf(t string) string { 59 | if s := stdIfaces[t]; s != "" { 60 | return s 61 | } 62 | if s := c.cur.exp.ifaces[t]; s != "" { 63 | return s 64 | } 65 | return c.cur.unexp.ifaces[t] 66 | } 67 | 68 | func (c *cache) grabNames(pkg *types.Package) { 69 | c.fillCache(pkg) 70 | c.cur = c.grabbed[pkg.Path()] 71 | } 72 | 73 | func (c *cache) fillCache(pkg *types.Package) { 74 | path := pkg.Path() 75 | if _, e := stdPkgs[path]; e { 76 | return 77 | } 78 | if _, e := c.grabbed[path]; e { 79 | return 80 | } 81 | for _, imp := range pkg.Imports() { 82 | c.fillCache(imp) 83 | } 84 | cur := pkgCache{ 85 | exp: typeSet{ 86 | ifaces: make(map[string]string), 87 | funcs: make(map[string]string), 88 | }, 89 | unexp: typeSet{ 90 | ifaces: make(map[string]string), 91 | funcs: make(map[string]string), 92 | }, 93 | } 94 | addTypes := func(impPath string, ifs, funs map[string]string, top bool) { 95 | fullName := func(name string) string { 96 | if !top { 97 | return impPath + "." + name 98 | } 99 | return name 100 | } 101 | for iftype, name := range ifs { 102 | if _, e := stdIfaces[iftype]; e { 103 | continue 104 | } 105 | if util.Exported(name) { 106 | cur.exp.ifaces[iftype] = fullName(name) 107 | } 108 | } 109 | for ftype, name := range funs { 110 | if _, e := stdFuncs[ftype]; e { 111 | continue 112 | } 113 | if !util.Exported(name) { 114 | cur.unexp.funcs[ftype] = fullName(name) 115 | } else { 116 | cur.exp.funcs[ftype] = fullName(name) 117 | } 118 | } 119 | } 120 | for _, imp := range pkg.Imports() { 121 | pc := c.grabbed[imp.Path()] 122 | addTypes(imp.Path(), pc.exp.ifaces, pc.exp.funcs, false) 123 | } 124 | ifs, funs := FromScope(pkg.Scope()) 125 | addTypes(path, ifs, funs, true) 126 | c.grabbed[path] = cur 127 | } 128 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/mvdan/interfacer/cmd/interfacer/main.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015, Daniel Martí 2 | // See LICENSE for licensing information 3 | 4 | package main 5 | 6 | import ( 7 | "flag" 8 | "fmt" 9 | "os" 10 | 11 | "github.com/mvdan/interfacer" 12 | ) 13 | 14 | var ( 15 | verbose = flag.Bool("v", false, "print the names of packages as they are checked") 16 | ) 17 | 18 | func main() { 19 | flag.Parse() 20 | if err := interfacer.CheckArgsOutput(flag.Args(), os.Stdout, *verbose); err != nil { 21 | errExit(err) 22 | } 23 | } 24 | 25 | func errExit(err error) { 26 | fmt.Fprintf(os.Stderr, "%v\n", err) 27 | os.Exit(1) 28 | } 29 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/mvdan/interfacer/internal/util/util.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015, Daniel Martí 2 | // See LICENSE for licensing information 3 | 4 | package util 5 | 6 | import ( 7 | "unicode" 8 | "unicode/utf8" 9 | ) 10 | 11 | type ByAlph []string 12 | 13 | func (l ByAlph) Len() int { return len(l) } 14 | func (l ByAlph) Less(i, j int) bool { return l[i] < l[j] } 15 | func (l ByAlph) Swap(i, j int) { l[i], l[j] = l[j], l[i] } 16 | 17 | func Exported(name string) bool { 18 | ch, _ := utf8.DecodeRuneInString(name) 19 | return unicode.IsUpper(ch) 20 | } 21 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/opennota/check/cmd/aligncheck/aligncheck.go: -------------------------------------------------------------------------------- 1 | // This program is free software: you can redistribute it and/or modify 2 | // it under the terms of the GNU General Public License as published by 3 | // the Free Software Foundation, either version 3 of the License, or 4 | // (at your option) any later version. 5 | // 6 | // This program is distributed in the hope that it will be useful, 7 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | // GNU General Public License for more details. 10 | // 11 | // You should have received a copy of the GNU General Public License 12 | // along with this program. If not, see . 13 | 14 | package main 15 | 16 | import ( 17 | "flag" 18 | "fmt" 19 | "go/build" 20 | "log" 21 | "os" 22 | "sort" 23 | "unsafe" 24 | 25 | "github.com/kisielk/gotool" 26 | "go/types" 27 | "golang.org/x/tools/go/loader" 28 | ) 29 | 30 | var stdSizes = types.StdSizes{ 31 | WordSize: int64(unsafe.Sizeof(int(0))), 32 | MaxAlign: 8, 33 | } 34 | 35 | func main() { 36 | flag.Parse() 37 | exitStatus := 0 38 | 39 | importPaths := gotool.ImportPaths(flag.Args()) 40 | if len(importPaths) == 0 { 41 | importPaths = []string{"."} 42 | } 43 | 44 | ctx := build.Default 45 | loadcfg := loader.Config{ 46 | Build: &ctx, 47 | } 48 | rest, err := loadcfg.FromArgs(importPaths, false) 49 | if err != nil { 50 | log.Fatalf("could not parse arguments: %s", err) 51 | } 52 | if len(rest) > 0 { 53 | log.Fatalf("unhandled extra arguments: %v", rest) 54 | } 55 | 56 | program, err := loadcfg.Load() 57 | if err != nil { 58 | log.Fatalf("could not type check: %s", err) 59 | } 60 | 61 | var lines []string 62 | 63 | for _, pkgInfo := range program.InitialPackages() { 64 | for _, obj := range pkgInfo.Defs { 65 | if obj == nil { 66 | continue 67 | } 68 | 69 | if _, ok := obj.(*types.TypeName); !ok { 70 | continue 71 | } 72 | 73 | typ, ok := obj.Type().(*types.Named) 74 | if !ok { 75 | continue 76 | } 77 | 78 | strukt, ok := typ.Underlying().(*types.Struct) 79 | if !ok { 80 | continue 81 | } 82 | 83 | structAlign := int(stdSizes.Alignof(strukt)) 84 | structSize := int(stdSizes.Sizeof(strukt)) 85 | if structSize%structAlign != 0 { 86 | structSize += structAlign - structSize%structAlign 87 | } 88 | 89 | minSize := 0 90 | for i := 0; i < strukt.NumFields(); i++ { 91 | field := strukt.Field(i) 92 | fieldType := field.Type() 93 | typeSize := int(stdSizes.Sizeof(fieldType)) 94 | minSize += typeSize 95 | } 96 | if minSize%structAlign != 0 { 97 | minSize += structAlign - minSize%structAlign 98 | } 99 | 100 | if minSize != structSize { 101 | pos := program.Fset.Position(obj.Pos()) 102 | lines = append(lines, fmt.Sprintf( 103 | "%s: %s:%d:%d: struct %s could have size %d (currently %d)", 104 | obj.Pkg().Path(), 105 | pos.Filename, 106 | pos.Line, 107 | pos.Column, 108 | obj.Name(), 109 | minSize, 110 | structSize, 111 | )) 112 | exitStatus = 1 113 | } 114 | } 115 | } 116 | 117 | sort.Strings(lines) 118 | for _, line := range lines { 119 | fmt.Println(line) 120 | } 121 | 122 | os.Exit(exitStatus) 123 | } 124 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/walle/lll/cmd/lll/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "path/filepath" 8 | "regexp" 9 | 10 | "github.com/alexflint/go-arg" 11 | 12 | "github.com/walle/lll" 13 | ) 14 | 15 | var args struct { 16 | MaxLength int `arg:"-l,env,help:max line length to check for"` 17 | TabWidth int `arg:"-w,env,help:tab width in spaces"` 18 | GoOnly bool `arg:"-g,env,help:only check .go files"` 19 | Input []string `arg:"positional"` 20 | SkipList []string `arg:"-s,env,help:list of dirs to skip"` 21 | Vendor bool `arg:"env,help:check files in vendor directory"` 22 | Files bool `arg:"help:read file names from stdin one at each line"` 23 | Exclude string `arg:"-e,env,help:exclude lines that matches this regex"` 24 | } 25 | 26 | func main() { 27 | args.MaxLength = 80 28 | args.TabWidth = 1 29 | args.SkipList = []string{".git", "vendor"} 30 | arg.MustParse(&args) 31 | 32 | var exclude *regexp.Regexp 33 | if args.Exclude != "" { 34 | e, err := regexp.Compile(args.Exclude) 35 | if err != nil { 36 | fmt.Fprintf(os.Stderr, "Error compiling exclude regexp: %s\n", err) 37 | os.Exit(1) 38 | } 39 | exclude = e 40 | } 41 | 42 | // If we should include the vendor dir, attempt to remove it from the skip list 43 | if args.Vendor { 44 | for i, p := range args.SkipList { 45 | if p == "vendor" { 46 | args.SkipList = append(args.SkipList[:i], args.SkipList[:i]...) 47 | } 48 | } 49 | } 50 | 51 | // If we should read files from stdin, read each line and process the file 52 | if args.Files { 53 | s := bufio.NewScanner(os.Stdin) 54 | for s.Scan() { 55 | err := lll.ProcessFile(os.Stdout, s.Text(), 56 | args.MaxLength, args.TabWidth, exclude) 57 | if err != nil { 58 | fmt.Fprintf(os.Stderr, "Error processing file: %s\n", err) 59 | } 60 | } 61 | os.Exit(0) 62 | } 63 | 64 | // Otherwise, walk the inputs recursively 65 | for _, d := range args.Input { 66 | err := filepath.Walk(d, func(p string, i os.FileInfo, e error) error { 67 | if i == nil { 68 | fmt.Fprintf(os.Stderr, "lll: %s no such file or directory\n", p) 69 | return nil 70 | } 71 | if e != nil { 72 | fmt.Fprintf(os.Stderr, "lll: %s\n", e) 73 | return nil 74 | } 75 | skip, ret := lll.ShouldSkip(p, i.IsDir(), args.SkipList, args.GoOnly) 76 | if skip { 77 | return ret 78 | } 79 | 80 | err := lll.ProcessFile(os.Stdout, p, args.MaxLength, args.TabWidth, exclude) 81 | return err 82 | }) 83 | 84 | if err != nil { 85 | fmt.Fprintf(os.Stderr, "Error walking the file system: %s\n", err) 86 | os.Exit(1) 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/walle/lll/lll.go: -------------------------------------------------------------------------------- 1 | // Package lll provides validation functions regarding line length 2 | package lll 3 | 4 | import ( 5 | "bufio" 6 | "fmt" 7 | "io" 8 | "io/ioutil" 9 | "net/http" 10 | "os" 11 | "path/filepath" 12 | "regexp" 13 | "strings" 14 | "unicode/utf8" 15 | ) 16 | 17 | // ShouldSkip checks the input and determines if the path should be skipped. 18 | // Use the SkipList to quickly skip paths. 19 | // All directories are skipped, only files are processed. 20 | // If GoOnly is supplied check that the file is a go file. 21 | // Otherwise check so the file is a "text file". 22 | func ShouldSkip(path string, isDir bool, skipList []string, 23 | goOnly bool) (bool, error) { 24 | 25 | name := filepath.Base(path) 26 | for _, d := range skipList { 27 | if name == d { 28 | if isDir { 29 | return true, filepath.SkipDir 30 | } 31 | return true, nil 32 | } 33 | } 34 | if isDir { 35 | return true, nil 36 | } 37 | 38 | if goOnly { 39 | if !strings.HasSuffix(path, ".go") { 40 | return true, nil 41 | } 42 | } else { 43 | b, err := ioutil.ReadFile(path) 44 | if err != nil { 45 | return true, err 46 | } 47 | m := http.DetectContentType(b) 48 | if !strings.Contains(m, "text/") { 49 | return true, nil 50 | } 51 | } 52 | 53 | return false, nil 54 | } 55 | 56 | // ProcessFile checks all lines in the file and writes an error if the line 57 | // length is greater than MaxLength. 58 | func ProcessFile(w io.Writer, path string, maxLength, tabWidth int, 59 | exclude *regexp.Regexp) error { 60 | f, err := os.Open(path) 61 | if err != nil { 62 | return err 63 | } 64 | defer func() { 65 | err := f.Close() 66 | if err != nil { 67 | fmt.Printf("Error closing file: %s\n", err) 68 | } 69 | }() 70 | 71 | return Process(f, w, path, maxLength, tabWidth, exclude) 72 | } 73 | 74 | // Process checks all lines in the reader and writes an error if the line length 75 | // is greater than MaxLength. 76 | func Process(r io.Reader, w io.Writer, path string, maxLength, tabWidth int, 77 | exclude *regexp.Regexp) error { 78 | spaces := strings.Repeat(" ", tabWidth) 79 | l := 1 80 | s := bufio.NewScanner(r) 81 | for s.Scan() { 82 | t := s.Text() 83 | t = strings.Replace(t, "\t", spaces, -1) 84 | c := utf8.RuneCountInString(t) 85 | if c > maxLength { 86 | if exclude != nil { 87 | if exclude.MatchString(t) { 88 | continue 89 | } 90 | } 91 | fmt.Fprintf(w, "%s:%d: line is %d characters\n", path, l, c) 92 | } 93 | l++ 94 | } 95 | 96 | if err := s.Err(); err != nil { 97 | return err 98 | } 99 | 100 | return nil 101 | } 102 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/github.com/walle/lll/vendor/github.com/alexflint/go-arg/doc.go: -------------------------------------------------------------------------------- 1 | // Package arg parses command line arguments using the fields from a struct. 2 | // 3 | // For example, 4 | // 5 | // var args struct { 6 | // Iter int 7 | // Debug bool 8 | // } 9 | // arg.MustParse(&args) 10 | // 11 | // defines two command line arguments, which can be set using any of 12 | // 13 | // ./example --iter=1 --debug // debug is a boolean flag so its value is set to true 14 | // ./example -iter 1 // debug defaults to its zero value (false) 15 | // ./example --debug=true // iter defaults to its zero value (zero) 16 | // 17 | // The fastest way to see how to use go-arg is to read the examples below. 18 | // 19 | // Fields can be bool, string, any float type, or any signed or unsigned integer type. 20 | // They can also be slices of any of the above, or slices of pointers to any of the above. 21 | // 22 | // Tags can be specified using the `arg` package name: 23 | // 24 | // var args struct { 25 | // Input string `arg:"positional"` 26 | // Log string `arg:"positional,required"` 27 | // Debug bool `arg:"-d,help:turn on debug mode"` 28 | // RealMode bool `arg:"--real" 29 | // Wr io.Writer `arg:"-"` 30 | // } 31 | // 32 | // The valid tag strings are `positional`, `required`, and `help`. Further, any tag string 33 | // that starts with a single hyphen is the short form for an argument (e.g. `./example -d`), 34 | // and any tag string that starts with two hyphens is the long form for the argument 35 | // (instead of the field name). Fields can be excluded from processing with `arg:"-"`. 36 | package arg 37 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/text/internal/triegen/compact.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package triegen 6 | 7 | // This file defines Compacter and its implementations. 8 | 9 | import "io" 10 | 11 | // A Compacter generates an alternative, more space-efficient way to store a 12 | // trie value block. A trie value block holds all possible values for the last 13 | // byte of a UTF-8 encoded rune. Excluding ASCII characters, a trie value block 14 | // always has 64 values, as a UTF-8 encoding ends with a byte in [0x80, 0xC0). 15 | type Compacter interface { 16 | // Size returns whether the Compacter could encode the given block as well 17 | // as its size in case it can. len(v) is always 64. 18 | Size(v []uint64) (sz int, ok bool) 19 | 20 | // Store stores the block using the Compacter's compression method. 21 | // It returns a handle with which the block can be retrieved. 22 | // len(v) is always 64. 23 | Store(v []uint64) uint32 24 | 25 | // Print writes the data structures associated to the given store to w. 26 | Print(w io.Writer) error 27 | 28 | // Handler returns the name of a function that gets called during trie 29 | // lookup for blocks generated by the Compacter. The function should be of 30 | // the form func (n uint32, b byte) uint64, where n is the index returned by 31 | // the Compacter's Store method and b is the last byte of the UTF-8 32 | // encoding, where 0x80 <= b < 0xC0, for which to do the lookup in the 33 | // block. 34 | Handler() string 35 | } 36 | 37 | // simpleCompacter is the default Compacter used by builder. It implements a 38 | // normal trie block. 39 | type simpleCompacter builder 40 | 41 | func (b *simpleCompacter) Size([]uint64) (sz int, ok bool) { 42 | return blockSize * b.ValueSize, true 43 | } 44 | 45 | func (b *simpleCompacter) Store(v []uint64) uint32 { 46 | h := uint32(len(b.ValueBlocks) - blockOffset) 47 | b.ValueBlocks = append(b.ValueBlocks, v) 48 | return h 49 | } 50 | 51 | func (b *simpleCompacter) Print(io.Writer) error { 52 | // Structures are printed in print.go. 53 | return nil 54 | } 55 | 56 | func (b *simpleCompacter) Handler() string { 57 | panic("Handler should be special-cased for this Compacter") 58 | } 59 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/text/unicode/cldr/base.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cldr 6 | 7 | import ( 8 | "encoding/xml" 9 | "regexp" 10 | "strconv" 11 | ) 12 | 13 | // Elem is implemented by every XML element. 14 | type Elem interface { 15 | setEnclosing(Elem) 16 | setName(string) 17 | enclosing() Elem 18 | 19 | GetCommon() *Common 20 | } 21 | 22 | type hidden struct { 23 | CharData string `xml:",chardata"` 24 | Alias *struct { 25 | Common 26 | Source string `xml:"source,attr"` 27 | Path string `xml:"path,attr"` 28 | } `xml:"alias"` 29 | Def *struct { 30 | Common 31 | Choice string `xml:"choice,attr,omitempty"` 32 | Type string `xml:"type,attr,omitempty"` 33 | } `xml:"default"` 34 | } 35 | 36 | // Common holds several of the most common attributes and sub elements 37 | // of an XML element. 38 | type Common struct { 39 | XMLName xml.Name 40 | name string 41 | enclElem Elem 42 | Type string `xml:"type,attr,omitempty"` 43 | Reference string `xml:"reference,attr,omitempty"` 44 | Alt string `xml:"alt,attr,omitempty"` 45 | ValidSubLocales string `xml:"validSubLocales,attr,omitempty"` 46 | Draft string `xml:"draft,attr,omitempty"` 47 | hidden 48 | } 49 | 50 | // Default returns the default type to select from the enclosed list 51 | // or "" if no default value is specified. 52 | func (e *Common) Default() string { 53 | if e.Def == nil { 54 | return "" 55 | } 56 | if e.Def.Choice != "" { 57 | return e.Def.Choice 58 | } else if e.Def.Type != "" { 59 | // Type is still used by the default element in collation. 60 | return e.Def.Type 61 | } 62 | return "" 63 | } 64 | 65 | // GetCommon returns e. It is provided such that Common implements Elem. 66 | func (e *Common) GetCommon() *Common { 67 | return e 68 | } 69 | 70 | // Data returns the character data accumulated for this element. 71 | func (e *Common) Data() string { 72 | e.CharData = charRe.ReplaceAllStringFunc(e.CharData, replaceUnicode) 73 | return e.CharData 74 | } 75 | 76 | func (e *Common) setName(s string) { 77 | e.name = s 78 | } 79 | 80 | func (e *Common) enclosing() Elem { 81 | return e.enclElem 82 | } 83 | 84 | func (e *Common) setEnclosing(en Elem) { 85 | e.enclElem = en 86 | } 87 | 88 | // Escape characters that can be escaped without further escaping the string. 89 | var charRe = regexp.MustCompile(`&#x[0-9a-fA-F]*;|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|\\x[0-9a-fA-F]{2}|\\[0-7]{3}|\\[abtnvfr]`) 90 | 91 | // replaceUnicode converts hexadecimal Unicode codepoint notations to a one-rune string. 92 | // It assumes the input string is correctly formatted. 93 | func replaceUnicode(s string) string { 94 | if s[1] == '#' { 95 | r, _ := strconv.ParseInt(s[3:len(s)-1], 16, 32) 96 | return string(r) 97 | } 98 | r, _, _, _ := strconv.UnquoteChar(s, 0) 99 | return string(r) 100 | } 101 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/text/width/gen_common.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package main 8 | 9 | // This code is shared between the main code generator and the test code. 10 | 11 | import ( 12 | "flag" 13 | "log" 14 | "strconv" 15 | "strings" 16 | 17 | "golang.org/x/text/internal/gen" 18 | "golang.org/x/text/internal/ucd" 19 | ) 20 | 21 | var ( 22 | outputFile = flag.String("out", "tables.go", "output file") 23 | ) 24 | 25 | var typeMap = map[string]elem{ 26 | "A": tagAmbiguous, 27 | "N": tagNeutral, 28 | "Na": tagNarrow, 29 | "W": tagWide, 30 | "F": tagFullwidth, 31 | "H": tagHalfwidth, 32 | } 33 | 34 | // getWidthData calls f for every entry for which it is defined. 35 | // 36 | // f may be called multiple times for the same rune. The last call to f is the 37 | // correct value. f is not called for all runes. The default tag type is 38 | // Neutral. 39 | func getWidthData(f func(r rune, tag elem, alt rune)) { 40 | // Set the default values for Unified Ideographs. In line with Annex 11, 41 | // we encode full ranges instead of the defined runes in Unified_Ideograph. 42 | for _, b := range []struct{ lo, hi rune }{ 43 | {0x4E00, 0x9FFF}, // the CJK Unified Ideographs block, 44 | {0x3400, 0x4DBF}, // the CJK Unified Ideographs Externsion A block, 45 | {0xF900, 0xFAFF}, // the CJK Compatibility Ideographs block, 46 | {0x20000, 0x2FFFF}, // the Supplementary Ideographic Plane, 47 | {0x30000, 0x3FFFF}, // the Tertiary Ideographic Plane, 48 | } { 49 | for r := b.lo; r <= b.hi; r++ { 50 | f(r, tagWide, 0) 51 | } 52 | } 53 | 54 | inverse := map[rune]rune{} 55 | maps := map[string]bool{ 56 | "": true, 57 | "": true, 58 | } 59 | 60 | // We cannot reuse package norm's decomposition, as we need an unexpanded 61 | // decomposition. We make use of the opportunity to verify that the 62 | // decomposition type is as expected. 63 | ucd.Parse(gen.OpenUCDFile("UnicodeData.txt"), func(p *ucd.Parser) { 64 | r := p.Rune(0) 65 | s := strings.SplitN(p.String(ucd.DecompMapping), " ", 2) 66 | if !maps[s[0]] { 67 | return 68 | } 69 | x, err := strconv.ParseUint(s[1], 16, 32) 70 | if err != nil { 71 | log.Fatalf("Error parsing rune %q", s[1]) 72 | } 73 | if inverse[r] != 0 || inverse[rune(x)] != 0 { 74 | log.Fatalf("Circular dependency in mapping between %U and %U", r, x) 75 | } 76 | inverse[r] = rune(x) 77 | inverse[rune(x)] = r 78 | }) 79 | 80 | // ; 81 | ucd.Parse(gen.OpenUCDFile("EastAsianWidth.txt"), func(p *ucd.Parser) { 82 | tag, ok := typeMap[p.String(1)] 83 | if !ok { 84 | log.Fatalf("Unknown width type %q", p.String(1)) 85 | } 86 | r := p.Rune(0) 87 | alt, ok := inverse[r] 88 | if tag == tagFullwidth || tag == tagHalfwidth && r != wonSign { 89 | tag |= tagNeedsFold 90 | if !ok { 91 | log.Fatalf("Narrow or wide rune %U has no decomposition", r) 92 | } 93 | } 94 | f(r, tag, alt) 95 | }) 96 | } 97 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/text/width/gen_trieval.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package main 8 | 9 | // elem is an entry of the width trie. The high byte is used to encode the type 10 | // of the rune. The low byte is used to store the index to a mapping entry in 11 | // the inverseData array. 12 | type elem uint16 13 | 14 | const ( 15 | tagNeutral elem = iota << typeShift 16 | tagAmbiguous 17 | tagWide 18 | tagNarrow 19 | tagFullwidth 20 | tagHalfwidth 21 | ) 22 | 23 | const ( 24 | numTypeBits = 3 25 | typeShift = 16 - numTypeBits 26 | 27 | // tagNeedsFold is true for all fullwidth and halfwidth runes except for 28 | // the Won sign U+20A9. 29 | tagNeedsFold = 0x1000 30 | 31 | // The Korean Won sign is halfwidth, but SHOULD NOT be mapped to a wide 32 | // variant. 33 | wonSign rune = 0x20A9 34 | ) 35 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/text/width/kind_string.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -type=Kind"; DO NOT EDIT 2 | 3 | package width 4 | 5 | import "fmt" 6 | 7 | const _Kind_name = "NeutralEastAsianAmbiguousEastAsianWideEastAsianNarrowEastAsianFullwidthEastAsianHalfwidth" 8 | 9 | var _Kind_index = [...]uint8{0, 7, 25, 38, 53, 71, 89} 10 | 11 | func (i Kind) String() string { 12 | if i < 0 || i >= Kind(len(_Kind_index)-1) { 13 | return fmt.Sprintf("Kind(%d)", i) 14 | } 15 | return _Kind_name[_Kind_index[i]:_Kind_index[i+1]] 16 | } 17 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/text/width/trieval.go: -------------------------------------------------------------------------------- 1 | // This file was generated by go generate; DO NOT EDIT 2 | 3 | package width 4 | 5 | // elem is an entry of the width trie. The high byte is used to encode the type 6 | // of the rune. The low byte is used to store the index to a mapping entry in 7 | // the inverseData array. 8 | type elem uint16 9 | 10 | const ( 11 | tagNeutral elem = iota << typeShift 12 | tagAmbiguous 13 | tagWide 14 | tagNarrow 15 | tagFullwidth 16 | tagHalfwidth 17 | ) 18 | 19 | const ( 20 | numTypeBits = 3 21 | typeShift = 16 - numTypeBits 22 | 23 | // tagNeedsFold is true for all fullwidth and halfwidth runes except for 24 | // the Won sign U+20A9. 25 | tagNeedsFold = 0x1000 26 | 27 | // The Korean Won sign is halfwidth, but SHOULD NOT be mapped to a wide 28 | // variant. 29 | wonSign rune = 0x20A9 30 | ) 31 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/cmd/goimports/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Command goimports updates your Go import lines, 4 | adding missing ones and removing unreferenced ones. 5 | 6 | $ go get golang.org/x/tools/cmd/goimports 7 | 8 | It's a drop-in replacement for your editor's gofmt-on-save hook. 9 | It has the same command-line interface as gofmt and formats 10 | your code in the same way. 11 | 12 | For emacs, make sure you have the latest go-mode.el: 13 | https://github.com/dominikh/go-mode.el 14 | Then in your .emacs file: 15 | (setq gofmt-command "goimports") 16 | (add-to-list 'load-path "/home/you/somewhere/emacs/") 17 | (require 'go-mode-load) 18 | (add-hook 'before-save-hook 'gofmt-before-save) 19 | 20 | For vim, set "gofmt_command" to "goimports": 21 | https://golang.org/change/39c724dd7f252 22 | https://golang.org/wiki/IDEsAndTextEditorPlugins 23 | etc 24 | 25 | For GoSublime, follow the steps described here: 26 | http://michaelwhatcott.com/gosublime-goimports/ 27 | 28 | For other editors, you probably know what to do. 29 | 30 | To exclude directories in your $GOPATH from being scanned for Go 31 | files, goimports respects a configuration file at 32 | $GOPATH/src/.goimportsignore which may contain blank lines, comment 33 | lines (beginning with '#'), or lines naming a directory relative to 34 | the configuration file to ignore when scanning. No globbing or regex 35 | patterns are allowed. Use the "-v" verbose flag to verify it's 36 | working and see what goimports is doing. 37 | 38 | File bugs or feature requests at: 39 | 40 | https://golang.org/issues/new?title=x/tools/cmd/goimports:+ 41 | 42 | Happy hacking! 43 | 44 | */ 45 | package main // import "golang.org/x/tools/cmd/goimports" 46 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/cmd/gotype/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | The gotype command does syntactic and semantic analysis of Go files 7 | and packages like the front-end of a Go compiler. Errors are reported 8 | if the analysis fails; otherwise gotype is quiet (unless -v is set). 9 | 10 | Without a list of paths, gotype reads from standard input, which 11 | must provide a single Go source file defining a complete package. 12 | 13 | If a single path is specified that is a directory, gotype checks 14 | the Go files in that directory; they must all belong to the same 15 | package. 16 | 17 | Otherwise, each path must be the filename of Go file belonging to 18 | the same package. 19 | 20 | Usage: 21 | gotype [flags] [path...] 22 | 23 | The flags are: 24 | -a 25 | use all (incl. _test.go) files when processing a directory 26 | -e 27 | report all errors (not just the first 10) 28 | -v 29 | verbose mode 30 | -gccgo 31 | use gccimporter instead of gcimporter 32 | 33 | Debugging flags: 34 | -seq 35 | parse sequentially, rather than in parallel 36 | -ast 37 | print AST (forces -seq) 38 | -trace 39 | print parse trace (forces -seq) 40 | -comments 41 | parse comments (ignored unless -ast or -trace is provided) 42 | 43 | Examples: 44 | 45 | To check the files a.go, b.go, and c.go: 46 | 47 | gotype a.go b.go c.go 48 | 49 | To check an entire package in the directory dir and print the processed files: 50 | 51 | gotype -v dir 52 | 53 | To check an entire package including tests in the local directory: 54 | 55 | gotype -a . 56 | 57 | To verify the output of a pipe: 58 | 59 | echo "package foo" | gotype 60 | 61 | */ 62 | package main // import "golang.org/x/tools/cmd/gotype" 63 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/container/intsets/popcnt_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build amd64,!appengine,!gccgo 6 | 7 | package intsets 8 | 9 | func popcnt(x word) int 10 | func havePOPCNT() bool 11 | 12 | var hasPOPCNT = havePOPCNT() 13 | 14 | // popcount returns the population count (number of set bits) of x. 15 | func popcount(x word) int { 16 | if hasPOPCNT { 17 | return popcnt(x) 18 | } 19 | return popcountTable(x) // faster than Hacker's Delight 20 | } 21 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/container/intsets/popcnt_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build amd64,!appengine,!gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // func havePOPCNT() bool 10 | TEXT ·havePOPCNT(SB),4,$0 11 | MOVQ $1, AX 12 | CPUID 13 | SHRQ $23, CX 14 | ANDQ $1, CX 15 | MOVB CX, ret+0(FP) 16 | RET 17 | 18 | // func popcnt(word) int 19 | TEXT ·popcnt(SB),NOSPLIT,$0-8 20 | XORQ AX, AX 21 | MOVQ x+0(FP), SI 22 | // POPCNT (SI), AX is not recognized by Go assembler, 23 | // so we assemble it ourselves. 24 | BYTE $0xf3 25 | BYTE $0x48 26 | BYTE $0x0f 27 | BYTE $0xb8 28 | BYTE $0xc6 29 | MOVQ AX, ret+8(FP) 30 | RET 31 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/container/intsets/popcnt_gccgo.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build gccgo 6 | 7 | package intsets 8 | 9 | func popcount(x word) int 10 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/container/intsets/popcnt_gccgo_c.c: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build gccgo 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #define _STRINGIFY2_(x) #x 12 | #define _STRINGIFY_(x) _STRINGIFY2_(x) 13 | #define GOSYM_PREFIX _STRINGIFY_(__USER_LABEL_PREFIX__) 14 | 15 | extern intptr_t popcount(uintptr_t x) __asm__(GOSYM_PREFIX GOPKGPATH ".popcount"); 16 | 17 | intptr_t popcount(uintptr_t x) { 18 | return __builtin_popcountl((unsigned long)(x)); 19 | } 20 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/container/intsets/popcnt_generic.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !amd64 appengine 6 | // +build !gccgo 7 | 8 | package intsets 9 | 10 | import "runtime" 11 | 12 | // We compared three algorithms---Hacker's Delight, table lookup, 13 | // and AMD64's SSE4.1 hardware POPCNT---on a 2.67GHz Xeon X5550. 14 | // 15 | // % GOARCH=amd64 go test -run=NONE -bench=Popcount 16 | // POPCNT 5.12 ns/op 17 | // Table 8.53 ns/op 18 | // HackersDelight 9.96 ns/op 19 | // 20 | // % GOARCH=386 go test -run=NONE -bench=Popcount 21 | // Table 10.4 ns/op 22 | // HackersDelight 5.23 ns/op 23 | // 24 | // (AMD64's ABM1 hardware supports ntz and nlz too, 25 | // but they aren't critical.) 26 | 27 | // popcount returns the population count (number of set bits) of x. 28 | func popcount(x word) int { 29 | if runtime.GOARCH == "386" { 30 | return popcountHD(uint32(x)) 31 | } 32 | return popcountTable(x) 33 | } 34 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/container/intsets/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package intsets 6 | 7 | // From Hacker's Delight, fig 5.2. 8 | func popcountHD(x uint32) int { 9 | x -= (x >> 1) & 0x55555555 10 | x = (x & 0x33333333) + ((x >> 2) & 0x33333333) 11 | x = (x + (x >> 4)) & 0x0f0f0f0f 12 | x = x + (x >> 8) 13 | x = x + (x >> 16) 14 | return int(x & 0x0000003f) 15 | } 16 | 17 | var a [1 << 8]byte 18 | 19 | func init() { 20 | for i := range a { 21 | var n byte 22 | for x := i; x != 0; x >>= 1 { 23 | if x&1 != 0 { 24 | n++ 25 | } 26 | } 27 | a[i] = n 28 | } 29 | } 30 | 31 | func popcountTable(x word) int { 32 | return int(a[byte(x>>(0*8))] + 33 | a[byte(x>>(1*8))] + 34 | a[byte(x>>(2*8))] + 35 | a[byte(x>>(3*8))] + 36 | a[byte(x>>(4*8))] + 37 | a[byte(x>>(5*8))] + 38 | a[byte(x>>(6*8))] + 39 | a[byte(x>>(7*8))]) 40 | } 41 | 42 | // nlz returns the number of leading zeros of x. 43 | // From Hacker's Delight, fig 5.11. 44 | func nlz(x word) int { 45 | x |= (x >> 1) 46 | x |= (x >> 2) 47 | x |= (x >> 4) 48 | x |= (x >> 8) 49 | x |= (x >> 16) 50 | x |= (x >> 32) 51 | return popcount(^x) 52 | } 53 | 54 | // ntz returns the number of trailing zeros of x. 55 | // From Hacker's Delight, fig 5.13. 56 | func ntz(x word) int { 57 | if x == 0 { 58 | return bitsPerWord 59 | } 60 | n := 1 61 | if bitsPerWord == 64 { 62 | if (x & 0xffffffff) == 0 { 63 | n = n + 32 64 | x = x >> 32 65 | } 66 | } 67 | if (x & 0x0000ffff) == 0 { 68 | n = n + 16 69 | x = x >> 16 70 | } 71 | if (x & 0x000000ff) == 0 { 72 | n = n + 8 73 | x = x >> 8 74 | } 75 | if (x & 0x0000000f) == 0 { 76 | n = n + 4 77 | x = x >> 4 78 | } 79 | if (x & 0x00000003) == 0 { 80 | n = n + 2 81 | x = x >> 2 82 | } 83 | return n - int(x&1) 84 | } 85 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/go/ast/astutil/util.go: -------------------------------------------------------------------------------- 1 | package astutil 2 | 3 | import "go/ast" 4 | 5 | // Unparen returns e with any enclosing parentheses stripped. 6 | func Unparen(e ast.Expr) ast.Expr { 7 | for { 8 | p, ok := e.(*ast.ParenExpr) 9 | if !ok { 10 | return e 11 | } 12 | e = p.X 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/go/buildutil/tags.go: -------------------------------------------------------------------------------- 1 | package buildutil 2 | 3 | // This logic was copied from stringsFlag from $GOROOT/src/cmd/go/build.go. 4 | 5 | import "fmt" 6 | 7 | const TagsFlagDoc = "a list of `build tags` to consider satisfied during the build. " + 8 | "For more information about build tags, see the description of " + 9 | "build constraints in the documentation for the go/build package" 10 | 11 | // TagsFlag is an implementation of the flag.Value and flag.Getter interfaces that parses 12 | // a flag value in the same manner as go build's -tags flag and 13 | // populates a []string slice. 14 | // 15 | // See $GOROOT/src/go/build/doc.go for description of build tags. 16 | // See $GOROOT/src/cmd/go/doc.go for description of 'go build -tags' flag. 17 | // 18 | // Example: 19 | // flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc) 20 | type TagsFlag []string 21 | 22 | func (v *TagsFlag) Set(s string) error { 23 | var err error 24 | *v, err = splitQuotedFields(s) 25 | if *v == nil { 26 | *v = []string{} 27 | } 28 | return err 29 | } 30 | 31 | func (v *TagsFlag) Get() interface{} { return *v } 32 | 33 | func splitQuotedFields(s string) ([]string, error) { 34 | // Split fields allowing '' or "" around elements. 35 | // Quotes further inside the string do not count. 36 | var f []string 37 | for len(s) > 0 { 38 | for len(s) > 0 && isSpaceByte(s[0]) { 39 | s = s[1:] 40 | } 41 | if len(s) == 0 { 42 | break 43 | } 44 | // Accepted quoted string. No unescaping inside. 45 | if s[0] == '"' || s[0] == '\'' { 46 | quote := s[0] 47 | s = s[1:] 48 | i := 0 49 | for i < len(s) && s[i] != quote { 50 | i++ 51 | } 52 | if i >= len(s) { 53 | return nil, fmt.Errorf("unterminated %c string", quote) 54 | } 55 | f = append(f, s[:i]) 56 | s = s[i+1:] 57 | continue 58 | } 59 | i := 0 60 | for i < len(s) && !isSpaceByte(s[i]) { 61 | i++ 62 | } 63 | f = append(f, s[:i]) 64 | s = s[i:] 65 | } 66 | return f, nil 67 | } 68 | 69 | func (v *TagsFlag) String() string { 70 | return "" 71 | } 72 | 73 | func isSpaceByte(c byte) bool { 74 | return c == ' ' || c == '\t' || c == '\n' || c == '\r' 75 | } 76 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/go/gcimporter15/exportdata.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.5 6 | 7 | // This file is a copy of $GOROOT/src/go/internal/gcimporter/exportdata.go, tagged for go1.5. 8 | 9 | // This file implements FindExportData. 10 | 11 | package gcimporter 12 | 13 | import ( 14 | "bufio" 15 | "errors" 16 | "fmt" 17 | "io" 18 | "strconv" 19 | "strings" 20 | ) 21 | 22 | func readGopackHeader(r *bufio.Reader) (name string, size int, err error) { 23 | // See $GOROOT/include/ar.h. 24 | hdr := make([]byte, 16+12+6+6+8+10+2) 25 | _, err = io.ReadFull(r, hdr) 26 | if err != nil { 27 | return 28 | } 29 | // leave for debugging 30 | if false { 31 | fmt.Printf("header: %s", hdr) 32 | } 33 | s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10])) 34 | size, err = strconv.Atoi(s) 35 | if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' { 36 | err = errors.New("invalid archive header") 37 | return 38 | } 39 | name = strings.TrimSpace(string(hdr[:16])) 40 | return 41 | } 42 | 43 | // FindExportData positions the reader r at the beginning of the 44 | // export data section of an underlying GC-created object/archive 45 | // file by reading from it. The reader must be positioned at the 46 | // start of the file before calling this function. The hdr result 47 | // is the string before the export data, either "$$" or "$$B". 48 | // 49 | func FindExportData(r *bufio.Reader) (hdr string, err error) { 50 | // Read first line to make sure this is an object file. 51 | line, err := r.ReadSlice('\n') 52 | if err != nil { 53 | return 54 | } 55 | 56 | if string(line) == "!\n" { 57 | // Archive file. Scan to __.PKGDEF. 58 | var name string 59 | var size int 60 | if name, size, err = readGopackHeader(r); err != nil { 61 | return 62 | } 63 | 64 | // Optional leading __.GOSYMDEF or __.SYMDEF. 65 | // Read and discard. 66 | if name == "__.SYMDEF" || name == "__.GOSYMDEF" { 67 | const block = 4096 68 | tmp := make([]byte, block) 69 | for size > 0 { 70 | n := size 71 | if n > block { 72 | n = block 73 | } 74 | if _, err = io.ReadFull(r, tmp[:n]); err != nil { 75 | return 76 | } 77 | size -= n 78 | } 79 | 80 | if name, _, err = readGopackHeader(r); err != nil { 81 | return 82 | } 83 | } 84 | 85 | // First real entry should be __.PKGDEF. 86 | if name != "__.PKGDEF" { 87 | err = errors.New("go archive is missing __.PKGDEF") 88 | return 89 | } 90 | 91 | // Read first line of __.PKGDEF data, so that line 92 | // is once again the first line of the input. 93 | if line, err = r.ReadSlice('\n'); err != nil { 94 | return 95 | } 96 | } 97 | 98 | // Now at __.PKGDEF in archive or still at beginning of file. 99 | // Either way, line should begin with "go object ". 100 | if !strings.HasPrefix(string(line), "go object ") { 101 | err = errors.New("not a go object file") 102 | return 103 | } 104 | 105 | // Skip over object header to export data. 106 | // Begins after first line starting with $$. 107 | for line[0] != '$' { 108 | if line, err = r.ReadSlice('\n'); err != nil { 109 | return 110 | } 111 | } 112 | hdr = string(line) 113 | 114 | return 115 | } 116 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/go/gcimporter15/setname15.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.5,!go1.6 6 | 7 | package gcimporter 8 | 9 | import ( 10 | "go/types" 11 | "unsafe" 12 | ) 13 | 14 | func setName(pkg *types.Package, name string) { 15 | (*types_Package)(unsafe.Pointer(pkg)).name = name 16 | } 17 | 18 | // The underlying type of types_Package is identical to 19 | // the underlying type of types.Package. We use it with 20 | // package unsafe to set the name field since 1.5 does 21 | // not have the Package.SetName method. 22 | // TestSetName verifies that the layout with respect to 23 | // the name field is correct. 24 | type types_Package struct { 25 | path string 26 | name string 27 | scope *types.Scope 28 | complete bool 29 | imports []*types.Package 30 | fake bool 31 | } 32 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/go/gcimporter15/setname16.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.6 6 | 7 | package gcimporter 8 | 9 | import "go/types" 10 | 11 | func setName(pkg *types.Package, name string) { 12 | pkg.SetName(name) 13 | } 14 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/go/loader/cgo_pkgconfig.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package loader 6 | 7 | import ( 8 | "errors" 9 | "fmt" 10 | "go/build" 11 | "os/exec" 12 | "strings" 13 | ) 14 | 15 | // pkgConfig runs pkg-config with the specified arguments and returns the flags it prints. 16 | func pkgConfig(mode string, pkgs []string) (flags []string, err error) { 17 | cmd := exec.Command("pkg-config", append([]string{mode}, pkgs...)...) 18 | out, err := cmd.CombinedOutput() 19 | if err != nil { 20 | s := fmt.Sprintf("%s failed: %v", strings.Join(cmd.Args, " "), err) 21 | if len(out) > 0 { 22 | s = fmt.Sprintf("%s: %s", s, out) 23 | } 24 | return nil, errors.New(s) 25 | } 26 | if len(out) > 0 { 27 | flags = strings.Fields(string(out)) 28 | } 29 | return 30 | } 31 | 32 | // pkgConfigFlags calls pkg-config if needed and returns the cflags 33 | // needed to build the package. 34 | func pkgConfigFlags(p *build.Package) (cflags []string, err error) { 35 | if len(p.CgoPkgConfig) == 0 { 36 | return nil, nil 37 | } 38 | return pkgConfig("--cflags", p.CgoPkgConfig) 39 | } 40 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/go/loader/go16.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.6 6 | 7 | package loader 8 | 9 | import "go/build" 10 | 11 | func init() { 12 | ignoreVendor = build.IgnoreVendor 13 | } 14 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/go/ssa/interp/external_darwin.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build darwin 6 | 7 | package interp 8 | 9 | import "syscall" 10 | 11 | func init() { 12 | externals["syscall.Sysctl"] = ext۰syscall۰Sysctl 13 | } 14 | 15 | func ext۰syscall۰Sysctl(fr *frame, args []value) value { 16 | r, err := syscall.Sysctl(args[0].(string)) 17 | return tuple{r, wrapError(err)} 18 | } 19 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/go/ssa/interp/external_freebsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build freebsd 6 | 7 | package interp 8 | 9 | import "syscall" 10 | 11 | func init() { 12 | externals["syscall.Sysctl"] = ext۰syscall۰Sysctl 13 | externals["syscall.SysctlUint32"] = ext۰syscall۰SysctlUint32 14 | } 15 | 16 | func ext۰syscall۰Sysctl(fr *frame, args []value) value { 17 | r, err := syscall.Sysctl(args[0].(string)) 18 | return tuple{r, wrapError(err)} 19 | } 20 | 21 | func ext۰syscall۰SysctlUint32(fr *frame, args []value) value { 22 | r, err := syscall.SysctlUint32(args[0].(string)) 23 | return tuple{r, wrapError(err)} 24 | } 25 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/go/ssa/interp/external_plan9.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package interp 6 | 7 | import "syscall" 8 | 9 | func ext۰os۰Pipe(fr *frame, args []value) value { 10 | panic("os.Pipe not yet implemented") 11 | } 12 | func ext۰syscall۰Close(fr *frame, args []value) value { 13 | panic("syscall.Close not yet implemented") 14 | } 15 | func ext۰syscall۰Fstat(fr *frame, args []value) value { 16 | panic("syscall.Fstat not yet implemented") 17 | } 18 | func ext۰syscall۰Kill(fr *frame, args []value) value { 19 | panic("syscall.Kill not yet implemented") 20 | } 21 | func ext۰syscall۰Lstat(fr *frame, args []value) value { 22 | panic("syscall.Lstat not yet implemented") 23 | } 24 | func ext۰syscall۰Open(fr *frame, args []value) value { 25 | panic("syscall.Open not yet implemented") 26 | } 27 | func ext۰syscall۰ParseDirent(fr *frame, args []value) value { 28 | panic("syscall.ParseDirent not yet implemented") 29 | } 30 | func ext۰syscall۰Read(fr *frame, args []value) value { 31 | panic("syscall.Read not yet implemented") 32 | } 33 | func ext۰syscall۰ReadDirent(fr *frame, args []value) value { 34 | panic("syscall.ReadDirent not yet implemented") 35 | } 36 | func ext۰syscall۰Stat(fr *frame, args []value) value { 37 | panic("syscall.Stat not yet implemented") 38 | } 39 | func ext۰syscall۰Write(fr *frame, args []value) value { 40 | // func Write(fd int, p []byte) (n int, err error) 41 | n, err := write(args[0].(int), valueToBytes(args[1])) 42 | return tuple{n, wrapError(err)} 43 | } 44 | func ext۰syscall۰RawSyscall(fr *frame, args []value) value { 45 | return tuple{^uintptr(0), uintptr(0), uintptr(0)} 46 | } 47 | 48 | func syswrite(fd int, b []byte) (int, error) { 49 | return syscall.Write(fd, b) 50 | } 51 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/go/ssa/interp/external_windows.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package interp 6 | 7 | import "syscall" 8 | 9 | func ext۰os۰Pipe(fr *frame, args []value) value { 10 | panic("os.Pipe not yet implemented") 11 | } 12 | func ext۰syscall۰Close(fr *frame, args []value) value { 13 | panic("syscall.Close not yet implemented") 14 | } 15 | func ext۰syscall۰Fstat(fr *frame, args []value) value { 16 | panic("syscall.Fstat not yet implemented") 17 | } 18 | func ext۰syscall۰Kill(fr *frame, args []value) value { 19 | panic("syscall.Kill not yet implemented") 20 | } 21 | func ext۰syscall۰Lstat(fr *frame, args []value) value { 22 | panic("syscall.Lstat not yet implemented") 23 | } 24 | func ext۰syscall۰Open(fr *frame, args []value) value { 25 | panic("syscall.Open not yet implemented") 26 | } 27 | func ext۰syscall۰ParseDirent(fr *frame, args []value) value { 28 | panic("syscall.ParseDirent not yet implemented") 29 | } 30 | func ext۰syscall۰Read(fr *frame, args []value) value { 31 | panic("syscall.Read not yet implemented") 32 | } 33 | func ext۰syscall۰ReadDirent(fr *frame, args []value) value { 34 | panic("syscall.ReadDirent not yet implemented") 35 | } 36 | func ext۰syscall۰Stat(fr *frame, args []value) value { 37 | panic("syscall.Stat not yet implemented") 38 | } 39 | func ext۰syscall۰Write(fr *frame, args []value) value { 40 | panic("syscall.Write not yet implemented") 41 | } 42 | func ext۰syscall۰RawSyscall(fr *frame, args []value) value { 43 | return tuple{uintptr(0), uintptr(0), uintptr(syscall.ENOSYS)} 44 | } 45 | func syswrite(fd int, b []byte) (int, error) { 46 | panic("syswrite not yet implemented") 47 | } 48 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/go/ssa/mode.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ssa 6 | 7 | // This file defines the BuilderMode type and its command-line flag. 8 | 9 | import ( 10 | "bytes" 11 | "fmt" 12 | ) 13 | 14 | // BuilderMode is a bitmask of options for diagnostics and checking. 15 | // 16 | // *BuilderMode satisfies the flag.Value interface. Example: 17 | // 18 | // var mode = ssa.BuilderMode(0) 19 | // func init() { flag.Var(&mode, "build", ssa.BuilderModeDoc) } 20 | // 21 | type BuilderMode uint 22 | 23 | const ( 24 | PrintPackages BuilderMode = 1 << iota // Print package inventory to stdout 25 | PrintFunctions // Print function SSA code to stdout 26 | LogSource // Log source locations as SSA builder progresses 27 | SanityCheckFunctions // Perform sanity checking of function bodies 28 | NaiveForm // Build naïve SSA form: don't replace local loads/stores with registers 29 | BuildSerially // Build packages serially, not in parallel. 30 | GlobalDebug // Enable debug info for all packages 31 | BareInits // Build init functions without guards or calls to dependent inits 32 | ) 33 | 34 | const BuilderModeDoc = `Options controlling the SSA builder. 35 | The value is a sequence of zero or more of these letters: 36 | C perform sanity [C]hecking of the SSA form. 37 | D include [D]ebug info for every function. 38 | P print [P]ackage inventory. 39 | F print [F]unction SSA code. 40 | S log [S]ource locations as SSA builder progresses. 41 | L build distinct packages seria[L]ly instead of in parallel. 42 | N build [N]aive SSA form: don't replace local loads/stores with registers. 43 | I build bare [I]nit functions: no init guards or calls to dependent inits. 44 | ` 45 | 46 | func (m BuilderMode) String() string { 47 | var buf bytes.Buffer 48 | if m&GlobalDebug != 0 { 49 | buf.WriteByte('D') 50 | } 51 | if m&PrintPackages != 0 { 52 | buf.WriteByte('P') 53 | } 54 | if m&PrintFunctions != 0 { 55 | buf.WriteByte('F') 56 | } 57 | if m&LogSource != 0 { 58 | buf.WriteByte('S') 59 | } 60 | if m&SanityCheckFunctions != 0 { 61 | buf.WriteByte('C') 62 | } 63 | if m&NaiveForm != 0 { 64 | buf.WriteByte('N') 65 | } 66 | if m&BuildSerially != 0 { 67 | buf.WriteByte('L') 68 | } 69 | return buf.String() 70 | } 71 | 72 | // Set parses the flag characters in s and updates *m. 73 | func (m *BuilderMode) Set(s string) error { 74 | var mode BuilderMode 75 | for _, c := range s { 76 | switch c { 77 | case 'D': 78 | mode |= GlobalDebug 79 | case 'P': 80 | mode |= PrintPackages 81 | case 'F': 82 | mode |= PrintFunctions 83 | case 'S': 84 | mode |= LogSource | BuildSerially 85 | case 'C': 86 | mode |= SanityCheckFunctions 87 | case 'N': 88 | mode |= NaiveForm 89 | case 'L': 90 | mode |= BuildSerially 91 | default: 92 | return fmt.Errorf("unknown BuilderMode option: %q", c) 93 | } 94 | } 95 | *m = mode 96 | return nil 97 | } 98 | 99 | // Get returns m. 100 | func (m BuilderMode) Get() interface{} { return m } 101 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/go/ssa/ssautil/load.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.5 6 | 7 | package ssautil 8 | 9 | // This file defines utility functions for constructing programs in SSA form. 10 | 11 | import ( 12 | "go/ast" 13 | "go/token" 14 | "go/types" 15 | 16 | "golang.org/x/tools/go/loader" 17 | "golang.org/x/tools/go/ssa" 18 | ) 19 | 20 | // CreateProgram returns a new program in SSA form, given a program 21 | // loaded from source. An SSA package is created for each transitively 22 | // error-free package of lprog. 23 | // 24 | // Code for bodies of functions is not built until Build is called 25 | // on the result. 26 | // 27 | // mode controls diagnostics and checking during SSA construction. 28 | // 29 | func CreateProgram(lprog *loader.Program, mode ssa.BuilderMode) *ssa.Program { 30 | prog := ssa.NewProgram(lprog.Fset, mode) 31 | 32 | for _, info := range lprog.AllPackages { 33 | if info.TransitivelyErrorFree { 34 | prog.CreatePackage(info.Pkg, info.Files, &info.Info, info.Importable) 35 | } 36 | } 37 | 38 | return prog 39 | } 40 | 41 | // BuildPackage builds an SSA program with IR for a single package. 42 | // 43 | // It populates pkg by type-checking the specified file ASTs. All 44 | // dependencies are loaded using the importer specified by tc, which 45 | // typically loads compiler export data; SSA code cannot be built for 46 | // those packages. BuildPackage then constructs an ssa.Program with all 47 | // dependency packages created, and builds and returns the SSA package 48 | // corresponding to pkg. 49 | // 50 | // The caller must have set pkg.Path() to the import path. 51 | // 52 | // The operation fails if there were any type-checking or import errors. 53 | // 54 | // See ../ssa/example_test.go for an example. 55 | // 56 | func BuildPackage(tc *types.Config, fset *token.FileSet, pkg *types.Package, files []*ast.File, mode ssa.BuilderMode) (*ssa.Package, *types.Info, error) { 57 | if fset == nil { 58 | panic("no token.FileSet") 59 | } 60 | if pkg.Path() == "" { 61 | panic("package has no import path") 62 | } 63 | 64 | info := &types.Info{ 65 | Types: make(map[ast.Expr]types.TypeAndValue), 66 | Defs: make(map[*ast.Ident]types.Object), 67 | Uses: make(map[*ast.Ident]types.Object), 68 | Implicits: make(map[ast.Node]types.Object), 69 | Scopes: make(map[ast.Node]*types.Scope), 70 | Selections: make(map[*ast.SelectorExpr]*types.Selection), 71 | } 72 | if err := types.NewChecker(tc, fset, pkg, info).Files(files); err != nil { 73 | return nil, nil, err 74 | } 75 | 76 | prog := ssa.NewProgram(fset, mode) 77 | 78 | // Create SSA packages for all imports. 79 | // Order is not significant. 80 | created := make(map[*types.Package]bool) 81 | var createAll func(pkgs []*types.Package) 82 | createAll = func(pkgs []*types.Package) { 83 | for _, p := range pkgs { 84 | if !created[p] { 85 | created[p] = true 86 | prog.CreatePackage(p, nil, nil, true) 87 | createAll(p.Imports()) 88 | } 89 | } 90 | } 91 | createAll(pkg.Imports()) 92 | 93 | // Create and build the primary package. 94 | ssapkg := prog.CreatePackage(pkg, files, info, false) 95 | ssapkg.Build() 96 | return ssapkg, info, nil 97 | } 98 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/go/ssa/ssautil/visit.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ssautil // import "golang.org/x/tools/go/ssa/ssautil" 6 | 7 | import "golang.org/x/tools/go/ssa" 8 | 9 | // This file defines utilities for visiting the SSA representation of 10 | // a Program. 11 | // 12 | // TODO(adonovan): test coverage. 13 | 14 | // AllFunctions finds and returns the set of functions potentially 15 | // needed by program prog, as determined by a simple linker-style 16 | // reachability algorithm starting from the members and method-sets of 17 | // each package. The result may include anonymous functions and 18 | // synthetic wrappers. 19 | // 20 | // Precondition: all packages are built. 21 | // 22 | func AllFunctions(prog *ssa.Program) map[*ssa.Function]bool { 23 | visit := visitor{ 24 | prog: prog, 25 | seen: make(map[*ssa.Function]bool), 26 | } 27 | visit.program() 28 | return visit.seen 29 | } 30 | 31 | type visitor struct { 32 | prog *ssa.Program 33 | seen map[*ssa.Function]bool 34 | } 35 | 36 | func (visit *visitor) program() { 37 | for _, pkg := range visit.prog.AllPackages() { 38 | for _, mem := range pkg.Members { 39 | if fn, ok := mem.(*ssa.Function); ok { 40 | visit.function(fn) 41 | } 42 | } 43 | } 44 | for _, T := range visit.prog.RuntimeTypes() { 45 | mset := visit.prog.MethodSets.MethodSet(T) 46 | for i, n := 0, mset.Len(); i < n; i++ { 47 | visit.function(visit.prog.MethodValue(mset.At(i))) 48 | } 49 | } 50 | } 51 | 52 | func (visit *visitor) function(fn *ssa.Function) { 53 | if !visit.seen[fn] { 54 | visit.seen[fn] = true 55 | var buf [10]*ssa.Value // avoid alloc in common case 56 | for _, b := range fn.Blocks { 57 | for _, instr := range b.Instrs { 58 | for _, op := range instr.Operands(buf[:0]) { 59 | if fn, ok := (*op).(*ssa.Function); ok { 60 | visit.function(fn) 61 | } 62 | } 63 | } 64 | } 65 | } 66 | } 67 | 68 | // MainPackages returns the subset of the specified packages 69 | // named "main" that define a main function. 70 | // The result may include synthetic "testmain" packages. 71 | func MainPackages(pkgs []*ssa.Package) []*ssa.Package { 72 | var mains []*ssa.Package 73 | for _, pkg := range pkgs { 74 | if pkg.Pkg.Name() == "main" && pkg.Func("main") != nil { 75 | mains = append(mains, pkg) 76 | } 77 | } 78 | return mains 79 | } 80 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/go/types/typeutil/imports.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.5 6 | 7 | package typeutil 8 | 9 | import "go/types" 10 | 11 | // Dependencies returns all dependencies of the specified packages. 12 | // 13 | // Dependent packages appear in topological order: if package P imports 14 | // package Q, Q appears earlier than P in the result. 15 | // The algorithm follows import statements in the order they 16 | // appear in the source code, so the result is a total order. 17 | // 18 | func Dependencies(pkgs ...*types.Package) []*types.Package { 19 | var result []*types.Package 20 | seen := make(map[*types.Package]bool) 21 | var visit func(pkgs []*types.Package) 22 | visit = func(pkgs []*types.Package) { 23 | for _, p := range pkgs { 24 | if !seen[p] { 25 | seen[p] = true 26 | visit(p.Imports()) 27 | result = append(result, p) 28 | } 29 | } 30 | } 31 | visit(pkgs) 32 | return result 33 | } 34 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/go/types/typeutil/methodsetcache.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.5 6 | 7 | // This file implements a cache of method sets. 8 | 9 | package typeutil 10 | 11 | import ( 12 | "go/types" 13 | "sync" 14 | ) 15 | 16 | // A MethodSetCache records the method set of each type T for which 17 | // MethodSet(T) is called so that repeat queries are fast. 18 | // The zero value is a ready-to-use cache instance. 19 | type MethodSetCache struct { 20 | mu sync.Mutex 21 | named map[*types.Named]struct{ value, pointer *types.MethodSet } // method sets for named N and *N 22 | others map[types.Type]*types.MethodSet // all other types 23 | } 24 | 25 | // MethodSet returns the method set of type T. It is thread-safe. 26 | // 27 | // If cache is nil, this function is equivalent to types.NewMethodSet(T). 28 | // Utility functions can thus expose an optional *MethodSetCache 29 | // parameter to clients that care about performance. 30 | // 31 | func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet { 32 | if cache == nil { 33 | return types.NewMethodSet(T) 34 | } 35 | cache.mu.Lock() 36 | defer cache.mu.Unlock() 37 | 38 | switch T := T.(type) { 39 | case *types.Named: 40 | return cache.lookupNamed(T).value 41 | 42 | case *types.Pointer: 43 | if N, ok := T.Elem().(*types.Named); ok { 44 | return cache.lookupNamed(N).pointer 45 | } 46 | } 47 | 48 | // all other types 49 | // (The map uses pointer equivalence, not type identity.) 50 | mset := cache.others[T] 51 | if mset == nil { 52 | mset = types.NewMethodSet(T) 53 | if cache.others == nil { 54 | cache.others = make(map[types.Type]*types.MethodSet) 55 | } 56 | cache.others[T] = mset 57 | } 58 | return mset 59 | } 60 | 61 | func (cache *MethodSetCache) lookupNamed(named *types.Named) struct{ value, pointer *types.MethodSet } { 62 | if cache.named == nil { 63 | cache.named = make(map[*types.Named]struct{ value, pointer *types.MethodSet }) 64 | } 65 | // Avoid recomputing mset(*T) for each distinct Pointer 66 | // instance whose underlying type is a named type. 67 | msets, ok := cache.named[named] 68 | if !ok { 69 | msets.value = types.NewMethodSet(named) 70 | msets.pointer = types.NewMethodSet(types.NewPointer(named)) 71 | cache.named[named] = msets 72 | } 73 | return msets 74 | } 75 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/go/types/typeutil/ui.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.5 6 | 7 | package typeutil 8 | 9 | // This file defines utilities for user interfaces that display types. 10 | 11 | import "go/types" 12 | 13 | // IntuitiveMethodSet returns the intuitive method set of a type T, 14 | // which is the set of methods you can call on an addressable value of 15 | // that type. 16 | // 17 | // The result always contains MethodSet(T), and is exactly MethodSet(T) 18 | // for interface types and for pointer-to-concrete types. 19 | // For all other concrete types T, the result additionally 20 | // contains each method belonging to *T if there is no identically 21 | // named method on T itself. 22 | // 23 | // This corresponds to user intuition about method sets; 24 | // this function is intended only for user interfaces. 25 | // 26 | // The order of the result is as for types.MethodSet(T). 27 | // 28 | func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection { 29 | isPointerToConcrete := func(T types.Type) bool { 30 | ptr, ok := T.(*types.Pointer) 31 | return ok && !types.IsInterface(ptr.Elem()) 32 | } 33 | 34 | var result []*types.Selection 35 | mset := msets.MethodSet(T) 36 | if types.IsInterface(T) || isPointerToConcrete(T) { 37 | for i, n := 0, mset.Len(); i < n; i++ { 38 | result = append(result, mset.At(i)) 39 | } 40 | } else { 41 | // T is some other concrete type. 42 | // Report methods of T and *T, preferring those of T. 43 | pmset := msets.MethodSet(types.NewPointer(T)) 44 | for i, n := 0, pmset.Len(); i < n; i++ { 45 | meth := pmset.At(i) 46 | if m := mset.Lookup(meth.Obj().Pkg(), meth.Obj().Name()); m != nil { 47 | meth = m 48 | } 49 | result = append(result, meth) 50 | } 51 | 52 | } 53 | return result 54 | } 55 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/imports/fastwalk_dirent_fileno.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build freebsd openbsd netbsd 6 | 7 | package imports 8 | 9 | import "syscall" 10 | 11 | func direntInode(dirent *syscall.Dirent) uint64 { 12 | return uint64(dirent.Fileno) 13 | } 14 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/imports/fastwalk_dirent_ino.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build linux darwin 6 | 7 | package imports 8 | 9 | import "syscall" 10 | 11 | func direntInode(dirent *syscall.Dirent) uint64 { 12 | return uint64(dirent.Ino) 13 | } 14 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/imports/fastwalk_portable.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !linux,!darwin,!freebsd,!openbsd,!netbsd 6 | 7 | package imports 8 | 9 | import ( 10 | "io/ioutil" 11 | "os" 12 | ) 13 | 14 | // readDir calls fn for each directory entry in dirName. 15 | // It does not descend into directories or follow symlinks. 16 | // If fn returns a non-nil error, readDir returns with that error 17 | // immediately. 18 | func readDir(dirName string, fn func(dirName, entName string, typ os.FileMode) error) error { 19 | fis, err := ioutil.ReadDir(dirName) 20 | if err != nil { 21 | return err 22 | } 23 | for _, fi := range fis { 24 | if err := fn(dirName, fi.Name(), fi.Mode()&os.ModeType); err != nil { 25 | return err 26 | } 27 | } 28 | return nil 29 | } 30 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/golang.org/x/tools/imports/mkstdlib.go: -------------------------------------------------------------------------------- 1 | // +build ignore 2 | 3 | // mkstdlib generates the zstdlib.go file, containing the Go standard 4 | // library API symbols. It's baked into the binary to avoid scanning 5 | // GOPATH in the common case. 6 | package main 7 | 8 | import ( 9 | "bufio" 10 | "bytes" 11 | "fmt" 12 | "go/format" 13 | "io" 14 | "io/ioutil" 15 | "log" 16 | "os" 17 | "path" 18 | "path/filepath" 19 | "regexp" 20 | "sort" 21 | "strings" 22 | ) 23 | 24 | func mustOpen(name string) io.Reader { 25 | f, err := os.Open(name) 26 | if err != nil { 27 | log.Fatal(err) 28 | } 29 | return f 30 | } 31 | 32 | func api(base string) string { 33 | return filepath.Join(os.Getenv("GOROOT"), "api", base) 34 | } 35 | 36 | var sym = regexp.MustCompile(`^pkg (\S+).*?, (?:var|func|type|const) ([A-Z]\w*)`) 37 | 38 | func main() { 39 | var buf bytes.Buffer 40 | outf := func(format string, args ...interface{}) { 41 | fmt.Fprintf(&buf, format, args...) 42 | } 43 | outf("// AUTO-GENERATED BY mkstdlib.go\n\n") 44 | outf("package imports\n") 45 | outf("var stdlib = map[string]string{\n") 46 | f := io.MultiReader( 47 | mustOpen(api("go1.txt")), 48 | mustOpen(api("go1.1.txt")), 49 | mustOpen(api("go1.2.txt")), 50 | mustOpen(api("go1.3.txt")), 51 | mustOpen(api("go1.4.txt")), 52 | mustOpen(api("go1.5.txt")), 53 | mustOpen(api("go1.6.txt")), 54 | ) 55 | sc := bufio.NewScanner(f) 56 | fullImport := map[string]string{} // "zip.NewReader" => "archive/zip" 57 | ambiguous := map[string]bool{} 58 | var keys []string 59 | for sc.Scan() { 60 | l := sc.Text() 61 | has := func(v string) bool { return strings.Contains(l, v) } 62 | if has("struct, ") || has("interface, ") || has(", method (") { 63 | continue 64 | } 65 | if m := sym.FindStringSubmatch(l); m != nil { 66 | full := m[1] 67 | key := path.Base(full) + "." + m[2] 68 | if exist, ok := fullImport[key]; ok { 69 | if exist != full { 70 | ambiguous[key] = true 71 | } 72 | } else { 73 | fullImport[key] = full 74 | keys = append(keys, key) 75 | } 76 | } 77 | } 78 | if err := sc.Err(); err != nil { 79 | log.Fatal(err) 80 | } 81 | sort.Strings(keys) 82 | for _, key := range keys { 83 | if ambiguous[key] { 84 | outf("\t// %q is ambiguous\n", key) 85 | } else { 86 | outf("\t%q: %q,\n", key, fullImport[key]) 87 | } 88 | } 89 | outf("\n") 90 | for _, sym := range [...]string{"Alignof", "ArbitraryType", "Offsetof", "Pointer", "Sizeof"} { 91 | outf("\t%q: %q,\n", "unsafe."+sym, "unsafe") 92 | } 93 | outf("}\n") 94 | fmtbuf, err := format.Source(buf.Bytes()) 95 | if err != nil { 96 | log.Fatal(err) 97 | } 98 | err = ioutil.WriteFile("zstdlib.go", fmtbuf, 0666) 99 | if err != nil { 100 | log.Fatal(err) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/honnef.co/go/lint/lint16.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 The Go Authors. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file or at 5 | // https://developers.google.com/open-source/licenses/bsd. 6 | 7 | // +build go1.6 8 | 9 | package lint 10 | 11 | import "go/types" 12 | 13 | // This is in its own file so it can be ignored under Go 1.5. 14 | 15 | func (i importer) ImportFrom(path, srcDir string, mode types.ImportMode) (*types.Package, error) { 16 | return i.impFn(i.packages, path, srcDir) 17 | } 18 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/honnef.co/go/simple/cmd/gosimple/gosimple.go: -------------------------------------------------------------------------------- 1 | // gosimple lints the Go source files named on its command line. 2 | package main // import "honnef.co/go/simple/cmd/gosimple" 3 | import ( 4 | "os" 5 | 6 | "honnef.co/go/lint/lintutil" 7 | "honnef.co/go/simple" 8 | ) 9 | 10 | func main() { 11 | lintutil.ProcessArgs("gosimple", simple.Funcs, os.Args[1:]) 12 | } 13 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/honnef.co/go/simple/lint17.go: -------------------------------------------------------------------------------- 1 | // +build !go1.8 2 | 3 | package simple 4 | 5 | import "go/types" 6 | 7 | var structsIdentical = types.Identical 8 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/honnef.co/go/simple/lint18.go: -------------------------------------------------------------------------------- 1 | // +build go1.8 2 | 3 | package simple 4 | 5 | import "go/types" 6 | 7 | // TODO(dh): use types.IdenticalIgnoreTags once CL 24190 has been merged 8 | // var structsIdentical = types.IdenticalIgnoreTags 9 | var structsIdentical = types.Identical 10 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/gometalinter/vendor/src/honnef.co/go/staticcheck/cmd/staticcheck/staticcheck.go: -------------------------------------------------------------------------------- 1 | // staticcheck statically checks arguments to certain functions 2 | package main // import "honnef.co/go/staticcheck/cmd/staticcheck" 3 | 4 | import ( 5 | "os" 6 | 7 | "honnef.co/go/lint/lintutil" 8 | "honnef.co/go/staticcheck" 9 | ) 10 | 11 | var checkDubious bool 12 | 13 | func main() { 14 | var args []string 15 | for _, arg := range os.Args[1:] { 16 | if arg == "-dubious" { 17 | checkDubious = true 18 | continue 19 | } 20 | args = append(args, arg) 21 | } 22 | lintutil.ProcessArgs("staticcheck", staticcheck.Funcs, args) 23 | if checkDubious { 24 | lintutil.ProcessArgs("staticcheck", staticcheck.DubiousFuncs, args) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/template/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/units/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (C) 2014 Alec Thomas 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/units/bytes.go: -------------------------------------------------------------------------------- 1 | package units 2 | 3 | // Base2Bytes is the old non-SI power-of-2 byte scale (1024 bytes in a kilobyte, 4 | // etc.). 5 | type Base2Bytes int64 6 | 7 | // Base-2 byte units. 8 | const ( 9 | Kibibyte Base2Bytes = 1024 10 | KiB = Kibibyte 11 | Mebibyte = Kibibyte * 1024 12 | MiB = Mebibyte 13 | Gibibyte = Mebibyte * 1024 14 | GiB = Gibibyte 15 | Tebibyte = Gibibyte * 1024 16 | TiB = Tebibyte 17 | Pebibyte = Tebibyte * 1024 18 | PiB = Pebibyte 19 | Exbibyte = Pebibyte * 1024 20 | EiB = Exbibyte 21 | ) 22 | 23 | var ( 24 | bytesUnitMap = MakeUnitMap("iB", "B", 1024) 25 | oldBytesUnitMap = MakeUnitMap("B", "B", 1024) 26 | ) 27 | 28 | // ParseBase2Bytes supports both iB and B in base-2 multipliers. That is, KB 29 | // and KiB are both 1024. 30 | func ParseBase2Bytes(s string) (Base2Bytes, error) { 31 | n, err := ParseUnit(s, bytesUnitMap) 32 | if err != nil { 33 | n, err = ParseUnit(s, oldBytesUnitMap) 34 | } 35 | return Base2Bytes(n), err 36 | } 37 | 38 | func (b Base2Bytes) String() string { 39 | return ToString(int64(b), 1024, "iB", "B") 40 | } 41 | 42 | var ( 43 | metricBytesUnitMap = MakeUnitMap("B", "B", 1000) 44 | ) 45 | 46 | // MetricBytes are SI byte units (1000 bytes in a kilobyte). 47 | type MetricBytes SI 48 | 49 | // SI base-10 byte units. 50 | const ( 51 | Kilobyte MetricBytes = 1000 52 | KB = Kilobyte 53 | Megabyte = Kilobyte * 1000 54 | MB = Megabyte 55 | Gigabyte = Megabyte * 1000 56 | GB = Gigabyte 57 | Terabyte = Gigabyte * 1000 58 | TB = Terabyte 59 | Petabyte = Terabyte * 1000 60 | PB = Petabyte 61 | Exabyte = Petabyte * 1000 62 | EB = Exabyte 63 | ) 64 | 65 | // ParseMetricBytes parses base-10 metric byte units. That is, KB is 1000 bytes. 66 | func ParseMetricBytes(s string) (MetricBytes, error) { 67 | n, err := ParseUnit(s, metricBytesUnitMap) 68 | return MetricBytes(n), err 69 | } 70 | 71 | func (m MetricBytes) String() string { 72 | return ToString(int64(m), 1000, "B", "B") 73 | } 74 | 75 | // ParseStrictBytes supports both iB and B suffixes for base 2 and metric, 76 | // respectively. That is, KiB represents 1024 and KB represents 1000. 77 | func ParseStrictBytes(s string) (int64, error) { 78 | n, err := ParseUnit(s, bytesUnitMap) 79 | if err != nil { 80 | n, err = ParseUnit(s, metricBytesUnitMap) 81 | } 82 | return int64(n), err 83 | } 84 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/units/doc.go: -------------------------------------------------------------------------------- 1 | // Package units provides helpful unit multipliers and functions for Go. 2 | // 3 | // The goal of this package is to have functionality similar to the time [1] package. 4 | // 5 | // 6 | // [1] http://golang.org/pkg/time/ 7 | // 8 | // It allows for code like this: 9 | // 10 | // n, err := ParseBase2Bytes("1KB") 11 | // // n == 1024 12 | // n = units.Mebibyte * 512 13 | package units 14 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/alecthomas/units/si.go: -------------------------------------------------------------------------------- 1 | package units 2 | 3 | // SI units. 4 | type SI int64 5 | 6 | // SI unit multiples. 7 | const ( 8 | Kilo SI = 1000 9 | Mega = Kilo * 1000 10 | Giga = Mega * 1000 11 | Tera = Giga * 1000 12 | Peta = Tera * 1000 13 | Exa = Peta * 1000 14 | ) 15 | 16 | func MakeUnitMap(suffix, shortSuffix string, scale int64) map[string]float64 { 17 | return map[string]float64{ 18 | shortSuffix: 1, 19 | "K" + suffix: float64(scale), 20 | "M" + suffix: float64(scale * scale), 21 | "G" + suffix: float64(scale * scale * scale), 22 | "T" + suffix: float64(scale * scale * scale * scale), 23 | "P" + suffix: float64(scale * scale * scale * scale * scale), 24 | "E" + suffix: float64(scale * scale * scale * scale * scale * scale), 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/stretchr/testify/assert/LICENCE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell 2 | 3 | Please consider promoting this project if you find it useful. 4 | 5 | Permission is hereby granted, free of charge, to any person 6 | obtaining a copy of this software and associated documentation 7 | files (the "Software"), to deal in the Software without restriction, 8 | including without limitation the rights to use, copy, modify, merge, 9 | publish, distribute, sublicense, and/or sell copies of the Software, 10 | and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 21 | OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 22 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/stretchr/testify/assert/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell 2 | 3 | Please consider promoting this project if you find it useful. 4 | 5 | Permission is hereby granted, free of charge, to any person 6 | obtaining a copy of this software and associated documentation 7 | files (the "Software"), to deal in the Software without restriction, 8 | including without limitation the rights to use, copy, modify, merge, 9 | publish, distribute, sublicense, and/or sell copies of the Software, 10 | and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 21 | OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 22 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/stretchr/testify/assert/doc.go: -------------------------------------------------------------------------------- 1 | // Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. 2 | // 3 | // Example Usage 4 | // 5 | // The following is a complete example using assert in a standard test function: 6 | // import ( 7 | // "testing" 8 | // "github.com/stretchr/testify/assert" 9 | // ) 10 | // 11 | // func TestSomething(t *testing.T) { 12 | // 13 | // var a string = "Hello" 14 | // var b string = "Hello" 15 | // 16 | // assert.Equal(t, a, b, "The two words should be the same.") 17 | // 18 | // } 19 | // 20 | // if you assert many times, use the format below: 21 | // 22 | // import ( 23 | // "testing" 24 | // "github.com/stretchr/testify/assert" 25 | // ) 26 | // 27 | // func TestSomething(t *testing.T) { 28 | // assert := assert.New(t) 29 | // 30 | // var a string = "Hello" 31 | // var b string = "Hello" 32 | // 33 | // assert.Equal(a, b, "The two words should be the same.") 34 | // } 35 | // 36 | // Assertions 37 | // 38 | // Assertions allow you to easily write test code, and are global funcs in the `assert` package. 39 | // All assertion functions take, as the first argument, the `*testing.T` object provided by the 40 | // testing framework. This allows the assertion funcs to write the failings and other details to 41 | // the correct place. 42 | // 43 | // Every assertion function also takes an optional string message as the final argument, 44 | // allowing custom error messages to be appended to the message the assertion method outputs. 45 | package assert 46 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/stretchr/testify/assert/errors.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | // AnError is an error instance useful for testing. If the code does not care 8 | // about error specifics, and only needs to return the error for example, this 9 | // error should be used to make the test code more readable. 10 | var AnError = errors.New("assert.AnError general error for testing") 11 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/stretchr/testify/assert/forward_assertions.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | // Assertions provides assertion methods around the 4 | // TestingT interface. 5 | type Assertions struct { 6 | t TestingT 7 | } 8 | 9 | // New makes a new Assertions object for the specified TestingT. 10 | func New(t TestingT) *Assertions { 11 | return &Assertions{ 12 | t: t, 13 | } 14 | } 15 | 16 | //go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_forward.go.tmpl 17 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/LICENCE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell 2 | 3 | Please consider promoting this project if you find it useful. 4 | 5 | Permission is hereby granted, free of charge, to any person 6 | obtaining a copy of this software and associated documentation 7 | files (the "Software"), to deal in the Software without restriction, 8 | including without limitation the rights to use, copy, modify, merge, 9 | publish, distribute, sublicense, and/or sell copies of the Software, 10 | and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 21 | OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 22 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell 2 | 3 | Please consider promoting this project if you find it useful. 4 | 5 | Permission is hereby granted, free of charge, to any person 6 | obtaining a copy of this software and associated documentation 7 | files (the "Software"), to deal in the Software without restriction, 8 | including without limitation the rights to use, copy, modify, merge, 9 | publish, distribute, sublicense, and/or sell copies of the Software, 10 | and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 21 | OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 22 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Dave Collins 2 | // 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when the code is running on Google App Engine, compiled by GopherJS, or 17 | // "-tags safe" is added to the go build command line. The "disableunsafe" 18 | // tag is deprecated and thus should not be used. 19 | // +build js appengine safe disableunsafe 20 | 21 | package spew 22 | 23 | import "reflect" 24 | 25 | const ( 26 | // UnsafeDisabled is a build-time constant which specifies whether or 27 | // not access to the unsafe package is available. 28 | UnsafeDisabled = true 29 | ) 30 | 31 | // unsafeReflectValue typically converts the passed reflect.Value into a one 32 | // that bypasses the typical safety restrictions preventing access to 33 | // unaddressable and unexported data. However, doing this relies on access to 34 | // the unsafe package. This is a stub version which simply returns the passed 35 | // reflect.Value when the unsafe package is not available. 36 | func unsafeReflectValue(v reflect.Value) reflect.Value { 37 | return v 38 | } 39 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/stretchr/testify/vendor/github.com/pmezard/go-difflib/difflib/LICENCE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell 2 | 3 | Please consider promoting this project if you find it useful. 4 | 5 | Permission is hereby granted, free of charge, to any person 6 | obtaining a copy of this software and associated documentation 7 | files (the "Software"), to deal in the Software without restriction, 8 | including without limitation the rights to use, copy, modify, merge, 9 | publish, distribute, sublicense, and/or sell copies of the Software, 10 | and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 21 | OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 22 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/github.com/stretchr/testify/vendor/github.com/pmezard/go-difflib/difflib/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell 2 | 3 | Please consider promoting this project if you find it useful. 4 | 5 | Permission is hereby granted, free of charge, to any person 6 | obtaining a copy of this software and associated documentation 7 | files (the "Software"), to deal in the Software without restriction, 8 | including without limitation the rights to use, copy, modify, merge, 9 | publish, distribute, sublicense, and/or sell copies of the Software, 10 | and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 21 | OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 22 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/gopkg.in/alecthomas/kingpin.v2/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (C) 2014 Alec Thomas 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/gopkg.in/alecthomas/kingpin.v2/actions.go: -------------------------------------------------------------------------------- 1 | package kingpin 2 | 3 | // Action callback executed at various stages after all values are populated. 4 | // The application, commands, arguments and flags all have corresponding 5 | // actions. 6 | type Action func(*ParseContext) error 7 | 8 | type actionMixin struct { 9 | actions []Action 10 | preActions []Action 11 | } 12 | 13 | type actionApplier interface { 14 | applyActions(*ParseContext) error 15 | applyPreActions(*ParseContext) error 16 | } 17 | 18 | func (a *actionMixin) addAction(action Action) { 19 | a.actions = append(a.actions, action) 20 | } 21 | 22 | func (a *actionMixin) addPreAction(action Action) { 23 | a.preActions = append(a.preActions, action) 24 | } 25 | 26 | func (a *actionMixin) applyActions(context *ParseContext) error { 27 | for _, action := range a.actions { 28 | if err := action(context); err != nil { 29 | return err 30 | } 31 | } 32 | return nil 33 | } 34 | 35 | func (a *actionMixin) applyPreActions(context *ParseContext) error { 36 | for _, preAction := range a.preActions { 37 | if err := preAction(context); err != nil { 38 | return err 39 | } 40 | } 41 | return nil 42 | } 43 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/gopkg.in/alecthomas/kingpin.v2/cmd/genvalues/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "os" 6 | "os/exec" 7 | "strings" 8 | 9 | "github.com/alecthomas/template" 10 | ) 11 | 12 | const ( 13 | tmpl = `package kingpin 14 | 15 | // This file is autogenerated by "go generate .". Do not modify. 16 | 17 | {{range .}} 18 | {{if not .NoValueParser}} 19 | // -- {{.Type}} Value 20 | type {{.|ValueName}} struct { v *{{.Type}} } 21 | 22 | func new{{.|Name}}Value(p *{{.Type}}) *{{.|ValueName}} { 23 | return &{{.|ValueName}}{p} 24 | } 25 | 26 | func (f *{{.|ValueName}}) Set(s string) error { 27 | v, err := {{.Parser}} 28 | if err == nil { 29 | *f.v = ({{.Type}})(v) 30 | } 31 | return err 32 | } 33 | 34 | func (f *{{.|ValueName}}) Get() interface{} { return ({{.Type}})(*f.v) } 35 | 36 | func (f *{{.|ValueName}}) String() string { return {{.|Format}} } 37 | 38 | {{if .Help}} 39 | // {{.Help}} 40 | {{else}}\ 41 | // {{.|Name}} parses the next command-line value as {{.Type}}. 42 | {{end}}\ 43 | func (p *parserMixin) {{.|Name}}() (target *{{.Type}}) { 44 | target = new({{.Type}}) 45 | p.{{.|Name}}Var(target) 46 | return 47 | } 48 | 49 | func (p *parserMixin) {{.|Name}}Var(target *{{.Type}}) { 50 | p.SetValue(new{{.|Name}}Value(target)) 51 | } 52 | 53 | {{end}} 54 | // {{.|Plural}} accumulates {{.Type}} values into a slice. 55 | func (p *parserMixin) {{.|Plural}}() (target *[]{{.Type}}) { 56 | target = new([]{{.Type}}) 57 | p.{{.|Plural}}Var(target) 58 | return 59 | } 60 | 61 | func (p *parserMixin) {{.|Plural}}Var(target *[]{{.Type}}) { 62 | p.SetValue(newAccumulator(target, func(v interface{}) Value { 63 | return new{{.|Name}}Value(v.(*{{.Type}})) 64 | })) 65 | } 66 | 67 | {{end}} 68 | ` 69 | ) 70 | 71 | type Value struct { 72 | Name string `json:"name"` 73 | NoValueParser bool `json:"no_value_parser"` 74 | Type string `json:"type"` 75 | Parser string `json:"parser"` 76 | Format string `json:"format"` 77 | Plural string `json:"plural"` 78 | Help string `json:"help"` 79 | } 80 | 81 | func fatalIfError(err error) { 82 | if err != nil { 83 | panic(err) 84 | } 85 | } 86 | 87 | func main() { 88 | r, err := os.Open("values.json") 89 | fatalIfError(err) 90 | defer r.Close() 91 | 92 | v := []Value{} 93 | err = json.NewDecoder(r).Decode(&v) 94 | fatalIfError(err) 95 | 96 | valueName := func(v *Value) string { 97 | if v.Name != "" { 98 | return v.Name 99 | } 100 | return strings.Title(v.Type) 101 | } 102 | 103 | t, err := template.New("genvalues").Funcs(template.FuncMap{ 104 | "Lower": strings.ToLower, 105 | "Format": func(v *Value) string { 106 | if v.Format != "" { 107 | return v.Format 108 | } 109 | return "fmt.Sprintf(\"%v\", *f)" 110 | }, 111 | "ValueName": func(v *Value) string { 112 | name := valueName(v) 113 | return strings.ToLower(name[0:1]) + name[1:] + "Value" 114 | }, 115 | "Name": valueName, 116 | "Plural": func(v *Value) string { 117 | if v.Plural != "" { 118 | return v.Plural 119 | } 120 | return valueName(v) + "List" 121 | }, 122 | }).Parse(tmpl) 123 | fatalIfError(err) 124 | 125 | w, err := os.Create("values_generated.go") 126 | fatalIfError(err) 127 | defer w.Close() 128 | 129 | err = t.Execute(w, v) 130 | fatalIfError(err) 131 | 132 | err = exec.Command("goimports", "-w", "values_generated.go").Run() 133 | fatalIfError(err) 134 | } 135 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/gopkg.in/alecthomas/kingpin.v2/completions.go: -------------------------------------------------------------------------------- 1 | package kingpin 2 | 3 | // HintAction is a function type who is expected to return a slice of possible 4 | // command line arguments. 5 | type HintAction func() []string 6 | type completionsMixin struct { 7 | hintActions []HintAction 8 | builtinHintActions []HintAction 9 | } 10 | 11 | func (a *completionsMixin) addHintAction(action HintAction) { 12 | a.hintActions = append(a.hintActions, action) 13 | } 14 | 15 | // Allow adding of HintActions which are added internally, ie, EnumVar 16 | func (a *completionsMixin) addHintActionBuiltin(action HintAction) { 17 | a.builtinHintActions = append(a.builtinHintActions, action) 18 | } 19 | 20 | func (a *completionsMixin) resolveCompletions() []string { 21 | var hints []string 22 | 23 | options := a.builtinHintActions 24 | if len(a.hintActions) > 0 { 25 | // User specified their own hintActions. Use those instead. 26 | options = a.hintActions 27 | } 28 | 29 | for _, hintAction := range options { 30 | hints = append(hints, hintAction()...) 31 | } 32 | return hints 33 | } 34 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/gopkg.in/alecthomas/kingpin.v2/doc.go: -------------------------------------------------------------------------------- 1 | // Package kingpin provides command line interfaces like this: 2 | // 3 | // $ chat 4 | // usage: chat [] [] [ ...] 5 | // 6 | // Flags: 7 | // --debug enable debug mode 8 | // --help Show help. 9 | // --server=127.0.0.1 server address 10 | // 11 | // Commands: 12 | // help 13 | // Show help for a command. 14 | // 15 | // post [] 16 | // Post a message to a channel. 17 | // 18 | // register 19 | // Register a new user. 20 | // 21 | // $ chat help post 22 | // usage: chat [] post [] [] 23 | // 24 | // Post a message to a channel. 25 | // 26 | // Flags: 27 | // --image=IMAGE image to post 28 | // 29 | // Args: 30 | // channel to post to 31 | // [] text to post 32 | // $ chat post --image=~/Downloads/owls.jpg pics 33 | // 34 | // From code like this: 35 | // 36 | // package main 37 | // 38 | // import "gopkg.in/alecthomas/kingpin.v1" 39 | // 40 | // var ( 41 | // debug = kingpin.Flag("debug", "enable debug mode").Default("false").Bool() 42 | // serverIP = kingpin.Flag("server", "server address").Default("127.0.0.1").IP() 43 | // 44 | // register = kingpin.Command("register", "Register a new user.") 45 | // registerNick = register.Arg("nick", "nickname for user").Required().String() 46 | // registerName = register.Arg("name", "name of user").Required().String() 47 | // 48 | // post = kingpin.Command("post", "Post a message to a channel.") 49 | // postImage = post.Flag("image", "image to post").ExistingFile() 50 | // postChannel = post.Arg("channel", "channel to post to").Required().String() 51 | // postText = post.Arg("text", "text to post").String() 52 | // ) 53 | // 54 | // func main() { 55 | // switch kingpin.Parse() { 56 | // // Register user 57 | // case "register": 58 | // println(*registerNick) 59 | // 60 | // // Post message 61 | // case "post": 62 | // if *postImage != nil { 63 | // } 64 | // if *postText != "" { 65 | // } 66 | // } 67 | // } 68 | package kingpin 69 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/gopkg.in/alecthomas/kingpin.v2/envar.go: -------------------------------------------------------------------------------- 1 | package kingpin 2 | 3 | import ( 4 | "os" 5 | "regexp" 6 | ) 7 | 8 | var ( 9 | envVarValuesSeparator = "\r?\n" 10 | envVarValuesTrimmer = regexp.MustCompile(envVarValuesSeparator + "$") 11 | envVarValuesSplitter = regexp.MustCompile(envVarValuesSeparator) 12 | ) 13 | 14 | type envarMixin struct { 15 | envar string 16 | noEnvar bool 17 | } 18 | 19 | func (e *envarMixin) HasEnvarValue() bool { 20 | return e.GetEnvarValue() != "" 21 | } 22 | 23 | func (e *envarMixin) GetEnvarValue() string { 24 | if e.noEnvar || e.envar == "" { 25 | return "" 26 | } 27 | return os.Getenv(e.envar) 28 | } 29 | 30 | func (e *envarMixin) GetSplitEnvarValue() []string { 31 | values := make([]string, 0) 32 | 33 | envarValue := e.GetEnvarValue() 34 | if envarValue == "" { 35 | return values 36 | } 37 | 38 | // Split by new line to extract multiple values, if any. 39 | trimmed := envVarValuesTrimmer.ReplaceAllString(envarValue, "") 40 | for _, value := range envVarValuesSplitter.Split(trimmed, -1) { 41 | values = append(values, value) 42 | } 43 | 44 | return values 45 | } 46 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/gopkg.in/alecthomas/kingpin.v2/global.go: -------------------------------------------------------------------------------- 1 | package kingpin 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | ) 7 | 8 | var ( 9 | // CommandLine is the default Kingpin parser. 10 | CommandLine = New(filepath.Base(os.Args[0]), "") 11 | // Global help flag. Exposed for user customisation. 12 | HelpFlag = CommandLine.HelpFlag 13 | // Top-level help command. Exposed for user customisation. May be nil. 14 | HelpCommand = CommandLine.HelpCommand 15 | // Global version flag. Exposed for user customisation. May be nil. 16 | VersionFlag = CommandLine.VersionFlag 17 | ) 18 | 19 | // Command adds a new command to the default parser. 20 | func Command(name, help string) *CmdClause { 21 | return CommandLine.Command(name, help) 22 | } 23 | 24 | // Flag adds a new flag to the default parser. 25 | func Flag(name, help string) *FlagClause { 26 | return CommandLine.Flag(name, help) 27 | } 28 | 29 | // Arg adds a new argument to the top-level of the default parser. 30 | func Arg(name, help string) *ArgClause { 31 | return CommandLine.Arg(name, help) 32 | } 33 | 34 | // Parse and return the selected command. Will call the termination handler if 35 | // an error is encountered. 36 | func Parse() string { 37 | selected := MustParse(CommandLine.Parse(os.Args[1:])) 38 | if selected == "" && CommandLine.cmdGroup.have() { 39 | Usage() 40 | CommandLine.terminate(0) 41 | } 42 | return selected 43 | } 44 | 45 | // Errorf prints an error message to stderr. 46 | func Errorf(format string, args ...interface{}) { 47 | CommandLine.Errorf(format, args...) 48 | } 49 | 50 | // Fatalf prints an error message to stderr and exits. 51 | func Fatalf(format string, args ...interface{}) { 52 | CommandLine.Fatalf(format, args...) 53 | } 54 | 55 | // FatalIfError prints an error and exits if err is not nil. The error is printed 56 | // with the given prefix. 57 | func FatalIfError(err error, format string, args ...interface{}) { 58 | CommandLine.FatalIfError(err, format, args...) 59 | } 60 | 61 | // FatalUsage prints an error message followed by usage information, then 62 | // exits with a non-zero status. 63 | func FatalUsage(format string, args ...interface{}) { 64 | CommandLine.FatalUsage(format, args...) 65 | } 66 | 67 | // FatalUsageContext writes a printf formatted error message to stderr, then 68 | // usage information for the given ParseContext, before exiting. 69 | func FatalUsageContext(context *ParseContext, format string, args ...interface{}) { 70 | CommandLine.FatalUsageContext(context, format, args...) 71 | } 72 | 73 | // Usage prints usage to stderr. 74 | func Usage() { 75 | CommandLine.Usage(os.Args[1:]) 76 | } 77 | 78 | // Set global usage template to use (defaults to DefaultUsageTemplate). 79 | func UsageTemplate(template string) *Application { 80 | return CommandLine.UsageTemplate(template) 81 | } 82 | 83 | // MustParse can be used with app.Parse(args) to exit with an error if parsing fails. 84 | func MustParse(command string, err error) string { 85 | if err != nil { 86 | Fatalf("%s, try --help", err) 87 | } 88 | return command 89 | } 90 | 91 | // Version adds a flag for displaying the application version number. 92 | func Version(version string) *Application { 93 | return CommandLine.Version(version) 94 | } 95 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/gopkg.in/alecthomas/kingpin.v2/guesswidth.go: -------------------------------------------------------------------------------- 1 | // +build appengine !linux,!freebsd,!darwin,!dragonfly,!netbsd,!openbsd 2 | 3 | package kingpin 4 | 5 | import "io" 6 | 7 | func guessWidth(w io.Writer) int { 8 | return 80 9 | } 10 | -------------------------------------------------------------------------------- /gometalinter/_vendored/src/gopkg.in/alecthomas/kingpin.v2/guesswidth_unix.go: -------------------------------------------------------------------------------- 1 | // +build !appengine,linux freebsd darwin dragonfly netbsd openbsd 2 | 3 | package kingpin 4 | 5 | import ( 6 | "io" 7 | "os" 8 | "strconv" 9 | "syscall" 10 | "unsafe" 11 | ) 12 | 13 | func guessWidth(w io.Writer) int { 14 | // check if COLUMNS env is set to comply with 15 | // http://pubs.opengroup.org/onlinepubs/009604499/basedefs/xbd_chap08.html 16 | colsStr := os.Getenv("COLUMNS") 17 | if colsStr != "" { 18 | if cols, err := strconv.Atoi(colsStr); err == nil { 19 | return cols 20 | } 21 | } 22 | 23 | if t, ok := w.(*os.File); ok { 24 | fd := t.Fd() 25 | var dimensions [4]uint16 26 | 27 | if _, _, err := syscall.Syscall6( 28 | syscall.SYS_IOCTL, 29 | uintptr(fd), 30 | uintptr(syscall.TIOCGWINSZ), 31 | uintptr(unsafe.Pointer(&dimensions)), 32 | 0, 0, 0, 33 | ); err == 0 { 34 | return int(dimensions[1]) 35 | } 36 | } 37 | return 80 38 | } 39 | -------------------------------------------------------------------------------- /gometalinter/metalinter_test.go: -------------------------------------------------------------------------------- 1 | package gometalinter_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "log" 7 | 8 | "github.com/surullabs/lint/gometalinter" 9 | "github.com/surullabs/lint/testutil" 10 | ) 11 | 12 | func TestMetaLinter(t *testing.T) { 13 | testutil.Test(t, "gometalintertest", []testutil.StaticCheckTest{ 14 | { 15 | Checker: gometalinter.Check{}, 16 | Content: []byte(`package gometalintertest 17 | import ( 18 | "fmt" 19 | ) 20 | 21 | // TestFunc is a test function 22 | func TestFunc() { 23 | fmt.Println("This is a properly formatted file") 24 | } 25 | `), 26 | Validate: testutil.NoError, 27 | }, 28 | { 29 | Checker: gometalinter.Check{}, 30 | Content: []byte(`package gometalintertest 31 | 32 | import ( 33 | "fmt" 34 | ) 35 | sfsff 36 | 37 | func TestFunc() { 38 | fmt.Println("undocumented") 39 | } 40 | `), 41 | Validate: testutil.Contains("expected declaration, found 'IDENT' sfsff"), 42 | }, 43 | { 44 | Checker: gometalinter.Check{}, 45 | Content: []byte(`package gometalintertest 46 | import ( 47 | "fmt" 48 | ) 49 | 50 | func TestFunc() { 51 | fmt.Println("This is a properly formatted file") 52 | } 53 | `), 54 | Validate: testutil.HasSuffix( 55 | "file.go:6:1:warning: exported function TestFunc should have comment or be unexported (golint)"), 56 | }, 57 | { 58 | Checker: gometalinter.Check{}, 59 | Content: []byte(`package gometalintertest 60 | func TestFunc() { 61 | } 62 | `), 63 | Validate: testutil.SkippedErrors( 64 | `exported function TestFunc should have comment or be unexported`), 65 | }, 66 | }, 67 | ) 68 | } 69 | 70 | func Example() { 71 | metalinter := gometalinter.Check{ 72 | Args: []string{ 73 | // These are not recommendations for linters to disable. 74 | "--disable=gocyclo", 75 | "--disable=gas", 76 | "--deadline=20s", 77 | }, 78 | } 79 | if err := metalinter.Check("./..."); err != nil { 80 | log.Fatal(err) 81 | } 82 | 83 | // Output: 84 | } 85 | -------------------------------------------------------------------------------- /gosimple/gosimple.go: -------------------------------------------------------------------------------- 1 | package gosimple 2 | 3 | import ( 4 | "github.com/surullabs/lint/checkers" 5 | _ "honnef.co/go/tools/simple" // Ensure the gosimple bin is downloaded. 6 | ) 7 | 8 | // Check implements a gosimple Checker (https://github.com/dominikh/go-simple) 9 | type Check struct { 10 | // Tags is a list of space separated build tags 11 | Tags string 12 | } 13 | 14 | // Check runs gosimple for pkg 15 | func (c Check) Check(pkgs ...string) error { 16 | return checkers.Lint("gosimple", "", "honnef.co/go/tools/cmd/gosimple", pkgs, c.Args()...) 17 | } 18 | 19 | // Args returns command line arguments used for gosimple 20 | func (c Check) Args() []string { 21 | var args []string 22 | if c.Tags != "" { 23 | args = append(args, "-tags", c.Tags) 24 | } 25 | return args 26 | } 27 | -------------------------------------------------------------------------------- /gosimple/gosimple_test.go: -------------------------------------------------------------------------------- 1 | package gosimple_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/surullabs/lint/gosimple" 7 | "github.com/surullabs/lint/testutil" 8 | ) 9 | 10 | func TestGosimple(t *testing.T) { 11 | testutil.Test(t, "gosimpletest", []testutil.StaticCheckTest{ 12 | { 13 | Checker: gosimple.Check{}, 14 | Content: []byte(`package gosimpletest 15 | import ( 16 | "fmt" 17 | ) 18 | 19 | // TestFunc is a test function 20 | func TestFunc() { 21 | fmt.Println("This is a properly formatted file") 22 | } 23 | `), 24 | Validate: testutil.NoError, 25 | }, 26 | { 27 | Checker: gosimple.Check{}, 28 | Content: []byte(`package gosimpletest 29 | 30 | import ( 31 | "fmt" 32 | ) 33 | sfsff 34 | 35 | func TestFunc() { 36 | fmt.Println("undocumented") 37 | } 38 | `), 39 | Validate: testutil.Contains("expected declaration, found 'IDENT' sfsff"), 40 | }, 41 | { 42 | Checker: gosimple.Check{}, 43 | Content: []byte(`package gosimpletest 44 | 45 | func TestFunc() { 46 | for _ = range []string{"a", "b"} { 47 | } 48 | } 49 | `), 50 | Validate: testutil.Contains( 51 | "should omit values from range; this loop is equivalent to `for range ...`"), 52 | }, 53 | }, 54 | ) 55 | } 56 | 57 | func TestGosimpleMultiFile(t *testing.T) { 58 | test := testutil.StaticCheckMultiFileTest{ 59 | Contents: [][]byte{ 60 | []byte(`package gosimpletest 61 | 62 | func main() { 63 | f() 64 | } 65 | `), 66 | []byte(`// +build tag 67 | 68 | package gosimpletest 69 | 70 | func f() { 71 | b := true 72 | if b == true { 73 | } 74 | } 75 | `), 76 | }, 77 | Checker: gosimple.Check{Tags: "tag"}, 78 | Validate: testutil.Contains(" should omit comparison to bool constant"), 79 | } 80 | 81 | if err := test.Test("gosimpletest"); err != nil { 82 | t.Error("Check", err) 83 | } 84 | } 85 | 86 | func TestArgs(t *testing.T) { 87 | testutil.TestArgs(t, []testutil.ArgTest{ 88 | {A: gosimple.Check{}, Expected: nil}, 89 | {A: gosimple.Check{Tags: "test"}, Expected: []string{"-tags", "test"}}, 90 | }) 91 | } 92 | -------------------------------------------------------------------------------- /gostaticcheck/gostaticcheck.go: -------------------------------------------------------------------------------- 1 | package gostaticcheck 2 | 3 | import ( 4 | "github.com/surullabs/lint/checkers" 5 | _ "honnef.co/go/tools/staticcheck" // Ensure the staticcheck bin is downloaded. 6 | ) 7 | 8 | // Check implements a gostaticcheck Checker (https://github.com/dominikh/go-staticcheck) 9 | type Check struct { 10 | // Tags is a list of space separated build tags 11 | Tags string 12 | } 13 | 14 | // Check runs gostaticcheck for pkgs 15 | func (c Check) Check(pkgs ...string) error { 16 | return checkers.Lint("staticcheck", "", "honnef.co/go/tools/cmd/staticcheck", pkgs, c.Args()...) 17 | } 18 | 19 | // Args returns command line arguments used for staticcheck 20 | func (c Check) Args() []string { 21 | var args []string 22 | if c.Tags != "" { 23 | args = append(args, "-tags", c.Tags) 24 | } 25 | return args 26 | } 27 | -------------------------------------------------------------------------------- /gostaticcheck/gostaticcheck_test.go: -------------------------------------------------------------------------------- 1 | package gostaticcheck_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/surullabs/lint/gostaticcheck" 7 | "github.com/surullabs/lint/testutil" 8 | ) 9 | 10 | func TestGostaticcheck(t *testing.T) { 11 | testutil.Test(t, "gostaticchecktest", []testutil.StaticCheckTest{ 12 | { 13 | Checker: gostaticcheck.Check{}, 14 | Content: []byte(`package gostaticchecktest 15 | import ( 16 | "fmt" 17 | ) 18 | 19 | // TestFunc is a test function 20 | func TestFunc() { 21 | fmt.Println("This is a properly formatted file") 22 | } 23 | `), 24 | Validate: testutil.NoError, 25 | }, 26 | { 27 | Checker: gostaticcheck.Check{}, 28 | Content: []byte(`package gostaticchecktest 29 | 30 | import ( 31 | "fmt" 32 | ) 33 | sfsff 34 | 35 | func TestFunc() { 36 | fmt.Println("undocumented") 37 | } 38 | `), 39 | Validate: testutil.Contains("expected declaration, found 'IDENT' sfsff"), 40 | }, 41 | { 42 | Checker: gostaticcheck.Check{}, 43 | Content: []byte(`package gostaticchecktest 44 | import ( 45 | "regexp" 46 | ) 47 | 48 | func TestFunc() { 49 | regexp.Compile("foo(") 50 | } 51 | `), 52 | Validate: testutil.Contains( 53 | " error parsing regexp: missing closing ): `foo(`"), 54 | }, 55 | }, 56 | ) 57 | } 58 | 59 | func TestGostaticcheckMultiFile(t *testing.T) { 60 | test := testutil.StaticCheckMultiFileTest{ 61 | Contents: [][]byte{ 62 | []byte(`package gostaticchecktest 63 | 64 | func main() { 65 | f() 66 | } 67 | `), 68 | []byte(`// +build tag 69 | 70 | package gostaticchecktest 71 | 72 | func f() { 73 | b := true 74 | if !!b { 75 | } 76 | } 77 | `), 78 | }, 79 | Checker: gostaticcheck.Check{Tags: "tag"}, 80 | Validate: testutil.Contains(" negating a boolean twice has no effect"), 81 | } 82 | 83 | if err := test.Test("gostaticchecktest"); err != nil { 84 | t.Error("Check", err) 85 | } 86 | } 87 | 88 | func TestArgs(t *testing.T) { 89 | testutil.TestArgs(t, []testutil.ArgTest{ 90 | {A: gostaticcheck.Check{}, Expected: nil}, 91 | {A: gostaticcheck.Check{Tags: "test"}, Expected: []string{"-tags", "test"}}, 92 | }) 93 | } 94 | -------------------------------------------------------------------------------- /govet/govet.go: -------------------------------------------------------------------------------- 1 | package govet 2 | 3 | import ( 4 | "os/exec" 5 | "strings" 6 | 7 | "github.com/surullabs/lint/checkers" 8 | ) 9 | 10 | // Check implements a lint.Checker for the govet command. 11 | type Check struct { 12 | Args []string 13 | } 14 | 15 | // Shadow is a Checker that runs 16 | // go tool vet --all --shadow. 17 | var Shadow = Check{Args: []string{"--all", "--shadow"}} 18 | 19 | // Check runs go tool vet for pkgs. 20 | func (c Check) Check(pkgs ...string) error { 21 | var errs []string 22 | for _, pkg := range pkgs { 23 | // Check files per package. If all files for all packages are 24 | // passed in as a glob, it causes incorrect reports as described 25 | // in TestGoVetMultiPackage_Issue7. Instead run go vet for each package. 26 | errs = append(errs, c.checkPackage(pkg)...) 27 | } 28 | return checkers.Error(errs...) 29 | } 30 | 31 | func (c Check) checkPackage(pkg string) []string { 32 | if strings.HasSuffix(pkg, "...") { 33 | return c.checkDir(pkg) 34 | } 35 | files, err := checkers.GoFiles(pkg) 36 | if err != nil { 37 | return []string{err.Error()} 38 | } 39 | return c.runVet(files) 40 | } 41 | 42 | func (c Check) runVet(paths []string) []string { 43 | if len(paths) == 0 { 44 | return nil 45 | } 46 | args := append([]string{"tool", "vet"}, append(c.Args, paths...)...) 47 | res, err := checkers.Exec(exec.Command("go", args...)) 48 | if err == nil { 49 | return nil 50 | } 51 | switch res.Code { 52 | case 1: 53 | return strings.Split(strings.TrimSpace(res.Stderr), "\n") 54 | default: 55 | return []string{err.Error()} 56 | } 57 | } 58 | 59 | func (c Check) checkDir(pkg string) []string { 60 | p, err := checkers.Load(pkg) 61 | if err != nil { 62 | return []string{err.Error()} 63 | } 64 | // Loop through each package since we'd like to ignore directories which have 65 | // an _ prefix. In the future this allows us to skip vendor directories as well. 66 | var errs []string 67 | for _, pkg := range p.Pkgs { 68 | errs = append(errs, c.checkPackage(pkg)...) 69 | } 70 | return errs 71 | } 72 | -------------------------------------------------------------------------------- /lint.go: -------------------------------------------------------------------------------- 1 | // Package lint runs linters as part of go test. 2 | // 3 | // It is intended to be used as a substitute for an external build 4 | // step that runs tools such as go vet or golint. 5 | // 6 | package lint 7 | 8 | import ( 9 | "reflect" 10 | 11 | "github.com/surullabs/lint/checkers" 12 | "github.com/surullabs/lint/errcheck" 13 | "github.com/surullabs/lint/gofmt" 14 | "github.com/surullabs/lint/golint" 15 | "github.com/surullabs/lint/gosimple" 16 | "github.com/surullabs/lint/gostaticcheck" 17 | "github.com/surullabs/lint/govet" 18 | ) 19 | 20 | // Default holds a default list of lint tools for convenient use. These include 21 | // 22 | // - gofmt -d 23 | // - go tool vet -shadow 24 | // - golint 25 | // - gosimple (https://github.com/dominikh/go-simple) 26 | // - gostaticcheck (https://github.com/dominikh/go-staticcheck) 27 | // - errcheck (https://github.com/kisielk/errcheck) 28 | var Default = Group{ 29 | gofmt.Check{}, // Verify that all files are properly formatted 30 | govet.Shadow, // go vet 31 | golint.Check{}, // golint 32 | gosimple.Check{}, // honnef.co/go/simple 33 | gostaticcheck.Check{}, // honnef.co/go/staticcheck 34 | errcheck.Check{}, 35 | } 36 | 37 | type errors interface { 38 | Errors() []string 39 | } 40 | 41 | // Checker is the interface that wraps the Check method. 42 | // 43 | // Check lints all files in pkgs. Each item in pkgs may be a fully 44 | // qualified import path, relative import path or a path with the wildcard 45 | // suffix ... 46 | type Checker interface { 47 | Check(pkgs ...string) error 48 | } 49 | 50 | // Group is a Checker list that is applied in sequence. See Check for details on 51 | // how it is applied. 52 | type Group []Checker 53 | 54 | // Check applies each of checkers in g in the order provided. 55 | // 56 | // The error returned is either nil or contains errors returned by each Checker. 57 | // These are exposed using the errors interface described in Skip and prefixed with the type of the 58 | // Checker that generated the error. For example, the following error generated by govet.Checker: 59 | // 60 | // file.go:23: err is unintentionally shadowed. 61 | // 62 | // is converted to: 63 | // 64 | // govet.Checker: file.go:23: err is unintentionally shadowed. 65 | // 66 | // A checker is not shorted-circuited by a previous checker returning an error. 67 | // 68 | // Any error that implements errors is flattened into the final error list. 69 | func (g Group) Check(pkgs ...string) error { 70 | var errs []string 71 | for _, checker := range g { 72 | name := reflect.TypeOf(checker).String() 73 | switch err := checker.Check(pkgs...).(type) { 74 | case nil: 75 | continue 76 | case errors: 77 | cerrs := err.Errors() 78 | for _, e := range cerrs { 79 | errs = append(errs, name+": "+e) 80 | } 81 | default: 82 | errs = append(errs, name+": "+err.Error()) 83 | } 84 | } 85 | if len(errs) == 0 { 86 | return nil 87 | } 88 | return checkers.Error(errs...) 89 | } 90 | 91 | // With returns a copy of g with checkers appended 92 | func (g Group) With(checkers ...Checker) Group { 93 | copied := make([]Checker, len(g)) 94 | copy(copied, g) 95 | return Group(append(copied, checkers...)) 96 | } 97 | -------------------------------------------------------------------------------- /skip.go: -------------------------------------------------------------------------------- 1 | package lint 2 | 3 | import ( 4 | "regexp" 5 | 6 | "github.com/surullabs/lint/checkers" 7 | ) 8 | 9 | // Skipper is the interface that wraps the Skip method. 10 | // 11 | // Skip returns true if err is an error that must be ignored. 12 | type Skipper interface { 13 | Skip(err string) bool 14 | } 15 | 16 | // StringSkipper implements Skipper and skips an error if Matcher(err, str) == true for 17 | // any of Strings 18 | type StringSkipper struct { 19 | Strings []string 20 | Matcher func(err, str string) bool 21 | } 22 | 23 | // Skip returns true if Matcher(check, str) == true for any of Strings. 24 | func (s StringSkipper) Skip(check string) bool { 25 | for _, str := range s.Strings { 26 | if s.Matcher(check, str) { 27 | return true 28 | } 29 | } 30 | return false 31 | } 32 | 33 | func skip(check string, skippers []Skipper) bool { 34 | for _, s := range skippers { 35 | if s.Skip(check) { 36 | return true 37 | } 38 | } 39 | return false 40 | } 41 | 42 | // Skip filters errors using skippers. If err satisfies the below interface 43 | // 44 | // type errors interface { 45 | // Errors() []string 46 | // } 47 | // 48 | // the filters are applied to each string returned by Errors and then concatenated. 49 | // If the error implements the above interface, it is guaranteed that any returned 50 | // error will also implement the same. 51 | // 52 | // Skippers are run in the order provided and a single 53 | // skipper returning true will result in that error being skipped. 54 | func Skip(err error, skippers ...Skipper) error { 55 | switch serr := err.(type) { 56 | case nil: 57 | return nil 58 | case errors: 59 | var n []string 60 | errs := serr.Errors() 61 | for _, e := range errs { 62 | if !skip(e, skippers) { 63 | n = append(n, e) 64 | } 65 | } 66 | if len(n) == 0 { 67 | return nil 68 | } 69 | return checkers.Error(n...) 70 | default: 71 | if skip(serr.Error(), skippers) { 72 | return nil 73 | } 74 | return serr 75 | } 76 | } 77 | 78 | // RegexpMatch returns a Skipper that skips all errors which match 79 | // any of the provided regular expression patterns. SkipRegexpMatch expects 80 | // all patterns to be valid regexps and panics otherwise. 81 | func RegexpMatch(regexps ...string) Skipper { 82 | return StringSkipper{ 83 | Strings: regexps, 84 | Matcher: func(errstr, pattern string) bool { 85 | matched, err := regexp.MatchString(pattern, errstr) 86 | if err != nil { 87 | panic(err) 88 | } 89 | return matched 90 | }, 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /structcheck/structcheck.go: -------------------------------------------------------------------------------- 1 | // Package structcheck provides lint integration for the structcheck linter 2 | package structcheck 3 | 4 | import "github.com/surullabs/lint/checkers" 5 | 6 | // Check runs the structcheck linter (https://github.com/opennota/check) 7 | type Check struct { 8 | // ReportExported reports exported fields that are unused 9 | ReportExported bool 10 | // OnlyCountAssignments ensures only assignments are counted 11 | OnlyCountAssignments bool 12 | // IncludeTests loads test files 13 | IncludeTests bool 14 | } 15 | 16 | // Check runs structcheck and returns any errors found. 17 | func (c Check) Check(pkgs ...string) error { 18 | return checkers.Lint("structcheck", 19 | "github.com/opennota/check", 20 | "github.com/opennota/check/cmd/structcheck", pkgs, c.Args()...) 21 | } 22 | 23 | // Args returns command line flags for structcheck 24 | func (c Check) Args() []string { 25 | var args []string 26 | if c.ReportExported { 27 | args = append(args, "-e") 28 | } 29 | if c.OnlyCountAssignments { 30 | args = append(args, "-a") 31 | } 32 | if c.IncludeTests { 33 | args = append(args, "-t") 34 | } 35 | return args 36 | } 37 | -------------------------------------------------------------------------------- /structcheck/structcheck_test.go: -------------------------------------------------------------------------------- 1 | package structcheck_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/surullabs/lint/structcheck" 7 | "github.com/surullabs/lint/testutil" 8 | ) 9 | 10 | func TestStructcheck(t *testing.T) { 11 | testutil.Test(t, "structchecktest", []testutil.StaticCheckTest{ 12 | { 13 | Checker: structcheck.Check{}, 14 | Content: []byte(`package structchecktest 15 | // TestFunc is a test function 16 | func TestFunc() { 17 | } 18 | `), 19 | Validate: testutil.NoError, 20 | }, 21 | { 22 | Checker: structcheck.Check{}, 23 | Content: []byte(`package structchecktest 24 | sfsff 25 | 26 | func TestFunc() { 27 | } 28 | `), 29 | Validate: testutil.Contains("expected declaration, found 'IDENT' sfsff"), 30 | }, 31 | { 32 | Checker: structcheck.Check{}, 33 | Content: []byte(`package structchecktest 34 | type s struct { 35 | b bool 36 | } 37 | `), 38 | Validate: testutil.HasSuffix("structchecktest.s.b"), 39 | }, 40 | { 41 | Checker: structcheck.Check{}, 42 | Content: []byte(`package structchecktest 43 | type s struct { 44 | b bool 45 | } 46 | `), 47 | Validate: testutil.SkippedErrors(`structchecktest\.s\.b`), 48 | }, 49 | }, 50 | ) 51 | } 52 | 53 | func TestArgs(t *testing.T) { 54 | testutil.TestArgs(t, []testutil.ArgTest{ 55 | {A: structcheck.Check{}, Expected: nil}, 56 | {A: structcheck.Check{IncludeTests: true}, Expected: []string{"-t"}}, 57 | {A: structcheck.Check{OnlyCountAssignments: true}, Expected: []string{"-a"}}, 58 | {A: structcheck.Check{ReportExported: true}, Expected: []string{"-e"}}, 59 | {A: structcheck.Check{IncludeTests: true, ReportExported: true}, Expected: []string{"-e", "-t"}}, 60 | }) 61 | } 62 | -------------------------------------------------------------------------------- /testcovered.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -x 5 | 6 | go list -f '{{if len .XTestGoFiles}}"go test -coverprofile={{.Dir}}/.coverprofile -coverpkg {{.ImportPath}},github.com/surullabs/lint/checkers {{.ImportPath}}" 7 | {{end}}' ./... | xargs -L 1 sh -c 8 | gover 9 | -------------------------------------------------------------------------------- /unused.go: -------------------------------------------------------------------------------- 1 | package lint 2 | 3 | import ( 4 | _ "fmt" 5 | ) 6 | 7 | const vet_Err = "constant present to trigger error" 8 | -------------------------------------------------------------------------------- /varcheck/varcheck.go: -------------------------------------------------------------------------------- 1 | // Package varcheck provides lint integration for the varcheck linter 2 | package varcheck 3 | 4 | import "github.com/surullabs/lint/checkers" 5 | 6 | // Check runs the varcheck linter (https://github.com/opennota/check) 7 | type Check struct { 8 | // ReportExported reports exported variables that are unused 9 | ReportExported bool 10 | } 11 | 12 | // Check runs varcheck and returns any errors found. 13 | func (c Check) Check(pkgs ...string) error { 14 | if _, err := checkers.InstallMissing("varcheck", "github.com/opennota/check", "github.com/opennota/check/cmd/varcheck"); err != nil { 15 | return err 16 | } 17 | return checkers.Lint("varcheck", 18 | "github.com/opennota/check", 19 | "github.com/opennota/check/cmd/varcheck", pkgs, c.Args()...) 20 | } 21 | 22 | // Args returns all args passed to varcheck 23 | func (c Check) Args() []string { 24 | var args []string 25 | if c.ReportExported { 26 | args = append(args, "-e") 27 | } 28 | return args 29 | } 30 | -------------------------------------------------------------------------------- /varcheck/varcheck_test.go: -------------------------------------------------------------------------------- 1 | package varcheck_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/surullabs/lint/testutil" 7 | "github.com/surullabs/lint/varcheck" 8 | ) 9 | 10 | func TestGoVarcheck(t *testing.T) { 11 | testutil.Test(t, "varchecktest", []testutil.StaticCheckTest{ 12 | { 13 | Checker: varcheck.Check{}, 14 | Content: []byte(`package varchecktest 15 | // TestFunc is a test function 16 | func TestFunc() { 17 | } 18 | `), 19 | Validate: testutil.NoError, 20 | }, 21 | { 22 | Checker: varcheck.Check{}, 23 | Content: []byte(`package varchecktest 24 | sfsff 25 | 26 | func TestFunc() { 27 | } 28 | `), 29 | Validate: testutil.Contains("expected declaration, found 'IDENT' sfsff"), 30 | }, 31 | { 32 | Checker: varcheck.Check{}, 33 | Content: []byte(`package varchecktest 34 | var unused bool 35 | `), 36 | Validate: testutil.HasSuffix("unused"), 37 | }, 38 | { 39 | Checker: varcheck.Check{}, 40 | Content: []byte(`package varchecktest 41 | 42 | var unused bool 43 | `), 44 | Validate: testutil.SkippedErrors("unused"), 45 | }, 46 | }, 47 | ) 48 | } 49 | 50 | func TestArgs(t *testing.T) { 51 | testutil.TestArgs(t, []testutil.ArgTest{ 52 | {A: varcheck.Check{}, Expected: nil}, 53 | {A: varcheck.Check{ReportExported: true}, Expected: []string{"-e"}}, 54 | }) 55 | } 56 | --------------------------------------------------------------------------------