-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
add support for golangci-lint #2182
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8c4a062
ad0181e
394e450
093b38b
380b1d6
a62c7ce
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,22 +9,14 @@ function! go#lint#Gometa(bang, autosave, ...) abort | |
let goargs = a:000 | ||
endif | ||
|
||
if empty(go#config#MetalinterCommand()) | ||
let bin_path = go#path#CheckBinPath("gometalinter") | ||
if empty(bin_path) | ||
let l:metalinter = go#config#MetalinterCommand() | ||
|
||
if l:metalinter == 'gometalinter' || l:metalinter == 'golangci-lint' | ||
let cmd = s:metalintercmd(l:metalinter) | ||
if empty(cmd) | ||
return | ||
endif | ||
|
||
let cmd = [bin_path] | ||
let cmd += ["--disable-all"] | ||
|
||
" gometalinter has a --tests flag to tell its linters whether to run | ||
" against tests. While not all of its linters respect this flag, for those | ||
" that do, it means if we don't pass --tests, the linter won't run against | ||
" test files. One example of a linter that will not run against tests if | ||
" we do not specify this flag is errcheck. | ||
let cmd += ["--tests"] | ||
|
||
" linters | ||
let linters = a:autosave ? go#config#MetalinterAutosaveEnabled() : go#config#MetalinterEnabled() | ||
for linter in linters | ||
|
@@ -44,24 +36,41 @@ function! go#lint#Gometa(bang, autosave, ...) abort | |
" will be cleared | ||
redraw | ||
|
||
" Include only messages for the active buffer for autosave. | ||
let include = [printf('--include=^%s:.*$', fnamemodify(expand('%:p'), ":."))] | ||
if go#util#has_job() | ||
let include = [printf('--include=^%s:.*$', expand('%:p:t'))] | ||
if l:metalinter == "gometalinter" | ||
" Include only messages for the active buffer for autosave. | ||
let include = [printf('--include=^%s:.*$', fnamemodify(expand('%:p'), ":."))] | ||
if go#util#has_job() | ||
let include = [printf('--include=^%s:.*$', expand('%:p:t'))] | ||
endif | ||
let cmd += include | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How can we ensure that only messages for the active buffer are included when using golangci-lint? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. they unfortunately don't have an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. figured this out, golangci-lint can be run per file so I added f574b1f |
||
elseif l:metalinter == "golangci-lint" | ||
let goargs[0] = expand('%:p') | ||
endif | ||
let cmd += include | ||
endif | ||
|
||
" Call gometalinter asynchronously. | ||
" Call metalinter asynchronously. | ||
let deadline = go#config#MetalinterDeadline() | ||
if deadline != '' | ||
let cmd += ["--deadline=" . deadline] | ||
endif | ||
|
||
let cmd += goargs | ||
|
||
if l:metalinter == "gometalinter" | ||
" Gometalinter can output one of the two, so we look for both: | ||
" <file>:<line>:<column>:<severity>: <message> (<linter>) | ||
" <file>:<line>::<severity>: <message> (<linter>) | ||
" This can be defined by the following errorformat: | ||
let errformat = "%f:%l:%c:%t%*[^:]:\ %m,%f:%l::%t%*[^:]:\ %m" | ||
else | ||
" Golangci-lint can output the following: | ||
" <file>:<line>:<column>: <message> (<linter>) | ||
" This can be defined by the following errorformat: | ||
let errformat = "%f:%l:%c:\ %m" | ||
endif | ||
|
||
if go#util#has_job() | ||
call s:lint_job({'cmd': cmd}, a:bang, a:autosave) | ||
call s:lint_job({'cmd': cmd, 'statustype': l:metalinter, 'errformat': errformat}, a:bang, a:autosave) | ||
return | ||
endif | ||
|
||
|
@@ -77,12 +86,6 @@ function! go#lint#Gometa(bang, autosave, ...) abort | |
call go#list#Clean(l:listtype) | ||
echon "vim-go: " | echohl Function | echon "[metalinter] PASS" | echohl None | ||
else | ||
" GoMetaLinter can output one of the two, so we look for both: | ||
" <file>:<line>:<column>:<severity>: <message> (<linter>) | ||
" <file>:<line>::<severity>: <message> (<linter>) | ||
" This can be defined by the following errorformat: | ||
let errformat = "%f:%l:%c:%t%*[^:]:\ %m,%f:%l::%t%*[^:]:\ %m" | ||
|
||
" Parse and populate our location list | ||
call go#list#ParseFormat(l:listtype, errformat, split(out, "\n"), 'GoMetaLinter') | ||
|
||
|
@@ -205,8 +208,8 @@ endfunction | |
|
||
function! s:lint_job(args, bang, autosave) | ||
let l:opts = { | ||
\ 'statustype': "gometalinter", | ||
\ 'errorformat': '%f:%l:%c:%t%*[^:]:\ %m,%f:%l::%t%*[^:]:\ %m', | ||
\ 'statustype': a:args.statustype, | ||
\ 'errorformat': a:args.errformat, | ||
\ 'for': "GoMetaLinter", | ||
\ 'bang': a:bang, | ||
\ } | ||
|
@@ -221,6 +224,45 @@ function! s:lint_job(args, bang, autosave) | |
call go#job#Spawn(a:args.cmd, l:opts) | ||
endfunction | ||
|
||
function! s:metalintercmd(metalinter) | ||
let l:cmd = [] | ||
let bin_path = go#path#CheckBinPath(a:metalinter) | ||
if !empty(bin_path) | ||
if a:metalinter == "gometalinter" | ||
let l:cmd = s:gometalintercmd(bin_path) | ||
elseif a:metalinter == "golangci-lint" | ||
let l:cmd = s:golangcilintcmd(bin_path) | ||
endif | ||
endif | ||
|
||
return cmd | ||
endfunction | ||
|
||
function! s:gometalintercmd(bin_path) | ||
let cmd = [a:bin_path] | ||
let cmd += ["--disable-all"] | ||
|
||
" gometalinter has a --tests flag to tell its linters whether to run | ||
" against tests. While not all of its linters respect this flag, for those | ||
" that do, it means if we don't pass --tests, the linter won't run against | ||
" test files. One example of a linter that will not run against tests if | ||
" we do not specify this flag is errcheck. | ||
let cmd += ["--tests"] | ||
return cmd | ||
endfunction | ||
|
||
function! s:golangcilintcmd(bin_path) | ||
let cmd = [a:bin_path] | ||
let cmd += ["run"] | ||
let cmd += ["--print-issued-lines=false"] | ||
let cmd += ["--disable-all"] | ||
" do not use the default exclude patterns, because doing so causes golint | ||
" problems about missing doc strings to be ignored and other things that | ||
" golint identifies. | ||
let cmd += ["--exclude-use-default=false"] | ||
return cmd | ||
endfunction | ||
|
||
" restore Vi compatibility settings | ||
let &cpo = s:cpo_save | ||
unlet s:cpo_save | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This block changes things somewhat. When
a:autosave
is not set, then both gometalinter and golangci-lint should be passed the directory. Whena:autosave
is set thengolangci-lint
should be passed the file to check.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be clear,
gometalinter
also needs to be passed the file to check whena:autosave
is set; that already happens forgometalinter
a little further down the file. Perhaps this block could be restored to its previous glory, and the section below that ensure thatgometalinter
is given the--include
option whena:autosave
is set could be extended to append the file path togoargs
whengolangci-lint
is used.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, that makes sense to me. I did this 2461989, do you think it could just be
let goargs = [expand('%p')]
instead of what I put in there? What all do we expect goargs could be when autosave is enabled?