]> git.madduck.net Git - etc/vim.git/blob - ale_linters/dockerfile/hadolint.vim

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Squashed '.vim/bundle/ale/' content from commit 22185c4c
[etc/vim.git] / ale_linters / dockerfile / hadolint.vim
1 " Author: hauleth - https://github.com/hauleth
2
3 " always, yes, never
4 call ale#Set('dockerfile_hadolint_use_docker', 'never')
5 call ale#Set('dockerfile_hadolint_docker_image', 'hadolint/hadolint')
6 call ale#Set('dockerfile_hadolint_options', '')
7
8 function! ale_linters#dockerfile#hadolint#Handle(buffer, lines) abort
9     " Matches patterns line the following:
10     "
11     " -:19 DL3001 warning: Pipe chain should start with a raw value.
12     " /dev/stdin:19:3 unexpected thing
13     let l:pattern = '\v^%(/dev/stdin|-):(\d+):?(\d+)? ((DL|SC)(\d+) )?((.+)?: )?(.+)$'
14     let l:output = []
15
16     for l:match in ale#util#GetMatches(a:lines, l:pattern)
17         let l:lnum = 0
18         let l:colnum = 0
19
20         if l:match[1] isnot# ''
21             let l:lnum = l:match[1] + 0
22         endif
23
24         if l:match[2] isnot# ''
25             let l:colnum = l:match[2] + 0
26         endif
27
28         " Shellcheck knows a 'style' severity - pin it to info level as well.
29         if l:match[7] is# 'style'
30             let l:type = 'I'
31         elseif l:match[7] is# 'info'
32             let l:type = 'I'
33         elseif l:match[7] is# 'warning'
34             let l:type = 'W'
35         else
36             let l:type = 'E'
37         endif
38
39         let l:text = l:match[8]
40         let l:detail = l:match[8]
41         let l:domain = 'https://github.com/hadolint/hadolint/wiki/'
42         let l:code = ''
43         let l:link = ''
44
45         if l:match[4] is# 'SC'
46             let l:domain = 'https://github.com/koalaman/shellcheck/wiki/'
47         endif
48
49         if l:match[5] isnot# ''
50             let l:code = l:match[4] . l:match[5]
51             let l:link = ' ( ' . l:domain . l:code . ' )'
52             let l:detail = l:code . l:link . "\n\n" . l:detail
53         else
54             let l:type = 'E'
55             let l:detail = 'hadolint could not parse the file because of a syntax error.'
56         endif
57
58         let l:line_output = {
59         \   'lnum': l:lnum,
60         \   'col': l:colnum,
61         \   'type': l:type,
62         \   'text': l:text,
63         \   'detail': l:detail
64         \}
65
66         if l:code isnot# ''
67             let l:line_output['code'] = l:code
68         endif
69
70         call add(l:output, l:line_output)
71     endfor
72
73     return l:output
74 endfunction
75
76 " This is a little different than the typical 'executable' callback.  We want
77 " to afford the user the chance to say always use docker, never use docker,
78 " and use docker if the hadolint executable is not present on the system.
79 "
80 " In the case of neither docker nor hadolint executables being present, it
81 " really doesn't matter which we return -- either will have the effect of
82 " 'nope, can't use this linter!'.
83
84 function! ale_linters#dockerfile#hadolint#GetExecutable(buffer) abort
85     let l:use_docker = ale#Var(a:buffer, 'dockerfile_hadolint_use_docker')
86
87     " check for mandatory directives
88     if l:use_docker is# 'never'
89         return 'hadolint'
90     elseif l:use_docker is# 'always'
91         return 'docker'
92     endif
93
94     " if we reach here, we want to use 'hadolint' if present...
95     if executable('hadolint')
96         return 'hadolint'
97     endif
98
99     "... and 'docker' as a fallback.
100     return 'docker'
101 endfunction
102
103 function! ale_linters#dockerfile#hadolint#GetCommand(buffer) abort
104     let l:command = ale_linters#dockerfile#hadolint#GetExecutable(a:buffer)
105     let l:opts = ale#Var(a:buffer, 'dockerfile_hadolint_options') . ' --no-color -'
106
107     if l:command is# 'docker'
108         return printf('docker run --rm -i %s hadolint %s',
109         \ ale#Var(a:buffer, 'dockerfile_hadolint_docker_image'),
110         \ l:opts)
111     endif
112
113     return 'hadolint ' . l:opts
114 endfunction
115
116
117 call ale#linter#Define('dockerfile', {
118 \   'name': 'hadolint',
119 \   'executable': function('ale_linters#dockerfile#hadolint#GetExecutable'),
120 \   'command': function('ale_linters#dockerfile#hadolint#GetCommand'),
121 \   'callback': 'ale_linters#dockerfile#hadolint#Handle',
122 \})