Skip to content

Commit

Permalink
Add golangci-lint (#1890)
Browse files Browse the repository at this point in the history
  • Loading branch information
saschagrunert authored and w0rp committed Sep 6, 2018
1 parent 580bd36 commit 7b62a15
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ formatting.
| FusionScript | [fusion-lint](https://github.com/RyanSquared/fusionscript) |
| Git Commit Messages | [gitlint](https://github.com/jorisroovers/gitlint) |
| GLSL | [glslang](https://github.com/KhronosGroup/glslang), [glslls](https://github.com/svenstaro/glsl-language-server) |
| Go | [gofmt](https://golang.org/cmd/gofmt/), [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports), [go vet](https://golang.org/cmd/vet/) !!, [golint](https://godoc.org/github.com/golang/lint), [gotype](https://godoc.org/golang.org/x/tools/cmd/gotype) !!, [gometalinter](https://github.com/alecthomas/gometalinter) !!, [go build](https://golang.org/cmd/go/) !!, [gosimple](https://github.com/dominikh/go-tools/tree/master/cmd/gosimple) !!, [staticcheck](https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck) !!, [golangserver](https://github.com/sourcegraph/go-langserver) |
| Go | [gofmt](https://golang.org/cmd/gofmt/), [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports), [go vet](https://golang.org/cmd/vet/) !!, [golint](https://godoc.org/github.com/golang/lint), [gotype](https://godoc.org/golang.org/x/tools/cmd/gotype) !!, [gometalinter](https://github.com/alecthomas/gometalinter) !!, [go build](https://golang.org/cmd/go/) !!, [gosimple](https://github.com/dominikh/go-tools/tree/master/cmd/gosimple) !!, [staticcheck](https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck) !!, [golangserver](https://github.com/sourcegraph/go-langserver), [golangci-lint](https://github.com/golangci/golangci-lint) !! |
| GraphQL | [eslint](http://eslint.org/), [gqlint](https://github.com/happylinks/gqlint), [prettier](https://github.com/prettier/prettier) |
| Hack | [hack](http://hacklang.org/), [hackfmt](https://github.com/facebook/hhvm/tree/master/hphp/hack/hackfmt), [hhast](https://github.com/hhvm/hhast) (disabled by default; see `:help ale-integration-hack`) |
| Haml | [haml-lint](https://github.com/brigade/haml-lint) |
Expand Down
56 changes: 56 additions & 0 deletions ale_linters/go/golangci_lint.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
" Author: Sascha Grunert <mail@saschagrunert.de>
" Description: Adds support of golangci-lint

call ale#Set('go_golangci_lint_options', '--enable-all')
call ale#Set('go_golangci_lint_executable', 'golangci-lint')
call ale#Set('go_golangci_lint_package', 0)

function! ale_linters#go#golangci_lint#GetCommand(buffer) abort
let l:filename = expand('#' . a:buffer . ':t')
let l:options = ale#Var(a:buffer, 'go_golangci_lint_options')
let l:lint_package = ale#Var(a:buffer, 'go_golangci_lint_package')

if l:lint_package
return ale#path#BufferCdString(a:buffer)
\ . '%e run '
\ . l:options
endif

return ale#path#BufferCdString(a:buffer)
\ . '%e run '
\ . ale#util#EscapePCRE(l:filename)
\ . ' ' . l:options
endfunction

function! ale_linters#go#golangci_lint#GetMatches(lines) abort
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?:?:?:?\s\*?(.+)$'

return ale#util#GetMatches(a:lines, l:pattern)
endfunction

function! ale_linters#go#golangci_lint#Handler(buffer, lines) abort
let l:dir = expand('#' . a:buffer . ':p:h')
let l:output = []

for l:match in ale_linters#go#golangci_lint#GetMatches(a:lines)
" l:match[1] will already be an absolute path, output from
" golangci_lint
call add(l:output, {
\ 'filename': ale#path#GetAbsPath(l:dir, l:match[1]),
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'type': 'E',
\ 'text': l:match[4],
\})
endfor

return l:output
endfunction

call ale#linter#Define('go', {
\ 'name': 'golangci-lint',
\ 'executable_callback': ale#VarFunc('go_golangci_lint_executable'),
\ 'command_callback': 'ale_linters#go#golangci_lint#GetCommand',
\ 'callback': 'ale_linters#go#golangci_lint#Handler',
\ 'lint_file': 1,
\})
33 changes: 33 additions & 0 deletions doc/ale-go.txt
Original file line number Diff line number Diff line change
Expand Up @@ -134,5 +134,38 @@ g:ale_go_langserver_options *g:ale_go_langserver_options*
by the |g:ale_completion_enabled| variable.


===============================================================================
golangci-lint *ale-go-golangci-lint*

`golangci-lint` is a `lint_file` linter, which only lints files that are
written to disk. This differs from the default behavior of linting the buffer.
See: |ale-lint-file|

g:ale_go_golangci_lint_executable *g:ale_go_golangci_lint_executable*
*b:ale_go_golangci_lint_executable*
Type: |String|
Default: `'golangci-lint'`

The executable that will be run for golangci-lint.


g:ale_go_golangci_lint_options *g:ale_go_golangci_lint_options*
*b:ale_go_golangci_lint_options*
Type: |String|
Default: `'--enable-all'`

This variable can be changed to alter the command-line arguments to the
golangci-lint invocation.


g:ale_go_golangci_lint_package *g:ale_go_golangci_lint_package*
*b:ale_go_golangci_lint_package*
Type: |Number|
Default: `0`

When set to `1`, the whole Go package will be checked instead of only the
current file.


===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
3 changes: 2 additions & 1 deletion doc/ale.txt
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ CONTENTS *ale-contents*
gometalinter........................|ale-go-gometalinter|
staticcheck.........................|ale-go-staticcheck|
golangserver........................|ale-go-golangserver|
golangci-lint.......................|ale-go-golangci-lint|
graphql...............................|ale-graphql-options|
eslint..............................|ale-graphql-eslint|
gqlint..............................|ale-graphql-gqlint|
Expand Down Expand Up @@ -385,7 +386,7 @@ Notes:
* FusionScript: `fusion-lint`
* Git Commit Messages: `gitlint`
* GLSL: glslang, `glslls`
* Go: `gofmt`, `goimports`, `go vet`!!, `golint`, `gotype`!!, `gometalinter`!!, `go build`!!, `gosimple`!!, `staticcheck`!!, `golangserver`
* Go: `gofmt`, `goimports`, `go vet`!!, `golint`, `gotype`!!, `gometalinter`!!, `go build`!!, `gosimple`!!, `staticcheck`!!, `golangserver`, `golangci-lint`!!
* GraphQL: `eslint`, `gqlint`, `prettier`
* Hack: `hack`, `hackfmt`, `hhast`
* Haml: `haml-lint`
Expand Down
38 changes: 38 additions & 0 deletions test/command_callback/test_golangci_lint_command_callback.vader
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
Before:
call ale#assert#SetUpLinterTest('go', 'golangci_lint')
call ale#test#SetFilename('test.go')

After:
call ale#assert#TearDownLinterTest()

Execute(The golangci-lint defaults should be correct):
AssertLinter 'golangci-lint',
\ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
\ . ale#Escape('golangci-lint')
\ . ' run ' . ale#util#EscapePCRE(expand('%' . ':t'))
\ . ' --enable-all'

Execute(The golangci-lint callback should use a configured executable):
let b:ale_go_golangci_lint_executable = 'something else'

AssertLinter 'something else',
\ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
\ . ale#Escape('something else')
\ . ' run ' . ale#util#EscapePCRE(expand('%' . ':t'))
\ . ' --enable-all'

Execute(The golangci-lint callback should use configured options):
let b:ale_go_golangci_lint_options = '--foobar'

AssertLinter 'golangci-lint',
\ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
\ . ale#Escape('golangci-lint')
\ . ' run ' . ale#util#EscapePCRE(expand('%' . ':t'))
\ . ' --foobar'

Execute(The golangci-lint `lint_package` option should use the correct command):
let b:ale_go_golangci_lint_package = 1

AssertLinter 'golangci-lint',
\ 'cd ' . ale#Escape(expand('%:p:h')) . ' && '
\ . ale#Escape('golangci-lint') . ' run --enable-all'
55 changes: 55 additions & 0 deletions test/handler/test_golangci_lint_handler.vader
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
Before:
runtime ale_linters/go/golangci_lint.vim

After:
call ale#linter#Reset()

Execute (The golangci-lint handler should handle names with spaces):
" We can't test Windows paths with the path resovling on Linux, but we can
" test the regex.
AssertEqual
\ [
\ [
\ 'C:\something\file with spaces.go',
\ '12',
\ '3',
\ 'expected ''package'', found ''IDENT'' gibberish (staticcheck)',
\ ],
\ [
\ 'C:\something\file with spaces.go',
\ '37',
\ '5',
\ 'expected ''package'', found ''IDENT'' gibberish (golint)',
\ ],
\ ],
\ map(ale_linters#go#golangci_lint#GetMatches([
\ 'C:\something\file with spaces.go:12:3: expected ''package'', found ''IDENT'' gibberish (staticcheck)',
\ 'C:\something\file with spaces.go:37:5: expected ''package'', found ''IDENT'' gibberish (golint)',
\ ]), 'v:val[1:4]')

Execute (The golangci-lint handler should handle paths correctly):
call ale#test#SetFilename('app/test.go')

let file = ale#path#GetAbsPath(expand('%:p:h'), 'test.go')

AssertEqual
\ [
\ {
\ 'lnum': 12,
\ 'col': 3,
\ 'text': 'expected ''package'', found ''IDENT'' gibberish (staticcheck)',
\ 'type': 'E',
\ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.go'),
\ },
\ {
\ 'lnum': 37,
\ 'col': 5,
\ 'text': 'expected ''package'', found ''IDENT'' gibberish (golint)',
\ 'type': 'E',
\ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.go'),
\ },
\ ],
\ ale_linters#go#golangci_lint#Handler(bufnr(''), [
\ file . ':12:3: expected ''package'', found ''IDENT'' gibberish (staticcheck)',
\ file . ':37:5: expected ''package'', found ''IDENT'' gibberish (golint)',
\ ])

0 comments on commit 7b62a15

Please sign in to comment.