From 8e4bac54a60ade993eba16fac74e18c2a7697bcf Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 8 May 2017 22:59:25 +0100 Subject: [PATCH 1/8] #540 Fix shell escaping pretty much everywhere --- ale_linters/asm/gcc.vim | 2 +- ale_linters/c/clang.vim | 2 +- ale_linters/c/gcc.vim | 2 +- ale_linters/cpp/clang.vim | 2 +- ale_linters/cpp/gcc.vim | 2 +- ale_linters/css/csslint.vim | 2 +- ale_linters/d/dmd.vim | 4 +-- ale_linters/elm/make.vim | 2 +- ale_linters/erlang/erlc.vim | 2 +- ale_linters/go/gometalinter.vim | 2 +- ale_linters/java/javac.vim | 7 +++-- ale_linters/javascript/eslint.vim | 2 +- ale_linters/javascript/flow.vim | 2 +- ale_linters/javascript/jshint.vim | 4 +-- ale_linters/javascript/standard.vim | 2 +- ale_linters/javascript/xo.vim | 2 +- ale_linters/kotlin/kotlinc.vim | 4 +-- ale_linters/lua/luacheck.vim | 2 +- ale_linters/nim/nimcheck.vim | 2 +- ale_linters/python/flake8.vim | 4 +-- ale_linters/python/mypy.vim | 2 +- ale_linters/python/pylint.vim | 2 +- ale_linters/tex/chktex.vim | 2 +- ale_linters/typescript/tslint.vim | 2 +- ale_linters/verilog/verilator.vim | 2 +- autoload/ale/engine.vim | 6 ++--- autoload/ale/path.vim | 2 +- .../test_cppcheck_command_callbacks.vader | 4 +-- .../test_flake8_command_callback.vader | 26 +++++++++---------- .../test_javac_command_callback.vader | 16 ++++++------ .../test_luacheck_command_callback.vader | 6 ++--- .../test_mypy_command_callback.vader | 14 +++++----- .../test_pylint_command_callback.vader | 12 ++++----- test/test_csslint_config_detection.vader | 2 +- test/test_flow_command.vader | 2 +- test/test_format_command.vader | 14 +++++----- test/util/test_cd_string_commands.vader | 5 ++-- 37 files changed, 85 insertions(+), 87 deletions(-) diff --git a/ale_linters/asm/gcc.vim b/ale_linters/asm/gcc.vim index 4288f5d..1ff348d 100644 --- a/ale_linters/asm/gcc.vim +++ b/ale_linters/asm/gcc.vim @@ -5,7 +5,7 @@ let g:ale_asm_gcc_options = get(g:, 'ale_asm_gcc_options', '-Wall') function! ale_linters#asm#gcc#GetCommand(buffer) abort return 'gcc -x assembler -fsyntax-only ' - \ . '-iquote ' . fnameescape(fnamemodify(bufname(a:buffer), ':p:h')) + \ . '-iquote ' . shellescape(fnamemodify(bufname(a:buffer), ':p:h')) \ . ' ' . ale#Var(a:buffer, 'asm_gcc_options') . ' -' endfunction diff --git a/ale_linters/c/clang.vim b/ale_linters/c/clang.vim index 38e0d48..8a5c84c 100644 --- a/ale_linters/c/clang.vim +++ b/ale_linters/c/clang.vim @@ -13,7 +13,7 @@ function! ale_linters#c#clang#GetCommand(buffer) abort " -iquote with the directory the file is in makes #include work for " headers in the same directory. return 'clang -S -x c -fsyntax-only ' - \ . '-iquote ' . fnameescape(fnamemodify(bufname(a:buffer), ':p:h')) + \ . '-iquote ' . shellescape(fnamemodify(bufname(a:buffer), ':p:h')) \ . ' ' . ale#Var(a:buffer, 'c_clang_options') . ' -' endfunction diff --git a/ale_linters/c/gcc.vim b/ale_linters/c/gcc.vim index 7eed0f4..b783a7d 100644 --- a/ale_linters/c/gcc.vim +++ b/ale_linters/c/gcc.vim @@ -13,7 +13,7 @@ function! ale_linters#c#gcc#GetCommand(buffer) abort " -iquote with the directory the file is in makes #include work for " headers in the same directory. return 'gcc -S -x c -fsyntax-only ' - \ . '-iquote ' . fnameescape(fnamemodify(bufname(a:buffer), ':p:h')) + \ . '-iquote ' . shellescape(fnamemodify(bufname(a:buffer), ':p:h')) \ . ' ' . ale#Var(a:buffer, 'c_gcc_options') . ' -' endfunction diff --git a/ale_linters/cpp/clang.vim b/ale_linters/cpp/clang.vim index b830f6a..bd4d26e 100644 --- a/ale_linters/cpp/clang.vim +++ b/ale_linters/cpp/clang.vim @@ -10,7 +10,7 @@ function! ale_linters#cpp#clang#GetCommand(buffer) abort " -iquote with the directory the file is in makes #include work for " headers in the same directory. return 'clang++ -S -x c++ -fsyntax-only ' - \ . '-iquote ' . fnameescape(fnamemodify(bufname(a:buffer), ':p:h')) + \ . '-iquote ' . shellescape(fnamemodify(bufname(a:buffer), ':p:h')) \ . ' ' . ale#Var(a:buffer, 'cpp_clang_options') . ' -' endfunction diff --git a/ale_linters/cpp/gcc.vim b/ale_linters/cpp/gcc.vim index 19de0c9..981caec 100644 --- a/ale_linters/cpp/gcc.vim +++ b/ale_linters/cpp/gcc.vim @@ -20,7 +20,7 @@ function! ale_linters#cpp#gcc#GetCommand(buffer) abort " -iquote with the directory the file is in makes #include work for " headers in the same directory. return 'gcc -S -x c++ -fsyntax-only ' - \ . '-iquote ' . fnameescape(fnamemodify(bufname(a:buffer), ':p:h')) + \ . '-iquote ' . shellescape(fnamemodify(bufname(a:buffer), ':p:h')) \ . ' ' . ale#Var(a:buffer, 'cpp_gcc_options') . ' -' endfunction diff --git a/ale_linters/css/csslint.vim b/ale_linters/css/csslint.vim index fb26249..83698f5 100644 --- a/ale_linters/css/csslint.vim +++ b/ale_linters/css/csslint.vim @@ -4,7 +4,7 @@ function! ale_linters#css#csslint#GetCommand(buffer) abort let l:csslintrc = ale#path#FindNearestFile(a:buffer, '.csslintrc') let l:config_option = !empty(l:csslintrc) - \ ? '--config=' . fnameescape(l:csslintrc) + \ ? '--config=' . shellescape(l:csslintrc) \ : '' return 'csslint --format=compact ' . l:config_option . ' %t' diff --git a/ale_linters/d/dmd.vim b/ale_linters/d/dmd.vim index 3805e02..7068681 100644 --- a/ale_linters/d/dmd.vim +++ b/ale_linters/d/dmd.vim @@ -31,7 +31,7 @@ function! ale_linters#d#dmd#DUBCommand(buffer) abort " To support older dub versions, we just change the directory to " the directory where we found the dub config, and then run `dub describe` " from that directory. - return 'cd ' . fnameescape(fnamemodify(l:dub_file, ':h')) + return 'cd ' . shellescape(fnamemodify(l:dub_file, ':h')) \ . ' && dub describe --import-paths' endfunction @@ -42,7 +42,7 @@ function! ale_linters#d#dmd#DMDCommand(buffer, dub_output) abort for l:line in a:dub_output if !empty(l:line) " The arguments must be '-Ifilename', not '-I filename' - call add(l:import_list, '-I' . fnameescape(l:line)) + call add(l:import_list, '-I' . shellescape(l:line)) endif endfor diff --git a/ale_linters/elm/make.vim b/ale_linters/elm/make.vim index 32f824e..75a124a 100644 --- a/ale_linters/elm/make.vim +++ b/ale_linters/elm/make.vim @@ -43,7 +43,7 @@ function! ale_linters#elm#make#GetCommand(buffer) abort let l:dir_set_cmd = '' else let l:root_dir = fnamemodify(l:elm_package, ':p:h') - let l:dir_set_cmd = 'cd ' . fnameescape(l:root_dir) . ' && ' + let l:dir_set_cmd = 'cd ' . shellescape(l:root_dir) . ' && ' endif " The elm-make compiler, at the time of this writing, uses '/dev/null' as diff --git a/ale_linters/erlang/erlc.vim b/ale_linters/erlang/erlc.vim index a44e988..1b0f16c 100644 --- a/ale_linters/erlang/erlc.vim +++ b/ale_linters/erlang/erlc.vim @@ -6,7 +6,7 @@ function! ale_linters#erlang#erlc#GetCommand(buffer) abort let l:output_file = tempname() call ale#engine#ManageFile(a:buffer, l:output_file) - return 'erlc -o ' . fnameescape(l:output_file) + return 'erlc -o ' . shellescape(l:output_file) \ . ' ' . ale#Var(a:buffer, 'erlang_erlc_options') \ . ' %t' endfunction diff --git a/ale_linters/go/gometalinter.vim b/ale_linters/go/gometalinter.vim index 6ad78ca..9913f21 100644 --- a/ale_linters/go/gometalinter.vim +++ b/ale_linters/go/gometalinter.vim @@ -8,7 +8,7 @@ endif function! ale_linters#go#gometalinter#GetCommand(buffer) abort return 'gometalinter ' \ . ale#Var(a:buffer, 'go_gometalinter_options') - \ . ' ' . fnameescape(fnamemodify(bufname(a:buffer), ':p:h')) + \ . ' ' . shellescape(fnamemodify(bufname(a:buffer), ':p:h')) endfunction function! ale_linters#go#gometalinter#GetMatches(lines) abort diff --git a/ale_linters/java/javac.vim b/ale_linters/java/javac.vim index 5a10999..2966d06 100644 --- a/ale_linters/java/javac.vim +++ b/ale_linters/java/javac.vim @@ -41,14 +41,13 @@ endfunction function! s:BuildClassPathOption(buffer, import_paths) abort " Filter out lines like [INFO], etc. let l:class_paths = filter(a:import_paths[:], 'v:val !~# ''[''') - call map(l:class_paths, 'fnameescape(v:val)') call extend( \ l:class_paths, \ split(ale#Var(a:buffer, 'java_javac_classpath'), s:classpath_sep), \) return !empty(l:class_paths) - \ ? '-cp ' . join(l:class_paths, s:classpath_sep) + \ ? '-cp ' . shellescape(join(l:class_paths, s:classpath_sep)) \ : '' endfunction @@ -65,7 +64,7 @@ function! ale_linters#java#javac#GetCommand(buffer, import_paths) abort let l:src_dir = ale#path#FindNearestDirectory(a:buffer, 'src/main/java') if !empty(l:src_dir) - let l:sp_option = '-sourcepath ' . fnameescape(l:src_dir) + let l:sp_option = '-sourcepath ' . shellescape(l:src_dir) endif " Create .class files in a temporary directory, which we will delete later. @@ -74,7 +73,7 @@ function! ale_linters#java#javac#GetCommand(buffer, import_paths) abort return 'javac -Xlint' \ . ' ' . l:cp_option \ . ' ' . l:sp_option - \ . ' -d ' . fnameescape(l:class_file_directory) + \ . ' -d ' . shellescape(l:class_file_directory) \ . ' ' . ale#Var(a:buffer, 'java_javac_options') \ . ' %t' endfunction diff --git a/ale_linters/javascript/eslint.vim b/ale_linters/javascript/eslint.vim index 67b6583..7e4929b 100644 --- a/ale_linters/javascript/eslint.vim +++ b/ale_linters/javascript/eslint.vim @@ -34,7 +34,7 @@ function! ale_linters#javascript#eslint#GetExecutable(buffer) abort endfunction function! ale_linters#javascript#eslint#GetCommand(buffer) abort - return fnameescape(ale_linters#javascript#eslint#GetExecutable(a:buffer)) + return shellescape(ale_linters#javascript#eslint#GetExecutable(a:buffer)) \ . ' ' . ale#Var(a:buffer, 'javascript_eslint_options') \ . ' -f unix --stdin --stdin-filename %s' endfunction diff --git a/ale_linters/javascript/flow.vim b/ale_linters/javascript/flow.vim index 14f6512..36247cd 100644 --- a/ale_linters/javascript/flow.vim +++ b/ale_linters/javascript/flow.vim @@ -27,7 +27,7 @@ function! ale_linters#javascript#flow#GetCommand(buffer) abort return '' endif - return fnameescape(ale_linters#javascript#flow#GetExecutable(a:buffer)) + return shellescape(ale_linters#javascript#flow#GetExecutable(a:buffer)) \ . ' check-contents --respect-pragma --json --from ale %s' endfunction diff --git a/ale_linters/javascript/jshint.vim b/ale_linters/javascript/jshint.vim index 657b0ff..ec3c2c9 100644 --- a/ale_linters/javascript/jshint.vim +++ b/ale_linters/javascript/jshint.vim @@ -27,11 +27,11 @@ function! ale_linters#javascript#jshint#GetCommand(buffer) abort \ get(g:, 'ale_jshint_config_loc', '') \) - let l:command = fnameescape(ale_linters#javascript#jshint#GetExecutable(a:buffer)) + let l:command = shellescape(ale_linters#javascript#jshint#GetExecutable(a:buffer)) let l:command .= ' --reporter unix --extract auto' if !empty(l:jshint_config) - let l:command .= ' --config ' . fnameescape(l:jshint_config) + let l:command .= ' --config ' . shellescape(l:jshint_config) endif let l:command .= ' -' diff --git a/ale_linters/javascript/standard.vim b/ale_linters/javascript/standard.vim index 1b82823..30ebae1 100644 --- a/ale_linters/javascript/standard.vim +++ b/ale_linters/javascript/standard.vim @@ -23,7 +23,7 @@ function! ale_linters#javascript#standard#GetExecutable(buffer) abort endfunction function! ale_linters#javascript#standard#GetCommand(buffer) abort - return fnameescape(ale_linters#javascript#standard#GetExecutable(a:buffer)) + return shellescape(ale_linters#javascript#standard#GetExecutable(a:buffer)) \ . ' ' . ale#Var(a:buffer, 'javascript_standard_options') \ . ' --stdin %s' endfunction diff --git a/ale_linters/javascript/xo.vim b/ale_linters/javascript/xo.vim index a3e9f99..b7a549f 100644 --- a/ale_linters/javascript/xo.vim +++ b/ale_linters/javascript/xo.vim @@ -23,7 +23,7 @@ function! ale_linters#javascript#xo#GetExecutable(buffer) abort endfunction function! ale_linters#javascript#xo#GetCommand(buffer) abort - return fnameescape(ale_linters#javascript#xo#GetExecutable(a:buffer)) + return shellescape(ale_linters#javascript#xo#GetExecutable(a:buffer)) \ . ' ' . ale#Var(a:buffer, 'javascript_xo_options') \ . ' --reporter unix --stdin --stdin-filename %s' endfunction diff --git a/ale_linters/kotlin/kotlinc.vim b/ale_linters/kotlin/kotlinc.vim index 0ada361..543c3a9 100644 --- a/ale_linters/kotlin/kotlinc.vim +++ b/ale_linters/kotlin/kotlinc.vim @@ -16,13 +16,13 @@ function! ale_linters#kotlin#kotlinc#GetCommand(buffer) abort " If the config file is enabled and readable, source it if ale#Var(a:buffer, 'kotlin_kotlinc_enable_config') if filereadable(expand(ale#Var(a:buffer, 'kotlin_kotlinc_config_file'), 1)) - execute 'source ' . fnameescape(expand(ale#Var(a:buffer, 'kotlin_kotlinc_config_file'), 1)) + execute 'source ' . shellescape(expand(ale#Var(a:buffer, 'kotlin_kotlinc_config_file'), 1)) endif endif " If use module and module file is readable use that and return if ale#Var(a:buffer, 'kotlin_kotlinc_use_module_file') - let l:module_filename = fnameescape(expand(ale#Var(a:buffer, 'kotlin_kotlinc_module_filename'), 1)) + let l:module_filename = shellescape(expand(ale#Var(a:buffer, 'kotlin_kotlinc_module_filename'), 1)) if filereadable(l:module_filename) let l:kotlinc_opts .= ' -module ' . l:module_filename diff --git a/ale_linters/lua/luacheck.vim b/ale_linters/lua/luacheck.vim index 0098e66..8e3e986 100644 --- a/ale_linters/lua/luacheck.vim +++ b/ale_linters/lua/luacheck.vim @@ -12,7 +12,7 @@ function! ale_linters#lua#luacheck#GetExecutable(buffer) abort endfunction function! ale_linters#lua#luacheck#GetCommand(buffer) abort - return ale_linters#lua#luacheck#GetExecutable(a:buffer) + return shellescape(ale_linters#lua#luacheck#GetExecutable(a:buffer)) \ . ' ' . ale#Var(a:buffer, 'lua_luacheck_options') \ . ' --formatter plain --codes --filename %s -' endfunction diff --git a/ale_linters/nim/nimcheck.vim b/ale_linters/nim/nimcheck.vim index 02a7c93..9bd1972 100644 --- a/ale_linters/nim/nimcheck.vim +++ b/ale_linters/nim/nimcheck.vim @@ -44,7 +44,7 @@ endfunction function! ale_linters#nim#nimcheck#GetCommand(buffer) abort - let l:directory = fnameescape(fnamemodify(bufname(a:buffer), ':p:h')) + let l:directory = shellescape(fnamemodify(bufname(a:buffer), ':p:h')) return 'nim check --path:' . l:directory \ . ' --threads:on --verbosity:0 --colors:off --listFullPaths %t' diff --git a/ale_linters/python/flake8.vim b/ale_linters/python/flake8.vim index 4959583..99e9372 100644 --- a/ale_linters/python/flake8.vim +++ b/ale_linters/python/flake8.vim @@ -48,7 +48,7 @@ function! ale_linters#python#flake8#VersionCheck(buffer) abort return '' endif - let l:executable = fnameescape(ale_linters#python#flake8#GetExecutable(a:buffer)) + let l:executable = shellescape(ale_linters#python#flake8#GetExecutable(a:buffer)) let l:module_string = s:UsingModule(a:buffer) ? ' -m flake8' : '' return l:executable . l:module_string . ' --version' @@ -89,7 +89,7 @@ function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort let l:options = ale#Var(a:buffer, 'python_flake8_options') - return fnameescape(ale_linters#python#flake8#GetExecutable(a:buffer)) + return shellescape(ale_linters#python#flake8#GetExecutable(a:buffer)) \ . (!empty(l:options) ? ' ' . l:options : '') \ . l:display_name_args . ' -' endfunction diff --git a/ale_linters/python/mypy.vim b/ale_linters/python/mypy.vim index 135084d..7275af3 100644 --- a/ale_linters/python/mypy.vim +++ b/ale_linters/python/mypy.vim @@ -30,7 +30,7 @@ function! ale_linters#python#mypy#GetCommand(buffer) abort let l:executable = ale_linters#python#mypy#GetExecutable(a:buffer) return l:cd_command - \ . fnameescape(l:executable) + \ . shellescape(l:executable) \ . ' --show-column-numbers ' \ . ale#Var(a:buffer, 'python_mypy_options') \ . ' %s' diff --git a/ale_linters/python/pylint.vim b/ale_linters/python/pylint.vim index b2cc07f..cce2847 100644 --- a/ale_linters/python/pylint.vim +++ b/ale_linters/python/pylint.vim @@ -26,7 +26,7 @@ function! ale_linters#python#pylint#GetExecutable(buffer) abort endfunction function! ale_linters#python#pylint#GetCommand(buffer) abort - return fnameescape(ale_linters#python#pylint#GetExecutable(a:buffer)) + return shellescape(ale_linters#python#pylint#GetExecutable(a:buffer)) \ . ' ' . ale#Var(a:buffer, 'python_pylint_options') \ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n' \ . ' %s' diff --git a/ale_linters/tex/chktex.vim b/ale_linters/tex/chktex.vim index c65deed..776974a 100644 --- a/ale_linters/tex/chktex.vim +++ b/ale_linters/tex/chktex.vim @@ -18,7 +18,7 @@ function! ale_linters#tex#chktex#GetCommand(buffer) abort let l:command .= ' -v0 -p stdin -q' if !empty(l:chktex_config) - let l:command .= ' -l ' . fnameescape(l:chktex_config) + let l:command .= ' -l ' . shellescape(l:chktex_config) endif let l:command .= ' ' . ale#Var(a:buffer, 'tex_chktex_options') diff --git a/ale_linters/typescript/tslint.vim b/ale_linters/typescript/tslint.vim index c56c8b2..8ba99cc 100644 --- a/ale_linters/typescript/tslint.vim +++ b/ale_linters/typescript/tslint.vim @@ -55,7 +55,7 @@ function! ale_linters#typescript#tslint#BuildLintCommand(buffer) abort \) let l:tslint_config_option = !empty(l:tslint_config_path) - \ ? '-c ' . fnameescape(l:tslint_config_path) + \ ? '-c ' . shellescape(l:tslint_config_path) \ : '' return ale_linters#typescript#tslint#GetExecutable(a:buffer) diff --git a/ale_linters/verilog/verilator.vim b/ale_linters/verilog/verilator.vim index e2dbafa..ed26c1f 100644 --- a/ale_linters/verilog/verilator.vim +++ b/ale_linters/verilog/verilator.vim @@ -8,7 +8,7 @@ function! ale_linters#verilog#verilator#GetCommand(buffer) abort call ale#engine#ManageFile(a:buffer, l:filename) call writefile(getbufline(a:buffer, 1, '$'), l:filename) - return 'verilator --lint-only -Wall -Wno-DECLFILENAME ' . fnameescape(l:filename) + return 'verilator --lint-only -Wall -Wno-DECLFILENAME ' . shellescape(l:filename) endfunction function! ale_linters#verilog#verilator#Handle(buffer, lines) abort diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim index 047392d..339f7ee 100644 --- a/autoload/ale/engine.vim +++ b/autoload/ale/engine.vim @@ -480,14 +480,14 @@ function! ale#engine#FormatCommand(buffer, command) abort " file. if l:command =~# '%s' let l:filename = fnamemodify(bufname(a:buffer), ':p') - let l:command = substitute(l:command, '%s', '\=fnameescape(l:filename)', 'g') + let l:command = substitute(l:command, '%s', '\=shellescape(l:filename)', 'g') endif if l:command =~# '%t' " Create a temporary filename, / " The file itself will not be created by this function. let l:temporary_file = s:TemporaryFilename(a:buffer) - let l:command = substitute(l:command, '%t', '\=fnameescape(l:temporary_file)', 'g') + let l:command = substitute(l:command, '%t', '\=shellescape(l:temporary_file)', 'g') endif " Finish formatting so %% becomes %. @@ -529,7 +529,7 @@ function! s:RunJob(options) abort " in the shell. We'll write out the file to a temporary file, " and then read it back in, in the shell. let l:temporary_file = s:TemporaryFilename(l:buffer) - let l:command = l:command . ' < ' . fnameescape(l:temporary_file) + let l:command = l:command . ' < ' . shellescape(l:temporary_file) endif if s:CreateTemporaryFileForJob(l:buffer, l:temporary_file) diff --git a/autoload/ale/path.vim b/autoload/ale/path.vim index 0ea1335..26da9e2 100644 --- a/autoload/ale/path.vim +++ b/autoload/ale/path.vim @@ -47,7 +47,7 @@ endfunction " Output 'cd && ' " This function can be used changing the directory for a linter command. function! ale#path#CdString(directory) abort - return 'cd ' . fnameescape(a:directory) . ' && ' + return 'cd ' . shellescape(a:directory) . ' && ' endfunction " Output 'cd && ' diff --git a/test/command_callback/test_cppcheck_command_callbacks.vader b/test/command_callback/test_cppcheck_command_callbacks.vader index 665b4f1..6395864 100644 --- a/test/command_callback/test_cppcheck_command_callbacks.vader +++ b/test/command_callback/test_cppcheck_command_callbacks.vader @@ -19,7 +19,7 @@ Execute(cppcheck for C should detect compile_commands.json files): cd cppcheck_paths/one AssertEqual - \ 'cd ' . fnameescape(b:dir . '/cppcheck_paths/one') . ' && ' + \ 'cd ' . shellescape(b:dir . '/cppcheck_paths/one') . ' && ' \ . 'cppcheck -q --language=c --project=compile_commands.json --enable=style %t', \ ale_linters#c#cppcheck#GetCommand(bufnr('')) @@ -35,6 +35,6 @@ Execute(cppcheck for C++ should detect compile_commands.json files): cd cppcheck_paths/one AssertEqual - \ 'cd ' . fnameescape(b:dir . '/cppcheck_paths/one') . ' && ' + \ 'cd ' . shellescape(b:dir . '/cppcheck_paths/one') . ' && ' \ . 'cppcheck -q --language=c++ --project=compile_commands.json --enable=style %t', \ ale_linters#cpp#cppcheck#GetCommand(bufnr('')) diff --git a/test/command_callback/test_flake8_command_callback.vader b/test/command_callback/test_flake8_command_callback.vader index baec533..7c1f8c7 100644 --- a/test/command_callback/test_flake8_command_callback.vader +++ b/test/command_callback/test_flake8_command_callback.vader @@ -22,26 +22,26 @@ Execute(The flake8 callbacks should return the correct default values): \ 'flake8', \ ale_linters#python#flake8#GetExecutable(bufnr('')) AssertEqual - \ 'flake8 --version', + \ '''flake8'' --version', \ ale_linters#python#flake8#VersionCheck(bufnr('')) AssertEqual - \ 'flake8 --stdin-display-name %s -', + \ '''flake8'' --stdin-display-name %s -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['3.0.0']) " Try with older versions. call ale_linters#python#flake8#ClearVersionCache() AssertEqual - \ 'flake8 -', + \ '''flake8'' -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['2.9.9']) Execute(The flake8 command callback should let you set options): let g:ale_python_flake8_options = '--some-option' AssertEqual - \ 'flake8 --some-option --stdin-display-name %s -', + \ '''flake8'' --some-option --stdin-display-name %s -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['3.0.4']) call ale_linters#python#flake8#ClearVersionCache() AssertEqual - \ 'flake8 --some-option -', + \ '''flake8'' --some-option -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['2.9.9']) Execute(You should be able to set a custom executable and it should be escaped): @@ -51,10 +51,10 @@ Execute(You should be able to set a custom executable and it should be escaped): \ 'executable with spaces', \ ale_linters#python#flake8#GetExecutable(bufnr('')) AssertEqual - \ 'executable\ with\ spaces --version', + \ '''executable with spaces'' --version', \ ale_linters#python#flake8#VersionCheck(bufnr('')) AssertEqual - \ 'executable\ with\ spaces --stdin-display-name %s -', + \ '''executable with spaces'' --stdin-display-name %s -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['3.0.0']) Execute(The flake8 callbacks should detect virtualenv directories): @@ -64,10 +64,10 @@ Execute(The flake8 callbacks should detect virtualenv directories): \ g:dir . '/python_paths/with_virtualenv/env/bin/flake8', \ ale_linters#python#flake8#GetExecutable(bufnr('')) AssertEqual - \ g:dir . '/python_paths/with_virtualenv/env/bin/flake8 --version', + \ '''' . g:dir . '/python_paths/with_virtualenv/env/bin/flake8'' --version', \ ale_linters#python#flake8#VersionCheck(bufnr('')) AssertEqual - \ g:dir . '/python_paths/with_virtualenv/env/bin/flake8' + \ '''' . g:dir . '/python_paths/with_virtualenv/env/bin/flake8''' \ . ' --stdin-display-name %s -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['3.0.0']) @@ -82,10 +82,10 @@ Execute(Using `python -m flake8` should be supported for running flake8): \ 'python', \ ale_linters#python#flake8#GetExecutable(bufnr('')) AssertEqual - \ 'python -m flake8 --version', + \ '''python'' -m flake8 --version', \ ale_linters#python#flake8#VersionCheck(bufnr('')) AssertEqual - \ 'python -m flake8 --some-option -', + \ '''python'' -m flake8 --some-option -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['2.9.9']) call ale_linters#python#flake8#ClearVersionCache() @@ -97,8 +97,8 @@ Execute(Using `python -m flake8` should be supported for running flake8): \ 'python', \ ale_linters#python#flake8#GetExecutable(bufnr('')) AssertEqual - \ 'python -m flake8 --version', + \ '''python'' -m flake8 --version', \ ale_linters#python#flake8#VersionCheck(bufnr('')) AssertEqual - \ 'python -m flake8 --some-option -', + \ '''python'' -m flake8 --some-option -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['2.9.9']) diff --git a/test/command_callback/test_javac_command_callback.vader b/test/command_callback/test_javac_command_callback.vader index 534e63d..2f0bc50 100644 --- a/test/command_callback/test_javac_command_callback.vader +++ b/test/command_callback/test_javac_command_callback.vader @@ -15,7 +15,7 @@ After: Execute(The javac callback should return the correct default value): let b:command = ale_linters#java#javac#GetCommand(bufnr(''), []) - Assert match(b:command, '\v^javac +-Xlint +-d +/tmp/[0-9a-zA-Z/]+ +\%t$') >= 0, + Assert match(b:command, '\v^javac +-Xlint +-d +''/tmp/[0-9a-zA-Z/]+'' +\%t$') >= 0, \ 'Invalid command string: ' . b:command Execute(The javac callback should use g:ale_java_javac_classpath correctly): @@ -23,7 +23,7 @@ Execute(The javac callback should use g:ale_java_javac_classpath correctly): let b:command = ale_linters#java#javac#GetCommand(bufnr(''), []) - Assert match(b:command, '\v^javac +-Xlint +-cp +foo\.jar +-d +/tmp/[0-9a-zA-Z/]+ +\%t$') >= 0, + Assert match(b:command, '\v^javac +-Xlint +-cp ''+foo\.jar'' +-d ''+/tmp/[0-9a-zA-Z/]+'' +\%t$') >= 0, \ 'Invalid command string: ' . b:command Execute(The javac callback should include discovered classpaths): @@ -34,7 +34,7 @@ Execute(The javac callback should include discovered classpaths): \ '/xyz/abc.jar', \]) - Assert match(b:command, '\v^javac +-Xlint +-cp +/foo/bar\.jar:/xyz/abc\.jar +-d +/tmp/[0-9a-zA-Z/]+ +\%t$') >= 0, + Assert match(b:command, '\v^javac +-Xlint +-cp ''+/foo/bar\.jar:/xyz/abc\.jar'' +-d +''/tmp/[0-9a-zA-Z/]+'' +\%t$') >= 0, \ 'Invalid command string: ' . b:command Execute(The javac callback should combine discovered classpaths and manual ones): @@ -47,7 +47,7 @@ Execute(The javac callback should combine discovered classpaths and manual ones) \ '/xyz/abc.jar', \]) - Assert match(b:command, '\v^javac +-Xlint +-cp +/foo/bar\.jar:/xyz/abc\.jar:configured\.jar +-d +/tmp/[0-9a-zA-Z/]+ +\%t$') >= 0, + Assert match(b:command, '\v^javac +-Xlint +-cp +''/foo/bar\.jar:/xyz/abc\.jar:configured\.jar'' +-d ''+/tmp/[0-9a-zA-Z/]+'' +\%t$') >= 0, \ 'Invalid command string: ' . b:command let g:ale_java_javac_classpath = 'configured.jar:configured2.jar' @@ -59,7 +59,7 @@ Execute(The javac callback should combine discovered classpaths and manual ones) \ '/xyz/abc.jar', \]) - Assert match(b:command, '\v^javac +-Xlint +-cp +/foo/bar\.jar:/xyz/abc\.jar:configured\.jar:configured2\.jar +-d +/tmp/[0-9a-zA-Z/]+ +\%t$') >= 0, + Assert match(b:command, '\v^javac +-Xlint +-cp +''/foo/bar\.jar:/xyz/abc\.jar:configured\.jar:configured2\.jar'' +-d +''/tmp/[0-9a-zA-Z/]+'' +\%t$') >= 0, \ 'Invalid command string: ' . b:command Execute(The javac callback should detect source directories): @@ -69,7 +69,7 @@ Execute(The javac callback should detect source directories): let b:command = ale_linters#java#javac#GetCommand(bufnr(''), []) - Assert match(b:command, '\v^javac +-Xlint +-sourcepath /.*java_paths/src/main/java/ +-d +/tmp/[0-9a-zA-Z/]+ +\%t$') >= 0, + Assert match(b:command, '\v^javac +-Xlint +-sourcepath ''/.*java_paths/src/main/java/'' +-d +''/tmp/[0-9a-zA-Z/]+'' +\%t$') >= 0, \ 'Invalid command string: ' . b:command Execute(The javac callback should combine detected source directories and classpaths): @@ -84,7 +84,7 @@ Execute(The javac callback should combine detected source directories and classp \ '/xyz/abc.jar', \]) - Assert match(b:command, '\v^javac +-Xlint +-cp +/foo/bar\.jar:/xyz/abc\.jar +-sourcepath /.*java_paths/src/main/java/ +-d +/tmp/[0-9a-zA-Z/]+ +\%t$') >= 0, + Assert match(b:command, '\v^javac +-Xlint +-cp +''/foo/bar\.jar:/xyz/abc\.jar'' +-sourcepath ''/.*java_paths/src/main/java/'' +-d +''/tmp/[0-9a-zA-Z/]+'' +\%t$') >= 0, \ 'Invalid command string: ' . b:command Execute(The javac callback should use g:ale_java_javac_options correctly): @@ -93,5 +93,5 @@ Execute(The javac callback should use g:ale_java_javac_options correctly): let b:command = ale_linters#java#javac#GetCommand(bufnr(''), []) - Assert match(b:command, '\v^javac +-Xlint +-d +/tmp/[0-9a-zA-Z/]+ --anything --else +\%t$') >= 0, + Assert match(b:command, '\v^javac +-Xlint +-d +''/tmp/[0-9a-zA-Z/]+'' --anything --else +\%t$') >= 0, \ 'Invalid command string: ' . b:command diff --git a/test/command_callback/test_luacheck_command_callback.vader b/test/command_callback/test_luacheck_command_callback.vader index f283b98..c4ee98a 100644 --- a/test/command_callback/test_luacheck_command_callback.vader +++ b/test/command_callback/test_luacheck_command_callback.vader @@ -7,18 +7,18 @@ After: let g:ale_lua_luacheck_executable = 'luacheck' Execute(The lua luacheck command callback should return the correct default string): - AssertEqual 'luacheck --formatter plain --codes --filename %s -', + AssertEqual '''luacheck'' --formatter plain --codes --filename %s -', \ join(split(ale_linters#lua#luacheck#GetCommand(1))) Execute(The lua luacheck command callback should let you set options): let g:ale_lua_luacheck_options = '--config filename' - AssertEqual 'luacheck --config filename --formatter plain --codes --filename %s -', + AssertEqual '''luacheck'' --config filename --formatter plain --codes --filename %s -', \ join(split(ale_linters#lua#luacheck#GetCommand(1))) Execute(The luacheck executable should be configurable): let g:ale_lua_luacheck_executable = 'luacheck.sh' AssertEqual 'luacheck.sh', ale_linters#lua#luacheck#GetExecutable(1) - AssertEqual 'luacheck.sh --formatter plain --codes --filename %s -', + AssertEqual '''luacheck.sh'' --formatter plain --codes --filename %s -', \ join(split(ale_linters#lua#luacheck#GetCommand(1))) diff --git a/test/command_callback/test_mypy_command_callback.vader b/test/command_callback/test_mypy_command_callback.vader index ec82c87..14c9af4 100644 --- a/test/command_callback/test_mypy_command_callback.vader +++ b/test/command_callback/test_mypy_command_callback.vader @@ -20,7 +20,7 @@ Execute(The mypy callbacks should return the correct default values): \ 'mypy', \ ale_linters#python#mypy#GetExecutable(bufnr('')) AssertEqual - \ 'cd ' . g:dir . ' && mypy --show-column-numbers %s', + \ 'cd ''' . g:dir . ''' && ''mypy'' --show-column-numbers %s', \ ale_linters#python#mypy#GetCommand(bufnr('')) Execute(The mypy executable should be configurable, and escaped properly): @@ -30,14 +30,14 @@ Execute(The mypy executable should be configurable, and escaped properly): \ 'executable with spaces', \ ale_linters#python#mypy#GetExecutable(bufnr('')) AssertEqual - \ 'cd ' . g:dir . ' && executable\ with\ spaces --show-column-numbers %s', + \ 'cd ''' . g:dir . ''' && ''executable with spaces'' --show-column-numbers %s', \ ale_linters#python#mypy#GetCommand(bufnr('')) Execute(The mypy command callback should let you set options): let g:ale_python_mypy_options = '--some-option' AssertEqual - \ 'cd ' . g:dir . ' && mypy --show-column-numbers --some-option %s', + \ 'cd ''' . g:dir . ''' && ''mypy'' --show-column-numbers --some-option %s', \ ale_linters#python#mypy#GetCommand(bufnr('')) Execute(The mypy command should switch directories to the detected project root): @@ -47,7 +47,7 @@ Execute(The mypy command should switch directories to the detected project root) \ 'mypy', \ ale_linters#python#mypy#GetExecutable(bufnr('')) AssertEqual - \ 'cd ' . g:dir . '/python_paths/no_virtualenv/subdir && mypy --show-column-numbers %s', + \ 'cd ''' . g:dir . '/python_paths/no_virtualenv/subdir'' && ''mypy'' --show-column-numbers %s', \ ale_linters#python#mypy#GetCommand(bufnr('')) Execute(The mypy callbacks should detect virtualenv directories and switch to the project root): @@ -57,8 +57,8 @@ Execute(The mypy callbacks should detect virtualenv directories and switch to th \ g:dir . '/python_paths/with_virtualenv/env/bin/mypy', \ ale_linters#python#mypy#GetExecutable(bufnr('')) AssertEqual - \ 'cd ' . g:dir . '/python_paths/with_virtualenv/subdir && ' - \ . g:dir . '/python_paths/with_virtualenv/env/bin/mypy --show-column-numbers %s', + \ 'cd ''' . g:dir . '/python_paths/with_virtualenv/subdir'' && ''' + \ . g:dir . '/python_paths/with_virtualenv/env/bin/mypy'' --show-column-numbers %s', \ ale_linters#python#mypy#GetCommand(bufnr('')) Execute(You should able able to use the global mypy instead): @@ -69,5 +69,5 @@ Execute(You should able able to use the global mypy instead): \ 'mypy', \ ale_linters#python#mypy#GetExecutable(bufnr('')) AssertEqual - \ 'cd ' . g:dir . '/python_paths/with_virtualenv/subdir && mypy --show-column-numbers %s', + \ 'cd ''' . g:dir . '/python_paths/with_virtualenv/subdir'' && ''mypy'' --show-column-numbers %s', \ ale_linters#python#mypy#GetCommand(bufnr('')) diff --git a/test/command_callback/test_pylint_command_callback.vader b/test/command_callback/test_pylint_command_callback.vader index 533d06a..040c9ef 100644 --- a/test/command_callback/test_pylint_command_callback.vader +++ b/test/command_callback/test_pylint_command_callback.vader @@ -21,7 +21,7 @@ Execute(The pylint callbacks should return the correct default values): \ 'pylint', \ ale_linters#python#pylint#GetExecutable(bufnr('')) AssertEqual - \ 'pylint ' . b:command_tail, + \ '''pylint'' ' . b:command_tail, \ ale_linters#python#pylint#GetCommand(bufnr('')) Execute(The pylint executable should be configurable, and escaped properly): @@ -31,14 +31,14 @@ Execute(The pylint executable should be configurable, and escaped properly): \ 'executable with spaces', \ ale_linters#python#pylint#GetExecutable(bufnr('')) AssertEqual - \ 'executable\ with\ spaces ' . b:command_tail, + \ '''executable with spaces'' ' . b:command_tail, \ ale_linters#python#pylint#GetCommand(bufnr('')) Execute(The pylint command callback should let you set options): let g:ale_python_pylint_options = '--some-option' AssertEqual - \ 'pylint --some-option' . b:command_tail, + \ '''pylint'' --some-option' . b:command_tail, \ ale_linters#python#pylint#GetCommand(bufnr('')) Execute(The pylint callbacks shouldn't detect virtualenv directories where they don't exist): @@ -48,7 +48,7 @@ Execute(The pylint callbacks shouldn't detect virtualenv directories where they \ 'pylint', \ ale_linters#python#pylint#GetExecutable(bufnr('')) AssertEqual - \ 'pylint ' . b:command_tail, + \ '''pylint'' ' . b:command_tail, \ ale_linters#python#pylint#GetCommand(bufnr('')) Execute(The pylint callbacks should detect virtualenv directories): @@ -58,7 +58,7 @@ Execute(The pylint callbacks should detect virtualenv directories): \ g:dir . '/python_paths/with_virtualenv/env/bin/pylint', \ ale_linters#python#pylint#GetExecutable(bufnr('')) AssertEqual - \ g:dir . '/python_paths/with_virtualenv/env/bin/pylint ' . b:command_tail, + \ ''''. g:dir . '/python_paths/with_virtualenv/env/bin/pylint'' ' . b:command_tail, \ ale_linters#python#pylint#GetCommand(bufnr('')) Execute(You should able able to use the global pylint instead): @@ -69,5 +69,5 @@ Execute(You should able able to use the global pylint instead): \ 'pylint', \ ale_linters#python#pylint#GetExecutable(bufnr('')) AssertEqual - \ 'pylint ' . b:command_tail, + \ '''pylint'' ' . b:command_tail, \ ale_linters#python#pylint#GetCommand(bufnr('')) diff --git a/test/test_csslint_config_detection.vader b/test/test_csslint_config_detection.vader index a06258c..7a78374 100644 --- a/test/test_csslint_config_detection.vader +++ b/test/test_csslint_config_detection.vader @@ -16,7 +16,7 @@ Execute(--config should be set when the .csslintrc file is found): AssertEqual \ ( \ 'csslint --format=compact ' - \ . '--config=' . fnameescape(g:dir . '/csslint-test-files/some-app/.csslintrc') + \ . '--config=' . shellescape(g:dir . '/csslint-test-files/some-app/.csslintrc') \ . ' %t' \ ), \ ale_linters#css#csslint#GetCommand(bufnr('')) diff --git a/test/test_flow_command.vader b/test/test_flow_command.vader index 00a2c2a..f7754f6 100644 --- a/test/test_flow_command.vader +++ b/test/test_flow_command.vader @@ -8,7 +8,7 @@ Execute(flow should return a command to run if a .flowconfig file exists): silent! cd /testplugin/test :e! flow/a/sub/dummy - AssertEqual 'flow check-contents --respect-pragma --json --from ale %s', ale_linters#javascript#flow#GetCommand(bufnr('%')) + AssertEqual '''flow'' check-contents --respect-pragma --json --from ale %s', ale_linters#javascript#flow#GetCommand(bufnr('%')) Execute(flow should not return a command to run if no .flowconfig file exists): silent! cd /testplugin/test diff --git a/test/test_format_command.vader b/test/test_format_command.vader index d57729b..08496c1 100644 --- a/test/test_format_command.vader +++ b/test/test_format_command.vader @@ -1,6 +1,6 @@ Before: silent! cd /testplugin/test - :e! top/middle/bottom/dummy.txt + silent file top/middle/bottom/dummy.txt After: unlet! g:result @@ -13,29 +13,29 @@ Execute(FormatCommand should handle %%, and ignore other percents): AssertEqual ['', '% %%d %%f %x %'], ale#engine#FormatCommand(bufnr('%'), '%% %%%d %%%f %x %') Execute(FormatCommand should convert %s to the current filename): - AssertEqual ['', 'foo ' . fnameescape(expand('%:p')) . ' bar ' . fnameescape(expand('%:p'))], ale#engine#FormatCommand(bufnr('%'), 'foo %s bar %s') + AssertEqual ['', 'foo ' . shellescape(expand('%:p')) . ' bar ' . shellescape(expand('%:p'))], ale#engine#FormatCommand(bufnr('%'), 'foo %s bar %s') Execute(FormatCommand should convert %t to a new temporary filename): let g:result = ale#engine#FormatCommand(bufnr('%'), 'foo %t bar %t') - let g:match = matchlist(g:result[1], '\v^foo (/tmp/.*/dummy.txt) bar (/tmp/.*/dummy.txt)$') + let g:match = matchlist(g:result[1], '\v^foo (''/tmp/[^'']*/dummy.txt'') bar (''/tmp/[^'']*/dummy.txt'')$') Assert !empty(g:match), 'No match found! Result was: ' . g:result[1] " The first item of the result should be a temporary filename, and it should " be the same as the escaped name in the command string. - AssertEqual g:result[0], fnameescape(g:match[1]) + AssertEqual shellescape(g:result[0]), g:match[1] " The two temporary filenames formatted in should be the same. AssertEqual g:match[1], g:match[2] Execute(FormatCommand should let you combine %s and %t): let g:result = ale#engine#FormatCommand(bufnr('%'), 'foo %t bar %s') - let g:match = matchlist(g:result[1], '\v^foo (/tmp/.*/dummy.txt) bar (.*/dummy.txt)$') + let g:match = matchlist(g:result[1], '\v^foo (''/tmp/.*/dummy.txt'') bar (''.*/dummy.txt'')$') Assert !empty(g:match), 'No match found! Result was: ' . g:result[1] " The first item of the result should be a temporary filename, and it should " be the same as the escaped name in the command string. - AssertEqual g:result[0], fnameescape(g:match[1]) + AssertEqual shellescape(g:result[0]), g:match[1] " The second item should be equal to the original filename. - AssertEqual fnameescape(expand('%:p')), g:match[2] + AssertEqual shellescape(expand('%:p')), g:match[2] Execute(EscapeCommandPart should escape all percent signs): AssertEqual '%%s %%t %%%% %%s %%t %%%%', ale#engine#EscapeCommandPart('%s %t %% %s %t %%') diff --git a/test/util/test_cd_string_commands.vader b/test/util/test_cd_string_commands.vader index 36212e3..b0b6c15 100644 --- a/test/util/test_cd_string_commands.vader +++ b/test/util/test_cd_string_commands.vader @@ -2,8 +2,7 @@ Before: silent! cd /testplugin/test/util Execute(CdString should output the correct command string): - AssertEqual 'cd /foo\ bar/baz && ', ale#path#CdString('/foo bar/baz') + AssertEqual 'cd ''/foo bar/baz'' && ', ale#path#CdString('/foo bar/baz') Execute(BufferCdString should output the correct command string): - Assert match(ale#path#BufferCdString(bufnr('')), '^cd .*test/util && $') >= 0, - \ 'String didn''t match regex: ' . ale#path#BufferCdString(bufnr('')) + AssertEqual 'cd ' . shellescape(getcwd()) . ' && ', ale#path#BufferCdString(bufnr('')) From 2503eda68bdb7ada35b6a3c049cdb5384dac0725 Mon Sep 17 00:00:00 2001 From: Adriaan Zonnenberg Date: Tue, 9 May 2017 18:34:38 +0200 Subject: [PATCH 2/8] Merge pull request #533 from pbogut/add_php7_compatibility Add PHP 7 compatibility --- ale_linters/php/php.vim | 6 +++--- test/handler/test_php_handler.vader | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ale_linters/php/php.vim b/ale_linters/php/php.vim index 6d15168..7c9e8c1 100644 --- a/ale_linters/php/php.vim +++ b/ale_linters/php/php.vim @@ -5,7 +5,7 @@ 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 = '\vPHP %(Fatal|Parse) error:\s+(.+unexpected ''(.+)%(expecting.+)@ Date: Mon, 15 May 2017 20:43:55 +0100 Subject: [PATCH 3/8] Fix #553 - Filter out errors from other files for gometalinter --- ale_linters/go/gometalinter.vim | 2 +- test/handler/test_gometalinter_handler.vader | 25 ++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/ale_linters/go/gometalinter.vim b/ale_linters/go/gometalinter.vim index 9913f21..ef4bf57 100644 --- a/ale_linters/go/gometalinter.vim +++ b/ale_linters/go/gometalinter.vim @@ -22,7 +22,7 @@ function! ale_linters#go#gometalinter#Handler(buffer, lines) abort for l:match in ale_linters#go#gometalinter#GetMatches(a:lines) " Omit errors from files other than the one currently open - if ale#path#IsBufferPath(a:buffer, l:match[0]) + if !ale#path#IsBufferPath(a:buffer, l:match[1]) continue endif diff --git a/test/handler/test_gometalinter_handler.vader b/test/handler/test_gometalinter_handler.vader index 3b62213..52a4fc9 100644 --- a/test/handler/test_gometalinter_handler.vader +++ b/test/handler/test_gometalinter_handler.vader @@ -30,7 +30,7 @@ Execute (The gometalinter handler should handle names with spaces): \ ]), 'v:val[1:5]') Execute (The gometalinter handler should handle relative paths correctly): - :file! /foo/bar/baz.go + silent file /foo/bar/baz.go AssertEqual \ [ @@ -47,7 +47,28 @@ Execute (The gometalinter handler should handle relative paths correctly): \ 'type': 'E', \ }, \ ], - \ ale_linters#go#gometalinter#Handler(42, [ + \ ale_linters#go#gometalinter#Handler(bufnr(''), [ \ 'baz.go:12:3:warning: expected ''package'', found ''IDENT'' gibberish (staticcheck)', \ 'baz.go:37:5:error: expected ''package'', found ''IDENT'' gibberish (golint)', \ ]) + + +Execute (The gometalinter handler should filter out errors from other files): + silent file! /some/path/sql.go + + AssertEqual + \ [], + \ ale_linters#go#gometalinter#Handler(bufnr(''), [ + \ '/some/path/interface_implementation_test.go:417::warning: cyclomatic complexity 24 of function testGetUserHeaders() is high (> 10) (gocyclo)', + \ '/some/path/sql_helpers.go:38::warning: cyclomatic complexity 11 of function CreateTestUserMetadataDB() is high (> 10) (gocyclo)', + \ '/some/path/sql_alpha.go:560:7:warning: ineffectual assignment to err (ineffassign)', + \ '/some/path/sql_alpha.go:589:7:warning: ineffectual assignment to err (ineffassign)', + \ '/some/path/sql_test.go:124:9:warning: should not use basic type untyped string as key in context.WithValue (golint)', + \ '/some/path/interface_implementation_test.go:640::warning: declaration of "cfg" shadows declaration at sql_test.go:21 (vetshadow)', + \ '/some/path/sql_helpers.go:55::warning: declaration of "err" shadows declaration at sql_helpers.go:48 (vetshadow)', + \ '/some/path/sql_helpers.go:91::warning: declaration of "err" shadows declaration at sql_helpers.go:48 (vetshadow)', + \ '/some/path/sql_helpers.go:108::warning: declaration of "err" shadows declaration at sql_helpers.go:48 (vetshadow)', + \ '/some/path/user_metadata_db.go:149::warning: declaration of "err" shadows declaration at user_metadata_db.go:140 (vetshadow)', + \ '/some/path/user_metadata_db.go:188::warning: declaration of "err" shadows declaration at user_metadata_db.go:179 (vetshadow)', + \ '/some/path/queries_alpha.go:62::warning: Potential hardcoded credentials,HIGH,LOW (gas)', + \ ]) From 72f5aae74ec878d46f2988b00cdd9e497945a11a Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 15 May 2017 20:49:22 +0100 Subject: [PATCH 4/8] Update the Makefile so tests will run correctly --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 86ac17d..40c2045 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,12 @@ SHELL := /usr/bin/env bash -IMAGE ?= w0rp/ale +IMAGE ?= w0rp/ale:30a9967dbdb1 CURRENT_IMAGE_ID = 30a9967dbdb1 DOCKER_FLAGS = --rm -v $(PWD):/testplugin -v $(PWD)/test:/home "$(IMAGE)" tests = test/*.vader test/*/*.vader test/*/*/*.vader test/*/*/*/*.vader test-setup: docker images -q w0rp/ale | grep ^$(CURRENT_IMAGE_ID) > /dev/null || \ - docker pull $(IMAGE) + docker pull w0rp/ale vader: test-setup @:; \ From 64b56f84ef2eccaba41bfdcdae1bf623b41976f9 Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 15 May 2017 21:21:09 +0100 Subject: [PATCH 5/8] Fix #555 - Handle csslint errors without groups --- autoload/ale/handlers/css.vim | 9 ++++++--- test/handler/test_common_handlers.vader | 25 +++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/autoload/ale/handlers/css.vim b/autoload/ale/handlers/css.vim index 37ee5ee..7c4d3d1 100644 --- a/autoload/ale/handlers/css.vim +++ b/autoload/ale/handlers/css.vim @@ -10,17 +10,20 @@ function! ale#handlers#css#HandleCSSLintFormat(buffer, lines) abort " " These errors can be very massive, so the type will be moved to the front " so you can actually read the error type. - let l:pattern = '^.*: line \(\d\+\), col \(\d\+\), \(Error\|Warning\) - \(.\+\) (\([^)]\+\))$' + let l:pattern = '\v^.*: line (\d+), col (\d+), (Error|Warning) - (.+)$' let l:output = [] for l:match in ale#util#GetMatches(a:lines, l:pattern) let l:text = l:match[4] let l:type = l:match[3] - let l:errorGroup = l:match[5] + + let l:group_match = matchlist(l:text, '\v^(.+) \((.+)\)$') " Put the error group at the front, so we can see what kind of error " it is on small echo lines. - let l:text = '(' . l:errorGroup . ') ' . l:text + if !empty(l:group_match) + let l:text = '(' . l:group_match[2] . ') ' . l:group_match[1] + endif call add(l:output, { \ 'lnum': l:match[1] + 0, diff --git a/test/handler/test_common_handlers.vader b/test/handler/test_common_handlers.vader index a9fc914..e945b2c 100644 --- a/test/handler/test_common_handlers.vader +++ b/test/handler/test_common_handlers.vader @@ -11,12 +11,33 @@ Execute(HandleCSSLintFormat should handle CSS errors): \ 'lnum': 2, \ 'col': 5, \ 'type': 'W', - \ 'text': "(known-properties) Expected ... but found 'wat'.", + \ 'text': '(known-properties) Expected ... but found ''wat''.', \ }, \ ], \ ale#handlers#css#HandleCSSLintFormat(42, [ \ 'something.css: line 2, col 1, Error - Expected RBRACE at line 2, col 1. (errors)', - \ "something.css: line 2, col 5, Warning - Expected ... but found 'wat'. (known-properties)", + \ 'something.css: line 2, col 5, Warning - Expected ... but found ''wat''. (known-properties)', + \ ]) + +Execute(HandleCSSLintFormat should handle CSS errors without groups): + AssertEqual + \ [ + \ { + \ 'lnum': 7, + \ 'col': 3, + \ 'type': 'W', + \ 'text': 'Unknown property ''fill''.', + \ }, + \ { + \ 'lnum': 8, + \ 'col': 3, + \ 'type': 'W', + \ 'text': 'Unknown property ''fill-opacity''.', + \ }, + \ ], + \ ale#handlers#css#HandleCSSLintFormat(42, [ + \ 'something.css: line 7, col 3, Warning - Unknown property ''fill''.', + \ 'something.css: line 8, col 3, Warning - Unknown property ''fill-opacity''.', \ ]) Execute (HandlePEP8Format should handle the correct lines of output): From e94aea91445662379eb8f67c197bed6d6be08697 Mon Sep 17 00:00:00 2001 From: w0rp Date: Thu, 25 May 2017 13:36:44 +0100 Subject: [PATCH 6/8] Merge pull request #578 from nOkuda/master Translate pylint output column to 1-based index --- ale_linters/python/pylint.vim | 35 ++++++++++++++++- test/handler/test_pylint_handler.vader | 53 ++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 test/handler/test_pylint_handler.vader diff --git a/ale_linters/python/pylint.vim b/ale_linters/python/pylint.vim index cce2847..b8e5d81 100644 --- a/ale_linters/python/pylint.vim +++ b/ale_linters/python/pylint.vim @@ -32,10 +32,43 @@ function! ale_linters#python#pylint#GetCommand(buffer) abort \ . ' %s' endfunction +function! ale_linters#python#pylint#Handle(buffer, lines) abort + " Matches patterns like the following: + " + " test.py:4:4: W0101 (unreachable) Unreachable code + let l:pattern = '\v^[^:]+:(\d+):(\d+): ([[:alnum:]]+) \((.*)\) (.*)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + "let l:failed = append(0, l:match) + let l:code = l:match[3] + + if (l:code ==# 'C0303') + \ && !ale#Var(a:buffer, 'warn_about_trailing_whitespace') + " Skip warnings for trailing whitespace if the option is off. + continue + endif + + if l:code ==# 'I0011' + " Skip 'Locally disabling' message + continue + endif + + call add(l:output, { + \ 'lnum': l:match[1] + 0, + \ 'col': l:match[2] + 1, + \ 'text': l:code . ': ' . l:match[5], + \ 'type': l:code[:0] ==# 'E' ? 'E' : 'W', + \}) + endfor + + return l:output +endfunction + call ale#linter#Define('python', { \ 'name': 'pylint', \ 'executable_callback': 'ale_linters#python#pylint#GetExecutable', \ 'command_callback': 'ale_linters#python#pylint#GetCommand', -\ 'callback': 'ale#handlers#python#HandlePEP8Format', +\ 'callback': 'ale_linters#python#pylint#Handle', \ 'lint_file': 1, \}) diff --git a/test/handler/test_pylint_handler.vader b/test/handler/test_pylint_handler.vader new file mode 100644 index 0000000..590a795 --- /dev/null +++ b/test/handler/test_pylint_handler.vader @@ -0,0 +1,53 @@ +Before: + runtime ale_linters/python/pylint.vim + +After: + call ale#linter#Reset() + silent file something_else.py + +Execute(pylint handler parsing, translating columns to 1-based index): + AssertEqual + \ [ + \ { + \ 'lnum': 4, + \ 'col': 1, + \ 'text': 'C0303: Trailing whitespace', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 1, + \ 'col': 1, + \ 'text': 'C0111: Missing module docstring', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 2, + \ 'col': 1, + \ 'text': 'C0111: Missing function docstring', + \ 'type': 'W', + \ }, + \ { + \ 'lnum': 3, + \ 'col': 5, + \ 'text': 'E0103: ''break'' not properly in loop', + \ 'type': 'E', + \ }, + \ { + \ 'lnum': 4, + \ 'col': 5, + \ 'text': 'W0101: Unreachable code', + \ 'type': 'W', + \ }, + \ ], + \ ale_linters#python#pylint#Handle(bufnr(''), [ + \ 'No config file found, using default configuration', + \ '************* Module test', + \ 'test.py:4:0: C0303 (trailing-whitespace) Trailing whitespace', + \ 'test.py:1:0: C0111 (missing-docstring) Missing module docstring', + \ 'test.py:2:0: C0111 (missing-docstring) Missing function docstring', + \ 'test.py:3:4: E0103 (not-in-loop) ''break'' not properly in loop', + \ 'test.py:4:4: W0101 (unreachable) Unreachable code', + \ '', + \ '------------------------------------------------------------------', + \ 'Your code has been rated at 0.00/10 (previous run: 2.50/10, -2.50)', + \ ]) From 9b6d6344b21d5eabee9c958b95bb81ed0631d604 Mon Sep 17 00:00:00 2001 From: w0rp Date: Tue, 30 May 2017 09:45:20 +0100 Subject: [PATCH 7/8] Merge pull request #589 from bardzusny/ember-template-lint-handler-parsing-error Ember-template-lint handler: properly handle template parsing errors. --- ale_linters/handlebars/embertemplatelint.vim | 24 ++++++++++++----- .../test_embertemplatelint_handler.vader | 27 +++++++++++++++++++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/ale_linters/handlebars/embertemplatelint.vim b/ale_linters/handlebars/embertemplatelint.vim index 91dda70..690acbb 100644 --- a/ale_linters/handlebars/embertemplatelint.vim +++ b/ale_linters/handlebars/embertemplatelint.vim @@ -35,13 +35,23 @@ function! ale_linters#handlebars#embertemplatelint#Handle(buffer, lines) abort let l:file_errors = values(l:input_json)[0] for l:error in l:file_errors - call add(l:output, { - \ 'bufnr': a:buffer, - \ 'lnum': l:error.line, - \ 'col': l:error.column, - \ 'text': l:error.rule . ': ' . l:error.message, - \ 'type': l:error.severity == 1 ? 'W' : 'E', - \}) + if has_key(l:error, 'fatal') + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'lnum': 1, + \ 'col': 1, + \ 'text': l:error.message, + \ 'type': l:error.severity == 1 ? 'W' : 'E', + \}) + else + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'lnum': l:error.line, + \ 'col': l:error.column, + \ 'text': l:error.rule . ': ' . l:error.message, + \ 'type': l:error.severity == 1 ? 'W' : 'E', + \}) + endif endfor return l:output diff --git a/test/handler/test_embertemplatelint_handler.vader b/test/handler/test_embertemplatelint_handler.vader index 5261bbe..cc3e8bb 100644 --- a/test/handler/test_embertemplatelint_handler.vader +++ b/test/handler/test_embertemplatelint_handler.vader @@ -46,6 +46,33 @@ Execute(The ember-template-lint handler should parse lines correctly): \ ], \ ale_linters#handlebars#embertemplatelint#Handle(347, input_lines) +Execute(The ember-template-lint handler should handle template parsing error correctly): + let input_lines = split('{ + \ "/ember-project/app/templates/application.hbs": [ + \ { + \ "fatal": true, + \ "moduleId": "app/templates/application", + \ "message": "Parse error on line 5 ...", + \ "line": 1, + \ "column": 1, + \ "source": "Error: Parse error on line 5 ...", + \ "severity": 2 + \ } + \ ] + \ }', '\n') + + AssertEqual + \ [ + \ { + \ 'bufnr': 347, + \ 'lnum': 1, + \ 'col': 1, + \ 'text': 'Parse error on line 5 ...', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#handlebars#embertemplatelint#Handle(347, input_lines) + Execute(The ember-template-lint handler should handle no lint errors/warnings): AssertEqual \ [ From 76b5c9283da30f90acadda0da3b77534909c88d7 Mon Sep 17 00:00:00 2001 From: w0rp Date: Fri, 2 Jun 2017 19:02:48 +0100 Subject: [PATCH 8/8] #574 Do not restore items with no columns for highlights from hidden buffers --- autoload/ale/highlight.vim | 6 +++++- test/test_highlight_placement.vader | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/autoload/ale/highlight.vim b/autoload/ale/highlight.vim index f3a479e..5e4cbdb 100644 --- a/autoload/ale/highlight.vim +++ b/autoload/ale/highlight.vim @@ -109,7 +109,11 @@ function! ale#highlight#BufferHidden(buffer) abort endif endfor - let s:buffer_restore_map[a:buffer] = l:loclist + let s:buffer_restore_map[a:buffer] = filter( + \ copy(l:loclist), + \ 'v:val.bufnr == a:buffer && v:val.col > 0' + \) + call clearmatches() endif endfunction diff --git a/test/test_highlight_placement.vader b/test/test_highlight_placement.vader index 25c9878..b581685 100644 --- a/test/test_highlight_placement.vader +++ b/test/test_highlight_placement.vader @@ -96,8 +96,10 @@ Execute(Highlights set by ALE should be removed when buffer cleanup is done): Execute(Highlights should be cleared when buffers are hidden): call ale#engine#InitBufferInfo(bufnr('%')) + " The second item should be ignored, as it has no column infomration. let g:ale_buffer_info[bufnr('%')].loclist = [ \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 3, 'col': 2}, + \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 4, 'col': 0}, \] call ale#highlight#SetHighlights( \ bufnr('%'),