公私でGoを書くときはVimを使っている。
ファイル保存時にgolangci-lintを実行するように設定しているのだが、表題のエラーが出て静的解析が実行されなかったので原因調査・解決した。
TL;DR
- VimでGoを書いているとき、
vim-go: [golangci-lint] FAILエラーがでてgolangci-lintが失敗するようになった :messagesを見てもわからなかった:GoMetaLinterコマンドを実行したところ、本当のエラーメッセージがわかったlevel=error msg="Running error: --enable-all and --disable-all options must not be combined"
.golangci.ymlの設定を修正して解決した
エラーが出てvim-goでgolangci-lintが動かない
公私でGoを書くときはVimを使っている。
私のVimでは(golangci-lintを使う設定をして、)GoMetaLinterAutoSaveToggleオプションを有効にしているので、ファイル保存時にgolangci-lintが実行される。
- GoMetaLinterAutoSaveToggle | fatih/vim-go
ここで、あるGoのプロジェクトで作業しているときだけ、ファイル保存時にvim-go: [golangci-lint] FAILとエラーメッセージが表示されるだけで静的解析が実行されなくなった。
原因調査: :GoMetaLinterコマンドを直接実行してみる
コマンドラインから直接golangci-lintコマンドを実行しても正常に実行できていた。
:messagesコマンドでVimが出力しているログを見ても、何が問題でgolangci-lintコマンドが失敗しているのかよくわからなかった。
- message - Vim日本語ドキュメント
起動直後にファイルを保存してエラーが出た状態で:messagesコマンドでログをみても以下の通り。
Messages maintainer: Bram Moolenaar <Bram@vim.org>
"main.go" 100L, 2767C
vim-go: initializing gopls
"main.go" 100L, 2767C written
vim-go: [golangci-lint] dispatched
vim-go: [golangci-lint] FAIL
ここで、vim-goを利用しているVimでは、:GoMetaLinterコマンドを使うことで、明示的にgolangci-lintを実行できる。
:GoMetaLinter| fatih/vim-go
:GoMetaLinterコマンドを実行してみたところ、以下のようなエラーメッセージを確認することができた。
level=error msg="Running error: --enable-all and --disable-all options must not be combined"
どうやら、プロジェクトに配置してある.golangci.ymlに記載されている設定と、vim-goでgolangci-lintコマンドを呼び出すときのオプションが競合しているのが原因だった。
vim-goはgolangci-lintコマンドを呼び出すとき以下のように実行コマンドを組み立てる。この中で、--disable-allオプションを指定している。
function! s:golangcilintcmd(bin_path)
let cmd = [a:bin_path]
let cmd += ["run"]
let cmd += ["--print-issued-lines=false"]
let cmd += ['--build-tags', go#config#BuildTags()]
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
今回、プロジェクトで設置してある.golangci.ymlファイルではenable-allをベースに静的解析の設定を組み立てていため、enable-allとdisable-all設定が競合していた。
linters:
enable-all: true
disable:
- funlen
- dogsled
解決方法:.golangci.ymlの設定を修正する
今回は以下の理由により、.golangci.yml側の設定方法を修正することで対応した。
- Vim側の
golangci-lintコマンドの呼び出し時の設定を変更する方法がよくわからなかった enable-allベースで設定していると、golangci-lintコマンドが新しいツールをサポートしたとき、意図せず有効化されるdisable-allしたあと、明示的に利用する静的解析ツールを指定したほうがヒューマンリーダブルな設定になる
golangci-lintコマンドはgolangci-lint lintersコマンドでそのプロジェクト上(ディレクトリ上)の静的解析の設定を確認することができる。
なので、一度enable-allベースの設定でgolangci-lint lintersコマンドを実行し、ファイルに出力を保存しておいた。
$ golangci-lint linters
Enabled by your configuration linters:
bodyclose: checks whether HTTP response body is closed successfully [fast: true, auto-fix: false]
deadcode: Finds unused code [fast: true, auto-fix: false]
...
Disabled by your configuration linters:
depguard: Go linter that checks if package imports are in a list of acceptable packages [fast: true, auto-fix: false]
dogsled: Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) [fast: true, auto-fix: false]
...
その後、disable-allベースの設定に書き直し、golangci-lint lintersコマンドの結果が以前と同じであることを確認した。
終わりに
私のVimの設定は一応golangci-lintやgoplsを利用するように設定しているのだが、一度整理したほうがよいかなと思いつつズルズル使っている。
LSP系のプラグイン経由でgoplsを実行するほうがいろいろ設定できるらしいので、一度整理しようかなあ。