summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--ale_linters/dockerfile/dockerfile_lint.vim61
-rw-r--r--doc/ale-dockerfile.txt23
-rw-r--r--doc/ale.txt3
-rw-r--r--test/command_callback/test_dockerfile_lint_command_callback.vader19
-rw-r--r--test/handler/test_dockerfile_lint_handler.vader108
6 files changed, 214 insertions, 2 deletions
diff --git a/README.md b/README.md
index 4b6d7663..de01c102 100644
--- a/README.md
+++ b/README.md
@@ -117,7 +117,7 @@ formatting.
| D | [dls](https://github.com/d-language-server/dls), [dmd](https://dlang.org/dmd-linux.html), [uncrustify](https://github.com/uncrustify/uncrustify) |
| Dafny | [dafny](https://rise4fun.com/Dafny) !! |
| Dart | [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) !!, [language_server](https://github.com/natebosch/dart_language_server), [dartfmt](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt) |
-| Dockerfile | [hadolint](https://github.com/hadolint/hadolint) |
+| Dockerfile | [dockerfile_lint](https://github.com/projectatomic/dockerfile_lint), [hadolint](https://github.com/hadolint/hadolint) |
| Elixir | [credo](https://github.com/rrrene/credo), [dialyxir](https://github.com/jeremyjh/dialyxir), [dogma](https://github.com/lpil/dogma), [mix](https://hexdocs.pm/mix/Mix.html) !!, [elixir-ls](https://github.com/JakeBecker/elixir-ls) |
| Elm | [elm-format](https://github.com/avh4/elm-format), [elm-make](https://github.com/elm-lang/elm-make) |
| Erb | [erb](https://apidock.com/ruby/ERB), [erubi](https://github.com/jeremyevans/erubi), [erubis](https://github.com/kwatch/erubis) |
diff --git a/ale_linters/dockerfile/dockerfile_lint.vim b/ale_linters/dockerfile/dockerfile_lint.vim
new file mode 100644
index 00000000..a5a846f2
--- /dev/null
+++ b/ale_linters/dockerfile/dockerfile_lint.vim
@@ -0,0 +1,61 @@
+" Author: Alexander Olofsson <alexander.olofsson@liu.se>
+
+call ale#Set('dockerfile_dockerfile_lint_executable', 'dockerfile_lint')
+call ale#Set('dockerfile_dockerfile_lint_options', '')
+
+function! ale_linters#dockerfile#dockerfile_lint#GetType(type) abort
+ if a:type is? 'error'
+ return 'E'
+ elseif a:type is? 'warn'
+ return 'W'
+ endif
+
+ return 'I'
+endfunction
+
+function! ale_linters#dockerfile#dockerfile_lint#Handle(buffer, lines) abort
+ try
+ let l:data = json_decode(join(a:lines, ''))
+ catch
+ return []
+ endtry
+
+ if empty(l:data)
+ " Should never happen, but it's better to be on the safe side
+ return []
+ endif
+
+ let l:messages = []
+
+ for l:type in ['error', 'warn', 'info']
+ for l:object in l:data[l:type]['data']
+ let l:line = get(l:object, 'line', -1)
+ let l:message = l:object['message']
+
+ if get(l:object, 'description', 'None') isnot# 'None'
+ let l:message = l:message . '. ' . l:object['description']
+ endif
+
+ call add(l:messages, {
+ \ 'lnum': l:line,
+ \ 'text': l:message,
+ \ 'type': ale_linters#dockerfile#dockerfile_lint#GetType(l:type),
+ \})
+ endfor
+ endfor
+
+ return l:messages
+endfunction
+
+function! ale_linters#dockerfile#dockerfile_lint#GetCommand(buffer) abort
+ return '%e' . ale#Pad(ale#Var(a:buffer, 'dockerfile_dockerfile_lint_options'))
+ \ . ' -p -j -f'
+ \ . ' %t'
+endfunction
+
+call ale#linter#Define('dockerfile', {
+\ 'name': 'dockerfile_lint',
+\ 'executable_callback': ale#VarFunc('dockerfile_dockerfile_lint_executable'),
+\ 'command_callback': 'ale_linters#dockerfile#dockerfile_lint#GetCommand',
+\ 'callback': 'ale_linters#dockerfile#dockerfile_lint#Handle',
+\})
diff --git a/doc/ale-dockerfile.txt b/doc/ale-dockerfile.txt
index 805cc478..284c6a10 100644
--- a/doc/ale-dockerfile.txt
+++ b/doc/ale-dockerfile.txt
@@ -3,6 +3,29 @@ ALE Dockerfile Integration *ale-dockerfile-options*
===============================================================================
+dockerfile_lint *ale-dockerfile-dockerfile_lint*
+
+g:ale_dockerfile_dockerfile_lint_executable
+ *g:ale_dockerfile_dockerfile_lint_executable*
+ *b:ale_dockerfile_dockerfile_lint_executable*
+ Type: |String|
+ Default: `'dockerfile_lint'`
+
+ This variable can be changed to specify the executable used to run
+ dockerfile_lint.
+
+
+g:ale_dockerfile_dockerfile_lint_options
+ *g:ale_dockerfile_dockerfile_lint_options*
+ *b:ale_dockerfile_dockerfile_lint_options*
+ Type: |String|
+ Default: `''`
+
+ This variable can be changed to add additional command-line arguments to
+ the dockerfile lint invocation - like custom rule file definitions.
+
+
+===============================================================================
hadolint *ale-dockerfile-hadolint*
hadolint can be found at: https://github.com/hadolint/hadolint
diff --git a/doc/ale.txt b/doc/ale.txt
index 95110431..e190cf2a 100644
--- a/doc/ale.txt
+++ b/doc/ale.txt
@@ -75,6 +75,7 @@ CONTENTS *ale-contents*
dartanalyzer........................|ale-dart-dartanalyzer|
dartfmt.............................|ale-dart-dartfmt|
dockerfile............................|ale-dockerfile-options|
+ dockerfile_lint.....................|ale-dockerfile-dockerfile_lint|
hadolint............................|ale-dockerfile-hadolint|
elixir................................|ale-elixir-options|
mix.................................|ale-elixir-mix|
@@ -407,7 +408,7 @@ Notes:
* D: `dls`, `dmd`, `uncrustify`
* Dafny: `dafny`!!
* Dart: `dartanalyzer`!!, `language_server`, dartfmt!!
-* Dockerfile: `hadolint`
+* Dockerfile: `dockerfile_lint`, `hadolint`
* Elixir: `credo`, `dialyxir`, `dogma`, `mix`!!, `elixir-ls`
* Elm: `elm-format, elm-make`
* Erb: `erb`, `erubi`, `erubis`
diff --git a/test/command_callback/test_dockerfile_lint_command_callback.vader b/test/command_callback/test_dockerfile_lint_command_callback.vader
new file mode 100644
index 00000000..abc32e0d
--- /dev/null
+++ b/test/command_callback/test_dockerfile_lint_command_callback.vader
@@ -0,0 +1,19 @@
+Before:
+ call ale#assert#SetUpLinterTest('dockerfile', 'dockerfile_lint')
+
+After:
+ call ale#assert#TearDownLinterTest()
+
+Execute(The default command should be correct):
+ AssertLinter 'dockerfile_lint', ale#Escape('dockerfile_lint') . ' -p -j -f %t'
+
+Execute(The executable should be configurable):
+ let b:ale_dockerfile_dockerfile_lint_executable = 'foobar'
+
+ AssertLinter 'foobar', ale#Escape('foobar') . ' -p -j -f %t'
+
+Execute(The options should be configurable):
+ let b:ale_dockerfile_dockerfile_lint_options = '-r additional.yaml'
+
+ AssertLinter 'dockerfile_lint', ale#Escape('dockerfile_lint') . ' -r additional.yaml -p -j -f %t'
+
diff --git a/test/handler/test_dockerfile_lint_handler.vader b/test/handler/test_dockerfile_lint_handler.vader
new file mode 100644
index 00000000..619b7bde
--- /dev/null
+++ b/test/handler/test_dockerfile_lint_handler.vader
@@ -0,0 +1,108 @@
+Before:
+ runtime ale_linters/dockerfile/dockerfile_lint.vim
+
+After:
+ call ale#linter#Reset()
+
+Execute(The dockerfile_lint handler should handle broken JSON):
+ AssertEqual
+ \ [],
+ \ ale_linters#dockerfile#dockerfile_lint#Handle(bufnr(''), ["{asdf"])
+
+Execute(The dockerfile_lint handler should handle an empty string response):
+ AssertEqual
+ \ [],
+ \ ale_linters#dockerfile#dockerfile_lint#Handle(bufnr(''), [])
+
+Execute(The dockerfile_lint handler should handle an empty result, even if it shouldn't happen):
+ AssertEqual
+ \ [],
+ \ ale_linters#dockerfile#dockerfile_lint#Handle(bufnr(''), ["{}"])
+
+Execute(The dockerfile_lint handler should handle a normal example):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': -1,
+ \ 'type': 'E',
+ \ 'text': "Required LABEL name/key 'Name' is not defined",
+ \ },
+ \ {
+ \ 'lnum': -1,
+ \ 'type': 'E',
+ \ 'text': "Required LABEL name/key 'Version' is not defined",
+ \ },
+ \ {
+ \ 'lnum': 3,
+ \ 'type': 'I',
+ \ 'text': "the MAINTAINER command is deprecated. MAINTAINER is deprecated in favor of using LABEL since Docker v1.13.0",
+ \ },
+ \ {
+ \ 'lnum': -1,
+ \ 'type': 'I',
+ \ 'text': "There is no 'CMD' instruction",
+ \ },
+ \ ],
+ \ ale_linters#dockerfile#dockerfile_lint#Handle(bufnr(''), [
+ \ '{',
+ \ ' "error": {',
+ \ ' "count": 2,',
+ \ ' "data": [',
+ \ ' {',
+ \ " \"message\": \"Required LABEL name/key 'Name' is not defined\",",
+ \ ' "line": -1,',
+ \ ' "level": "error",',
+ \ ' "lineContent": "",',
+ \ ' "reference_url": [',
+ \ ' "http://docs.projectatomic.io/container-best-practices/#",',
+ \ ' "_recommended_labels_for_your_project"',
+ \ ' ]',
+ \ ' },',
+ \ ' {',
+ \ " \"message\": \"Required LABEL name/key 'Version' is not defined\",",
+ \ ' "line": -1,',
+ \ ' "level": "error",',
+ \ ' "lineContent": "",',
+ \ ' "reference_url": [',
+ \ ' "http://docs.projectatomic.io/container-best-practices/#",',
+ \ ' "_recommended_labels_for_your_project"',
+ \ ' ]',
+ \ ' }',
+ \ ' ]',
+ \ ' },',
+ \ ' "warn": {',
+ \ ' "count": 0,',
+ \ ' "data": []',
+ \ ' },',
+ \ ' "info": {',
+ \ ' "count": 2,',
+ \ ' "data": [',
+ \ ' {',
+ \ ' "label": "maintainer_deprecated",',
+ \ ' "regex": {},',
+ \ ' "level": "info",',
+ \ ' "message": "the MAINTAINER command is deprecated",',
+ \ ' "description": "MAINTAINER is deprecated in favor of using LABEL since Docker v1.13.0",',
+ \ ' "reference_url": [',
+ \ ' "https://github.com/docker/cli/blob/master/docs/deprecated.md",',
+ \ ' "#maintainer-in-dockerfile"',
+ \ ' ],',
+ \ ' "lineContent": "MAINTAINER Alexander Olofsson <ace@haxalot.com>",',
+ \ ' "line": 3',
+ \ ' },',
+ \ ' {',
+ \ ' "instruction": "CMD",',
+ \ ' "count": 1,',
+ \ ' "level": "info",',
+ \ " \"message\": \"There is no 'CMD' instruction\",",
+ \ ' "description": "None",',
+ \ ' "reference_url": [',
+ \ ' "https://docs.docker.com/engine/reference/builder/",',
+ \ ' "#cmd"',
+ \ ' ]',
+ \ ' }',
+ \ ' ]',
+ \ ' },',
+ \ ' "summary": []',
+ \ '}',
+ \ ])