summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md30
-rw-r--r--README.md34
-rw-r--r--ale_linters/c/clang.vim2
-rw-r--r--ale_linters/c/gcc.vim2
-rw-r--r--ale_linters/coffee/coffee.vim2
-rw-r--r--ale_linters/cpp/clang.vim2
-rw-r--r--ale_linters/cpp/clangtidy.vim2
-rw-r--r--ale_linters/cpp/gcc.vim2
-rw-r--r--ale_linters/go/gobuild.vim226
-rw-r--r--ale_linters/php/php.vim4
-rw-r--r--ale_linters/puppet/puppetlint.vim28
-rw-r--r--ale_linters/sh/shellcheck.vim2
-rw-r--r--ale_linters/swift/swiftlint.vim2
-rw-r--r--ale_linters/vim/vint.vim2
-rw-r--r--autoload/ale/handlers.vim30
-rw-r--r--autoload/ale/handlers/gcc.vim88
-rw-r--r--doc/ale-puppet.txt26
-rw-r--r--test/c_tests/broken.h1
-rw-r--r--test/c_tests/test_gcc.vader53
-rw-r--r--test/handler/test_clang_handler.vader23
-rw-r--r--test/handler/test_common_handlers.vader8
-rw-r--r--test/handler/test_gcc_handler.vader68
-rw-r--r--test/handler/test_php_handler.vader10
-rw-r--r--test/handler/test_swiftlint_handler.vader8
-rw-r--r--test/handler/test_vint_handler.vader36
-rw-r--r--test/test_temporary_file_management.vader29
26 files changed, 417 insertions, 303 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e40ed5dc..0086e48d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -3,17 +3,17 @@
1. [Guidelines](#guidelines)
2. [Creating Issues](#issues)
3. [Creating Pull Requests](#pull-requests)
- 1. [Adding a New Linter](#adding-a-new-linter)
- 2. [Adding New Options](#adding-new-options)
+ 1. [Adding a New Linter](#adding-a-new-linter)
+ 2. [Adding New Options](#adding-new-options)
4. [Writing Documentation](#writing-documentation)
- 1. [Documenting New Linters](#documenting-new-linters)
- 2. [Editing the Online Documentation](#editing-online-documentation)
- 3. [Documenting Linter Options](#documenting-new-options)
+ 1. [Documenting New Linters](#documenting-new-linters)
+ 2. [Editing the Online Documentation](#editing-online-documentation)
+ 3. [Documenting Linter Options](#documenting-linter-options)
5. [In Case of Busses](#in-case-of-busses)
<a name="guidelines"></a>
-# 1. Guidelines
+## 1. Guidelines
Have fun, and work on whatever floats your boat. Take It Easy :tm:.
@@ -31,7 +31,7 @@ will check your code while you type.
<a name="issues"></a>
-# 2. Creating Issues
+## 2. Creating Issues
Before creating any issues, please look through the current list of issues and
pull requests, and ensure that the issue hasn't already been reported. If an
@@ -52,7 +52,7 @@ can understand you.
<a name="pull-requests"></a>
-# 3. Creating Pull Requests
+## 3. Creating Pull Requests
For code you write, make sure to credit yourself at the top of files you add,
and probably those you modify. You can write some comments at the top of your
@@ -71,7 +71,7 @@ If you want to credit multiple authors, you can comma separate them.
<a name="adding-a-new-linter"></a>
-# 3.i. Adding a New Linter
+### 3.i. Adding a New Linter
If you add a new linter, look for existing handlers first in the
[handlers.vim](autoload/ale/handlers.vim) file. One of the handlers there may
@@ -87,7 +87,7 @@ alphabetically in the table and list.
<a name="adding-new-options"></a>
-# 3.ii. Adding New Options
+### 3.ii. Adding New Options
If you add new options to the plugin, make sure to document those new options
in the [README.md](README.md) file, and also in the [help file](doc/ale.txt).
@@ -104,7 +104,7 @@ easy to see what the default is with `:echo g:ale...`.
<a name="writing-documentation"></a>
-# 4. Writing Documentation
+## 4. Writing Documentation
If you are adding new linters, changing the API, adding new options, etc., you
_must_ write some documentation describing it in the `doc/ale.txt` file. New
@@ -113,7 +113,7 @@ quick overview of the supported tools.
<a name="documenting-new-linters"></a>
-# 4.i Documenting New Linters
+### 4.i Documenting New Linters
If you add a new linter to the project, edit the table in the `README.md` file,
and edit the list of linters at the top of the `doc/ale.txt` file. The linters
@@ -125,7 +125,7 @@ giving some unfair preference to any particular tool or language.
<a name="editing-online-documentation"></a>
-# 4.ii Editing the Online Documentation
+### 4.ii Editing the Online Documentation
The "online documentation" file used for this project lives in `doc/ale.txt`.
This is the file used for generating `:help` text inside Vim itself. There are
@@ -145,7 +145,7 @@ some guidlines to follow for this file.
<a name="documenting-linter-options"></a>
-# 4.iii Documenting Linter Options
+### 4.iii Documenting Linter Options
For documenting new linter options, please add a new sub-section under the
"Linter Specific Options" section describing all of the global options added
@@ -155,7 +155,7 @@ to look up the default value easily by typing `:echo g:ale_...`.
<a name="in-case-of-busses"></a>
-# 5. In Case of Busses
+## 5. In Case of Busses
Should the principal author of the ALE project and all collaborators with the
required access needed to properly administrate the project on GitHub or any
diff --git a/README.md b/README.md
index 81793099..9c513e59 100644
--- a/README.md
+++ b/README.md
@@ -20,22 +20,22 @@ In other words, this plugin allows you to lint while you type.
1. [Supported Languages and Tools](#supported-languages)
2. [Usage](#usage)
3. [Installation](#installation)
- 1. [Installation with Pathogen](#installation-with-pathogen)
- 2. [Installation with Vundle](#installation-with-vundle)
- 3. [Manual Installation](#manual-installation)
+ 1. [Installation with Pathogen](#installation-with-pathogen)
+ 2. [Installation with Vundle](#installation-with-vundle)
+ 3. [Manual Installation](#manual-installation)
4. [Contributing](#contributing)
5. [FAQ](#faq)
- 1. [How do I disable particular linters?](#faq-disable-linters)
- 2. [How can I keep the sign gutter open?](#faq-disable-linters)
- 3. [How can I change the signs ALE uses?](#faq-change-signs)
- 4. [How can I show errors or warnings in my statusline?](#faq-statusline)
- 5. [How can I change the format for echo messages?](#faq-echo-format)
- 6. [How can I execute some code when ALE stops linting?](#faq-autocmd)
- 7. [How can I navigate between errors quickly?](#faq-navigation)
- 8. [How can I run linters only when I save files?](#faq-lint-on-save)
- 9. [How can I use the quickfix list instead of the loclist?](#faq-quickfix)
- 10. [How can I check JSX files with both stylelint and eslint?](#faq-jsx-stylelint-eslint)
- 11. [Will this plugin eat all of my laptop battery power?](#faq-my-battery-is-sad)
+ 1. [How do I disable particular linters?](#faq-disable-linters)
+ 2. [How can I keep the sign gutter open?](#faq-keep-signs)
+ 3. [How can I change the signs ALE uses?](#faq-change-signs)
+ 4. [How can I show errors or warnings in my statusline?](#faq-statusline)
+ 5. [How can I change the format for echo messages?](#faq-echo-format)
+ 6. [How can I execute some code when ALE stops linting?](#faq-autocmd)
+ 7. [How can I navigate between errors quickly?](#faq-navigation)
+ 8. [How can I run linters only when I save files?](#faq-lint-on-save)
+ 9. [How can I use the quickfix list instead of the loclist?](#faq-quickfix)
+ 10. [How can I check JSX files with both stylelint and eslint?](#faq-jsx-stylelint-eslint)
+ 11. [Will this plugin eat all of my laptop battery power?](#faq-my-battery-is-sad)
<a name="supported-languages"></a>
@@ -309,9 +309,9 @@ let g:ale_statusline_format = ['⨉ %d', '⚠ %d', '⬥ ok']
There are 3 global options that allow customizing the echoed message.
- `g:ale_echo_msg_format` where:
- * `%s` is the error message itself
- * `%linter%` is the linter name
- * `%severity` is the severity type
+ * `%s` is the error message itself
+ * `%linter%` is the linter name
+ * `%severity` is the severity type
- `g:ale_echo_msg_error_str` is the string used for error severity.
- `g:ale_echo_msg_warning_str` is the string used for warning severity.
diff --git a/ale_linters/c/clang.vim b/ale_linters/c/clang.vim
index 603e2b75..489245da 100644
--- a/ale_linters/c/clang.vim
+++ b/ale_linters/c/clang.vim
@@ -22,5 +22,5 @@ call ale#linter#Define('c', {
\ 'output_stream': 'stderr',
\ 'executable': 'clang',
\ 'command_callback': 'ale_linters#c#clang#GetCommand',
-\ 'callback': 'ale#handlers#HandleGCCFormat',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\})
diff --git a/ale_linters/c/gcc.vim b/ale_linters/c/gcc.vim
index a487909c..c89fae72 100644
--- a/ale_linters/c/gcc.vim
+++ b/ale_linters/c/gcc.vim
@@ -22,5 +22,5 @@ call ale#linter#Define('c', {
\ 'output_stream': 'stderr',
\ 'executable': 'gcc',
\ 'command_callback': 'ale_linters#c#gcc#GetCommand',
-\ 'callback': 'ale#handlers#HandleGCCFormat',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\})
diff --git a/ale_linters/coffee/coffee.vim b/ale_linters/coffee/coffee.vim
index ac9ef79e..f263a163 100644
--- a/ale_linters/coffee/coffee.vim
+++ b/ale_linters/coffee/coffee.vim
@@ -19,5 +19,5 @@ call ale#linter#Define('coffee', {
\ 'executable_callback': 'ale_linters#coffee#coffee#GetExecutable',
\ 'command_callback': 'ale_linters#coffee#coffee#GetCommand',
\ 'output_stream': 'stderr',
-\ 'callback': 'ale#handlers#HandleGCCFormat',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\})
diff --git a/ale_linters/cpp/clang.vim b/ale_linters/cpp/clang.vim
index 9915ac3a..e8af6dc2 100644
--- a/ale_linters/cpp/clang.vim
+++ b/ale_linters/cpp/clang.vim
@@ -19,5 +19,5 @@ call ale#linter#Define('cpp', {
\ 'output_stream': 'stderr',
\ 'executable': 'clang++',
\ 'command_callback': 'ale_linters#cpp#clang#GetCommand',
-\ 'callback': 'ale#handlers#HandleGCCFormat',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\})
diff --git a/ale_linters/cpp/clangtidy.vim b/ale_linters/cpp/clangtidy.vim
index 11088c43..6b72e1f5 100644
--- a/ale_linters/cpp/clangtidy.vim
+++ b/ale_linters/cpp/clangtidy.vim
@@ -14,5 +14,5 @@ call ale#linter#Define('cpp', {
\ 'output_stream': 'stdout',
\ 'executable': 'clang-tidy',
\ 'command_callback': 'ale_linters#cpp#clangtidy#GetCommand',
-\ 'callback': 'ale#handlers#HandleGCCFormat',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\})
diff --git a/ale_linters/cpp/gcc.vim b/ale_linters/cpp/gcc.vim
index ad1b93b7..f2261c4f 100644
--- a/ale_linters/cpp/gcc.vim
+++ b/ale_linters/cpp/gcc.vim
@@ -28,5 +28,5 @@ call ale#linter#Define('cpp', {
\ 'output_stream': 'stderr',
\ 'executable': 'g++',
\ 'command_callback': 'ale_linters#cpp#gcc#GetCommand',
-\ 'callback': 'ale#handlers#HandleGCCFormat',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\})
diff --git a/ale_linters/go/gobuild.vim b/ale_linters/go/gobuild.vim
index 0bac9f26..a40565d6 100644
--- a/ale_linters/go/gobuild.vim
+++ b/ale_linters/go/gobuild.vim
@@ -1,4 +1,4 @@
-" Author: Joshua Rubin <joshua@rubixconsulting.com>
+" Author: Joshua Rubin <joshua@rubixconsulting.com>, Ben Reedy <https://github.com/breed808>
" Description: go build for Go files
" inspired by work from dzhou121 <dzhou121@gmail.com>
@@ -11,198 +11,55 @@ function! ale_linters#go#gobuild#GoEnv(buffer) abort
return 'go env GOPATH GOROOT'
endfunction
-let s:SplitChar = has('unix') ? ':' : ':'
-
-" get a list of all source directories from $GOPATH and $GOROOT
-function! s:SrcDirs() abort
- let l:paths = split(s:go_env.GOPATH, s:SplitChar)
- call add(l:paths, s:go_env.GOROOT)
-
- return l:paths
-endfunction
-
-" figure out from a directory like `/home/user/go/src/some/package` that the
-" import for that path is simply `some/package`
-function! s:PackageImportPath(buffer) abort
- let l:bufname = resolve(bufname(a:buffer))
- let l:pkgdir = fnamemodify(l:bufname, ':p:h')
-
- for l:path in s:SrcDirs()
- let l:path = l:path . '/src/'
-
- if stridx(l:pkgdir, l:path) == 0
- return l:pkgdir[strlen(l:path):]
- endif
- endfor
-
- return ''
-endfunction
-
-" get the package info data structure using `go list`
-function! ale_linters#go#gobuild#GoList(buffer, goenv_output) abort
- if !empty(a:goenv_output)
+function! ale_linters#go#gobuild#GetCommand(buffer, goenv_output) abort
+ if !exists('s:go_env')
let s:go_env = {
\ 'GOPATH': a:goenv_output[0],
\ 'GOROOT': a:goenv_output[1],
\}
endif
- return 'go list -json ' . shellescape(s:PackageImportPath(a:buffer))
-endfunction
-
-let s:filekeys = [
-\ 'GoFiles',
-\ 'CgoFiles',
-\ 'CFiles',
-\ 'CXXFiles',
-\ 'MFiles',
-\ 'HFiles',
-\ 'FFiles',
-\ 'SFiles',
-\ 'SwigFiles',
-\ 'SwigCXXFiles',
-\ 'SysoFiles',
-\ 'TestGoFiles',
-\ 'XTestGoFiles',
-\]
-
-" get the go and test go files from the package
-" will return empty list if the package has any cgo or other invalid files
-function! s:PkgFiles(pkginfo) abort
- let l:files = []
-
- for l:key in s:filekeys
- if has_key(a:pkginfo, l:key)
- call extend(l:files, a:pkginfo[l:key])
- endif
- endfor
-
- " resolve the path of the file relative to the window directory
- return map(l:files, 'shellescape(fnamemodify(resolve(a:pkginfo.Dir . ''/'' . v:val), '':p''))')
-endfunction
-
-function! ale_linters#go#gobuild#CopyFiles(buffer, golist_output) abort
- let l:tempdir = tempname()
- let l:temppkgdir = l:tempdir . '/src/' . s:PackageImportPath(a:buffer)
- call mkdir(l:temppkgdir, 'p', 0700)
-
- if empty(a:golist_output)
- return 'echo ' . shellescape(l:tempdir)
- endif
-
- " parse the output
- let l:pkginfo = json_decode(join(a:golist_output, "\n"))
-
- " get all files for the package
- let l:files = s:PkgFiles(l:pkginfo)
-
- " copy the files to a temp directory with $GOPATH structure
- return 'cp ' . join(l:files, ' ') . ' ' . shellescape(l:temppkgdir) . ' && echo ' . shellescape(l:tempdir)
-endfunction
-
-function! ale_linters#go#gobuild#GetCommand(buffer, copy_output) abort
- " If for some reason we don't get any output from the last command, stop
- " here.
- if empty(a:copy_output)
- return ''
- endif
-
- let l:tempdir = a:copy_output[0]
- let l:importpath = s:PackageImportPath(a:buffer)
-
- " write the a:buffer and any modified buffers from the package to the tempdir
- for l:bufnum in range(1, bufnr('$'))
- " ignore unloaded buffers (can't be a:buffer or a modified buffer)
- if !bufloaded(l:bufnum)
- continue
- endif
-
- " ignore non-Go buffers
- if getbufvar(l:bufnum, '&ft') !=# 'go'
- continue
- endif
-
- " only consider buffers other than a:buffer if they have the same import
- " path as a:buffer and are modified
- if l:bufnum != a:buffer
- if s:PackageImportPath(l:bufnum) !=# l:importpath
- continue
- endif
-
- if !getbufvar(l:bufnum, '&mod')
- continue
- endif
- endif
-
- call writefile(getbufline(l:bufnum, 1, '$'), l:tempdir . '/src/' . s:PkgFile(l:bufnum))
- endfor
-
- let l:gopaths = [ l:tempdir ]
- call extend(l:gopaths, split(s:go_env.GOPATH, s:SplitChar))
-
- return 'GOPATH=' . shellescape(join(l:gopaths, s:SplitChar)) . ' go test -c -o /dev/null ' . shellescape(l:importpath)
-endfunction
-
-function! s:PkgFile(buffer) abort
- let l:bufname = resolve(bufname(a:buffer))
- let l:importpath = s:PackageImportPath(a:buffer)
- let l:fname = fnamemodify(l:bufname, ':t')
-
- return l:importpath . '/' . l:fname
+ return 'GOPATH=' . s:go_env.GOPATH . ' go test -c -o /dev/null %s'
endfunction
-function! s:FindBuffer(file) abort
- for l:buffer in range(1, bufnr('$'))
- if !buflisted(l:buffer)
- continue
- endif
-
- let l:pkgfile = s:PkgFile(l:buffer)
-
- if a:file =~ '/' . l:pkgfile . '$'
- return l:buffer
- endif
- endfor
-
- return -1
-endfunction
-
-let s:path_pattern = '[a-zA-Z]\?\\\?:\?[[:alnum:]/\.\-_]\+'
-let s:handler_pattern = '^\(' . s:path_pattern . '\):\(\d\+\):\?\(\d\+\)\?: \(.\+\)$'
-
-let s:multibuffer = 0
-
function! ale_linters#go#gobuild#Handler(buffer, lines) abort
- let l:output = []
-
- for l:line in a:lines
- let l:match = matchlist(l:line, s:handler_pattern)
-
- if len(l:match) == 0
- continue
- endif
-
- let l:buffer = s:FindBuffer(l:match[1])
-
- if l:buffer == -1
- continue
- endif
-
- if !s:multibuffer && l:buffer != a:buffer
- " strip lines from other buffers
- continue
- endif
-
- call add(l:output, {
- \ 'bufnr': l:buffer,
- \ 'lnum': l:match[2] + 0,
- \ 'col': l:match[3] + 0,
- \ 'text': l:match[4],
- \ 'type': 'E',
- \})
- endfor
+ return ale_linters#go#gobuild#HandleGoBuildErrors(a:buffer, bufname(a:buffer), a:lines)
+endfunction
- return l:output
+function! ale_linters#go#gobuild#HandleGoBuildErrors(buffer, full_filename, lines) abort
+ " Matches patterns line the following:
+ "
+ " file.go:27: missing argument for Printf("%s"): format reads arg 2, have only 1 args
+ " file.go:53:10: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)
+ " file.go:5:2: expected declaration, found 'STRING' "log"
+
+ " go test returns relative paths so use tail of filename as part of pattern matcher
+ let l:filename = fnamemodify(a:full_filename, ':t')
+ let l:path_pattern = '[a-zA-Z]\?\\\?:\?[[:alnum:]/\.\-_]\+'
+ let l:pattern = '^' . l:path_pattern . ':\(\d\+\):\?\(\d\+\)\?:\? \(.\+\)$'
+ let l:output = []
+
+ for l:line in a:lines
+ let l:match = matchlist(l:line, l:pattern)
+
+ " Omit errors from imported go packages
+ if len(l:match) == 0 || l:line !~ l:filename
+ continue
+ endif
+
+ " vcol is Needed to indicate that the column is a character.
+ call add(l:output, {
+ \ 'bufnr': a:buffer,
+ \ 'lnum': l:match[1] + 0,
+ \ 'vcol': 0,
+ \ 'col': l:match[2] + 0,
+ \ 'text': l:match[3],
+ \ 'type': 'E',
+ \ 'nr': -1,
+ \})
+ endfor
+
+ return l:output
endfunction
call ale#linter#Define('go', {
@@ -210,9 +67,8 @@ call ale#linter#Define('go', {
\ 'executable': 'go',
\ 'command_chain': [
\ {'callback': 'ale_linters#go#gobuild#GoEnv', 'output_stream': 'stdout'},
-\ {'callback': 'ale_linters#go#gobuild#GoList', 'output_stream': 'stdout'},
-\ {'callback': 'ale_linters#go#gobuild#CopyFiles', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#go#gobuild#GetCommand', 'output_stream': 'stderr'},
\ ],
\ 'callback': 'ale_linters#go#gobuild#Handler',
+\ 'lint_file': 1,
\})
diff --git a/ale_linters/php/php.vim b/ale_linters/php/php.vim
index ebc21ea3..3f354de5 100644
--- a/ale_linters/php/php.vim
+++ b/ale_linters/php/php.vim
@@ -1,11 +1,11 @@
-" Author: Spencer Wood <https://github.com/scwood>
+" Author: Spencer Wood <https://github.com/scwood>, Adriaan Zonnenberg <amz@adriaan.xyz>
" Description: This file adds support for checking PHP with php-cli
function! ale_linters#php#php#Handle(buffer, lines) abort
" Matches patterns like the following:
"
" PHP Parse error: syntax error, unexpected ';', expecting ']' in - on line 15
- let l:pattern = '\vParse error:\s+(.+unexpected ''(.+)%(expecting.+)@<!''.*|.+) in - on line (\d+)'
+ let l:pattern = '\vPHP %(Fatal|Parse) error:\s+(.+unexpected ''(.+)%(expecting.+)@<!''.*|.+) in - on line (\d+)'
let l:output = []
diff --git a/ale_linters/puppet/puppetlint.vim b/ale_linters/puppet/puppetlint.vim
index 05745cfe..902480d8 100644
--- a/ale_linters/puppet/puppetlint.vim
+++ b/ale_linters/puppet/puppetlint.vim
@@ -1,10 +1,26 @@
-" Author: Alexander Olofsson <alexander.olofsson@liu.se>
+" Author: Alexander Olofsson <alexander.olofsson@liu.se>, Robert Flechtner <flechtner@chemmedia.de>
+" Description: puppet-lint for puppet files
+
+let g:ale_puppet_puppetlint_executable =
+\ get(g:, 'ale_puppet_puppetlint_executable', 'puppet-lint')
+
+let g:ale_puppet_puppetlint_options =
+\ get(g:, 'ale_puppet_puppetlint_options', '--no-autoloader_layout-check')
+
+function! ale_linters#puppet#puppetlint#GetExecutable(buffer) abort
+ return g:ale_puppet_puppetlint_executable
+endfunction
+
+function! ale_linters#puppet#puppetlint#GetCommand(buffer) abort
+ return ale_linters#puppet#puppetlint#GetExecutable(a:buffer)
+ \ . ' ' . g:ale_puppet_puppetlint_options
+ \ . ' --log-format "-:%{line}:%{column}: %{kind}: [%{check}] %{message}"'
+ \ . ' %t'
+endfunction
call ale#linter#Define('puppet', {
\ 'name': 'puppetlint',
-\ 'executable': 'puppet-lint',
-\ 'command': 'puppet-lint --no-autoloader_layout-check'
-\ . ' --log-format "-:%{line}:%{column}: %{kind}: [%{check}] %{message}"'
-\ . ' %t',
-\ 'callback': 'ale#handlers#HandleGCCFormat',
+\ 'executable_callback': 'ale_linters#puppet#puppetlint#GetExecutable',
+\ 'command_callback': 'ale_linters#puppet#puppetlint#GetCommand',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\})
diff --git a/ale_linters/sh/shellcheck.vim b/ale_linters/sh/shellcheck.vim
index bb556460..5f932b19 100644
--- a/ale_linters/sh/shellcheck.vim
+++ b/ale_linters/sh/shellcheck.vim
@@ -48,5 +48,5 @@ call ale#linter#Define('sh', {
\ 'name': 'shellcheck',
\ 'executable_callback': 'ale_linters#sh#shellcheck#GetExecutable',
\ 'command_callback': 'ale_linters#sh#shellcheck#GetCommand',
-\ 'callback': 'ale#handlers#HandleGCCFormat',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\})
diff --git a/ale_linters/swift/swiftlint.vim b/ale_linters/swift/swiftlint.vim
index aaa77a9f..b7dcf935 100644
--- a/ale_linters/swift/swiftlint.vim
+++ b/ale_linters/swift/swiftlint.vim
@@ -5,5 +5,5 @@ call ale#linter#Define('swift', {
\ 'name': 'swiftlint',
\ 'executable': 'swiftlint',
\ 'command': 'swiftlint lint --use-stdin',
-\ 'callback': 'ale#handlers#HandleGCCFormat',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\})
diff --git a/ale_linters/vim/vint.vim b/ale_linters/vim/vint.vim
index 4b2c5445..821a0bdc 100644
--- a/ale_linters/vim/vint.vim
+++ b/ale_linters/vim/vint.vim
@@ -20,5 +20,5 @@ call ale#linter#Define('vim', {
\ . s:enable_neovim
\ . s:format
\ . ' %t',
-\ 'callback': 'ale#handlers#HandleGCCFormat',
+\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\})
diff --git a/autoload/ale/handlers.vim b/autoload/ale/handlers.vim
index 96be427f..75d881fa 100644
--- a/autoload/ale/handlers.vim
+++ b/autoload/ale/handlers.vim
@@ -45,36 +45,6 @@ function! ale#handlers#HandleUnixFormatAsWarning(buffer, lines) abort
return s:HandleUnixFormat(a:buffer, a:lines, 'W')
endfunction
-function! ale#handlers#HandleGCCFormat(buffer, lines) abort
- " Look for lines like the following.
- "
- " <stdin>:8:5: warning: conversion lacks type at end of format [-Wformat=]
- " <stdin>:10:27: error: invalid operands to binary - (have ‘int’ and ‘char *’)
- " -:189:7: note: $/${} is unnecessary on arithmetic variables. [SC2004]
- let l:pattern = '^.\+:\(\d\+\):\(\d\+\): \([^:]\+\): \(.\+\)$'
- let l:output = []
-
- for l:line in a:lines
- let l:match = matchlist(l:line, l:pattern)
-
- if len(l:match) == 0
- continue
- endif
-
- call add(l:output, {
- \ 'bufnr': a:buffer,
- \ 'lnum': l:match[1] + 0,
- \ 'vcol': 0,
- \ 'col': l:match[2] + 0,
- \ 'text': l:match[4],
- \ 'type': l:match[3] =~# 'error' ? 'E' : 'W',
- \ 'nr': -1,
- \})
- endfor
-
- return l:output
-endfunction
-
function! ale#handlers#HandleCppCheckFormat(buffer, lines) abort
" Look for lines like the following.
"
diff --git a/autoload/ale/handlers/gcc.vim b/autoload/ale/handlers/gcc.vim
new file mode 100644
index 00000000..0755e951
--- /dev/null
+++ b/autoload/ale/handlers/gcc.vim
@@ -0,0 +1,88 @@
+scriptencoding utf-8
+" Author: w0rp <devw0rp@gmail.com>
+" Description: This file defines a handler function which ought to work for
+" any program which outputs errors in the format that GCC uses.
+
+function! s:AddIncludedErrors(output, include_lnum, include_lines) abort
+ if a:include_lnum > 0
+ call add(a:output, {
+ \ 'lnum': a:include_lnum,
+ \ 'type': 'E',
+ \ 'text': 'Problems were found in the header (See :ALEDetail)',
+ \ 'detail': join(a:include_lines, "\n"),
+ \})
+ endif
+endfunction
+
+function! s:IsHeaderFile(filename) abort
+ return a:filename =~? '\v\.(h|hpp)$'
+endfunction
+
+function! ale#handlers#gcc#HandleGCCFormat(buffer, lines) abort
+ let l:include_pattern = '\v^(In file included | *)from ([^:]*):(\d+)'
+ let l:include_lnum = 0
+ let l:include_lines = []
+ let l:included_filename = ''
+ " Look for lines like the following.
+ "
+ " <stdin>:8:5: warning: conversion lacks type at end of format [-Wformat=]
+ " <stdin>:10:27: error: invalid operands to binary - (have ‘int’ and ‘char *’)
+ " -:189:7: note: $/${} is unnecessary on arithmetic variables. [SC2004]
+ let l:pattern = '^\(.\+\):\(\d\+\):\(\d\+\): \([^:]\+\): \(.\+\)$'
+ let l:output = []
+
+ for l:line in a:lines
+ let l:match = matchlist(l:line, l:pattern)
+
+ if empty(l:match)
+ " Check for matches in includes.
+ " We will keep matching lines until we hit the last file, which
+ " is our file.
+ let l:include_match = matchlist(l:line, l:include_pattern)
+
+ if empty(l:include_match)
+ " If this isn't another include header line, then we
+ " need to collect it.
+ call add(l:include_lines, l:line)
+ else
+ " GCC and clang return the lists of files in different orders,
+ " so we'll only grab the line number from lines which aren't
+ " header files.
+ if !s:IsHeaderFile(l:include_match[2])
+ " Get the line number out of the parsed include line,
+ " and reset the other variables.
+ let l:include_lnum = str2nr(l:include_match[3])
+ endif
+
+ let l:include_lines = []
+ let l:included_filename = ''
+ endif
+ elseif l:include_lnum > 0
+ \&& (empty(l:included_filename) || l:included_filename ==# l:match[1])
+ " If we hit the first error after an include header, or the
+ " errors below have the same name as the first filename we see,
+ " then include these lines, and remember what that filename was.
+ let l:included_filename = l:match[1]
+ call add(l:include_lines, l:line)
+ else
+ " If we hit a regular error again, then add the previously
+ " collected lines as one error, and reset the include variables.
+ call s:AddIncludedErrors(l:output, l:include_lnum, l:include_lines)
+ let l:include_lnum = 0
+ let l:include_lines = []
+ let l:included_filename = ''
+
+ call add(l:output, {
+ \ 'lnum': l:match[2] + 0,
+ \ 'col': l:match[3] + 0,
+ \ 'type': l:match[4] =~# 'error' ? 'E' : 'W',
+ \ 'text': l:match[5],
+ \})
+ endif
+ endfor
+
+ " Add remaining include errors after we go beyond the last line.
+ call s:AddIncludedErrors(l:output, l:include_lnum, l:include_lines)
+
+ return l:output
+endfunction
diff --git a/doc/ale-puppet.txt b/doc/ale-puppet.txt
new file mode 100644
index 00000000..1fd46e18
--- /dev/null
+++ b/doc/ale-puppet.txt
@@ -0,0 +1,26 @@
+===============================================================================
+ALE Puppet Integration *ale-puppet-options*
+
+
+-------------------------------------------------------------------------------
+puppetlint *ale-puppet-puppetlint*
+
+g:ale_puppet_puppetlint_executable *g:ale_puppet_puppetlint_executable*
+
+ Type: |String|
+ Default: `'puppet-lint'`
+
+ This variable can be changed to specify the executable used for puppet-lint.
+
+
+g:ale_puppet_puppetlint_options *g:ale_puppet_puppetlint_options*
+
+ Type: |String|
+ Default: `'--no-autoloader_layout-check'`
+
+ This variable can be changed to add command-line arguments to the
+ puppet-lint invocation.
+
+
+-------------------------------------------------------------------------------
+ vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
diff --git a/test/c_tests/broken.h b/test/c_tests/broken.h
new file mode 100644
index 00000000..3bd3571a
--- /dev/null
+++ b/test/c_tests/broken.h
@@ -0,0 +1 @@
+{{{
diff --git a/test/c_tests/test_gcc.vader b/test/c_tests/test_gcc.vader
index 67e4e426..0bf3eb1d 100644
--- a/test/c_tests/test_gcc.vader
+++ b/test/c_tests/test_gcc.vader
@@ -34,12 +34,9 @@ Given c (A test C file):
Execute(Basic errors should be returned for GCC for C files):
call ale#Lint()
- AssertEqual [{
- \ 'lnum': 3,
- \ 'col': 1,
- \ }],
- \ map(getloclist(0), '{''lnum'': v:val.lnum, ''col'': v:val.col}'),
- \ 'No errors returned! Got: ' . GetCommandOutput()
+ AssertEqual
+ \ [{'lnum': 3, 'col': 1}],
+ \ map(getloclist(0), '{''lnum'': v:val.lnum, ''col'': v:val.col}')
Assert match(getloclist(0)[0].text, '\v^expected .*;.* before .*\}.* token$') >= 0,
\ 'Invalid error text: ' . getloclist(0)[0].text
@@ -52,12 +49,42 @@ Given cpp (A test C++ file):
Execute(Basic errors should be returned for GCC for C++ files):
call ale#Lint()
- AssertEqual [{
- \ 'lnum': 3,
- \ 'col': 1,
- \ }],
- \ map(getloclist(0), '{''lnum'': v:val.lnum, ''col'': v:val.col}'),
- \ 'No errors returned! Got: ' . GetCommandOutput()
+ AssertEqual
+ \ [{'lnum': 3, 'col': 1}],
+ \ map(getloclist(0), '{''lnum'': v:val.lnum, ''col'': v:val.col}')
Assert match(getloclist(0)[0].text, '\v^expected .*;.* before .*\}.* token$') >= 0,
- \ 'Invalid error text: ' . getloclist(0)[0].text
+
+Given c (A test C file with a header containing broken code):
+ // Some comment line
+ #include "broken.h"
+
+ int main() {
+ return 0
+ }
+
+Execute(Basic errors should be returned for GCC for C files with headers):
+ call ale#Lint()
+
+ AssertEqual
+ \ [{'lnum': 2, 'col': 0}],
+ \ map(getloclist(0), '{''lnum'': v:val.lnum, ''col'': v:val.col}')
+
+ AssertEqual 'Problems were found in the header (See :ALEDetail)', getloclist(0)[0].text
+
+Given cpp (A test C++ file with a header containing broken code):
+ // Some comment line
+ #include "broken.h"
+
+ int main() {
+ return 0
+ }
+
+Execute(Basic errors should be returned for GCC for C++ files with headers):
+ call ale#Lint()
+
+ AssertEqual
+ \ [{'lnum': 2, 'col': 0}],
+ \ map(getloclist(0), '{''lnum'': v:val.lnum, ''col'': v:val.col}')
+
+ AssertEqual 'Problems were found in the header (See :ALEDetail)', getloclist(0)[0].text
diff --git a/test/handler/test_clang_handler.vader b/test/handler/test_clang_handler.vader
new file mode 100644
index 00000000..d28b9eb8
--- /dev/null
+++ b/test/handler/test_clang_handler.vader
@@ -0,0 +1,23 @@
+Execute(clang errors from included files should be parsed correctly):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 3,
+ \ 'type': 'E',
+ \ 'text': 'Problems were found in the header (See :ALEDetail)',
+ \ 'detail': join([
+ \ './b.h:1:1: error: expected identifier or ''(''',
+ \ '{{{',
+ \ '^',
+ \ '1 error generated.',
+ \ ], "\n"),
+ \ },
+ \ ],
+ \ ale#handlers#gcc#HandleGCCFormat(347, [
+ \ 'In file included from test.c:3:',
+ \ 'In file included from ./a.h:1:',
+ \ './b.h:1:1: error: expected identifier or ''(''',
+ \ '{{{',
+ \ '^',
+ \ '1 error generated.',
+ \ ])
diff --git a/test/handler/test_common_handlers.vader b/test/handler/test_common_handlers.vader
index 0968a916..f087fb55 100644
--- a/test/handler/test_common_handlers.vader
+++ b/test/handler/test_common_handlers.vader
@@ -55,7 +55,7 @@ Then (The loclist should be correct):
\], g:loclist
Execute (Run HandleGCCFormat):
- let g:loclist = ale#handlers#HandleGCCFormat(42, [
+ let g:loclist = ale#handlers#gcc#HandleGCCFormat(42, [
\ '<stdin>:8:5: warning: conversion lacks type at end of format [-Wformat=]',
\ '<stdin>:10:27: error: invalid operands to binary - (have ‘int’ and ‘char *’)',
\])
@@ -63,18 +63,12 @@ Execute (Run HandleGCCFormat):
Then (The loclist should be correct):
AssertEqual [
\ {
- \ 'bufnr': 42,
- \ 'vcol': 0,
- \ 'nr': -1,
\ 'lnum': 8,
\ 'col': 5,
\ 'type': 'W',
\ 'text': 'conversion lacks type at end of format [-Wformat=]',
\ },
\ {
- \ 'bufnr': 42,
- \ 'vcol': 0,
- \ 'nr': -1,
\ 'lnum': 10,
\ 'col': 27,
\ 'type': 'E',
diff --git a/test/handler/test_gcc_handler.vader b/test/handler/test_gcc_handler.vader
new file mode 100644
index 00000000..3d5a24d4
--- /dev/null
+++ b/test/handler/test_gcc_handler.vader
@@ -0,0 +1,68 @@
+Execute(GCC errors from included files should be parsed correctly):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 3,
+ \ 'type': 'E',
+ \ 'text': 'Problems were found in the header (See :ALEDetail)',
+ \ 'detail': join([
+ \ 'broken.h:1:1: error: expected identifier or ''('' before ''{'' token',
+ \ ' {{{',
+ \ ' ^',
+ \ ], "\n"),
+ \ },
+ \ ],
+ \ ale#handlers#gcc#HandleGCCFormat(347, [
+ \ 'In file included from <stdin>:3:0:',
+ \ 'broken.h:1:1: error: expected identifier or ''('' before ''{'' token',
+ \ ' {{{',
+ \ ' ^',
+ \ ])
+
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 3,
+ \ 'type': 'E',
+ \ 'text': 'Problems were found in the header (See :ALEDetail)',
+ \ 'detail': join([
+ \ 'b.h:1:1: error: expected identifier or ''('' before ''{'' token',
+ \ ' {{{',
+ \ ' ^',
+ \ ], "\n"),
+ \ },
+ \ ],
+ \ ale#handlers#gcc#HandleGCCFormat(347, [
+ \ 'In file included from a.h:1:0,',
+ \ ' from test.c:3:',
+ \ 'b.h:1:1: error: expected identifier or ''('' before ''{'' token',
+ \ ' {{{',
+ \ ' ^',
+ \ ])
+
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 3,
+ \ 'type': 'E',
+ \ 'text': 'Problems were found in the header (See :ALEDetail)',
+ \ 'detail': join([
+ \ 'b.h:1:1: error: unknown type name ‘bad_type’',
+ \ ' bad_type x;',
+ \ ' ^',
+ \ 'b.h:2:1: error: unknown type name ‘other_bad_type’',
+ \ ' other_bad_type y;',
+ \ ' ^',
+ \ ], "\n"),
+ \ },
+ \ ],
+ \ ale#handlers#gcc#HandleGCCFormat(347, [
+ \ 'In file included from a.h:1:0,',
+ \ ' from test.c:3:',
+ \ 'b.h:1:1: error: unknown type name ‘bad_type’',
+ \ ' bad_type x;',
+ \ ' ^',
+ \ 'b.h:2:1: error: unknown type name ‘other_bad_type’',
+ \ ' other_bad_type y;',
+ \ ' ^',
+ \ ])
diff --git a/test/handler/test_php_handler.vader b/test/handler/test_php_handler.vader
index bf6d45cc..e7c5dc29 100644
--- a/test/handler/test_php_handler.vader
+++ b/test/handler/test_php_handler.vader
@@ -3,6 +3,7 @@ Given (Some invalid lines of PHP):
class Foo { / }
$foo)
['foo' 'bar']
+ function count() {}
Execute(The php handler should parse lines correctly):
runtime ale_linters/php/php.vim
@@ -39,6 +40,13 @@ Execute(The php handler should parse lines correctly):
\ },
\ {
\ 'bufnr': 347,
+ \ 'lnum': 5,
+ \ 'col': 0,
+ \ 'text': "Cannot redeclare count()",
+ \ 'type': 'E',
+ \ },
+ \ {
+ \ 'bufnr': 347,
\ 'lnum': 21,
\ 'col': 0,
\ 'text': "syntax error, unexpected end of file",
@@ -54,10 +62,12 @@ Execute(The php handler should parse lines correctly):
\ ],
\ ale_linters#php#php#Handle(347, [
\ 'This line should be ignored completely',
+ \ "Parse error: syntax error, This line should be ignored completely in - on line 1",
\ "PHP Parse error: syntax error, unexpected ';', expecting ']' in - on line 1",
\ "PHP Parse error: syntax error, unexpected '/', expecting function (T_FUNCTION) or const (T_CONST) in - on line 2",
\ "PHP Parse error: syntax error, unexpected ')' in - on line 3",
\ "PHP Parse error: syntax error, unexpected ''bar'' (T_CONSTANT_ENCAPSED_STRING), expecting ']' in - on line 4",
+ \ "PHP Fatal error: Cannot redeclare count() in - on line 5",
\ 'PHP Parse error: syntax error, unexpected end of file in - on line 21',
\ 'PHP Parse error: Invalid numeric literal in - on line 47',
\ ])
diff --git a/test/handler/test_swiftlint_handler.vader b/test/handler/test_swiftlint_handler.vader
index 42fc8242..b77b4420 100644
--- a/test/handler/test_swiftlint_handler.vader
+++ b/test/handler/test_swiftlint_handler.vader
@@ -2,26 +2,20 @@ Execute(The swiftint handler should parse error messages correctly):
AssertEqual
\ [
\ {
- \ 'bufnr': 347,
\ 'lnum': 1,
\ 'col': 7,
\ 'text': 'Operator Usage Whitespace Violation: Operators should be surrounded by a single whitespace when they are being used. (operator_usage_whitespace)',
\ 'type': 'W',
- \ 'vcol': 0,
- \ 'nr': -1,
\ },
\ {
- \ 'bufnr': 347,
\ 'lnum': 1,
\ 'col': 11,
\ 'text': 'Operator Usage Whitespace Violation: Operators should be surrounded by a single whitespace when they are being used. (operator_usage_whitespace)',
\ 'type': 'W',
- \ 'vcol': 0,
- \ 'nr': -1,
\ },
\
\ ],
- \ ale#handlers#HandleGCCFormat(347, [
+ \ ale#handlers#gcc#HandleGCCFormat(347, [
\ 'This line should be ignored',
\ '<nopath>:1:7: warning: Operator Usage Whitespace Violation: Operators should be surrounded by a single whitespace when they are being used. (operator_usage_whitespace)',
\ '<nopath>:1:11: warning: Operator Usage Whitespace Violation: Operators should be surrounded by a single whitespace when they are being used. (operator_usage_whitespace)',
diff --git a/test/handler/test_vint_handler.vader b/test/handler/test_vint_handler.vader
new file mode 100644
index 00000000..efd33d10
--- /dev/null
+++ b/test/handler/test_vint_handler.vader
@@ -0,0 +1,36 @@
+Execute(The vint handler should parse error messages correctly):
+ :file! gxc.vim
+
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 1,
+ \ 'col': 1,
+ \ 'text': 'Use scriptencoding when multibyte char exists (see :help :script encoding)',
+ \ 'type': 'W',
+ \ },
+ \ {
+ \ 'lnum': 3,
+ \ 'col': 17,
+ \ 'text': 'Use robust operators `==#` or `==?` instead of `==` (see Google VimScript Style Guide (Matching))',
+ \ 'type': 'W',
+ \ },
+ \ {
+ \ 'lnum': 3,
+ \ 'col': 8,
+ \ 'text': 'Make the scope explicit like `l:filename` (see Anti-pattern of vimrc (Scope of identifier))',
+ \ 'type': 'W',
+ \ },
+ \ {
+ \ 'lnum': 7,
+ \ 'col': 8,
+ \ 'text': 'Undefined variable: filename (see :help E738)',
+ \ 'type': 'W',
+ \ },
+ \ ],
+ \ ale#handlers#gcc#HandleGCCFormat(347, [
+ \ 'gcc.vim:1:1: warning: Use scriptencoding when multibyte char exists (see :help :script encoding)',
+ \ 'gcc.vim:3:17: warning: Use robust operators `==#` or `==?` instead of `==` (see Google VimScript Style Guide (Matching))',
+ \ 'gcc.vim:3:8: style_problem: Make the scope explicit like `l:filename` (see Anti-pattern of vimrc (Scope of identifier))',
+ \ 'gcc.vim:7:8: warning: Undefined variable: filename (see :help E738)',
+ \ ])
diff --git a/test/test_temporary_file_management.vader b/test/test_temporary_file_management.vader
index b66f3d19..c8f379ab 100644
--- a/test/test_temporary_file_management.vader
+++ b/test/test_temporary_file_management.vader
@@ -1,22 +1,25 @@
Before:
let g:command = 'echo test'
- let g:filename = tempname()
- let g:directory = tempname()
- let g:preserved_directory = tempname()
+ let g:filename = ''
+ let g:directory = ''
+ let g:preserved_directory = ''
function! TestCommandCallback(buffer) abort
" We are registering a temporary file, so we should delete it.
+ let g:filename = tempname()
call writefile(['foo'], g:filename)
call ale#engine#ManageFile(a:buffer, g:filename)
" We are registering this directory appropriately, so we should delete
" the whole thing.
+ let g:directory = tempname()
call mkdir(g:directory)
call writefile(['foo'], g:directory . '/bar')
call ale#engine#ManageDirectory(a:buffer, g:directory)
" We are registering this directory as temporary file, so we
" shouldn't delete it.
+ let g:preserved_directory = tempname()
call mkdir(g:preserved_directory)
call writefile(['foo'], g:preserved_directory . '/bar')
call ale#engine#ManageFile(a:buffer, g:preserved_directory)
@@ -36,7 +39,9 @@ Before:
\})
After:
- call delete(g:preserved_directory, 'rf')
+ if !empty(g:preserved_directory)
+ call delete(g:preserved_directory, 'rf')
+ endif
unlet! g:command
unlet! g:filename
@@ -57,9 +62,9 @@ Execute(ALE should delete managed files/directories appropriately after linting)
call ale#Lint()
call ale#engine#WaitForJobs(2000)
- Assert !filereadable(g:filename), 'The tempoary file was not deleted'
- Assert !isdirectory(g:directory), 'The tempoary directory was not deleted'
- Assert isdirectory(g:preserved_directory), 'The tempoary directory was not kept'
+ Assert !filereadable(g:filename), 'The temporary file was not deleted'
+ Assert !isdirectory(g:directory), 'The temporary directory was not deleted'
+ Assert isdirectory(g:preserved_directory), 'The temporary directory was not kept'
Execute(ALE should delete managed files even if no command is run):
AssertEqual 'foobar', &filetype
@@ -69,17 +74,17 @@ Execute(ALE should delete managed files even if no command is run):
call ale#Lint()
call ale#engine#WaitForJobs(2000)
- Assert !filereadable(g:filename), 'The tempoary file was not deleted'
- Assert !isdirectory(g:directory), 'The tempoary directory was not deleted'
- Assert isdirectory(g:preserved_directory), 'The tempoary directory was not kept'
+ Assert !filereadable(g:filename), 'The temporary file was not deleted'
+ Assert !isdirectory(g:directory), 'The temporary directory was not deleted'
+ Assert isdirectory(g:preserved_directory), 'The temporary directory was not kept'
Execute(ALE should delete managed files when the buffer is removed):
call ale#engine#InitBufferInfo(bufnr('%'))
call TestCommandCallback(bufnr('%'))
call ale#cleanup#Buffer(bufnr('%'))
- Assert !filereadable(g:filename), 'The tempoary file was not deleted'
- Assert !isdirectory(g:directory), 'The tempoary directory was not deleted'
+ Assert !filereadable(g:filename), 'The temporary file was not deleted'
+ Assert !isdirectory(g:directory), 'The temporary directory was not deleted'
Assert isdirectory(g:preserved_directory), 'The tempoary directory was not kept'
Execute(ALE should create and delete directories for ale#engine#CreateDirectory()):