vim-testをdocker-composeに対応させる
January 02, 2021
お正月に環境の見直しをしていたのでブログにまとめる。 vim-testは様々なテストに対応したプラグインで、vimからコマンド一つでテストをすることが出来る。 しかし、docker-composeに対応するためにちょっとした工夫が必要だったのでメモとしてまとめる。
基本的な設定は以下の通り
let test#strategy = 'neovim'
let test#neovim#term_position = 'vert'
nnoremap [vim-test] <Nop>
nmap <Leader>e [vim-test]
nmap <silent> [vim-test]a <cmd>TestSuit<CR>
nmap <silent> [vim-test]f <cmd>TestFile<CR>
nmap <silent> [vim-test]t <cmd>TestVisit<CR>
これで、ショートカットを使ってvim-testを呼び出し可能。 ただし、vim-testでは初期ではdocker-composeに対応していないので、自分で対応するためのコードを書く必要がある。ドキュメントはいかにまとまっている。
https://github.com/vim-test/vim-test#transformations
つまり自分でtransformationを書く必要がある。ただ、docker-composeをいい感じにするには、テスト用のコンテナのservice名が分からないといけない。
$ docker-compose run --rm SERVICE_NAME CMD
この SERVICE_NAME
を頑張ってvim起動したら毎回打ち込むのでもいいけど、こういうのは怠惰になったほうがいいと偉い人が行ってたのでちょっと頑張ってみる
頑張ってみた結果が以下のとおり、
function! DockerComposeTransformation(cmd) abort
let docker_compose_project = findfile("docker-compose.yml", ".;")
if !empty(docker_compose_project)
let docker_compose = readfile(docker_compose_project)
let docker_compose_copy = copy(docker_compose)
let docker_compose = map(docker_compose, {key, val -> [key, val]})
let cwd = split(getcwd(), '/')[-1]
let context_lines = filter(docker_compose, 'v:val[1] =~ "context:"')
let target_context_line = filter(context_lines, printf('v:val[1] =~ "%s"', cwd))
if len(target_context_line) == 0
echohl ErrorMsg
echomsg 'context was not found'
echohl None
return a:cmd
endif
let target = ''
for i in range(target_context_line[0][0]-1, 0, -1)
" count tab
" for example
" services:
" SERVICE_NAME:
" # ^ this is not space
" build:
" context: ./DIR_NAME # <-- target_context_line[0][0]
if docker_compose_copy[i][2] != ' '
let target = docker_compose_copy[i][2:-2]
break
endif
endfor
return printf('docker-compose run --rm %s %s', target, a:cmd)
endif
return a:cmd
endfunction
let g:test#custom_transformations = {'docker': function('DockerComposeTransformation')}
let g:test#transformation = 'docker'
基本的にやっていることとしては、
- docker-compose.ymlファイルを探す
- docker-compose.ymlの
contexts:
が書いている場所を探す context:
以下がカレントディレクトリと同じ名前になっているものを探す- 見つけた
context:
の場所から上にたどっていき、service名を見つけ出す
基本的にはこんな感じでやってる。ロジックとしてはがばがばな気がするので、また不具合を見つけたら直していきます。 これでテストがちょっとやりやすくなった。