From 9fe7b1fe6a23fb55e6d782293585d58193123f59 Mon Sep 17 00:00:00 2001 From: w0rp Date: Mon, 1 Mar 2021 20:11:10 +0000 Subject: [PATCH] Close #2281 - Separate cwd commands from commands Working directories are now set seperately from the commands so they can later be swapped out when running linters over projects is supported, and also better support filename mapping for running linters on other machines in future. --- ale_linters/c/cppcheck.vim | 5 +- ale_linters/cpp/cppcheck.vim | 5 +- ale_linters/cs/csc.vim | 17 +-- ale_linters/cs/mcsc.vim | 16 +-- ale_linters/d/dmd.vim | 32 ++--- ale_linters/elixir/credo.vim | 7 +- ale_linters/elixir/dialyxir.vim | 11 +- ale_linters/elixir/dogma.vim | 10 +- ale_linters/elixir/mix.vim | 11 +- ale_linters/elm/make.vim | 18 +-- ale_linters/go/gobuild.vim | 4 +- ale_linters/go/golangci_lint.vim | 7 +- ale_linters/go/gometalinter.vim | 7 +- ale_linters/go/gosimple.vim | 8 +- ale_linters/go/gotype.vim | 12 +- ale_linters/go/govet.vim | 4 +- ale_linters/go/staticcheck.vim | 12 +- ale_linters/graphql/eslint.vim | 1 + ale_linters/graphql/gqlint.vim | 9 +- ale_linters/haskell/cabal_ghc.vim | 4 +- ale_linters/haskell/stack_ghc.vim | 4 +- ale_linters/java/javac.vim | 13 +- ale_linters/javascript/eslint.vim | 1 + ale_linters/kotlin/kotlinc.vim | 14 +- ale_linters/mercury/mmc.vim | 8 +- ale_linters/php/phpcs.vim | 4 +- ale_linters/python/flake8.vim | 18 ++- ale_linters/python/mypy.vim | 16 +-- ale_linters/python/pydocstyle.vim | 4 +- ale_linters/python/pylama.vim | 17 +-- ale_linters/python/pylint.vim | 18 +-- ale_linters/python/vulture.vim | 19 ++- ale_linters/r/lintr.vim | 5 +- ale_linters/rst/rstcheck.vim | 11 +- ale_linters/ruby/ruby.vim | 2 +- ale_linters/rust/cargo.vim | 28 ++-- ale_linters/typescript/eslint.vim | 1 + ale_linters/typescript/tslint.vim | 4 +- ale_linters/vim/ale_custom_linting_rules.vim | 11 +- autoload/ale/ant.vim | 24 ++-- autoload/ale/assert.vim | 126 ++++++++++++++---- autoload/ale/c.vim | 11 +- autoload/ale/command.vim | 66 ++++++++- autoload/ale/engine.vim | 16 +++ autoload/ale/fix.vim | 2 + autoload/ale/fixers/autoimport.vim | 6 +- autoload/ale/fixers/black.vim | 16 +-- autoload/ale/fixers/eslint.vim | 12 +- autoload/ale/fixers/isort.vim | 6 +- autoload/ale/fixers/prettier.vim | 20 +-- autoload/ale/fixers/prettier_eslint.vim | 4 +- autoload/ale/fixers/stylelint.vim | 4 +- autoload/ale/fixers/yamlfix.vim | 6 +- autoload/ale/gradle.vim | 25 ++-- autoload/ale/handlers/cppcheck.vim | 5 +- autoload/ale/handlers/eslint.vim | 10 +- autoload/ale/handlers/shellcheck.vim | 11 +- autoload/ale/linter.vim | 21 ++- autoload/ale/lsp_linter.vim | 1 + autoload/ale/maven.vim | 22 +-- autoload/ale/path.vim | 20 --- doc/ale-development.txt | 2 + doc/ale.txt | 35 +++++ .../test_c_cppcheck_command_callbacks.vader | 16 +-- .../test_cargo_command_callbacks.vader | 11 +- .../test_cpp_cppcheck_command_callbacks.vader | 16 +-- .../test_cs_csc_command_callbacks.vader | 23 ++-- .../test_cs_mcsc_command_callbacks.vader | 23 ++-- .../test_dialyxir_command_callback.vader | 16 +++ .../test_dogma_command_callback.vader | 16 +++ test/command_callback/test_elixir_credo.vader | 47 ------- .../test_elixir_credo_command_callback.vader | 43 ++++++ .../test_elixir_mix_command_callbacks.vader | 30 ++--- .../test_elm_make_command_callback.vader | 24 ++-- .../test_eslint_command_callback.vader | 76 +++++++++++ .../test_flake8_command_callback.vader | 51 ++++--- .../test_gobuild_command_callback.vader | 20 +-- .../test_golangci_lint_command_callback.vader | 16 +-- .../test_gometalinter_command_callback.vader | 17 +-- .../test_gosimple_command_callback.vader | 9 +- .../test_gotype_command_callback.vader | 12 +- .../test_govet_command_callback.vader | 12 +- ...est_graphql_gqlint_command_callbacks.vader | 6 +- ..._haskell_cabal_ghc_command_callbacks.vader | 20 +-- ...t_haskell_stack_ghc_command_callback.vader | 5 +- .../test_javac_command_callback.vader | 34 ++--- .../test_lintr_command_callback.vader | 10 +- .../test_mercury_mmc_command_callback.vader | 11 +- .../test_mypy_command_callback.vader | 41 +++--- .../test_phpcs_command_callback.vader | 16 +-- .../test_pydocstyle_command_callback.vader | 19 +-- .../test_pylama_command_callback.vader | 51 +++---- .../test_pylint_command_callback.vader | 51 +++---- .../test_ruby_command_callback.vader | 4 +- .../test_shellcheck_command_callback.vader | 34 +++-- .../test_staticcheck_command_callback.vader | 27 +--- .../test_tslint_command_callback.vader | 12 +- .../test_vulture_command_callback.vader | 38 ++---- .../test_autoimport_fixer_callback.vader | 8 +- test/fixers/test_black_fixer_callback.vader | 22 ++- .../test_dhall_format_fixer_callback.vader | 2 +- .../test_dhall_freeze_fixer_callback.vader | 2 +- .../test_dhall_lint_fixer_callback.vader | 2 +- test/fixers/test_eslint_fixer_callback.vader | 72 +++++----- test/fixers/test_isort_fixer_callback.vader | 30 ++--- .../test_prettier_eslint_fixer.callback.vader | 12 +- .../fixers/test_prettier_fixer_callback.vader | 80 +++++------ .../test_stylelint_fixer_callback.vader | 8 +- test/fixers/test_yamlfix_fixer_callback.vader | 25 +--- test/test_ant_build_classpath_command.vader | 22 ++- test/test_c_flag_parsing.vader | 18 ++- test/test_eslint_executable_detection.vader | 100 -------------- test/test_format_command.vader | 56 +++++--- .../test_gradle_build_classpath_command.vader | 15 ++- test/test_linter_defintion_processing.vader | 30 ++++- test/test_maven_build_classpath_command.vader | 17 ++- test/util/test_cd_string_commands.vader | 6 +- 117 files changed, 1142 insertions(+), 1111 deletions(-) create mode 100644 test/command_callback/test_dialyxir_command_callback.vader create mode 100644 test/command_callback/test_dogma_command_callback.vader delete mode 100644 test/command_callback/test_elixir_credo.vader create mode 100644 test/command_callback/test_elixir_credo_command_callback.vader create mode 100644 test/command_callback/test_eslint_command_callback.vader delete mode 100644 test/test_eslint_executable_detection.vader diff --git a/ale_linters/c/cppcheck.vim b/ale_linters/c/cppcheck.vim index 975ef047..28c2861f 100644 --- a/ale_linters/c/cppcheck.vim +++ b/ale_linters/c/cppcheck.vim @@ -5,15 +5,13 @@ call ale#Set('c_cppcheck_executable', 'cppcheck') call ale#Set('c_cppcheck_options', '--enable=style') function! ale_linters#c#cppcheck#GetCommand(buffer) abort - let l:cd_command = ale#handlers#cppcheck#GetCdCommand(a:buffer) let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer) let l:buffer_path_include = empty(l:compile_commands_option) \ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer) \ : '' let l:template = ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') - return l:cd_command - \ . '%e -q --language=c' + return '%e -q --language=c' \ . l:template \ . ale#Pad(l:compile_commands_option) \ . ale#Pad(ale#Var(a:buffer, 'c_cppcheck_options')) @@ -25,6 +23,7 @@ call ale#linter#Define('c', { \ 'name': 'cppcheck', \ 'output_stream': 'both', \ 'executable': {b -> ale#Var(b, 'c_cppcheck_executable')}, +\ 'cwd': function('ale#handlers#cppcheck#GetCwd'), \ 'command': function('ale_linters#c#cppcheck#GetCommand'), \ 'callback': 'ale#handlers#cppcheck#HandleCppCheckFormat', \}) diff --git a/ale_linters/cpp/cppcheck.vim b/ale_linters/cpp/cppcheck.vim index 2578861d..eb86adf4 100644 --- a/ale_linters/cpp/cppcheck.vim +++ b/ale_linters/cpp/cppcheck.vim @@ -5,15 +5,13 @@ call ale#Set('cpp_cppcheck_executable', 'cppcheck') call ale#Set('cpp_cppcheck_options', '--enable=style') function! ale_linters#cpp#cppcheck#GetCommand(buffer) abort - let l:cd_command = ale#handlers#cppcheck#GetCdCommand(a:buffer) let l:compile_commands_option = ale#handlers#cppcheck#GetCompileCommandsOptions(a:buffer) let l:buffer_path_include = empty(l:compile_commands_option) \ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer) \ : '' let l:template = ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') - return l:cd_command - \ . '%e -q --language=c++' + return '%e -q --language=c++' \ . l:template \ . ale#Pad(l:compile_commands_option) \ . ale#Pad(ale#Var(a:buffer, 'cpp_cppcheck_options')) @@ -25,6 +23,7 @@ call ale#linter#Define('cpp', { \ 'name': 'cppcheck', \ 'output_stream': 'both', \ 'executable': {b -> ale#Var(b, 'cpp_cppcheck_executable')}, +\ 'cwd': function('ale#handlers#cppcheck#GetCwd'), \ 'command': function('ale_linters#cpp#cppcheck#GetCommand'), \ 'callback': 'ale#handlers#cppcheck#HandleCppCheckFormat', \}) diff --git a/ale_linters/cs/csc.vim b/ale_linters/cs/csc.vim index 308abc77..5ee3de29 100644 --- a/ale_linters/cs/csc.vim +++ b/ale_linters/cs/csc.vim @@ -3,14 +3,10 @@ call ale#Set('cs_csc_source', '') call ale#Set('cs_csc_assembly_path', []) call ale#Set('cs_csc_assemblies', []) -function! s:GetWorkingDirectory(buffer) abort - let l:working_directory = ale#Var(a:buffer, 'cs_csc_source') +function! ale_linters#cs#csc#GetCwd(buffer) abort + let l:cwd = ale#Var(a:buffer, 'cs_csc_source') - if !empty(l:working_directory) - return l:working_directory - endif - - return expand('#' . a:buffer . ':p:h') + return !empty(l:cwd) ? l:cwd : expand('#' . a:buffer . ':p:h') endfunction function! ale_linters#cs#csc#GetCommand(buffer) abort @@ -34,8 +30,7 @@ function! ale_linters#cs#csc#GetCommand(buffer) abort " The code is compiled as a module and the output is redirected to a " temporary file. - return ale#path#CdString(s:GetWorkingDirectory(a:buffer)) - \ . 'csc /unsafe' + return 'csc /unsafe' \ . ale#Pad(ale#Var(a:buffer, 'cs_csc_options')) \ . ale#Pad(l:lib_option) \ . ale#Pad(l:r_option) @@ -57,8 +52,7 @@ function! ale_linters#cs#csc#Handle(buffer, lines) abort \ '^\v([^ ]+)\s+([Cc][sS][^ ]+):\s+(.+)$', \] let l:output = [] - - let l:dir = s:GetWorkingDirectory(a:buffer) + let l:dir = ale_linters#cs#csc#GetCwd(a:buffer) for l:match in ale#util#GetMatches(a:lines, l:patterns) if len(l:match) > 6 && strlen(l:match[5]) > 2 && l:match[5][:1] is? 'CS' @@ -89,6 +83,7 @@ call ale#linter#Define('cs',{ \ 'name': 'csc', \ 'output_stream': 'stdout', \ 'executable': 'csc', +\ 'cwd': function('ale_linters#cs#csc#GetCwd'), \ 'command': function('ale_linters#cs#csc#GetCommand'), \ 'callback': 'ale_linters#cs#csc#Handle', \ 'lint_file': 1 diff --git a/ale_linters/cs/mcsc.vim b/ale_linters/cs/mcsc.vim index 0e4e5667..2dd46661 100644 --- a/ale_linters/cs/mcsc.vim +++ b/ale_linters/cs/mcsc.vim @@ -3,14 +3,10 @@ call ale#Set('cs_mcsc_source', '') call ale#Set('cs_mcsc_assembly_path', []) call ale#Set('cs_mcsc_assemblies', []) -function! s:GetWorkingDirectory(buffer) abort - let l:working_directory = ale#Var(a:buffer, 'cs_mcsc_source') +function! ale_linters#cs#mcsc#GetCwd(buffer) abort + let l:cwd = ale#Var(a:buffer, 'cs_mcsc_source') - if !empty(l:working_directory) - return l:working_directory - endif - - return expand('#' . a:buffer . ':p:h') + return !empty(l:cwd) ? l:cwd : expand('#' . a:buffer . ':p:h') endfunction function! ale_linters#cs#mcsc#GetCommand(buffer) abort @@ -34,8 +30,7 @@ function! ale_linters#cs#mcsc#GetCommand(buffer) abort " The code is compiled as a module and the output is redirected to a " temporary file. - return ale#path#CdString(s:GetWorkingDirectory(a:buffer)) - \ . 'mcs -unsafe' + return 'mcs -unsafe' \ . ale#Pad(ale#Var(a:buffer, 'cs_mcsc_options')) \ . ale#Pad(l:lib_option) \ . ale#Pad(l:r_option) @@ -58,7 +53,7 @@ function! ale_linters#cs#mcsc#Handle(buffer, lines) abort \] let l:output = [] - let l:dir = s:GetWorkingDirectory(a:buffer) + let l:dir = ale_linters#cs#mcsc#GetCwd(a:buffer) for l:match in ale#util#GetMatches(a:lines, l:patterns) if len(l:match) > 6 && strlen(l:match[5]) > 2 && l:match[5][:1] is? 'CS' @@ -89,6 +84,7 @@ call ale#linter#Define('cs',{ \ 'name': 'mcsc', \ 'output_stream': 'stderr', \ 'executable': 'mcs', +\ 'cwd': function('ale_linters#cs#mcsc#GetCwd'), \ 'command': function('ale_linters#cs#mcsc#GetCommand'), \ 'callback': 'ale_linters#cs#mcsc#Handle', \ 'lint_file': 1 diff --git a/ale_linters/d/dmd.vim b/ale_linters/d/dmd.vim index 14461ae6..cc5d8bc6 100644 --- a/ale_linters/d/dmd.vim +++ b/ale_linters/d/dmd.vim @@ -1,35 +1,37 @@ " Author: w0rp " Description: "dmd for D files" -function! ale_linters#d#dmd#GetDUBCommand(buffer) abort +function! s:GetDUBCommand(buffer) abort " If we can't run dub, then skip this command. if !executable('dub') " Returning an empty string skips to the DMD command. - return '' + let l:config = ale#d#FindDUBConfig(a:buffer) + + " 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. + if !empty(l:config) + return [fnamemodify(l:config, ':h'), 'dub describe --import-paths'] + endif endif - let l:dub_file = ale#d#FindDUBConfig(a:buffer) - - if empty(l:dub_file) - return '' - endif - - " 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 ' . ale#Escape(fnamemodify(l:dub_file, ':h')) - \ . ' && dub describe --import-paths' + return ['', ''] endfunction function! ale_linters#d#dmd#RunDUBCommand(buffer) abort - let l:command = ale_linters#d#dmd#GetDUBCommand(a:buffer) + let [l:cwd, l:command] = s:GetDUBCommand(a:buffer) if empty(l:command) " If we can't run DUB, just run DMD. return ale_linters#d#dmd#DMDCommand(a:buffer, [], {}) endif - return ale#command#Run(a:buffer, l:command, function('ale_linters#d#dmd#DMDCommand')) + return ale#command#Run( + \ a:buffer, + \ l:command, + \ function('ale_linters#d#dmd#DMDCommand'), + \ {'cwd': l:cwd}, + \) endfunction function! ale_linters#d#dmd#DMDCommand(buffer, dub_output, meta) abort diff --git a/ale_linters/elixir/credo.vim b/ale_linters/elixir/credo.vim index 892d47b9..d6a861f4 100644 --- a/ale_linters/elixir/credo.vim +++ b/ale_linters/elixir/credo.vim @@ -56,11 +56,7 @@ function! ale_linters#elixir#credo#GetConfigFile() abort endfunction function! ale_linters#elixir#credo#GetCommand(buffer) abort - let l:project_root = ale#handlers#elixir#FindMixUmbrellaRoot(a:buffer) - let l:mode = ale_linters#elixir#credo#GetMode() - - return ale#path#CdString(l:project_root) - \ . 'mix help credo && ' + return 'mix help credo && ' \ . 'mix credo ' . ale_linters#elixir#credo#GetMode() \ . ale_linters#elixir#credo#GetConfigFile() \ . ' --format=flycheck --read-from-stdin %s' @@ -69,6 +65,7 @@ endfunction call ale#linter#Define('elixir', { \ 'name': 'credo', \ 'executable': 'mix', +\ 'cwd': function('ale#handlers#elixir#FindMixUmbrellaRoot'), \ 'command': function('ale_linters#elixir#credo#GetCommand'), \ 'callback': 'ale_linters#elixir#credo#Handle', \}) diff --git a/ale_linters/elixir/dialyxir.vim b/ale_linters/elixir/dialyxir.vim index c7da7757..9b8a5cda 100644 --- a/ale_linters/elixir/dialyxir.vim +++ b/ale_linters/elixir/dialyxir.vim @@ -25,17 +25,10 @@ function! ale_linters#elixir#dialyxir#Handle(buffer, lines) abort return l:output endfunction -function! ale_linters#elixir#dialyxir#GetCommand(buffer) abort - let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer) - - return ale#path#CdString(l:project_root) - \ . ' mix help dialyzer && mix dialyzer' -endfunction - call ale#linter#Define('elixir', { \ 'name': 'dialyxir', \ 'executable': 'mix', -\ 'command': function('ale_linters#elixir#dialyxir#GetCommand'), +\ 'cwd': function('ale#handlers#elixir#FindMixProjectRoot'), +\ 'command': 'mix help dialyzer && mix dialyzer', \ 'callback': 'ale_linters#elixir#dialyxir#Handle', \}) - diff --git a/ale_linters/elixir/dogma.vim b/ale_linters/elixir/dogma.vim index 1c721158..28e7f420 100644 --- a/ale_linters/elixir/dogma.vim +++ b/ale_linters/elixir/dogma.vim @@ -29,17 +29,11 @@ function! ale_linters#elixir#dogma#Handle(buffer, lines) abort return l:output endfunction -function! ale_linters#elixir#dogma#GetCommand(buffer) abort - let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer) - - return ale#path#CdString(l:project_root) - \ . ' mix help dogma && mix dogma %s --format=flycheck' -endfunction - call ale#linter#Define('elixir', { \ 'name': 'dogma', \ 'executable': 'mix', -\ 'command': function('ale_linters#elixir#dogma#GetCommand'), +\ 'cwd': function('ale#handlers#elixir#FindMixProjectRoot'), +\ 'command': 'mix help dogma && mix dogma %s --format=flycheck', \ 'lint_file': 1, \ 'callback': 'ale_linters#elixir#dogma#Handle', \}) diff --git a/ale_linters/elixir/mix.vim b/ale_linters/elixir/mix.vim index abf5d0aa..948c6d36 100644 --- a/ale_linters/elixir/mix.vim +++ b/ale_linters/elixir/mix.vim @@ -30,22 +30,15 @@ function! ale_linters#elixir#mix#Handle(buffer, lines) abort endfunction function! ale_linters#elixir#mix#GetCommand(buffer) abort - let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer) - let l:temp_dir = ale#command#CreateDirectory(a:buffer) - let l:mix_build_path = has('win32') - \ ? 'set MIX_BUILD_PATH=' . ale#Escape(l:temp_dir) . ' &&' - \ : 'MIX_BUILD_PATH=' . ale#Escape(l:temp_dir) - - return ale#path#CdString(l:project_root) - \ . l:mix_build_path - \ . ' mix compile %s' + return ale#Env('MIX_BUILD_PATH', l:temp_dir) . 'mix compile %s' endfunction call ale#linter#Define('elixir', { \ 'name': 'mix', \ 'executable': 'mix', +\ 'cwd': function('ale#handlers#elixir#FindMixProjectRoot'), \ 'command': function('ale_linters#elixir#mix#GetCommand'), \ 'callback': 'ale_linters#elixir#mix#Handle', \ 'lint_file': 1, diff --git a/ale_linters/elm/make.vim b/ale_linters/elm/make.vim index 6b93257f..48ed82f3 100644 --- a/ale_linters/elm/make.vim +++ b/ale_linters/elm/make.vim @@ -186,20 +186,19 @@ function! ale_linters#elm#make#IsTest(buffer) abort endif endfunction +function! ale_linters#elm#make#GetCwd(buffer) abort + let l:root_dir = ale_linters#elm#make#GetRootDir(a:buffer) + + return !empty(l:root_dir) ? l:root_dir : '' +endfunction + " Return the command to execute the linter in the projects directory. " If it doesn't, then this will fail when imports are needed. function! ale_linters#elm#make#GetCommand(buffer) abort let l:executable = ale_linters#elm#make#GetExecutable(a:buffer) - let l:root_dir = ale_linters#elm#make#GetRootDir(a:buffer) let l:is_v19 = ale_linters#elm#make#IsVersionGte19(a:buffer) let l:is_using_elm_test = l:executable =~# 'elm-test$' - if empty(l:root_dir) - let l:dir_set_cmd = '' - else - let l:dir_set_cmd = 'cd ' . ale#Escape(l:root_dir) . ' && ' - endif - " elm-test needs to know the path of elm-make if elm isn't installed globally. " https://github.com/rtfeldman/node-test-runner/blob/57728f10668f2d2ab3179e7e3208bcfa9a1f19aa/README.md#--compiler if l:is_v19 && l:is_using_elm_test @@ -213,7 +212,9 @@ function! ale_linters#elm#make#GetCommand(buffer) abort " a sort of flag to tell the compiler not to generate an output file, " which is why this is hard coded here. " Source: https://github.com/elm-lang/elm-compiler/blob/19d5a769b30ec0b2fc4475985abb4cd94cd1d6c3/builder/src/Generate/Output.hs#L253 - return l:dir_set_cmd . '%e make --report=json --output=/dev/null' . l:elm_test_compiler_flag . '%t' + return '%e make --report=json --output=/dev/null' + \ . l:elm_test_compiler_flag + \ . '%t' endfunction function! ale_linters#elm#make#GetExecutable(buffer) abort @@ -235,6 +236,7 @@ call ale#linter#Define('elm', { \ 'name': 'make', \ 'executable': function('ale_linters#elm#make#GetExecutable'), \ 'output_stream': 'both', +\ 'cwd': function('ale_linters#elm#make#GetCwd'), \ 'command': function('ale_linters#elm#make#GetCommand'), \ 'callback': 'ale_linters#elm#make#Handle' \}) diff --git a/ale_linters/go/gobuild.vim b/ale_linters/go/gobuild.vim index 1dfb6daa..5210c5a8 100644 --- a/ale_linters/go/gobuild.vim +++ b/ale_linters/go/gobuild.vim @@ -10,8 +10,7 @@ function! ale_linters#go#gobuild#GetCommand(buffer) abort let l:options = ale#Var(a:buffer, 'go_gobuild_options') " Run go test in local directory with relative path - return ale#path#BufferCdString(a:buffer) - \ . ale#go#EnvString(a:buffer) + return ale#go#EnvString(a:buffer) \ . ale#Var(a:buffer, 'go_go_executable') . ' test' \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' -c -o /dev/null ./' @@ -50,6 +49,7 @@ call ale#linter#Define('go', { \ 'name': 'gobuild', \ 'aliases': ['go build'], \ 'executable': {b -> ale#Var(b, 'go_go_executable')}, +\ 'cwd': '%s:h', \ 'command': function('ale_linters#go#gobuild#GetCommand'), \ 'output_stream': 'stderr', \ 'callback': 'ale_linters#go#gobuild#Handler', diff --git a/ale_linters/go/golangci_lint.vim b/ale_linters/go/golangci_lint.vim index dd0e975a..2c4b1a4f 100644 --- a/ale_linters/go/golangci_lint.vim +++ b/ale_linters/go/golangci_lint.vim @@ -12,14 +12,12 @@ function! ale_linters#go#golangci_lint#GetCommand(buffer) abort if l:lint_package - return ale#path#BufferCdString(a:buffer) - \ . ale#go#EnvString(a:buffer) + return ale#go#EnvString(a:buffer) \ . '%e run ' \ . l:options endif - return ale#path#BufferCdString(a:buffer) - \ . ale#go#EnvString(a:buffer) + return ale#go#EnvString(a:buffer) \ . '%e run ' \ . ale#Escape(l:filename) \ . ' ' . l:options @@ -53,6 +51,7 @@ endfunction call ale#linter#Define('go', { \ 'name': 'golangci-lint', \ 'executable': {b -> ale#Var(b, 'go_golangci_lint_executable')}, +\ 'cwd': '%s:h', \ 'command': function('ale_linters#go#golangci_lint#GetCommand'), \ 'callback': 'ale_linters#go#golangci_lint#Handler', \ 'lint_file': 1, diff --git a/ale_linters/go/gometalinter.vim b/ale_linters/go/gometalinter.vim index eed9550a..ac33a9f3 100644 --- a/ale_linters/go/gometalinter.vim +++ b/ale_linters/go/gometalinter.vim @@ -13,14 +13,12 @@ function! ale_linters#go#gometalinter#GetCommand(buffer) abort " BufferCdString is used so that we can be sure the paths output from gometalinter can " be calculated to absolute paths in the Handler if l:lint_package - return ale#path#BufferCdString(a:buffer) - \ . ale#go#EnvString(a:buffer) + return ale#go#EnvString(a:buffer) \ . '%e' \ . (!empty(l:options) ? ' ' . l:options : '') . ' .' endif - return ale#path#BufferCdString(a:buffer) - \ . ale#go#EnvString(a:buffer) + return ale#go#EnvString(a:buffer) \ . '%e' \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(l:filename)) \ . (!empty(l:options) ? ' ' . l:options : '') . ' .' @@ -53,6 +51,7 @@ endfunction call ale#linter#Define('go', { \ 'name': 'gometalinter', \ 'executable': {b -> ale#Var(b, 'go_gometalinter_executable')}, +\ 'cwd': '%s:h', \ 'command': function('ale_linters#go#gometalinter#GetCommand'), \ 'callback': 'ale_linters#go#gometalinter#Handler', \ 'lint_file': 1, diff --git a/ale_linters/go/gosimple.vim b/ale_linters/go/gosimple.vim index ad52c621..490d15a9 100644 --- a/ale_linters/go/gosimple.vim +++ b/ale_linters/go/gosimple.vim @@ -1,15 +1,11 @@ " Author: Ben Reedy " Description: gosimple for Go files -function! ale_linters#go#gosimple#GetCommand(buffer) abort - return ale#path#BufferCdString(a:buffer) . ' ' - \ . ale#go#EnvString(a:buffer) . 'gosimple .' -endfunction - call ale#linter#Define('go', { \ 'name': 'gosimple', \ 'executable': 'gosimple', -\ 'command': function('ale_linters#go#gosimple#GetCommand'), +\ 'cwd': '%s:h', +\ 'command': {b -> ale#go#EnvString(b) . 'gosimple .'}, \ 'callback': 'ale#handlers#go#Handler', \ 'output_stream': 'both', \ 'lint_file': 1, diff --git a/ale_linters/go/gotype.vim b/ale_linters/go/gotype.vim index 6a5149ca..8fd6df27 100644 --- a/ale_linters/go/gotype.vim +++ b/ale_linters/go/gotype.vim @@ -1,19 +1,23 @@ " Author: Jelte Fennema " Description: gotype for Go files -function! ale_linters#go#gotype#GetCommand(buffer) abort +function! ale_linters#go#gotype#GetExecutable(buffer) abort if expand('#' . a:buffer . ':p') =~# '_test\.go$' return '' endif - return ale#path#BufferCdString(a:buffer) . ' ' - \ . ale#go#EnvString(a:buffer) . 'gotype -e .' + return 'gotype' +endfunction + +function! ale_linters#go#gotype#GetCommand(buffer) abort + return ale#go#EnvString(a:buffer) . 'gotype -e .' endfunction call ale#linter#Define('go', { \ 'name': 'gotype', \ 'output_stream': 'stderr', -\ 'executable': 'gotype', +\ 'executable': function('ale_linters#go#gotype#GetExecutable'), +\ 'cwd': '%s:h', \ 'command': function('ale_linters#go#gotype#GetCommand'), \ 'callback': 'ale#handlers#go#Handler', \ 'lint_file': 1, diff --git a/ale_linters/go/govet.vim b/ale_linters/go/govet.vim index dddafe17..5da8261c 100644 --- a/ale_linters/go/govet.vim +++ b/ale_linters/go/govet.vim @@ -10,8 +10,7 @@ call ale#Set('go_govet_options', '') function! ale_linters#go#govet#GetCommand(buffer) abort let l:options = ale#Var(a:buffer, 'go_govet_options') - return ale#path#BufferCdString(a:buffer) . ' ' - \ . ale#go#EnvString(a:buffer) + return ale#go#EnvString(a:buffer) \ . ale#Var(a:buffer, 'go_go_executable') . ' vet ' \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' .' @@ -22,6 +21,7 @@ call ale#linter#Define('go', { \ 'aliases': ['go vet'], \ 'output_stream': 'stderr', \ 'executable': {b -> ale#Var(b, 'go_go_executable')}, +\ 'cwd': '%s:h', \ 'command': function('ale_linters#go#govet#GetCommand'), \ 'callback': 'ale#handlers#go#Handler', \ 'lint_file': 1, diff --git a/ale_linters/go/staticcheck.vim b/ale_linters/go/staticcheck.vim index ed40c6c2..84e70d58 100644 --- a/ale_linters/go/staticcheck.vim +++ b/ale_linters/go/staticcheck.vim @@ -5,28 +5,24 @@ call ale#Set('go_staticcheck_options', '') call ale#Set('go_staticcheck_lint_package', 0) function! ale_linters#go#staticcheck#GetCommand(buffer) abort - let l:filename = expand('#' . a:buffer . ':t') let l:options = ale#Var(a:buffer, 'go_staticcheck_options') let l:lint_package = ale#Var(a:buffer, 'go_staticcheck_lint_package') let l:env = ale#go#EnvString(a:buffer) - " BufferCdString is used so that we can be sure the paths output from - " staticcheck can be calculated to absolute paths in the Handler if l:lint_package - return ale#path#BufferCdString(a:buffer) - \ . l:env . 'staticcheck' + return l:env . 'staticcheck' \ . (!empty(l:options) ? ' ' . l:options : '') . ' .' endif - return ale#path#BufferCdString(a:buffer) - \ . l:env . 'staticcheck' + return l:env . 'staticcheck' \ . (!empty(l:options) ? ' ' . l:options : '') - \ . ' ' . ale#Escape(l:filename) + \ . ' %s:t' endfunction call ale#linter#Define('go', { \ 'name': 'staticcheck', \ 'executable': 'staticcheck', +\ 'cwd': '%s:h', \ 'command': function('ale_linters#go#staticcheck#GetCommand'), \ 'callback': 'ale#handlers#go#Handler', \ 'output_stream': 'both', diff --git a/ale_linters/graphql/eslint.vim b/ale_linters/graphql/eslint.vim index aed1a371..a98233e9 100644 --- a/ale_linters/graphql/eslint.vim +++ b/ale_linters/graphql/eslint.vim @@ -4,6 +4,7 @@ call ale#linter#Define('graphql', { \ 'name': 'eslint', \ 'executable': function('ale#handlers#eslint#GetExecutable'), +\ 'cwd': function('ale#handlers#eslint#GetCwd'), \ 'command': function('ale#handlers#eslint#GetCommand'), \ 'callback': 'ale#handlers#eslint#HandleJSON', \}) diff --git a/ale_linters/graphql/gqlint.vim b/ale_linters/graphql/gqlint.vim index d5029de1..6f1ca54a 100644 --- a/ale_linters/graphql/gqlint.vim +++ b/ale_linters/graphql/gqlint.vim @@ -1,15 +1,10 @@ " Author: Michiel Westerbeek " Description: Linter for GraphQL Schemas -function! ale_linters#graphql#gqlint#GetCommand(buffer) abort - return ale#path#BufferCdString(a:buffer) - \ . 'gqlint' - \ . ' --reporter=simple %t' -endfunction - call ale#linter#Define('graphql', { \ 'name': 'gqlint', \ 'executable': 'gqlint', -\ 'command': function('ale_linters#graphql#gqlint#GetCommand'), +\ 'cwd': '%s:h', +\ 'command': 'gqlint --reporter=simple %t', \ 'callback': 'ale#handlers#unix#HandleAsWarning', \}) diff --git a/ale_linters/haskell/cabal_ghc.vim b/ale_linters/haskell/cabal_ghc.vim index f3f248f5..1bb31ebb 100644 --- a/ale_linters/haskell/cabal_ghc.vim +++ b/ale_linters/haskell/cabal_ghc.vim @@ -4,8 +4,7 @@ call ale#Set('haskell_cabal_ghc_options', '-fno-code -v0') function! ale_linters#haskell#cabal_ghc#GetCommand(buffer) abort - return ale#path#BufferCdString(a:buffer) - \ . 'cabal exec -- ghc ' + return 'cabal exec -- ghc ' \ . ale#Var(a:buffer, 'haskell_cabal_ghc_options') \ . ' %t' endfunction @@ -15,6 +14,7 @@ call ale#linter#Define('haskell', { \ 'aliases': ['cabal-ghc'], \ 'output_stream': 'stderr', \ 'executable': 'cabal', +\ 'cwd': '%s:h', \ 'command': function('ale_linters#haskell#cabal_ghc#GetCommand'), \ 'callback': 'ale#handlers#haskell#HandleGHCFormat', \}) diff --git a/ale_linters/haskell/stack_ghc.vim b/ale_linters/haskell/stack_ghc.vim index c345fe43..51ecc744 100644 --- a/ale_linters/haskell/stack_ghc.vim +++ b/ale_linters/haskell/stack_ghc.vim @@ -4,8 +4,7 @@ call ale#Set('haskell_stack_ghc_options', '-fno-code -v0') function! ale_linters#haskell#stack_ghc#GetCommand(buffer) abort - return ale#path#BufferCdString(a:buffer) - \ . ale#handlers#haskell#GetStackExecutable(a:buffer) + return ale#handlers#haskell#GetStackExecutable(a:buffer) \ . ' ghc -- ' \ . ale#Var(a:buffer, 'haskell_stack_ghc_options') \ . ' %t' @@ -16,6 +15,7 @@ call ale#linter#Define('haskell', { \ 'aliases': ['stack-ghc'], \ 'output_stream': 'stderr', \ 'executable': function('ale#handlers#haskell#GetStackExecutable'), +\ 'cwd': '%s:h', \ 'command': function('ale_linters#haskell#stack_ghc#GetCommand'), \ 'callback': 'ale#handlers#haskell#HandleGHCFormat', \}) diff --git a/ale_linters/java/javac.vim b/ale_linters/java/javac.vim index a5e57e6c..760f234c 100644 --- a/ale_linters/java/javac.vim +++ b/ale_linters/java/javac.vim @@ -9,16 +9,16 @@ call ale#Set('java_javac_classpath', '') call ale#Set('java_javac_sourcepath', '') function! ale_linters#java#javac#RunWithImportPaths(buffer) abort - let l:command = ale#maven#BuildClasspathCommand(a:buffer) + let [l:cwd, l:command] = ale#maven#BuildClasspathCommand(a:buffer) " Try to use Gradle if Maven isn't available. if empty(l:command) - let l:command = ale#gradle#BuildClasspathCommand(a:buffer) + let [l:cwd, l:command] = ale#gradle#BuildClasspathCommand(a:buffer) endif " Try to use Ant if Gradle and Maven aren't available if empty(l:command) - let l:command = ale#ant#BuildClasspathCommand(a:buffer) + let [l:cwd, l:command] = ale#ant#BuildClasspathCommand(a:buffer) endif if empty(l:command) @@ -28,7 +28,8 @@ function! ale_linters#java#javac#RunWithImportPaths(buffer) abort return ale#command#Run( \ a:buffer, \ l:command, - \ function('ale_linters#java#javac#GetCommand') + \ function('ale_linters#java#javac#GetCommand'), + \ {'cwd': l:cwd}, \) endfunction @@ -110,8 +111,7 @@ function! ale_linters#java#javac#GetCommand(buffer, import_paths, meta) abort " Always run javac from the directory the file is in, so we can resolve " relative paths correctly. - return ale#path#BufferCdString(a:buffer) - \ . '%e -Xlint' + return '%e -Xlint' \ . ale#Pad(l:cp_option) \ . ale#Pad(l:sp_option) \ . ' -d ' . ale#Escape(l:class_file_directory) @@ -154,6 +154,7 @@ endfunction call ale#linter#Define('java', { \ 'name': 'javac', \ 'executable': {b -> ale#Var(b, 'java_javac_executable')}, +\ 'cwd': '%s:h', \ 'command': function('ale_linters#java#javac#RunWithImportPaths'), \ 'output_stream': 'stderr', \ 'callback': 'ale_linters#java#javac#Handle', diff --git a/ale_linters/javascript/eslint.vim b/ale_linters/javascript/eslint.vim index 31fb413f..cf4de6ec 100644 --- a/ale_linters/javascript/eslint.vim +++ b/ale_linters/javascript/eslint.vim @@ -5,6 +5,7 @@ call ale#linter#Define('javascript', { \ 'name': 'eslint', \ 'output_stream': 'both', \ 'executable': function('ale#handlers#eslint#GetExecutable'), +\ 'cwd': function('ale#handlers#eslint#GetCwd'), \ 'command': function('ale#handlers#eslint#GetCommand'), \ 'callback': 'ale#handlers#eslint#HandleJSON', \}) diff --git a/ale_linters/kotlin/kotlinc.vim b/ale_linters/kotlin/kotlinc.vim index 66c075be..e8bc924d 100644 --- a/ale_linters/kotlin/kotlinc.vim +++ b/ale_linters/kotlin/kotlinc.vim @@ -15,20 +15,15 @@ function! ale_linters#kotlin#kotlinc#RunWithImportPaths(buffer) abort let l:command = '' " exec maven/gradle only if classpath is not set - if ale#Var(a:buffer, 'kotlin_kotlinc_classpath') isnot# '' + if !empty(ale#Var(a:buffer, 'kotlin_kotlinc_classpath')) return ale_linters#kotlin#kotlinc#GetCommand(a:buffer, [], {}) endif - let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml') - - if !empty(l:pom_path) && executable('mvn') - let l:command = ale#path#CdString(fnamemodify(l:pom_path, ':h')) - \ . 'mvn dependency:build-classpath' - endif + let [l:cwd, l:command] = ale#maven#BuildClasspathCommand(a:buffer) " Try to use Gradle if Maven isn't available. if empty(l:command) - let l:command = ale#gradle#BuildClasspathCommand(a:buffer) + let [l:cwd, l:command] = ale#gradle#BuildClasspathCommand(a:buffer) endif if empty(l:command) @@ -38,7 +33,8 @@ function! ale_linters#kotlin#kotlinc#RunWithImportPaths(buffer) abort return ale#command#Run( \ a:buffer, \ l:command, - \ function('ale_linters#kotlin#kotlinc#GetCommand') + \ function('ale_linters#kotlin#kotlinc#GetCommand'), + \ {'cwd': l:cwd}, \) endfunction diff --git a/ale_linters/mercury/mmc.vim b/ale_linters/mercury/mmc.vim index 8a9ccc0e..85969e10 100644 --- a/ale_linters/mercury/mmc.vim +++ b/ale_linters/mercury/mmc.vim @@ -5,12 +5,9 @@ call ale#Set('mercury_mmc_executable', 'mmc') call ale#Set('mercury_mmc_options', '--make --output-compile-error-lines 100') function! ale_linters#mercury#mmc#GetCommand(buffer) abort - let l:module_name = expand('#' . a:buffer . ':t:r') - - return ale#path#BufferCdString(a:buffer) - \ . '%e --errorcheck-only ' + return '%e --errorcheck-only ' \ . ale#Var(a:buffer, 'mercury_mmc_options') - \ . ' ' . l:module_name + \ . ' %s:t:r' endfunction function! ale_linters#mercury#mmc#Handle(buffer, lines) abort @@ -34,6 +31,7 @@ call ale#linter#Define('mercury', { \ 'name': 'mmc', \ 'output_stream': 'stderr', \ 'executable': {b -> ale#Var(b, 'mercury_mmc_executable')}, +\ 'cwd': '%s:h', \ 'command': function('ale_linters#mercury#mmc#GetCommand'), \ 'callback': 'ale_linters#mercury#mmc#Handle', \ 'lint_file': 1, diff --git a/ale_linters/php/phpcs.vim b/ale_linters/php/phpcs.vim index c5a3faa9..3d88ad5d 100644 --- a/ale_linters/php/phpcs.vim +++ b/ale_linters/php/phpcs.vim @@ -13,8 +13,7 @@ function! ale_linters#php#phpcs#GetCommand(buffer) abort \ ? '--standard=' . ale#Escape(l:standard) \ : '' - return ale#path#BufferCdString(a:buffer) - \ . '%e -s --report=emacs --stdin-path=%s' + return '%e -s --report=emacs --stdin-path=%s' \ . ale#Pad(l:standard_option) \ . ale#Pad(ale#Var(a:buffer, 'php_phpcs_options')) endfunction @@ -49,6 +48,7 @@ call ale#linter#Define('php', { \ 'vendor/bin/phpcs', \ 'phpcs' \ ])}, +\ 'cwd': '%s:h', \ 'command': function('ale_linters#php#phpcs#GetCommand'), \ 'callback': 'ale_linters#php#phpcs#Handle', \}) diff --git a/ale_linters/python/flake8.vim b/ale_linters/python/flake8.vim index fc4ab692..1d49d03f 100644 --- a/ale_linters/python/flake8.vim +++ b/ale_linters/python/flake8.vim @@ -38,30 +38,28 @@ function! ale_linters#python#flake8#RunWithVersionCheck(buffer) abort \) endfunction -function! ale_linters#python#flake8#GetCdString(buffer) abort +function! ale_linters#python#flake8#GetCwd(buffer) abort let l:change_directory = ale#Var(a:buffer, 'python_flake8_change_directory') - let l:cd_string = '' + let l:cwd = '' if l:change_directory is# 'project' let l:project_root = ale#python#FindProjectRootIni(a:buffer) if !empty(l:project_root) - let l:cd_string = ale#path#CdString(l:project_root) + let l:cwd = l:project_root endif endif - if (l:change_directory is# 'project' && empty(l:cd_string)) + if (l:change_directory is# 'project' && empty(l:cwd)) \|| l:change_directory is# 1 \|| l:change_directory is# 'file' - let l:cd_string = ale#path#BufferCdString(a:buffer) + let l:cwd = '%s:h' endif - return l:cd_string + return l:cwd endfunction function! ale_linters#python#flake8#GetCommand(buffer, version) abort - let l:cd_string = ale_linters#python#flake8#GetCdString(a:buffer) - let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer) let l:exec_args = l:executable =~? 'pipenv$' @@ -76,8 +74,7 @@ function! ale_linters#python#flake8#GetCommand(buffer, version) abort let l:options = ale#Var(a:buffer, 'python_flake8_options') - return l:cd_string - \ . ale#Escape(l:executable) . l:exec_args + return ale#Escape(l:executable) . l:exec_args \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' --format=default' \ . l:display_name_args . ' -' @@ -161,6 +158,7 @@ endfunction call ale#linter#Define('python', { \ 'name': 'flake8', \ 'executable': function('ale_linters#python#flake8#GetExecutable'), +\ 'cwd': function('ale_linters#python#flake8#GetCwd'), \ 'command': function('ale_linters#python#flake8#RunWithVersionCheck'), \ 'callback': 'ale_linters#python#flake8#Handle', \}) diff --git a/ale_linters/python/mypy.vim b/ale_linters/python/mypy.vim index 1e35d929..48697421 100644 --- a/ale_linters/python/mypy.vim +++ b/ale_linters/python/mypy.vim @@ -18,7 +18,7 @@ function! ale_linters#python#mypy#GetExecutable(buffer) abort endfunction " The directory to change to before running mypy -function! s:GetDir(buffer) abort +function! ale_linters#python#mypy#GetCwd(buffer) abort " If we find a directory with "mypy.ini" in it use that, " else try and find the "python project" root, or failing " that, run from the same folder as the current file @@ -36,26 +36,19 @@ function! s:GetDir(buffer) abort endfunction function! ale_linters#python#mypy#GetCommand(buffer) abort - let l:dir = s:GetDir(a:buffer) let l:executable = ale_linters#python#mypy#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv$' \ ? ' run mypy' \ : '' - let l:options = ale#Var(a:buffer, 'python_mypy_options') - - " We have to always switch to an explicit directory for a command so - " we can know with certainty the base path for the 'filename' keys below. - return ale#path#CdString(l:dir) - \ . ale#Escape(l:executable) . l:exec_args - \ . (len(l:options) ? (' ' . l:options) : '') + return '%e' . l:exec_args + \ . ale#Pad(ale#Var(a:buffer, 'python_mypy_options')) \ . ' --show-column-numbers' \ . ' --shadow-file %s %t %s' endfunction function! ale_linters#python#mypy#Handle(buffer, lines) abort - let l:dir = s:GetDir(a:buffer) + let l:dir = ale_linters#python#mypy#GetCwd(a:buffer) " Look for lines like the following: " " file.py:4: error: No library stub file for module 'django.db' @@ -97,6 +90,7 @@ endfunction call ale#linter#Define('python', { \ 'name': 'mypy', \ 'executable': function('ale_linters#python#mypy#GetExecutable'), +\ 'cwd': function('ale_linters#python#mypy#GetCwd'), \ 'command': function('ale_linters#python#mypy#GetCommand'), \ 'callback': 'ale_linters#python#mypy#Handle', \ 'output_stream': 'both' diff --git a/ale_linters/python/pydocstyle.vim b/ale_linters/python/pydocstyle.vim index 69ae3807..abf95fa1 100644 --- a/ale_linters/python/pydocstyle.vim +++ b/ale_linters/python/pydocstyle.vim @@ -21,8 +21,7 @@ function! ale_linters#python#pydocstyle#GetCommand(buffer) abort \ ? ' run pydocstyle' \ : '' - return ale#path#BufferCdString(a:buffer) - \ . ale#Escape(l:executable) . l:exec_args + return ale#Escape(l:executable) . l:exec_args \ . ale#Pad(ale#Var(a:buffer, 'python_pydocstyle_options')) \ . ' %s:t' endfunction @@ -66,6 +65,7 @@ endfunction call ale#linter#Define('python', { \ 'name': 'pydocstyle', \ 'executable': function('ale_linters#python#pydocstyle#GetExecutable'), +\ 'cwd': '%s:h', \ 'command': function('ale_linters#python#pydocstyle#GetCommand'), \ 'callback': 'ale_linters#python#pydocstyle#Handle', \}) diff --git a/ale_linters/python/pylama.vim b/ale_linters/python/pylama.vim index 38dd2836..bad69667 100644 --- a/ale_linters/python/pylama.vim +++ b/ale_linters/python/pylama.vim @@ -16,19 +16,20 @@ function! ale_linters#python#pylama#GetExecutable(buffer) abort return ale#python#FindExecutable(a:buffer, 'python_pylama', ['pylama']) endfunction -function! ale_linters#python#pylama#GetCommand(buffer) abort - let l:cd_string = '' - +function! ale_linters#python#pylama#GetCwd(buffer) abort if ale#Var(a:buffer, 'python_pylama_change_directory') " Pylama loads its configuration from the current directory only, and " applies file masks using paths relative to the current directory. " Run from project root, if found, otherwise buffer dir. let l:project_root = ale#python#FindProjectRoot(a:buffer) - let l:cd_string = l:project_root isnot# '' - \ ? ale#path#CdString(l:project_root) - \ : ale#path#BufferCdString(a:buffer) + + return !empty(l:project_root) ? l:project_root : '%s:h' endif + return '' +endfunction + +function! ale_linters#python#pylama#GetCommand(buffer) abort let l:executable = ale_linters#python#pylama#GetExecutable(a:buffer) let l:exec_args = l:executable =~? 'pipenv$' \ ? ' run pylama' @@ -37,8 +38,7 @@ function! ale_linters#python#pylama#GetCommand(buffer) abort " Note: Using %t to lint changes would be preferable, but many pylama " checks use surrounding paths (e.g. C0103 module name, E0402 relative " import beyond top, etc.). Neither is ideal. - return l:cd_string - \ . ale#Escape(l:executable) . l:exec_args + return ale#Escape(l:executable) . l:exec_args \ . ale#Pad(ale#Var(a:buffer, 'python_pylama_options')) \ . ' %s' endfunction @@ -86,6 +86,7 @@ endfunction call ale#linter#Define('python', { \ 'name': 'pylama', \ 'executable': function('ale_linters#python#pylama#GetExecutable'), +\ 'cwd': function('ale_linters#python#pylama#GetCwd'), \ 'command': function('ale_linters#python#pylama#GetCommand'), \ 'callback': 'ale_linters#python#pylama#Handle', \ 'lint_file': 1, diff --git a/ale_linters/python/pylint.vim b/ale_linters/python/pylint.vim index 44eea246..f086a865 100644 --- a/ale_linters/python/pylint.vim +++ b/ale_linters/python/pylint.vim @@ -17,27 +17,26 @@ function! ale_linters#python#pylint#GetExecutable(buffer) abort return ale#python#FindExecutable(a:buffer, 'python_pylint', ['pylint']) endfunction -function! ale_linters#python#pylint#GetCommand(buffer, version) abort - let l:cd_string = '' - +function! ale_linters#python#pylint#GetCwd(buffer) abort if ale#Var(a:buffer, 'python_pylint_change_directory') " pylint only checks for pylintrc in the packages above its current " directory before falling back to user and global pylintrc. " Run from project root, if found, otherwise buffer dir. let l:project_root = ale#python#FindProjectRoot(a:buffer) - let l:cd_string = l:project_root isnot# '' - \ ? ale#path#CdString(l:project_root) - \ : ale#path#BufferCdString(a:buffer) + + return !empty(l:project_root) ? l:project_root : '%s:h' endif - let l:executable = ale_linters#python#pylint#GetExecutable(a:buffer) + return '' +endfunction +function! ale_linters#python#pylint#GetCommand(buffer, version) abort + let l:executable = ale_linters#python#pylint#GetExecutable(a:buffer) let l:exec_args = l:executable =~? 'pipenv$' \ ? ' run pylint' \ : '' - return l:cd_string - \ . ale#Escape(l:executable) . l:exec_args + return ale#Escape(l:executable) . l:exec_args \ . ale#Pad(ale#Var(a:buffer, 'python_pylint_options')) \ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n' \ . (ale#semver#GTE(a:version, [2, 4, 0]) ? ' --from-stdin' : '') @@ -104,6 +103,7 @@ call ale#linter#Define('python', { \ '%e --version', \ {buffer, version -> !ale#semver#GTE(version, [2, 4, 0])}, \ )}, +\ 'cwd': function('ale_linters#python#pylint#GetCwd'), \ 'command': {buffer -> ale#semver#RunWithVersionCheck( \ buffer, \ ale#Var(buffer, 'python_pylint_executable'), diff --git a/ale_linters/python/vulture.vim b/ale_linters/python/vulture.vim index d328d262..84ffd49a 100644 --- a/ale_linters/python/vulture.vim +++ b/ale_linters/python/vulture.vim @@ -6,7 +6,6 @@ call ale#Set('python_vulture_options', '') call ale#Set('python_vulture_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_vulture_change_directory', 1) - " The directory to change to before running vulture function! s:GetDir(buffer) abort let l:project_root = ale#python#FindProjectRoot(a:buffer) @@ -16,29 +15,28 @@ function! s:GetDir(buffer) abort \ : expand('#' . a:buffer . ':p:h') endfunction - function! ale_linters#python#vulture#GetExecutable(buffer) abort return ale#python#FindExecutable(a:buffer, 'python_vulture', ['vulture']) endfunction +function! ale_linters#python#vulture#GetCwd(buffer) abort + if !ale#Var(a:buffer, 'python_vulture_change_directory') + return '' + endif + + return s:GetDir(a:buffer) +endfunction function! ale_linters#python#vulture#GetCommand(buffer) abort - let l:change_dir = ale#Var(a:buffer, 'python_vulture_change_directory') - \ ? ale#path#CdString(s:GetDir(a:buffer)) - \ : '' - let l:executable = ale_linters#python#vulture#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv$' \ ? ' run vulture' \ : '' - let l:lint_dest = ale#Var(a:buffer, 'python_vulture_change_directory') \ ? ' .' \ : ' %s' - return l:change_dir - \ . ale#Escape(l:executable) . l:exec_args + return ale#Escape(l:executable) . l:exec_args \ . ' ' \ . ale#Var(a:buffer, 'python_vulture_options') \ . l:lint_dest @@ -74,6 +72,7 @@ endfunction call ale#linter#Define('python', { \ 'name': 'vulture', \ 'executable': function('ale_linters#python#vulture#GetExecutable'), +\ 'cwd': function('ale_linters#python#vulture#GetCwd'), \ 'command': function('ale_linters#python#vulture#GetCommand'), \ 'callback': 'ale_linters#python#vulture#Handle', \ 'lint_file': 1, diff --git a/ale_linters/r/lintr.vim b/ale_linters/r/lintr.vim index 3164c06f..799458fb 100644 --- a/ale_linters/r/lintr.vim +++ b/ale_linters/r/lintr.vim @@ -21,14 +21,13 @@ function! ale_linters#r#lintr#GetCommand(buffer) abort let l:cmd_string = 'suppressPackageStartupMessages(library(lintr));' \ . l:lint_cmd - return ale#path#BufferCdString(a:buffer) - \ . 'Rscript --vanilla -e ' - \ . ale#Escape(l:cmd_string) . ' %t' + return 'Rscript --vanilla -e ' . ale#Escape(l:cmd_string) . ' %t' endfunction call ale#linter#Define('r', { \ 'name': 'lintr', \ 'executable': 'Rscript', +\ 'cwd': '%s:h', \ 'command': function('ale_linters#r#lintr#GetCommand'), \ 'callback': 'ale#handlers#gcc#HandleGCCFormat', \ 'output_stream': 'both', diff --git a/ale_linters/rst/rstcheck.vim b/ale_linters/rst/rstcheck.vim index 39e11d6e..e0cf0798 100644 --- a/ale_linters/rst/rstcheck.vim +++ b/ale_linters/rst/rstcheck.vim @@ -1,6 +1,5 @@ " Author: John Nduli https://github.com/jnduli " Description: Rstcheck for reStructuredText files -" function! ale_linters#rst#rstcheck#Handle(buffer, lines) abort " matches: 'bad_rst.rst:1: (SEVERE/4) Title overline & underline @@ -22,17 +21,11 @@ function! ale_linters#rst#rstcheck#Handle(buffer, lines) abort return l:output endfunction -function! ale_linters#rst#rstcheck#GetCommand(buffer) abort - return ale#path#BufferCdString(a:buffer) - \ . 'rstcheck' - \ . ' %t' -endfunction - - call ale#linter#Define('rst', { \ 'name': 'rstcheck', \ 'executable': 'rstcheck', -\ 'command': function('ale_linters#rst#rstcheck#GetCommand'), +\ 'cwd': '%s:h', +\ 'command': 'rstcheck %t', \ 'callback': 'ale_linters#rst#rstcheck#Handle', \ 'output_stream': 'both', \}) diff --git a/ale_linters/ruby/ruby.vim b/ale_linters/ruby/ruby.vim index 621fcbc0..2dc55eb0 100644 --- a/ale_linters/ruby/ruby.vim +++ b/ale_linters/ruby/ruby.vim @@ -6,7 +6,7 @@ call ale#Set('ruby_ruby_executable', 'ruby') call ale#linter#Define('ruby', { \ 'name': 'ruby', \ 'executable': {b -> ale#Var(b, 'ruby_ruby_executable')}, -\ 'command': '%e -w -c %t', +\ 'command': '%e -w -c -T1 %t', \ 'output_stream': 'stderr', \ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors', \}) diff --git a/ale_linters/rust/cargo.vim b/ale_linters/rust/cargo.vim index 3407abed..37fd10a8 100644 --- a/ale_linters/rust/cargo.vim +++ b/ale_linters/rust/cargo.vim @@ -23,6 +23,19 @@ function! ale_linters#rust#cargo#GetCargoExecutable(bufnr) abort endif endfunction +function! ale_linters#rust#cargo#GetCwd(buffer) abort + if ale#Var(a:buffer, 'rust_cargo_avoid_whole_workspace') + let l:nearest_cargo = ale#path#FindNearestFile(a:buffer, 'Cargo.toml') + let l:nearest_cargo_dir = fnamemodify(l:nearest_cargo, ':h') + + if l:nearest_cargo_dir isnot# '.' + return l:nearest_cargo_dir + endif + endif + + return '' +endfunction + function! ale_linters#rust#cargo#GetCommand(buffer, version) abort let l:use_check = ale#Var(a:buffer, 'rust_cargo_use_check') \ && ale#semver#GTE(a:version, [0, 17, 0]) @@ -42,18 +55,6 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version) abort let l:include_features = ' --features ' . ale#Escape(l:include_features) endif - let l:avoid_whole_workspace = ale#Var(a:buffer, 'rust_cargo_avoid_whole_workspace') - let l:nearest_cargo_prefix = '' - - if l:avoid_whole_workspace - let l:nearest_cargo = ale#path#FindNearestFile(a:buffer, 'Cargo.toml') - let l:nearest_cargo_dir = fnamemodify(l:nearest_cargo, ':h') - - if l:nearest_cargo_dir isnot# '.' - let l:nearest_cargo_prefix = 'cd '. ale#Escape(l:nearest_cargo_dir) .' && ' - endif - endif - let l:default_feature_behavior = ale#Var(a:buffer, 'rust_cargo_default_feature_behavior') if l:default_feature_behavior is# 'all' @@ -81,7 +82,7 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version) abort endif endif - return l:nearest_cargo_prefix . 'cargo ' + return 'cargo ' \ . l:subcommand \ . (l:use_all_targets ? ' --all-targets' : '') \ . (l:use_examples ? ' --examples' : '') @@ -96,6 +97,7 @@ endfunction call ale#linter#Define('rust', { \ 'name': 'cargo', \ 'executable': function('ale_linters#rust#cargo#GetCargoExecutable'), +\ 'cwd': function('ale_linters#rust#cargo#GetCwd'), \ 'command': {buffer -> ale#semver#RunWithVersionCheck( \ buffer, \ ale_linters#rust#cargo#GetCargoExecutable(buffer), diff --git a/ale_linters/typescript/eslint.vim b/ale_linters/typescript/eslint.vim index 33a21440..eaeac307 100644 --- a/ale_linters/typescript/eslint.vim +++ b/ale_linters/typescript/eslint.vim @@ -4,6 +4,7 @@ call ale#linter#Define('typescript', { \ 'name': 'eslint', \ 'executable': function('ale#handlers#eslint#GetExecutable'), +\ 'cwd': function('ale#handlers#eslint#GetCwd'), \ 'command': function('ale#handlers#eslint#GetCommand'), \ 'callback': 'ale#handlers#eslint#HandleJSON', \}) diff --git a/ale_linters/typescript/tslint.vim b/ale_linters/typescript/tslint.vim index f70c2e45..886a3cd4 100644 --- a/ale_linters/typescript/tslint.vim +++ b/ale_linters/typescript/tslint.vim @@ -59,8 +59,7 @@ function! ale_linters#typescript#tslint#GetCommand(buffer) abort \ ? ' -r ' . ale#Escape(l:tslint_rules_dir) \ : '' - return ale#path#BufferCdString(a:buffer) - \ . ale#Escape(ale#handlers#tslint#GetExecutable(a:buffer)) + return ale#Escape(ale#handlers#tslint#GetExecutable(a:buffer)) \ . ' --format json' \ . l:tslint_config_option \ . l:tslint_rules_option @@ -70,6 +69,7 @@ endfunction call ale#linter#Define('typescript', { \ 'name': 'tslint', \ 'executable': function('ale#handlers#tslint#GetExecutable'), +\ 'cwd': '%s:h', \ 'command': function('ale_linters#typescript#tslint#GetCommand'), \ 'callback': 'ale_linters#typescript#tslint#Handle', \}) diff --git a/ale_linters/vim/ale_custom_linting_rules.vim b/ale_linters/vim/ale_custom_linting_rules.vim index 822eb30a..5ca2f149 100644 --- a/ale_linters/vim/ale_custom_linting_rules.vim +++ b/ale_linters/vim/ale_custom_linting_rules.vim @@ -22,16 +22,20 @@ function! s:GetALEProjectDir(buffer) abort return ale#path#Dirname(ale#path#Dirname(ale#path#Dirname(l:executable))) endfunction -function! ale_linters#vim#ale_custom_linting_rules#GetCommand(buffer) abort - let l:dir = s:GetALEProjectDir(a:buffer) +function! ale_linters#vim#ale_custom_linting_rules#GetCwd(buffer) abort + let l:executable = ale_linters#vim#ale_custom_linting_rules#GetExecutable(a:buffer) + return ale#path#Dirname(ale#path#Dirname(ale#path#Dirname(l:executable))) +endfunction + +function! ale_linters#vim#ale_custom_linting_rules#GetCommand(buffer) abort let l:temp_dir = ale#command#CreateDirectory(a:buffer) let l:temp_file = l:temp_dir . '/example.vim' let l:lines = getbufline(a:buffer, 1, '$') call ale#util#Writefile(a:buffer, l:lines, l:temp_file) - return ale#path#CdString(l:dir) . '%e ' . ale#Escape(l:temp_dir) + return '%e ' . ale#Escape(l:temp_dir) endfunction function! ale_linters#vim#ale_custom_linting_rules#Handle(buffer, lines) abort @@ -59,6 +63,7 @@ endfunction call ale#linter#Define('vim', { \ 'name': 'ale_custom_linting_rules', \ 'executable': function('ale_linters#vim#ale_custom_linting_rules#GetExecutable'), +\ 'cwd': function('ale_linters#vim#ale_custom_linting_rules#GetCwd'), \ 'command': function('ale_linters#vim#ale_custom_linting_rules#GetCommand'), \ 'callback': 'ale_linters#vim#ale_custom_linting_rules#Handle', \ 'read_buffer': 0, diff --git a/autoload/ale/ant.vim b/autoload/ale/ant.vim index 7d02484e..b6d4217f 100644 --- a/autoload/ale/ant.vim +++ b/autoload/ale/ant.vim @@ -23,19 +23,23 @@ function! ale#ant#FindExecutable(buffer) abort return '' endfunction -" Given a buffer number, build a command to print the classpath of the root -" project. Returns an empty string if cannot build the command. +" Given a buffer number, get a working directory and command to print the +" classpath of the root project. +" +" Returns an empty string for the command if Ant is not detected. function! ale#ant#BuildClasspathCommand(buffer) abort let l:executable = ale#ant#FindExecutable(a:buffer) - let l:project_root = ale#ant#FindProjectRoot(a:buffer) - if !empty(l:executable) && !empty(l:project_root) - return ale#path#CdString(l:project_root) - \ . ale#Escape(l:executable) - \ . ' classpath' - \ . ' -S' - \ . ' -q' + if !empty(l:executable) + let l:project_root = ale#ant#FindProjectRoot(a:buffer) + + if !empty(l:project_root) + return [ + \ l:project_root, + \ ale#Escape(l:executable) .' classpath -S -q' + \] + endif endif - return '' + return ['', ''] endfunction diff --git a/autoload/ale/assert.vim b/autoload/ale/assert.vim index 934fcaa8..7db0a22e 100644 --- a/autoload/ale/assert.vim +++ b/autoload/ale/assert.vim @@ -52,6 +52,36 @@ function! s:ProcessDeferredCommands(initial_result) abort return l:command endfunction +function! s:ProcessDeferredCwds(initial_command, initial_cwd) abort + let l:result = a:initial_command + let l:last_cwd = v:null + let l:command_index = 0 + let l:cwd_list = [] + + while ale#command#IsDeferred(l:result) + call add(l:cwd_list, l:result.cwd) + + if get(g:, 'ale_run_synchronously_emulate_commands') + " Don't run commands, but simulate the results. + let l:Callback = g:ale_run_synchronously_callbacks[0] + let l:output = get(s:command_output, l:command_index, []) + call l:Callback(0, l:output) + unlet g:ale_run_synchronously_callbacks + + let l:command_index += 1 + else + " Run the commands in the shell, synchronously. + call ale#test#FlushJobs() + endif + + let l:result = l:result.value + endwhile + + call add(l:cwd_list, a:initial_cwd is v:null ? l:last_cwd : a:initial_cwd) + + return l:cwd_list +endfunction + " Load the currently loaded linter for a test case, and check that the command " matches the given string. function! ale#assert#Linter(expected_executable, expected_command) abort @@ -85,6 +115,38 @@ function! ale#assert#Linter(expected_executable, expected_command) abort \ [l:executable, l:command] endfunction +function! ale#assert#LinterCwd(expected_cwd) abort + let l:buffer = bufnr('') + let l:linter = s:GetLinter() + + let l:initial_cwd = ale#linter#GetCwd(l:buffer, l:linter) + call ale#command#SetCwd(l:buffer, l:initial_cwd) + + let l:cwd = s:ProcessDeferredCwds( + \ ale#linter#GetCommand(l:buffer, l:linter), + \ l:initial_cwd, + \) + + call ale#command#ResetCwd(l:buffer) + + if type(a:expected_cwd) isnot v:t_list + let l:cwd = l:cwd[-1] + endif + + AssertEqual a:expected_cwd, l:cwd +endfunction + +function! ale#assert#FixerCwd(expected_cwd) abort + let l:buffer = bufnr('') + let l:cwd = s:ProcessDeferredCwds(s:FixerFunction(l:buffer), v:null) + + if type(a:expected_cwd) isnot v:t_list + let l:cwd = l:cwd[-1] + endif + + AssertEqual a:expected_cwd, l:cwd +endfunction + function! ale#assert#Fixer(expected_result) abort let l:buffer = bufnr('') let l:result = s:ProcessDeferredCommands(s:FixerFunction(l:buffer)) @@ -153,6 +215,7 @@ endfunction function! ale#assert#SetUpLinterTestCommands() abort command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput() + command! -nargs=+ AssertLinterCwd :call ale#assert#LinterCwd() command! -nargs=+ AssertLinter :call ale#assert#Linter() command! -nargs=0 AssertLinterNotExecuted :call ale#assert#LinterNotExecuted() command! -nargs=+ AssertLSPOptions :call ale#assert#LSPOptions() @@ -164,10 +227,35 @@ endfunction function! ale#assert#SetUpFixerTestCommands() abort command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput() + command! -nargs=+ AssertFixerCwd :call ale#assert#FixerCwd() command! -nargs=+ AssertFixer :call ale#assert#Fixer() command! -nargs=0 AssertFixerNotExecuted :call ale#assert#FixerNotExecuted() endfunction +function! ale#assert#ResetVariables(filetype, name, ...) abort + " If the suffix of the option names format is different, an additional + " argument can be used for that instead. + if a:0 > 1 + throw 'Too many arguments' + endif + + let l:option_suffix = get(a:000, 0, a:name) + let l:prefix = 'ale_' . a:filetype . '_' + \ . substitute(l:option_suffix, '-', '_', 'g') + let l:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix' + + " Save and clear linter variables. + " We'll load the runtime file to reset them to defaults. + for l:key in filter(keys(g:), l:filter_expr) + execute 'Save g:' . l:key + unlet g:[l:key] + endfor + + for l:key in filter(keys(b:), l:filter_expr) + unlet b:[l:key] + endfor +endfunction + " A dummy function for making sure this module is loaded. function! ale#assert#SetUpLinterTest(filetype, name) abort " Set up a marker so ALE doesn't create real random temporary filenames. @@ -177,31 +265,18 @@ function! ale#assert#SetUpLinterTest(filetype, name) abort call ale#linter#Reset() call ale#linter#PreventLoading(a:filetype) - let l:prefix = 'ale_' . a:filetype . '_' . a:name - let b:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix' - Save g:ale_lsp_root let g:ale_lsp_root = {} Save b:ale_lsp_root unlet! b:ale_lsp_root + call ale#assert#ResetVariables(a:filetype, a:name) + Save g:ale_c_build_dir unlet! g:ale_c_build_dir - - " Save and clear linter variables. - " We'll load the runtime file to reset them to defaults. - for l:key in filter(keys(g:), b:filter_expr) - execute 'Save g:' . l:key - unlet g:[l:key] - endfor - unlet! b:ale_c_build_dir - for l:key in filter(keys(b:), b:filter_expr) - unlet b:[l:key] - endfor - execute 'runtime ale_linters/' . a:filetype . '/' . a:name . '.vim' if !exists('g:dir') @@ -226,6 +301,10 @@ function! ale#assert#TearDownLinterTest() abort delcommand GivenCommandOutput endif + if exists(':AssertLinterCwd') + delcommand AssertLinterCwd + endif + if exists(':AssertLinter') delcommand AssertLinter endif @@ -281,18 +360,7 @@ function! ale#assert#SetUpFixerTest(filetype, name, ...) abort let s:FixerFunction = function(l:function_name) let l:option_suffix = get(a:000, 0, a:name) - let l:prefix = 'ale_' . a:filetype . '_' - \ . substitute(l:option_suffix, '-', '_', 'g') - let b:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix' - - for l:key in filter(keys(g:), b:filter_expr) - execute 'Save g:' . l:key - unlet g:[l:key] - endfor - - for l:key in filter(keys(b:), b:filter_expr) - unlet b:[l:key] - endfor + call ale#assert#ResetVariables(a:filetype, a:name, l:option_suffix) execute 'runtime autoload/ale/fixers/' . substitute(a:name, '-', '_', 'g') . '.vim' @@ -329,6 +397,10 @@ function! ale#assert#TearDownFixerTest() abort delcommand GivenCommandOutput endif + if exists(':AssertFixerCwd') + delcommand AssertFixerCwd + endif + if exists(':AssertFixer') delcommand AssertFixer endif diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim index 14621aa9..ec9d4482 100644 --- a/autoload/ale/c.vim +++ b/autoload/ale/c.vim @@ -513,16 +513,18 @@ function! ale#c#GetMakeCommand(buffer) abort if !empty(l:path) let l:always_make = ale#Var(a:buffer, 'c_always_make') - return ale#path#CdString(fnamemodify(l:path, ':h')) - \ . 'make -n' . (l:always_make ? ' --always-make' : '') + return [ + \ fnamemodify(l:path, ':h'), + \ 'make -n' . (l:always_make ? ' --always-make' : ''), + \] endif endif - return '' + return ['', ''] endfunction function! ale#c#RunMakeCommand(buffer, Callback) abort - let l:command = ale#c#GetMakeCommand(a:buffer) + let [l:cwd, l:command] = ale#c#GetMakeCommand(a:buffer) if empty(l:command) return a:Callback(a:buffer, []) @@ -532,6 +534,7 @@ function! ale#c#RunMakeCommand(buffer, Callback) abort \ a:buffer, \ l:command, \ {b, output -> a:Callback(a:buffer, output)}, + \ {'cwd': l:cwd}, \) endfunction diff --git a/autoload/ale/command.vim b/autoload/ale/command.vim index 8f497169..c9dc8d94 100644 --- a/autoload/ale/command.vim +++ b/autoload/ale/command.vim @@ -7,6 +7,9 @@ if !exists('s:buffer_data') let s:buffer_data = {} endif +" The regular expression used for formatting filenames with modifiers. +let s:path_format_regex = '\v\%s(%(:h|:t|:r|:e)*)' + " Used to get the data in tests. function! ale#command#GetData() abort return deepcopy(s:buffer_data) @@ -26,6 +29,19 @@ function! ale#command#InitData(buffer) abort endif endfunction +" Set the cwd for commands that are about to run. +" Used internally. +function! ale#command#SetCwd(buffer, cwd) abort + call ale#command#InitData(a:buffer) + let s:buffer_data[a:buffer].cwd = a:cwd +endfunction + +function! ale#command#ResetCwd(buffer) abort + if has_key(s:buffer_data, a:buffer) + let s:buffer_data[a:buffer].cwd = v:null + endif +endfunction + function! ale#command#ManageFile(buffer, file) abort call ale#command#InitData(a:buffer) call add(s:buffer_data[a:buffer].file_list, a:file) @@ -151,6 +167,24 @@ function! s:FormatFilename(filename, mappings, modifiers) abort return ale#Escape(l:filename) endfunction +" Produce a command prefix to check to a particular directory for a command. +" %s format markers with filename-modifiers can be used as the directory, and +" will be returned verbatim for formatting in paths relative to files. +function! ale#command#CdString(directory) abort + let l:match = matchstrpos(a:directory, s:path_format_regex) + " Do not escape the directory here if it's a valid format string. + " This allows us to use sequences like %s:h, %s:h:h, etc. + let l:directory = l:match[1:] == [0, len(a:directory)] + \ ? a:directory + \ : ale#Escape(a:directory) + + if has('win32') + return 'cd /d ' . l:directory . ' && ' + endif + + return 'cd ' . l:directory . ' && ' +endfunction + " Given a command string, replace every... " %s -> with the current filename " %t -> with the name of an unused file in a temporary directory @@ -161,11 +195,16 @@ function! ale#command#FormatCommand( \ command, \ pipe_file_if_needed, \ input, +\ cwd, \ mappings, \) abort let l:temporary_file = '' let l:command = a:command + if !empty(a:cwd) + let l:command = ale#command#CdString(a:cwd) . l:command + endif + " First replace all uses of %%, used for literal percent characters, " with an ugly string. let l:command = substitute(l:command, '%%', '<>', 'g') @@ -181,7 +220,7 @@ function! ale#command#FormatCommand( let l:filename = fnamemodify(bufname(a:buffer), ':p') let l:command = substitute( \ l:command, - \ '\v\%s(%(:h|:t|:r|:e)*)', + \ s:path_format_regex, \ '\=s:FormatFilename(l:filename, a:mappings, submatch(1))', \ 'g' \) @@ -279,9 +318,16 @@ function! s:ExitCallback(buffer, line_list, Callback, data) abort let l:result = a:data.result let l:result.value = l:value - if get(l:result, 'result_callback', v:null) isnot v:null - call call(l:result.result_callback, [l:value]) - endif + " Set the default cwd for this buffer in this call stack. + call ale#command#SetCwd(a:buffer, l:result.cwd) + + try + if get(l:result, 'result_callback', v:null) isnot v:null + call call(l:result.result_callback, [l:value]) + endif + finally + call ale#command#ResetCwd(a:buffer) + endtry endfunction function! ale#command#Run(buffer, command, Callback, ...) abort @@ -293,6 +339,13 @@ function! ale#command#Run(buffer, command, Callback, ...) abort let l:output_stream = get(l:options, 'output_stream', 'stdout') let l:line_list = [] + let l:cwd = get(l:options, 'cwd', v:null) + + if l:cwd is v:null + " Default the working directory to whatever it was for the last + " command run in the chain. + let l:cwd = get(get(s:buffer_data, a:buffer, {}), 'cwd', v:null) + endif let [l:temporary_file, l:command, l:file_created] = ale#command#FormatCommand( \ a:buffer, @@ -300,6 +353,7 @@ function! ale#command#Run(buffer, command, Callback, ...) abort \ a:command, \ get(l:options, 'read_buffer', 0), \ get(l:options, 'input', v:null), + \ l:cwd, \ get(l:options, 'filename_mappings', []), \) let l:command = ale#job#PrepareCommand(a:buffer, l:command) @@ -366,10 +420,14 @@ function! ale#command#Run(buffer, command, Callback, ...) abort " The `_deferred_job_id` is used for both checking the type of object, and " for checking the job ID and status. " + " The cwd is kept and used as the default value for the next command in + " the chain. + " " The original command here is used in tests. let l:result = { \ '_deferred_job_id': l:job_id, \ 'executable': get(l:options, 'executable', ''), + \ 'cwd': l:cwd, \ 'command': a:command, \} diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim index 3cafa25c..5b9b1fca 100644 --- a/autoload/ale/engine.vim +++ b/autoload/ale/engine.vim @@ -413,6 +413,7 @@ function! s:RunJob(command, options) abort return 0 endif + let l:cwd = a:options.cwd let l:executable = a:options.executable let l:buffer = a:options.buffer let l:linter = a:options.linter @@ -425,6 +426,7 @@ function! s:RunJob(command, options) abort \ 'executable': l:executable, \}]) let l:result = ale#command#Run(l:buffer, l:command, l:Callback, { + \ 'cwd': l:cwd, \ 'output_stream': l:output_stream, \ 'executable': l:executable, \ 'read_buffer': l:read_buffer, @@ -541,8 +543,22 @@ function! s:RunIfExecutable(buffer, linter, lint_file, executable) abort let l:job_type = a:lint_file ? 'file_linter' : 'linter' call setbufvar(a:buffer, 'ale_job_type', l:job_type) + " Get the cwd for the linter and set it before we call GetCommand. + " This will ensure that ale#command#Run uses it by default. + let l:cwd = ale#linter#GetCwd(a:buffer, a:linter) + + if l:cwd isnot v:null + call ale#command#SetCwd(a:buffer, l:cwd) + endif + let l:command = ale#linter#GetCommand(a:buffer, a:linter) + + if l:cwd isnot v:null + call ale#command#ResetCwd(a:buffer) + endif + let l:options = { + \ 'cwd': l:cwd, \ 'executable': a:executable, \ 'buffer': a:buffer, \ 'linter': a:linter, diff --git a/autoload/ale/fix.vim b/autoload/ale/fix.vim index c3338fc5..8ebba9fe 100644 --- a/autoload/ale/fix.vim +++ b/autoload/ale/fix.vim @@ -172,6 +172,7 @@ function! s:RunJob(result, options) abort let l:read_temporary_file = get(a:result, 'read_temporary_file', 0) let l:read_buffer = get(a:result, 'read_buffer', 1) let l:output_stream = get(a:result, 'output_stream', 'stdout') + let l:cwd = get(a:result, 'cwd', v:null) if l:read_temporary_file let l:output_stream = 'none' @@ -190,6 +191,7 @@ function! s:RunJob(result, options) abort \ 'read_buffer': l:read_buffer, \ 'input': l:input, \ 'log_output': 0, + \ 'cwd': l:cwd, \ 'filename_mappings': ale#GetFilenameMappings(l:buffer, l:fixer_name), \}) diff --git a/autoload/ale/fixers/autoimport.vim b/autoload/ale/fixers/autoimport.vim index 37a52db8..700d36b5 100644 --- a/autoload/ale/fixers/autoimport.vim +++ b/autoload/ale/fixers/autoimport.vim @@ -19,7 +19,9 @@ function! ale#fixers#autoimport#Fix(buffer) abort endif return { - \ 'command': ale#path#BufferCdString(a:buffer) - \ . ale#Escape(l:executable) . (!empty(l:options) ? ' ' . l:options : '') . ' -', + \ 'cwd': '%s:h', + \ 'command': ale#Escape(l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' -', \} endfunction diff --git a/autoload/ale/fixers/black.vim b/autoload/ale/fixers/black.vim index fba6c3b4..17697652 100644 --- a/autoload/ale/fixers/black.vim +++ b/autoload/ale/fixers/black.vim @@ -17,25 +17,25 @@ function! ale#fixers#black#GetExecutable(buffer) abort endfunction function! ale#fixers#black#Fix(buffer) abort - let l:cd_string = ale#Var(a:buffer, 'python_black_change_directory') - \ ? ale#path#BufferCdString(a:buffer) - \ : '' - let l:executable = ale#fixers#black#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv$' \ ? ' run black' \ : '' - let l:options = ale#Var(a:buffer, 'python_black_options') if expand('#' . a:buffer . ':e') is? 'pyi' let l:options .= '--pyi' endif - return { - \ 'command': l:cd_string . ale#Escape(l:executable) . l:exec_args + let l:result = { + \ 'command': ale#Escape(l:executable) . l:exec_args \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' -', \} + + if ale#Var(a:buffer, 'python_black_change_directory') + let l:result.cwd = '%s:h' + endif + + return l:result endfunction diff --git a/autoload/ale/fixers/eslint.vim b/autoload/ale/fixers/eslint.vim index f725875c..c9535cb0 100644 --- a/autoload/ale/fixers/eslint.vim +++ b/autoload/ale/fixers/eslint.vim @@ -53,8 +53,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort " Use --fix-to-stdout with eslint_d if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0]) return { - \ 'command': ale#handlers#eslint#GetCdString(a:buffer) - \ . ale#node#Executable(a:buffer, l:executable) + \ 'cwd': ale#handlers#eslint#GetCwd(a:buffer), + \ 'command': ale#node#Executable(a:buffer, l:executable) \ . ale#Pad(l:options) \ . ' --stdin-filename %s --stdin --fix-to-stdout', \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', @@ -64,8 +64,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort " 4.9.0 is the first version with --fix-dry-run if ale#semver#GTE(a:version, [4, 9, 0]) return { - \ 'command': ale#handlers#eslint#GetCdString(a:buffer) - \ . ale#node#Executable(a:buffer, l:executable) + \ 'cwd': ale#handlers#eslint#GetCwd(a:buffer), + \ 'command': ale#node#Executable(a:buffer, l:executable) \ . ale#Pad(l:options) \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', @@ -73,8 +73,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort endif return { - \ 'command': ale#handlers#eslint#GetCdString(a:buffer) - \ . ale#node#Executable(a:buffer, l:executable) + \ 'cwd': ale#handlers#eslint#GetCwd(a:buffer), + \ 'command': ale#node#Executable(a:buffer, l:executable) \ . ale#Pad(l:options) \ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '') \ . ' --fix %t', diff --git a/autoload/ale/fixers/isort.vim b/autoload/ale/fixers/isort.vim index 55bb550e..ba95bb10 100644 --- a/autoload/ale/fixers/isort.vim +++ b/autoload/ale/fixers/isort.vim @@ -17,9 +17,7 @@ endfunction function! ale#fixers#isort#Fix(buffer) abort let l:options = ale#Var(a:buffer, 'python_isort_options') - let l:executable = ale#fixers#isort#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv$' \ ? ' run isort' \ : '' @@ -29,8 +27,8 @@ function! ale#fixers#isort#Fix(buffer) abort endif return { - \ 'command': ale#path#BufferCdString(a:buffer) - \ . ale#Escape(l:executable) . l:exec_args + \ 'cwd': '%s:h', + \ 'command': ale#Escape(l:executable) . l:exec_args \ . (!empty(l:options) ? ' ' . l:options : '') . ' -', \} endfunction diff --git a/autoload/ale/fixers/prettier.vim b/autoload/ale/fixers/prettier.vim index 277f84c4..43806e8e 100644 --- a/autoload/ale/fixers/prettier.vim +++ b/autoload/ale/fixers/prettier.vim @@ -34,19 +34,11 @@ function! ale#fixers#prettier#ProcessPrettierDOutput(buffer, output) abort return a:output endfunction -function! ale#fixers#prettier#GetProjectRoot(buffer) abort +function! ale#fixers#prettier#GetCwd(buffer) abort let l:config = ale#path#FindNearestFile(a:buffer, '.prettierignore') - if !empty(l:config) - return fnamemodify(l:config, ':h') - endif - " Fall back to the directory of the buffer - return fnamemodify(bufname(a:buffer), ':p:h') -endfunction - -function! ale#fixers#prettier#CdProjectRoot(buffer) abort - return ale#path#CdString(ale#fixers#prettier#GetProjectRoot(a:buffer)) + return !empty(l:config) ? fnamemodify(l:config, ':h') : '%s:h' endfunction function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort @@ -103,8 +95,8 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort " Special error handling needed for prettier_d if l:executable =~# 'prettier_d$' return { - \ 'command': ale#path#BufferCdString(a:buffer) - \ . ale#Escape(l:executable) + \ 'cwd': '%s:h', + \ 'command':ale#Escape(l:executable) \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' --stdin-filepath %s --stdin', \ 'process_with': 'ale#fixers#prettier#ProcessPrettierDOutput', @@ -114,8 +106,8 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort " 1.4.0 is the first version with --stdin-filepath if ale#semver#GTE(a:version, [1, 4, 0]) return { - \ 'command': ale#fixers#prettier#CdProjectRoot(a:buffer) - \ . ale#Escape(l:executable) + \ 'cwd': ale#fixers#prettier#GetCwd(a:buffer), + \ 'command': ale#Escape(l:executable) \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' --stdin-filepath %s --stdin', \} diff --git a/autoload/ale/fixers/prettier_eslint.vim b/autoload/ale/fixers/prettier_eslint.vim index 1e66f49e..09fadd71 100644 --- a/autoload/ale/fixers/prettier_eslint.vim +++ b/autoload/ale/fixers/prettier_eslint.vim @@ -37,8 +37,8 @@ function! ale#fixers#prettier_eslint#ApplyFixForVersion(buffer, version) abort " 4.4.0 is the first version with --stdin-filepath if ale#semver#GTE(a:version, [4, 4, 0]) return { - \ 'command': ale#path#BufferCdString(a:buffer) - \ . ale#Escape(l:executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(l:executable) \ . l:eslint_config_option \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' --stdin-filepath %s --stdin', diff --git a/autoload/ale/fixers/stylelint.vim b/autoload/ale/fixers/stylelint.vim index 6f4cf177..0caab802 100644 --- a/autoload/ale/fixers/stylelint.vim +++ b/autoload/ale/fixers/stylelint.vim @@ -17,8 +17,8 @@ function! ale#fixers#stylelint#Fix(buffer) abort let l:options = ale#Var(a:buffer, 'stylelint_options') return { - \ 'command': ale#path#BufferCdString(a:buffer) - \ . ale#node#Executable(a:buffer, l:executable) + \ 'cwd': '%s:h', + \ 'command': ale#node#Executable(a:buffer, l:executable) \ . ' %t' \ . ale#Pad(l:options) \ . ' --fix', diff --git a/autoload/ale/fixers/yamlfix.vim b/autoload/ale/fixers/yamlfix.vim index 966556c9..6654a25c 100644 --- a/autoload/ale/fixers/yamlfix.vim +++ b/autoload/ale/fixers/yamlfix.vim @@ -7,7 +7,6 @@ call ale#Set('yaml_yamlfix_use_global', get(g:, 'ale_use_global_executables', 0) function! ale#fixers#yamlfix#Fix(buffer) abort let l:options = ale#Var(a:buffer, 'yaml_yamlfix_options') - let l:executable = ale#python#FindExecutable( \ a:buffer, \ 'yaml_yamlfix', @@ -19,7 +18,8 @@ function! ale#fixers#yamlfix#Fix(buffer) abort endif return { - \ 'command': ale#path#BufferCdString(a:buffer) - \ . ale#Escape(l:executable) . (!empty(l:options) ? ' ' . l:options : '') . ' -', + \ 'cwd': '%s:h', + \ 'command': ale#Escape(l:executable) + \ . (!empty(l:options) ? ' ' . l:options : '') . ' -', \} endfunction diff --git a/autoload/ale/gradle.vim b/autoload/ale/gradle.vim index dc377fb9..ba1add4d 100644 --- a/autoload/ale/gradle.vim +++ b/autoload/ale/gradle.vim @@ -50,18 +50,25 @@ function! ale#gradle#FindExecutable(buffer) abort return '' endfunction -" Given a buffer number, build a command to print the classpath of the root -" project. Returns an empty string if cannot build the command. +" Given a buffer number, get a working directory and command to print the +" classpath of the root project. +" +" Returns an empty string for the command if Gradle is not detected. function! ale#gradle#BuildClasspathCommand(buffer) abort let l:executable = ale#gradle#FindExecutable(a:buffer) - let l:project_root = ale#gradle#FindProjectRoot(a:buffer) - if !empty(l:executable) && !empty(l:project_root) - return ale#path#CdString(l:project_root) - \ . ale#Escape(l:executable) - \ . ' -I ' . ale#Escape(s:init_path) - \ . ' -q printClasspath' + if !empty(l:executable) + let l:project_root = ale#gradle#FindProjectRoot(a:buffer) + + if !empty(l:project_root) + return [ + \ l:project_root, + \ ale#Escape(l:executable) + \ . ' -I ' . ale#Escape(s:init_path) + \ . ' -q printClasspath' + \] + endif endif - return '' + return ['', ''] endfunction diff --git a/autoload/ale/handlers/cppcheck.vim b/autoload/ale/handlers/cppcheck.vim index 7f68ba67..b70ae1bf 100644 --- a/autoload/ale/handlers/cppcheck.vim +++ b/autoload/ale/handlers/cppcheck.vim @@ -1,10 +1,9 @@ " Description: Handle errors for cppcheck. -function! ale#handlers#cppcheck#GetCdCommand(buffer) abort +function! ale#handlers#cppcheck#GetCwd(buffer) abort let [l:dir, l:json_path] = ale#c#FindCompileCommands(a:buffer) - let l:cd_command = !empty(l:dir) ? ale#path#CdString(l:dir) : '' - return l:cd_command + return !empty(l:dir) ? l:dir : '' endfunction function! ale#handlers#cppcheck#GetBufferPathIncludeOptions(buffer) abort diff --git a/autoload/ale/handlers/eslint.vim b/autoload/ale/handlers/eslint.vim index b8610612..e953d40f 100644 --- a/autoload/ale/handlers/eslint.vim +++ b/autoload/ale/handlers/eslint.vim @@ -39,9 +39,8 @@ function! ale#handlers#eslint#GetExecutable(buffer) abort return ale#node#FindExecutable(a:buffer, 'javascript_eslint', s:executables) endfunction -" Given a buffer, return a command prefix string which changes directory -" as necessary for running ESLint. -function! ale#handlers#eslint#GetCdString(buffer) abort +" Given a buffer, return an appropriate working directory for ESLint. +function! ale#handlers#eslint#GetCwd(buffer) abort " ESLint 6 loads plugins/configs/parsers from the project root " By default, the project root is simply the CWD of the running process. " https://github.com/eslint/rfcs/blob/master/designs/2018-simplified-package-loading/README.md @@ -60,7 +59,7 @@ function! ale#handlers#eslint#GetCdString(buffer) abort let l:project_dir = !empty(l:modules_dir) ? fnamemodify(l:modules_dir, ':h:h') : '' endif - return !empty(l:project_dir) ? ale#path#CdString(l:project_dir) : '' + return !empty(l:project_dir) ? l:project_dir : '' endfunction function! ale#handlers#eslint#GetCommand(buffer) abort @@ -68,8 +67,7 @@ function! ale#handlers#eslint#GetCommand(buffer) abort let l:options = ale#Var(a:buffer, 'javascript_eslint_options') - return ale#handlers#eslint#GetCdString(a:buffer) - \ . ale#node#Executable(a:buffer, l:executable) + return ale#node#Executable(a:buffer, l:executable) \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' -f json --stdin --stdin-filename %s' endfunction diff --git a/autoload/ale/handlers/shellcheck.vim b/autoload/ale/handlers/shellcheck.vim index 701c43b2..17de2912 100644 --- a/autoload/ale/handlers/shellcheck.vim +++ b/autoload/ale/handlers/shellcheck.vim @@ -40,21 +40,21 @@ function! ale#handlers#shellcheck#GetDialectArgument(buffer) abort return '' endfunction +function! ale#handlers#shellcheck#GetCwd(buffer) abort + return ale#Var(a:buffer, 'sh_shellcheck_change_directory') ? '%s:h' : '' +endfunction + function! ale#handlers#shellcheck#GetCommand(buffer, version) abort let l:options = ale#Var(a:buffer, 'sh_shellcheck_options') let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions') let l:dialect = ale#Var(a:buffer, 'sh_shellcheck_dialect') let l:external_option = ale#semver#GTE(a:version, [0, 4, 0]) ? ' -x' : '' - let l:cd_string = ale#Var(a:buffer, 'sh_shellcheck_change_directory') - \ ? ale#path#BufferCdString(a:buffer) - \ : '' if l:dialect is# 'auto' let l:dialect = ale#handlers#shellcheck#GetDialectArgument(a:buffer) endif - return l:cd_string - \ . '%e' + return '%e' \ . (!empty(l:dialect) ? ' -s ' . l:dialect : '') \ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '') @@ -111,6 +111,7 @@ function! ale#handlers#shellcheck#DefineLinter(filetype) abort call ale#linter#Define(a:filetype, { \ 'name': 'shellcheck', \ 'executable': {buffer -> ale#Var(buffer, 'sh_shellcheck_executable')}, + \ 'cwd': function('ale#handlers#shellcheck#GetCwd'), \ 'command': {buffer -> ale#semver#RunWithVersionCheck( \ buffer, \ ale#Var(buffer, 'sh_shellcheck_executable'), diff --git a/autoload/ale/linter.vim b/autoload/ale/linter.vim index f9ec48d7..d7b6a1ac 100644 --- a/autoload/ale/linter.vim +++ b/autoload/ale/linter.vim @@ -151,17 +151,30 @@ function! ale#linter#PreProcess(filetype, linter) abort endif let l:obj.address = a:linter.address + + if has_key(a:linter, 'cwd') + throw '`cwd` makes no sense for socket LSP connections' + endif else throw '`address` must be defined for getting the LSP address' endif + if has_key(a:linter, 'cwd') + let l:obj.cwd = a:linter.cwd + + if type(l:obj.cwd) isnot v:t_string + \&& type(l:obj.cwd) isnot v:t_func + throw '`cwd` must be a String or Function if defined' + endif + endif + if l:needs_lsp_details " Default to using the filetype as the language. let l:obj.language = get(a:linter, 'language', a:filetype) if type(l:obj.language) isnot v:t_string \&& type(l:obj.language) isnot v:t_func - throw '`language` must be a String or Funcref if defined' + throw '`language` must be a String or Function if defined' endif if has_key(a:linter, 'project_root') @@ -415,6 +428,12 @@ function! ale#linter#GetExecutable(buffer, linter) abort \ : l:Executable endfunction +function! ale#linter#GetCwd(buffer, linter) abort + let l:Cwd = get(a:linter, 'cwd', v:null) + + return type(l:Cwd) is v:t_func ? l:Cwd(a:buffer) : l:Cwd +endfunction + " Given a buffer and linter, get the command String for the linter. function! ale#linter#GetCommand(buffer, linter) abort let l:Command = a:linter.command diff --git a/autoload/ale/lsp_linter.vim b/autoload/ale/lsp_linter.vim index 628dde78..2a3902b6 100644 --- a/autoload/ale/lsp_linter.vim +++ b/autoload/ale/lsp_linter.vim @@ -290,6 +290,7 @@ function! s:StartLSP(options, address, executable, command) abort \ a:command, \ 0, \ v:false, + \ v:null, \ [], \)[1] let l:command = ale#job#PrepareCommand(l:buffer, l:command) diff --git a/autoload/ale/maven.vim b/autoload/ale/maven.vim index 42735286..4f87ebb7 100644 --- a/autoload/ale/maven.vim +++ b/autoload/ale/maven.vim @@ -17,7 +17,6 @@ function! ale#maven#FindProjectRoot(buffer) abort return '' endfunction - " Given a buffer number, find the path to the executable. " First search on the path for 'mvnw' (mvnw.cmd on Windows), if nothing is found, " try the global command. Returns an empty string if cannot find the executable. @@ -36,16 +35,23 @@ function! ale#maven#FindExecutable(buffer) abort return '' endfunction -" Given a buffer number, build a command to print the classpath of the root -" project. Returns an empty string if cannot build the command. +" Given a buffer number, get a working directory and command to print the +" classpath of the root project. +" +" Returns an empty string for the command if Maven is not detected. function! ale#maven#BuildClasspathCommand(buffer) abort let l:executable = ale#maven#FindExecutable(a:buffer) - let l:project_root = ale#maven#FindProjectRoot(a:buffer) - if !empty(l:executable) && !empty(l:project_root) - return ale#path#CdString(l:project_root) - \ . l:executable . ' dependency:build-classpath' + if !empty(l:executable) + let l:project_root = ale#maven#FindProjectRoot(a:buffer) + + if !empty(l:project_root) + return [ + \ l:project_root, + \ ale#Escape(l:executable) . ' dependency:build-classpath' + \] + endif endif - return '' + return ['', ''] endfunction diff --git a/autoload/ale/path.vim b/autoload/ale/path.vim index fed95ccd..94de252d 100644 --- a/autoload/ale/path.vim +++ b/autoload/ale/path.vim @@ -77,26 +77,6 @@ function! ale#path#ResolveLocalPath(buffer, search_string, global_fallback) abor return l:path endfunction -" Output 'cd && ' -" This function can be used changing the directory for a linter command. -function! ale#path#CdString(directory) abort - if has('win32') - return 'cd /d ' . ale#Escape(a:directory) . ' && ' - endif - - return 'cd ' . ale#Escape(a:directory) . ' && ' -endfunction - -" Output 'cd && ' -" This function can be used changing the directory for a linter command. -function! ale#path#BufferCdString(buffer) abort - if has('win32') - return 'cd /d %s:h && ' - endif - - return 'cd %s:h && ' -endfunction - " Return 1 if a path is an absolute path. function! ale#path#IsAbsolute(filename) abort if has('win32') && a:filename[:0] is# '\' diff --git a/doc/ale-development.txt b/doc/ale-development.txt index dbbeb2da..0ebce87b 100644 --- a/doc/ale-development.txt +++ b/doc/ale-development.txt @@ -311,6 +311,7 @@ The full list of commands that will be temporarily defined for linter tests given the above setup are as follows. `GivenCommandOutput [...]` - Define output for ale#command#Run. +`AssertLinterCwd cwd` - Check the `cwd` for the linter. `AssertLinter executable, command` - Check the executable and command. `AssertLinterNotExecuted` - Check that linters will not be executed. `AssertLSPLanguage language` - Check the language given to an LSP server. @@ -357,6 +358,7 @@ The full list of commands that will be temporarily defined for fixer tests given the above setup are as follows. `GivenCommandOutput [...]` - Define output for ale#command#Run. +`AssertFixerCwd cwd` - Check the `cwd` for the fixer. `AssertFixer results` - Check the fixer results `AssertFixerNotExecuted` - Check that fixers will not be executed. diff --git a/doc/ale.txt b/doc/ale.txt index 1f7dbe76..1ea65a33 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -342,6 +342,12 @@ the buffers being checked. When a |Dictionary| is returned for an |ALEFix| callback, the following keys are supported for running the commands. + `cwd` An optional |String| for setting the working directory + for the command. + + If not set, or `v:null`, the `cwd` of the last command + that spawn this one will be used. + `command` A |String| for the command to run. This key is required. When `%t` is included in a command string, a temporary @@ -3578,6 +3584,12 @@ ale#command#Run(buffer, command, callback, [options]) *ale#command#Run()* < The following `options` can be provided. + `cwd` - An optional |String| for setting the working directory + for the command, just as per |ale#linter#Define|. + + If not set, or `v:null`, the `cwd` of the last command + that spawned this one will be used. + `output_stream` - Either `'stdout'`, `'stderr'`, `'both'`, or `'none`' for selecting which output streams to read lines from. @@ -3803,10 +3815,33 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* The result can be computed with |ale#command#Run()|. + The command string can be formatted with format + markers. See |ale-command-format-strings|. + This command will be fed the lines from the buffer to check, and will produce the lines of output given to the `callback`. + `cwd` An optional |String| for setting the working + directory for the command, or a |Funcref| for a + function to call for computing the command, accepting + a buffer number. The working directory can be + specified as a format string for determining the path + dynamically. See |ale-command-format-strings|. + + To set the working directory to the directory + containing the file you're checking, you should + probably use `'%s:h'` as the option value. + + If this option is absent or the string is empty, the + `command` will be run with no determined working + directory in particular. + + The directory specified with this option will be used + as the default working directory for all commands run + in a chain with |ale#command#Run()|, unless otherwise + specified. + `output_stream` A |String| for the output stream the lines of output should be read from for the command which is run. The accepted values are `'stdout'`, `'stderr'`, and diff --git a/test/command_callback/test_c_cppcheck_command_callbacks.vader b/test/command_callback/test_c_cppcheck_command_callbacks.vader index b8b0959d..d9b9c62c 100644 --- a/test/command_callback/test_c_cppcheck_command_callbacks.vader +++ b/test/command_callback/test_c_cppcheck_command_callbacks.vader @@ -17,14 +17,14 @@ Execute(The executable should be configurable): let b:ale_c_cppcheck_executable = 'foobar' + AssertLinterCwd '' AssertLinter 'foobar', ale#Escape('foobar') . b:command_tail Execute(cppcheck for C should detect compile_commands.json files): call ale#test#SetFilename('cppcheck_paths/one/foo.c') - AssertLinter 'cppcheck', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one')) - \ . ale#Escape('cppcheck') + AssertLinterCwd ale#path#Simplify(g:dir . '/cppcheck_paths/one') + AssertLinter 'cppcheck', ale#Escape('cppcheck') \ . ' -q --language=c' \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') \ . ' --project=' . ale#Escape('compile_commands.json') @@ -33,9 +33,8 @@ Execute(cppcheck for C should detect compile_commands.json files): Execute(cppcheck for C should detect compile_commands.json files in build directories): call ale#test#SetFilename('cppcheck_paths/with_build_dir/foo.cpp') - AssertLinter 'cppcheck', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/with_build_dir')) - \ . ale#Escape('cppcheck') + AssertLinterCwd ale#path#Simplify(g:dir . '/cppcheck_paths/with_build_dir') + AssertLinter 'cppcheck', ale#Escape('cppcheck') \ . ' -q --language=c' \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') \ . ' --project=' . ale#Escape(ale#path#Simplify('build/compile_commands.json')) @@ -58,9 +57,8 @@ Execute(cppcheck for C should ignore compile_commands.json file if buffer is mod set buftype= set modified - AssertLinter 'cppcheck', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one')) - \ . ale#Escape('cppcheck') + AssertLinterCwd ale#path#Simplify(g:dir . '/cppcheck_paths/one') + AssertLinter 'cppcheck', ale#Escape('cppcheck') \ . ' -q --language=c' \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') \ . ' --enable=style' diff --git a/test/command_callback/test_cargo_command_callbacks.vader b/test/command_callback/test_cargo_command_callbacks.vader index 2d83351e..ee942c28 100644 --- a/test/command_callback/test_cargo_command_callbacks.vader +++ b/test/command_callback/test_cargo_command_callbacks.vader @@ -118,20 +118,23 @@ Execute(--all-features should be used when g:ale_rust_cargo_default_feature_beha GivenCommandOutput ['cargo 0.22.0 (3423351a5 2017-10-06)'] AssertLinter 'cargo', [ale#Escape('cargo') . ' --version', 'cargo check --frozen --message-format=json -q --all-features'] -Execute(When a crate belongs to a workspace we should cd into the crate): +Execute(Cargo should run from the crate directory when set to avoid the workspace): let g:ale_rust_cargo_avoid_whole_workspace = 1 call ale#test#SetFilename('cargo_workspace_paths/subpath/test.rs') + AssertLinterCwd ale#path#Simplify(g:dir . '/cargo_workspace_paths/subpath') + call ale#semver#ResetVersionCache() AssertLinter 'cargo', [ \ ale#Escape('cargo') . ' --version', - \ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/cargo_workspace_paths/subpath')) . ' && ' - \ . 'cargo check --frozen --message-format=json -q', + \ 'cargo check --frozen --message-format=json -q', \] -Execute(When a crate belongs to a workspace we chdir into the crate, unless we disabled it): +Execute(Cargo should not run from the crate directory when not set to avoid the workspace): let g:ale_rust_cargo_avoid_whole_workspace = 0 call ale#test#SetFilename('cargo_workspace_paths/subpath/test.rs') + AssertLinterCwd '' + call ale#semver#ResetVersionCache() AssertLinter 'cargo', [ \ ale#Escape('cargo') . ' --version', \ 'cargo check --frozen --message-format=json -q', diff --git a/test/command_callback/test_cpp_cppcheck_command_callbacks.vader b/test/command_callback/test_cpp_cppcheck_command_callbacks.vader index 7eea4a69..01e4f776 100644 --- a/test/command_callback/test_cpp_cppcheck_command_callbacks.vader +++ b/test/command_callback/test_cpp_cppcheck_command_callbacks.vader @@ -17,14 +17,14 @@ Execute(The executable should be configurable): let b:ale_cpp_cppcheck_executable = 'foobar' + AssertLinterCwd '' AssertLinter 'foobar', ale#Escape('foobar') . b:command_tail Execute(cppcheck for C++ should detect compile_commands.json files): call ale#test#SetFilename('cppcheck_paths/one/foo.cpp') - AssertLinter 'cppcheck', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one')) - \ . ale#Escape('cppcheck') + AssertLinterCwd ale#path#Simplify(g:dir . '/cppcheck_paths/one') + AssertLinter 'cppcheck', ale#Escape('cppcheck') \ . ' -q --language=c++' \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') \ . ' --project=' . ale#Escape('compile_commands.json') @@ -33,9 +33,8 @@ Execute(cppcheck for C++ should detect compile_commands.json files): Execute(cppcheck for C++ should detect compile_commands.json files in build directories): call ale#test#SetFilename('cppcheck_paths/with_build_dir/foo.cpp') - AssertLinter 'cppcheck', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/with_build_dir')) - \ . ale#Escape('cppcheck') + AssertLinterCwd ale#path#Simplify(g:dir . '/cppcheck_paths/with_build_dir') + AssertLinter 'cppcheck', ale#Escape('cppcheck') \ . ' -q --language=c++' \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') \ . ' --project=' . ale#Escape(ale#path#Simplify('build/compile_commands.json')) @@ -58,9 +57,8 @@ Execute(cppcheck for C++ should ignore compile_commands.json file if buffer is m set buftype= set modified - AssertLinter 'cppcheck', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/cppcheck_paths/one')) - \ . ale#Escape('cppcheck') + AssertLinterCwd ale#path#Simplify(g:dir . '/cppcheck_paths/one') + AssertLinter 'cppcheck', ale#Escape('cppcheck') \ . ' -q --language=c++' \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') \ . ' --enable=style' diff --git a/test/command_callback/test_cs_csc_command_callbacks.vader b/test/command_callback/test_cs_csc_command_callbacks.vader index c21ce209..28d0304a 100644 --- a/test/command_callback/test_cs_csc_command_callbacks.vader +++ b/test/command_callback/test_cs_csc_command_callbacks.vader @@ -5,43 +5,38 @@ After: call ale#assert#TearDownLinterTest() Execute(The csc linter should return the correct default command): - AssertLinter 'csc', ale#path#CdString(g:dir) - \ . 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') + AssertLinterCwd expand('%:p:h') + AssertLinter 'csc', 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') Execute(The options should be be used in the command): let g:ale_cs_csc_options = '' - AssertLinter 'csc', ale#path#CdString(g:dir) - \ . 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') + AssertLinter 'csc', 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') Execute(The souce path should be be used in the command): let g:ale_cs_csc_source = '../foo/bar' - AssertLinter 'csc', ale#path#CdString('../foo/bar') - \ . 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') + AssertLinterCwd '../foo/bar' + AssertLinter 'csc', 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') Execute(The list of search pathes for assemblies should be be used in the command if not empty): let g:ale_cs_csc_assembly_path = ['/usr/lib/mono', '../foo/bar'] - AssertLinter 'csc', ale#path#CdString(g:dir) - \ . 'csc /unsafe' + AssertLinter 'csc', 'csc /unsafe' \ . ' /lib:' . ale#Escape('/usr/lib/mono') . ',' . ale#Escape('../foo/bar') \ . ' /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') let g:ale_cs_csc_assembly_path = [] - AssertLinter 'csc', ale#path#CdString(g:dir) - \ . 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') + AssertLinter 'csc', 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') Execute(The list of assemblies should be be used in the command if not empty): let g:ale_cs_csc_assemblies = ['foo.dll', 'bar.dll'] - AssertLinter 'csc', ale#path#CdString(g:dir) - \ . 'csc /unsafe' + AssertLinter 'csc', 'csc /unsafe' \ . ' /r:' . ale#Escape('foo.dll') . ',' . ale#Escape('bar.dll') \ . ' /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') let g:ale_cs_csc_assemblies = [] - AssertLinter 'csc', ale#path#CdString(g:dir) - \ . 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') + AssertLinter 'csc', 'csc /unsafe /out:TEMP /t:module /recurse:' . ale#Escape('*.cs') diff --git a/test/command_callback/test_cs_mcsc_command_callbacks.vader b/test/command_callback/test_cs_mcsc_command_callbacks.vader index d15898e0..e784cf15 100644 --- a/test/command_callback/test_cs_mcsc_command_callbacks.vader +++ b/test/command_callback/test_cs_mcsc_command_callbacks.vader @@ -5,43 +5,38 @@ After: call ale#assert#TearDownLinterTest() Execute(The mcsc linter should return the correct default command): - AssertLinter 'mcs', ale#path#CdString(g:dir) - \ . 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') + AssertLinterCwd expand('%:p:h') + AssertLinter 'mcs', 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') Execute(The options should be be used in the command): let g:ale_cs_mcsc_options = '-pkg:dotnet' - AssertLinter 'mcs', ale#path#CdString(g:dir) - \ . 'mcs -unsafe -pkg:dotnet -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') + AssertLinter 'mcs', 'mcs -unsafe -pkg:dotnet -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') Execute(The souce path should be be used in the command): let g:ale_cs_mcsc_source = '../foo/bar' - AssertLinter 'mcs', ale#path#CdString('../foo/bar') - \ . 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') + AssertLinterCwd '../foo/bar' + AssertLinter 'mcs', 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') Execute(The list of search pathes for assemblies should be be used in the command if not empty): let g:ale_cs_mcsc_assembly_path = ['/usr/lib/mono', '../foo/bar'] - AssertLinter 'mcs', ale#path#CdString(g:dir) - \ . 'mcs -unsafe' + AssertLinter 'mcs', 'mcs -unsafe' \ . ' -lib:' . ale#Escape('/usr/lib/mono') . ',' . ale#Escape('../foo/bar') \ . ' -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') let g:ale_cs_mcsc_assembly_path = [] - AssertLinter 'mcs', ale#path#CdString(g:dir) - \ . 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') + AssertLinter 'mcs', 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') Execute(The list of assemblies should be be used in the command if not empty): let g:ale_cs_mcsc_assemblies = ['foo.dll', 'bar.dll'] - AssertLinter 'mcs', ale#path#CdString(g:dir) - \ . 'mcs -unsafe' + AssertLinter 'mcs', 'mcs -unsafe' \ . ' -r:' . ale#Escape('foo.dll') . ',' . ale#Escape('bar.dll') \ . ' -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') let g:ale_cs_mcsc_assemblies = [] - AssertLinter 'mcs', ale#path#CdString(g:dir) - \ . 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') + AssertLinter 'mcs', 'mcs -unsafe -out:TEMP -t:module -recurse:' . ale#Escape('*.cs') diff --git a/test/command_callback/test_dialyxir_command_callback.vader b/test/command_callback/test_dialyxir_command_callback.vader new file mode 100644 index 00000000..9fe27dfb --- /dev/null +++ b/test/command_callback/test_dialyxir_command_callback.vader @@ -0,0 +1,16 @@ +Before: + call ale#assert#SetUpLinterTest('elixir', 'dialyxir') + call ale#test#SetFilename('elixir_paths/mix_project/lib/app.ex') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Builds dialyxir command with a normal project): + AssertLinterCwd ale#path#Simplify(g:dir . '/elixir_paths/mix_project') + AssertLinter 'mix', 'mix help dialyzer && mix dialyzer' + +Execute(Builds dialyxir command with an umbrella project): + call ale#test#SetFilename('elixir_paths/umbrella_project/apps/mix_project/lib/app.ex') + + AssertLinterCwd ale#path#Simplify(g:dir . '/elixir_paths/umbrella_project') + AssertLinter 'mix', 'mix help dialyzer && mix dialyzer' diff --git a/test/command_callback/test_dogma_command_callback.vader b/test/command_callback/test_dogma_command_callback.vader new file mode 100644 index 00000000..99267505 --- /dev/null +++ b/test/command_callback/test_dogma_command_callback.vader @@ -0,0 +1,16 @@ +Before: + call ale#assert#SetUpLinterTest('elixir', 'dogma') + call ale#test#SetFilename('elixir_paths/mix_project/lib/app.ex') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Builds dogma command with a normal project): + AssertLinterCwd ale#path#Simplify(g:dir . '/elixir_paths/mix_project') + AssertLinter 'mix', 'mix help dogma && mix dogma %s --format=flycheck' + +Execute(Builds dogma command with an umbrella project): + call ale#test#SetFilename('elixir_paths/umbrella_project/apps/mix_project/lib/app.ex') + + AssertLinterCwd ale#path#Simplify(g:dir . '/elixir_paths/umbrella_project') + AssertLinter 'mix', 'mix help dogma && mix dogma %s --format=flycheck' diff --git a/test/command_callback/test_elixir_credo.vader b/test/command_callback/test_elixir_credo.vader deleted file mode 100644 index b14444c6..00000000 --- a/test/command_callback/test_elixir_credo.vader +++ /dev/null @@ -1,47 +0,0 @@ -Before: - call ale#assert#SetUpLinterTest('elixir', 'credo') - call ale#test#SetFilename('elixir_paths/mix_project/lib/app.ex') - - -After: - unlet! g:ale_elixir_credo_strict - - call ale#assert#TearDownLinterTest() - -Execute(Builds credo command with normal project): - AssertLinter 'mix', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/mix_project')) - \ . 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' - -Execute(Builds credo command with umbrella project): - call ale#test#SetFilename('elixir_paths/umbrella_project/apps/mix_project/lib/app.ex') - - AssertLinter 'mix', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/umbrella_project')) - \ . 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' - -Execute(Builds credo command with --strict mode when set to 1): - let g:ale_elixir_credo_strict = 1 - - AssertLinter 'mix', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/mix_project')) - \ . 'mix help credo && mix credo --strict --format=flycheck --read-from-stdin %s' - -Execute(Builds credo command with suggest mode by default): - AssertLinter 'mix', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/mix_project')) - \ . 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' - -Execute(Builds credo command with suggest mode when set to 0): - let g:ale_elixir_credo_strict = 0 - - AssertLinter 'mix', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/mix_project')) - \ . 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' - -Execute(Builds credo command with a custom config file): - let g:ale_elixir_credo_config_file = '/home/user/custom_credo.exs' - - AssertLinter 'mix', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/mix_project')) - \ . 'mix help credo && mix credo suggest --config-file /home/user/custom_credo.exs --format=flycheck --read-from-stdin %s' diff --git a/test/command_callback/test_elixir_credo_command_callback.vader b/test/command_callback/test_elixir_credo_command_callback.vader new file mode 100644 index 00000000..e3c57c61 --- /dev/null +++ b/test/command_callback/test_elixir_credo_command_callback.vader @@ -0,0 +1,43 @@ +Before: + call ale#assert#SetUpLinterTest('elixir', 'credo') + call ale#test#SetFilename('elixir_paths/mix_project/lib/app.ex') + + +After: + unlet! g:ale_elixir_credo_strict + + call ale#assert#TearDownLinterTest() + +Execute(Builds credo command with normal project): + AssertLinterCwd ale#path#Simplify(g:dir . '/elixir_paths/mix_project') + AssertLinter 'mix', + \ 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' + +Execute(Builds credo command with umbrella project): + call ale#test#SetFilename('elixir_paths/umbrella_project/apps/mix_project/lib/app.ex') + + AssertLinterCwd ale#path#Simplify(g:dir . '/elixir_paths/umbrella_project') + AssertLinter 'mix', + \ 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' + +Execute(Builds credo command with --strict mode when set to 1): + let g:ale_elixir_credo_strict = 1 + + AssertLinter 'mix', + \ 'mix help credo && mix credo --strict --format=flycheck --read-from-stdin %s' + +Execute(Builds credo command with suggest mode by default): + AssertLinter 'mix', + \ 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' + +Execute(Builds credo command with suggest mode when set to 0): + let g:ale_elixir_credo_strict = 0 + + AssertLinter 'mix', + \ 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s' + +Execute(Builds credo command with a custom config file): + let g:ale_elixir_credo_config_file = '/home/user/custom_credo.exs' + + AssertLinter 'mix', + \ 'mix help credo && mix credo suggest --config-file /home/user/custom_credo.exs --format=flycheck --read-from-stdin %s' diff --git a/test/command_callback/test_elixir_mix_command_callbacks.vader b/test/command_callback/test_elixir_mix_command_callbacks.vader index b0d0af98..8dfba231 100644 --- a/test/command_callback/test_elixir_mix_command_callbacks.vader +++ b/test/command_callback/test_elixir_mix_command_callbacks.vader @@ -1,9 +1,7 @@ Before: call ale#assert#SetUpLinterTest('elixir', 'mix') - - let g:env_prefix = has('win32') - \ ? 'set MIX_BUILD_PATH=' . ale#Escape('TEMP_DIR') . ' && ' - \ : 'MIX_BUILD_PATH=' . ale#Escape('TEMP_DIR') . ' ' + call ale#test#SetFilename('elixir_paths/mix_project/lib/app.ex') + let g:env_prefix = ale#Env('MIX_BUILD_PATH', 'TEMP_DIR') After: unlet! g:env_prefix @@ -11,23 +9,11 @@ After: call ale#assert#TearDownLinterTest() Execute(The default mix command should be correct): - call ale#test#SetFilename('elixir_paths/mix_project/lib/app.ex') + AssertLinterCwd ale#path#Simplify(g:dir . '/elixir_paths/mix_project') + AssertLinter 'mix', g:env_prefix . 'mix compile %s' - AssertLinter 'mix', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/mix_project')) - \ . g:env_prefix - \ . 'mix compile %s' +Execute(Build mix commands with an umbrella root): + call ale#test#SetFilename('elixir_paths/umbrella_project/apps/mix_project/lib/app.ex') -Execute(FindMixProjectRoot should detect the project root directory via mix.exs): - silent execute 'file ' . fnameescape(g:dir . '/elixir_paths/mix_project/lib/app.ex') - - AssertEqual - \ ale#path#Simplify(g:dir . '/elixir_paths/mix_project'), - \ ale#handlers#elixir#FindMixProjectRoot(bufnr('')) - -Execute(FindMixUmbrellaRoot should detect the umbrella root directory via mix.exs): - silent execute 'file ' . fnameescape(g:dir . '/elixir_paths/umbrella_project/apps/app1/lib/app.ex') - - AssertEqual - \ ale#path#Simplify(g:dir . '/elixir_paths/umbrella_project'), - \ ale#handlers#elixir#FindMixUmbrellaRoot(bufnr('')) + AssertLinterCwd ale#path#Simplify(g:dir . '/elixir_paths/umbrella_project') + AssertLinter 'mix', g:env_prefix . 'mix compile %s' diff --git a/test/command_callback/test_elm_make_command_callback.vader b/test/command_callback/test_elm_make_command_callback.vader index 7ad439f9..97a9e91d 100644 --- a/test/command_callback/test_elm_make_command_callback.vader +++ b/test/command_callback/test_elm_make_command_callback.vader @@ -11,18 +11,18 @@ Execute(should get valid executable with default params): let g:executable = ale#path#Simplify(g:dir . '/../elm-test-files/newapp/node_modules/.bin/elm') + AssertLinterCwd ale#path#Simplify(g:dir . '/../elm-test-files/newapp') AssertLinter g:executable, - \ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/../elm-test-files/newapp')) . ' && ' - \ . ale#Escape(g:executable) . ' make --report=json --output=/dev/null %t' + \ ale#Escape(g:executable) . ' make --report=json --output=/dev/null %t' Execute(should get elm-test executable for test code with elm >= 0.19): call ale#test#SetFilename('../elm-test-files/newapp/tests/TestSuite.elm') let g:executable = ale#path#Simplify(g:dir . '/../elm-test-files/newapp/node_modules/.bin/elm-test') + AssertLinterCwd ale#path#Simplify(g:dir . '/../elm-test-files/newapp') AssertLinter g:executable, - \ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/../elm-test-files/newapp')) . ' && ' - \ . ale#Escape(g:executable) . ' make --report=json --output=/dev/null --compiler ' + \ ale#Escape(g:executable) . ' make --report=json --output=/dev/null --compiler ' \ . ale#path#Simplify(g:dir . '/../elm-test-files/newapp/node_modules/.bin/elm') . ' %t' Execute(should fallback to elm executable with elm >= 0.19): @@ -30,27 +30,27 @@ Execute(should fallback to elm executable with elm >= 0.19): let g:executable = ale#path#Simplify(g:dir . '/../elm-test-files/newapp-notests/node_modules/.bin/elm') + AssertLinterCwd ale#path#Simplify(g:dir . '/../elm-test-files/newapp-notests') AssertLinter g:executable, - \ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/../elm-test-files/newapp-notests')) . ' && ' - \ . ale#Escape(g:executable) . ' make --report=json --output=/dev/null %t' + \ ale#Escape(g:executable) . ' make --report=json --output=/dev/null %t' Execute(should get plain elm executable for test code with elm < 0.19): call ale#test#SetFilename('../elm-test-files/oldapp/tests/TestSuite.elm') let g:executable = ale#path#Simplify(g:dir . '/../elm-test-files/oldapp/node_modules/.bin/elm') + AssertLinterCwd ale#path#Simplify(g:dir . '/../elm-test-files/oldapp') AssertLinter g:executable, - \ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/../elm-test-files/oldapp')) . ' && ' - \ . ale#Escape(g:executable) . ' make --report=json --output=/dev/null %t' + \ ale#Escape(g:executable) . ' make --report=json --output=/dev/null %t' Execute(should get valid executable with 'use_global' params): let g:ale_elm_make_use_global = 1 call ale#test#SetFilename('../elm-test-files/newapp/src/Main.elm') + AssertLinterCwd ale#path#Simplify(g:dir . '/../elm-test-files/newapp') AssertLinter 'elm', - \ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/../elm-test-files/newapp')) . ' && ' - \ . ale#Escape('elm') . ' make --report=json --output=/dev/null %t' + \ ale#Escape('elm') . ' make --report=json --output=/dev/null %t' Execute(should get valid executable with 'use_global' and 'executable' params): let g:ale_elm_make_executable = 'other-elm' @@ -58,6 +58,6 @@ Execute(should get valid executable with 'use_global' and 'executable' params): call ale#test#SetFilename('../elm-test-files/newapp/src/Main.elm') + AssertLinterCwd ale#path#Simplify(g:dir . '/../elm-test-files/newapp') AssertLinter 'other-elm', - \ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/../elm-test-files/newapp')) . ' && ' - \ . ale#Escape('other-elm') . ' make --report=json --output=/dev/null %t' + \ ale#Escape('other-elm') . ' make --report=json --output=/dev/null %t' diff --git a/test/command_callback/test_eslint_command_callback.vader b/test/command_callback/test_eslint_command_callback.vader new file mode 100644 index 00000000..071ebdc6 --- /dev/null +++ b/test/command_callback/test_eslint_command_callback.vader @@ -0,0 +1,76 @@ +Before: + call ale#assert#SetUpLinterTest('javascript', 'eslint') + runtime autoload/ale/handlers/eslint.vim + + let b:args = ' -f json --stdin --stdin-filename %s' + +After: + unlet! b:args + unlet! b:executable + + call ale#assert#TearDownLinterTest() + +Execute(The default command should be correct): + AssertLinterCwd '' + AssertLinter 'eslint', ale#Escape('eslint') . b:args + +Execute(create-react-app directories should be detected correctly): + call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js') + + let b:executable = ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js') + AssertLinterCwd ale#path#Simplify(g:dir . '/../eslint-test-files/react-app') + AssertLinter b:executable, + \ (has('win32') ? ale#Escape('node.exe') . ' ' : '') + \ . ale#Escape(b:executable) . b:args + +Execute(use-global should override create-react-app detection): + call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js') + + let g:ale_javascript_eslint_use_global = 1 + let g:ale_javascript_eslint_executable = 'eslint_d' + + let b:executable = 'eslint_d' + AssertLinterCwd ale#path#Simplify(g:dir . '/../eslint-test-files/react-app') + AssertLinter b:executable, ale#Escape(b:executable) . b:args + +Execute(other app directories should be detected correctly): + call ale#test#SetFilename('../eslint-test-files/other-app/subdir/testfile.js') + + let b:executable = ale#path#Simplify(g:dir . '/../eslint-test-files/node_modules/.bin/eslint') + AssertLinterCwd ale#path#Simplify(g:dir . '/../eslint-test-files') + AssertLinter b:executable, ale#Escape(b:executable) . b:args + +Execute(use-global should override other app directories): + call ale#test#SetFilename('../eslint-test-files/other-app/subdir/testfile.js') + + let g:ale_javascript_eslint_use_global = 1 + let g:ale_javascript_eslint_executable = 'eslint_d' + + let b:executable = 'eslint_d' + AssertLinterCwd ale#path#Simplify(g:dir . '/../eslint-test-files') + AssertLinter b:executable, ale#Escape(b:executable) . b:args + +Execute(eslint_d should be detected correctly): + call ale#test#SetFilename('../eslint-test-files/app-with-eslint-d/testfile.js') + + let b:executable = ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d') + AssertLinterCwd ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d') + AssertLinter b:executable, ale#Escape(b:executable) . b:args + +Execute(eslint.js executables should be run with node on Windows): + call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js') + + let b:executable = ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js') + AssertLinterCwd ale#path#Simplify(g:dir . '/../eslint-test-files/react-app') + AssertLinter b:executable, + \ (has('win32') ? ale#Escape('node.exe') . ' ' : '') + \ . ale#Escape(b:executable) . b:args + +Execute(eslint.js should be run from a containing project with eslint): + call ale#test#SetFilename('../eslint-test-files/react-app/subdir-with-package-json/testfile.js') + + let b:executable = ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js') + AssertLinterCwd ale#path#Simplify(g:dir . '/../eslint-test-files/react-app') + AssertLinter b:executable, + \ (has('win32') ? ale#Escape('node.exe') . ' ' : '') + \ . ale#Escape(b:executable) . b:args diff --git a/test/command_callback/test_flake8_command_callback.vader b/test/command_callback/test_flake8_command_callback.vader index 09f64ee3..3cf1ed0c 100644 --- a/test/command_callback/test_flake8_command_callback.vader +++ b/test/command_callback/test_flake8_command_callback.vader @@ -13,15 +13,13 @@ After: Execute(The flake8 callbacks should return the correct default values): AssertLinter 'flake8', [ \ ale#Escape('flake8') . ' --version', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', + \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', \] " The version check should be cached. GivenCommandOutput [] AssertLinter 'flake8', [ - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', + \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', \] " Try with older versions. @@ -29,13 +27,14 @@ Execute(The flake8 callbacks should return the correct default values): GivenCommandOutput ['2.9.9'] AssertLinter 'flake8', [ \ ale#Escape('flake8') . ' --version', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('flake8') . ' --format=default -', + \ ale#Escape('flake8') . ' --format=default -', \] Execute(The option for disabling changing directories should work): let g:ale_python_flake8_change_directory = 'off' + AssertLinterCwd ['', ''] + call ale#semver#ResetVersionCache() AssertLinter 'flake8', [ \ ale#Escape('flake8') . ' --version', \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', @@ -43,6 +42,7 @@ Execute(The option for disabling changing directories should work): let g:ale_python_flake8_change_directory = 0 + AssertLinterCwd [''] AssertLinter 'flake8', [ \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', \] @@ -50,6 +50,7 @@ Execute(The option for disabling changing directories should work): " Invalid options should be considered the same as turning the setting off. let g:ale_python_flake8_change_directory = 'xxx' + AssertLinterCwd [''] AssertLinter 'flake8', [ \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', \] @@ -57,10 +58,11 @@ Execute(The option for disabling changing directories should work): Execute(The option for changing directory to project root should work): silent execute 'file ' . fnameescape(g:dir . '/python_paths/namespace_package_tox/namespace/foo/bar.py') + AssertLinterCwd ale#python#FindProjectRootIni(bufnr('')) + call ale#semver#ResetVersionCache() AssertLinter 'flake8', [ \ ale#Escape('flake8') . ' --version', - \ ale#path#CdString(ale#python#FindProjectRootIni(bufnr(''))) - \ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', + \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', \] Execute(The option for changing directory to file dir should work): @@ -69,15 +71,13 @@ Execute(The option for changing directory to file dir should work): AssertLinter 'flake8', [ \ ale#Escape('flake8') . ' --version', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', + \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', \] let g:ale_python_flake8_change_directory = 1 AssertLinter 'flake8', [ - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', + \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', \] Execute(The flake8 command callback should let you set options): @@ -86,8 +86,7 @@ Execute(The flake8 command callback should let you set options): GivenCommandOutput ['3.0.4'] AssertLinter 'flake8', [ \ ale#Escape('flake8') . ' --version', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('flake8') . ' --some-option' + \ ale#Escape('flake8') . ' --some-option' \ . ' --format=default --stdin-display-name %s -', \] @@ -95,17 +94,17 @@ Execute(The flake8 command callback should let you set options): GivenCommandOutput ['2.9.9'] AssertLinter 'flake8', [ \ ale#Escape('flake8') . ' --version', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('flake8') . ' --some-option --format=default -', + \ ale#Escape('flake8') . ' --some-option --format=default -', \] Execute(You should be able to set a custom executable and it should be escaped): let g:ale_python_flake8_executable = 'executable with spaces' + AssertLinterCwd ['%s:h', '%s:h'] + call ale#semver#ResetVersionCache() AssertLinter 'executable with spaces', [ \ ale#Escape('executable with spaces') . ' --version', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('executable with spaces') + \ ale#Escape('executable with spaces') \ . ' --format=default' \ . ' --stdin-display-name %s -', \] @@ -119,8 +118,7 @@ Execute(The flake8 callbacks should detect virtualenv directories): AssertLinter b:executable, [ \ ale#Escape(b:executable) . ' --version', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape(b:executable) + \ ale#Escape(b:executable) \ . ' --format=default' \ . ' --stdin-display-name %s -', \] @@ -170,8 +168,7 @@ Execute(Using `python -m flake8` should be supported for running flake8): GivenCommandOutput ['2.9.9'] AssertLinter 'python', [ \ ale#Escape('python') . ' -m flake8 --version', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('python') + \ ale#Escape('python') \ . ' -m flake8 --some-option --format=default -' \] @@ -183,8 +180,7 @@ Execute(Using `python -m flake8` should be supported for running flake8): GivenCommandOutput ['2.9.9'] AssertLinter 'python', [ \ ale#Escape('python') . ' -m flake8 --version', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('python') + \ ale#Escape('python') \ . ' -m flake8 --some-option --format=default -' \] @@ -194,13 +190,12 @@ Execute(Setting executable to 'pipenv' should append 'run flake8'): " FIXME: pipenv should check the version with flake8. GivenCommandOutput [] AssertLinter 'path/to/pipenv', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('path/to/pipenv') . ' run flake8 --format=default -' + \ ale#Escape('path/to/pipenv') . ' run flake8 --format=default -' Execute(Pipenv is detected when python_flake8_auto_pipenv is set): let g:ale_python_flake8_auto_pipenv = 1 call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py') + AssertLinterCwd ale#python#FindProjectRootIni(bufnr('')) AssertLinter 'pipenv', - \ ale#path#CdString(ale#python#FindProjectRootIni(bufnr(''))) - \ . ale#Escape('pipenv') . ' run flake8 --format=default --stdin-display-name %s -' + \ ale#Escape('pipenv') . ' run flake8 --format=default --stdin-display-name %s -' diff --git a/test/command_callback/test_gobuild_command_callback.vader b/test/command_callback/test_gobuild_command_callback.vader index 063f3f2f..bac4d74e 100644 --- a/test/command_callback/test_gobuild_command_callback.vader +++ b/test/command_callback/test_gobuild_command_callback.vader @@ -9,33 +9,25 @@ After: Restore call ale#assert#TearDownLinterTest() -Execute(The default commands should be correct): - AssertLinter 'go', - \ ale#path#BufferCdString(bufnr('')) - \ . 'go test -c -o /dev/null ./' +Execute(The default command should be correct): + AssertLinterCwd '%s:h' + AssertLinter 'go', 'go test -c -o /dev/null ./' Execute(Go environment variables should be supported): let b:ale_go_go111module = 'on' - AssertLinter 'go', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Env('GO111MODULE', 'on') - \ . 'go test -c -o /dev/null ./' + AssertLinter 'go', ale#Env('GO111MODULE', 'on') . 'go test -c -o /dev/null ./' unlet! b:ale_go_go111module Execute(Extra options should be supported): let g:ale_go_gobuild_options = '--foo-bar' - AssertLinter 'go', - \ ale#path#BufferCdString(bufnr('')) - \ . 'go test --foo-bar -c -o /dev/null ./' + AssertLinter 'go', 'go test --foo-bar -c -o /dev/null ./' let g:ale_go_gobuild_options = '' Execute(The executable should be configurable): let g:ale_go_go_executable = 'foobar' - AssertLinter 'foobar', - \ ale#path#BufferCdString(bufnr('')) - \ . 'foobar test -c -o /dev/null ./' + AssertLinter 'foobar', 'foobar test -c -o /dev/null ./' diff --git a/test/command_callback/test_golangci_lint_command_callback.vader b/test/command_callback/test_golangci_lint_command_callback.vader index 37fb1f7d..ee754bba 100644 --- a/test/command_callback/test_golangci_lint_command_callback.vader +++ b/test/command_callback/test_golangci_lint_command_callback.vader @@ -12,9 +12,9 @@ After: call ale#assert#TearDownLinterTest() Execute(The golangci-lint defaults should be correct): + AssertLinterCwd '%s:h', AssertLinter 'golangci-lint', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('golangci-lint') + \ ale#Escape('golangci-lint') \ . ' run ' . ale#Escape(expand('%' . ':t')) \ . ' --enable-all' @@ -22,8 +22,7 @@ Execute(The golangci-lint callback should use a configured executable): let b:ale_go_golangci_lint_executable = 'something else' AssertLinter 'something else', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('something else') + \ ale#Escape('something else') \ . ' run ' . ale#Escape(expand('%' . ':t')) \ . ' --enable-all' @@ -31,8 +30,7 @@ Execute(The golangci-lint callback should use configured options): let b:ale_go_golangci_lint_options = '--foobar' AssertLinter 'golangci-lint', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('golangci-lint') + \ ale#Escape('golangci-lint') \ . ' run ' . ale#Escape(expand('%' . ':t')) \ . ' --foobar' @@ -40,8 +38,7 @@ Execute(The golangci-lint callback should support environment variables): let b:ale_go_go111module = 'on' AssertLinter 'golangci-lint', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Env('GO111MODULE', 'on') + \ ale#Env('GO111MODULE', 'on') \ . ale#Escape('golangci-lint') \ . ' run ' . ale#Escape(expand('%' . ':t')) \ . ' --enable-all' @@ -50,5 +47,4 @@ Execute(The golangci-lint `lint_package` option should use the correct command): let b:ale_go_golangci_lint_package = 1 AssertLinter 'golangci-lint', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('golangci-lint') . ' run --enable-all' + \ ale#Escape('golangci-lint') . ' run --enable-all' diff --git a/test/command_callback/test_gometalinter_command_callback.vader b/test/command_callback/test_gometalinter_command_callback.vader index 567997d8..5ff744f5 100644 --- a/test/command_callback/test_gometalinter_command_callback.vader +++ b/test/command_callback/test_gometalinter_command_callback.vader @@ -12,9 +12,9 @@ After: call ale#assert#TearDownLinterTest() Execute(The gometalinter defaults should be correct): + AssertLinterCwd '%s:h', AssertLinter 'gometalinter', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('gometalinter') + \ ale#Escape('gometalinter') \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t'))) \ . ' .' @@ -22,8 +22,7 @@ Execute(The gometalinter callback should use a configured executable): let b:ale_go_gometalinter_executable = 'something else' AssertLinter 'something else', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('something else') + \ ale#Escape('something else') \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t'))) \ . ' .' @@ -31,8 +30,7 @@ Execute(The gometalinter callback should use configured options): let b:ale_go_gometalinter_options = '--foobar' AssertLinter 'gometalinter', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('gometalinter') + \ ale#Escape('gometalinter') \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t'))) \ . ' --foobar' . ' .' @@ -40,8 +38,7 @@ Execute(The gometalinter should use configured environment variables): let b:ale_go_go111module = 'off' AssertLinter 'gometalinter', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Env('GO111MODULE', 'off') + \ ale#Env('GO111MODULE', 'off') \ . ale#Escape('gometalinter') \ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t'))) \ . ' .' @@ -49,6 +46,4 @@ Execute(The gometalinter should use configured environment variables): Execute(The gometalinter `lint_package` option should use the correct command): let b:ale_go_gometalinter_lint_package = 1 - AssertLinter 'gometalinter', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('gometalinter') . ' .' + AssertLinter 'gometalinter', ale#Escape('gometalinter') . ' .' diff --git a/test/command_callback/test_gosimple_command_callback.vader b/test/command_callback/test_gosimple_command_callback.vader index b006f783..7206722f 100644 --- a/test/command_callback/test_gosimple_command_callback.vader +++ b/test/command_callback/test_gosimple_command_callback.vader @@ -10,13 +10,10 @@ After: call ale#assert#TearDownLinterTest() Execute(The default gosimple command should be correct): - AssertLinter 'gosimple', - \ ale#path#BufferCdString(bufnr('')) - \ . ' gosimple .' + AssertLinterCwd '%s:h' + AssertLinter 'gosimple', 'gosimple .' Execute(The gosimple command should support Go environment variables): let b:ale_go_go111module = 'on' - AssertLinter 'gosimple', - \ ale#path#BufferCdString(bufnr('')) - \ . ' ' . ale#Env('GO111MODULE', 'on') . 'gosimple .' + AssertLinter 'gosimple', ale#Env('GO111MODULE', 'on') . 'gosimple .' diff --git a/test/command_callback/test_gotype_command_callback.vader b/test/command_callback/test_gotype_command_callback.vader index 204197d9..47845dd6 100644 --- a/test/command_callback/test_gotype_command_callback.vader +++ b/test/command_callback/test_gotype_command_callback.vader @@ -10,19 +10,15 @@ After: call ale#assert#TearDownLinterTest() Execute(The default gotype command should be correct): - AssertLinter 'gotype', - \ ale#path#BufferCdString(bufnr('')) - \ . ' gotype -e .' + AssertLinterCwd '%s:h' + AssertLinter 'gotype', 'gotype -e .' Execute(The gotype callback should ignore test files): call ale#test#SetFilename('bla_test.go') - AssertLinter 'gotype', '' + AssertLinterNotExecuted Execute(The gotype callback should support Go environment variables): let b:ale_go_go111module = 'on' - AssertLinter 'gotype', - \ ale#path#BufferCdString(bufnr('')) - \ . ' ' . ale#Env('GO111MODULE', 'on') - \ . 'gotype -e .' + AssertLinter 'gotype', ale#Env('GO111MODULE', 'on') . 'gotype -e .' diff --git a/test/command_callback/test_govet_command_callback.vader b/test/command_callback/test_govet_command_callback.vader index 0e1ea092..12ec168a 100644 --- a/test/command_callback/test_govet_command_callback.vader +++ b/test/command_callback/test_govet_command_callback.vader @@ -13,22 +13,20 @@ After: call ale#assert#TearDownLinterTest() Execute(The default command should be correct): - AssertLinter 'go', ale#path#BufferCdString(bufnr('')) . ' go vet .' + AssertLinter 'go', 'go vet .' Execute(Extra options should be supported): let g:ale_go_govet_options = '--foo-bar' - AssertLinter 'go', ale#path#BufferCdString(bufnr('')) . ' go vet --foo-bar .' + AssertLinterCwd '%s:h' + AssertLinter 'go', 'go vet --foo-bar .' Execute(The executable should be configurable): let g:ale_go_go_executable = 'foobar' - AssertLinter 'foobar', ale#path#BufferCdString(bufnr('')) . ' foobar vet .' + AssertLinter 'foobar', 'foobar vet .' Execute(Go environment variables should be supported): let b:ale_go_go111module = 'on' - AssertLinter 'go', - \ ale#path#BufferCdString(bufnr('')) . ' ' - \ . ale#Env('GO111MODULE', 'on') - \ . 'go vet .' + AssertLinter 'go', ale#Env('GO111MODULE', 'on') . 'go vet .' diff --git a/test/command_callback/test_graphql_gqlint_command_callbacks.vader b/test/command_callback/test_graphql_gqlint_command_callbacks.vader index e8ed0e5d..22c05a6a 100644 --- a/test/command_callback/test_graphql_gqlint_command_callbacks.vader +++ b/test/command_callback/test_graphql_gqlint_command_callbacks.vader @@ -5,7 +5,5 @@ After: call ale#assert#TearDownLinterTest() Execute(The linter should run from the directory of the file in the buffer): - AssertLinter 'gqlint', - \ ale#path#BufferCdString(bufnr('')) - \ . 'gqlint --reporter=simple' - \ . ' %t' + AssertLinterCwd '%s:h' + AssertLinter 'gqlint', 'gqlint --reporter=simple %t' diff --git a/test/command_callback/test_haskell_cabal_ghc_command_callbacks.vader b/test/command_callback/test_haskell_cabal_ghc_command_callbacks.vader index 9e3712d6..b4976b34 100644 --- a/test/command_callback/test_haskell_cabal_ghc_command_callbacks.vader +++ b/test/command_callback/test_haskell_cabal_ghc_command_callbacks.vader @@ -1,23 +1,13 @@ Before: - Save g:ale_haskell_cabal_ghc_options - - unlet! g:ale_haskell_cabal_ghc_options - unlet! b:ale_haskell_cabal_ghc_options - - runtime ale_linters/haskell/cabal_ghc.vim + call ale#assert#SetUpLinterTest('haskell', 'cabal_ghc') After: - Restore - unlet! b:ale_haskell_cabal_ghc_options - call ale#linter#Reset() + call ale#assert#TearDownLinterTest() Execute(The options should be used in the command): - AssertEqual - \ ale#path#BufferCdString(bufnr('')) . 'cabal exec -- ghc -fno-code -v0 %t', - \ ale_linters#haskell#cabal_ghc#GetCommand(bufnr('')) + AssertLinterCwd '%s:h' + AssertLinter 'cabal', 'cabal exec -- ghc -fno-code -v0 %t' let b:ale_haskell_cabal_ghc_options = 'foobar' - AssertEqual - \ ale#path#BufferCdString(bufnr('')) . 'cabal exec -- ghc foobar %t', - \ ale_linters#haskell#cabal_ghc#GetCommand(bufnr('')) + AssertLinter 'cabal', 'cabal exec -- ghc foobar %t' diff --git a/test/command_callback/test_haskell_stack_ghc_command_callback.vader b/test/command_callback/test_haskell_stack_ghc_command_callback.vader index aa13fb2b..8b5e7485 100644 --- a/test/command_callback/test_haskell_stack_ghc_command_callback.vader +++ b/test/command_callback/test_haskell_stack_ghc_command_callback.vader @@ -10,8 +10,9 @@ Execute(The linter should not be executed when there's no stack.yaml file): Execute(The linter should be executed when there is a stack.yaml file): call ale#test#SetFilename('stack_ghc_paths/test.hs') - AssertLinter 'stack', ale#path#BufferCdString(bufnr('')) . 'stack ghc -- -fno-code -v0 %t' + AssertLinterCwd '%s:h' + AssertLinter 'stack', 'stack ghc -- -fno-code -v0 %t' let b:ale_haskell_stack_ghc_options = 'foobar' - AssertLinter 'stack', ale#path#BufferCdString(bufnr('')) . 'stack ghc -- foobar %t' + AssertLinter 'stack', 'stack ghc -- foobar %t' diff --git a/test/command_callback/test_javac_command_callback.vader b/test/command_callback/test_javac_command_callback.vader index ac898e5f..29ed09b8 100644 --- a/test/command_callback/test_javac_command_callback.vader +++ b/test/command_callback/test_javac_command_callback.vader @@ -3,8 +3,7 @@ Before: call ale#test#SetFilename('dummy.java') let g:cp_sep = has('unix') ? ':' : ';' - let g:prefix = ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('javac') . ' -Xlint' + let g:prefix = ale#Escape('javac') . ' -Xlint' function! GetCommand(previous_output) abort let l:command = ale_linters#java#javac#GetCommand( @@ -29,6 +28,7 @@ After: call ale#assert#TearDownLinterTest() Execute(The javac callback should return the correct default value): + AssertLinterCwd '%s:h' AssertLinter 'javac', g:prefix . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' Execute(The javac callback should use string type g:ale_java_javac_classpath correctly): @@ -51,8 +51,7 @@ Execute(The executable should be configurable): let g:ale_java_javac_executable = 'foobar' AssertLinter 'foobar', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('foobar') . ' -Xlint' + \ ale#Escape('foobar') . ' -Xlint' \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' Execute(The javac callback should include discovered classpaths): @@ -197,8 +196,7 @@ Execute(The javac callback should combine discovered sourcepath and manual ones) let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {}) AssertEqual - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('javac') . ' -Xlint' + \ ale#Escape('javac') . ' -Xlint' \ . ' -sourcepath ' . ale#Escape(join([ \ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'), \ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/'), @@ -211,8 +209,7 @@ Execute(The javac callback should combine discovered sourcepath and manual ones) let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {}) AssertEqual - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('javac') . ' -Xlint' + \ ale#Escape('javac') . ' -Xlint' \ . ' -sourcepath ' . ale#Escape(join([ \ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'), \ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/'), @@ -225,8 +222,7 @@ Execute(The javac callback should combine discovered sourcepath and manual ones) let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {}) AssertEqual - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('javac') . ' -Xlint' + \ ale#Escape('javac') . ' -Xlint' \ . ' -sourcepath ' . ale#Escape(join([ \ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'), \ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/') @@ -241,8 +237,7 @@ Execute(The javac callback should combine discovered sourcepath and manual ones) let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {}) AssertEqual - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('javac') . ' -Xlint' + \ ale#Escape('javac') . ' -Xlint' \ . ' -sourcepath ' . ale#Escape(join([ \ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'), \ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/'), @@ -257,8 +252,7 @@ Execute(The javac callback should detect source directories): call ale#engine#InitBufferInfo(bufnr('')) AssertLinter 'javac', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('javac') . ' -Xlint' + \ ale#Escape('javac') . ' -Xlint' \ . ' -sourcepath ' . ale#Escape( \ ale#path#Simplify(g:dir . '/java_paths/src/main/java/') \ ) @@ -277,8 +271,7 @@ Execute(The javac callback should combine detected source directories and classp \], {}) AssertEqual - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('javac') . ' -Xlint' + \ ale#Escape('javac') . ' -Xlint' \ . ' -cp ' . ale#Escape(join(['/foo/bar.jar', '/xyz/abc.jar'], g:cp_sep)) \ . ' -sourcepath ' . ale#Escape( \ ale#path#Simplify(g:dir . '/java_paths/src/main/java/') @@ -300,8 +293,7 @@ Execute(The javac callback should include src/test/java for test paths): call ale#engine#InitBufferInfo(bufnr('')) AssertLinter 'javac', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('javac') . ' -Xlint' + \ ale#Escape('javac') . ' -Xlint' \ . ' -sourcepath ' . ale#Escape(join([ \ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'), \ ale#path#Simplify(g:dir . '/java_paths/src/test/java/'), @@ -314,8 +306,7 @@ Execute(The javac callback should include src/main/jaxb when available): call ale#engine#InitBufferInfo(bufnr('')) AssertLinter 'javac', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('javac') . ' -Xlint' + \ ale#Escape('javac') . ' -Xlint' \ . ' -sourcepath ' . ale#Escape(join([ \ ale#path#Simplify(g:dir . '/java_paths_with_jaxb/src/main/java/'), \ ale#path#Simplify(g:dir . '/java_paths_with_jaxb/src/main/jaxb/'), @@ -328,8 +319,7 @@ Execute(The javac callback should add -sourcepath even if src/java/main doesn't call ale#engine#InitBufferInfo(bufnr('')) AssertLinter 'javac', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('javac') . ' -Xlint' + \ ale#Escape('javac') . ' -Xlint' \ . ' -sourcepath ' . ale#Escape(join([ \ ale#path#Simplify(g:dir . '/java_paths_no_main/src/test/java/'), \ ], g:cp_sep)) diff --git a/test/command_callback/test_lintr_command_callback.vader b/test/command_callback/test_lintr_command_callback.vader index ac4b419b..a2791c4d 100644 --- a/test/command_callback/test_lintr_command_callback.vader +++ b/test/command_callback/test_lintr_command_callback.vader @@ -5,9 +5,9 @@ After: call ale#assert#TearDownLinterTest() Execute(The default lintr command should be correct): + AssertLinterCwd '%s:h' AssertLinter 'Rscript', - \ ale#path#BufferCdString(bufnr('')) - \ . 'Rscript --vanilla -e ' + \ 'Rscript --vanilla -e ' \ . ale#Escape('suppressPackageStartupMessages(library(lintr));' \ . 'lint(cache = FALSE, commandArgs(TRUE), ' \ . 'with_defaults())') @@ -17,8 +17,7 @@ Execute(The lintr options should be configurable): let b:ale_r_lintr_options = 'with_defaults(object_usage_linter = NULL)' AssertLinter 'Rscript', - \ ale#path#BufferCdString(bufnr('')) - \ . 'Rscript --vanilla -e ' + \ 'Rscript --vanilla -e ' \ . ale#Escape('suppressPackageStartupMessages(library(lintr));' \ . 'lint(cache = FALSE, commandArgs(TRUE), ' \ . 'with_defaults(object_usage_linter = NULL))') @@ -28,8 +27,7 @@ Execute(If the lint_package flag is set, lintr::lint_package should be called): let b:ale_r_lintr_lint_package = 1 AssertLinter 'Rscript', - \ ale#path#BufferCdString(bufnr('')) - \ . 'Rscript --vanilla -e ' + \ 'Rscript --vanilla -e ' \ . ale#Escape('suppressPackageStartupMessages(library(lintr));' \ . 'lint_package(cache = FALSE, ' \ . 'linters = with_defaults())') diff --git a/test/command_callback/test_mercury_mmc_command_callback.vader b/test/command_callback/test_mercury_mmc_command_callback.vader index ab61fddf..5ab5e74f 100644 --- a/test/command_callback/test_mercury_mmc_command_callback.vader +++ b/test/command_callback/test_mercury_mmc_command_callback.vader @@ -1,25 +1,22 @@ Before: call ale#assert#SetUpLinterTest('mercury', 'mmc') - call ale#test#SetFilename('dummy') After: call ale#assert#TearDownLinterTest() Execute(The default command should be correct): + AssertLinterCwd '%s:h' AssertLinter 'mmc', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('mmc') . ' --errorcheck-only --make --output-compile-error-lines 100 dummy' + \ ale#Escape('mmc') . ' --errorcheck-only --make --output-compile-error-lines 100 %s:t:r' Execute(The executable should be configurable): let b:ale_mercury_mmc_executable = 'foo' AssertLinter 'foo', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('foo') . ' --errorcheck-only --make --output-compile-error-lines 100 dummy' + \ ale#Escape('foo') . ' --errorcheck-only --make --output-compile-error-lines 100 %s:t:r' Execute(The options should be configurable): let b:ale_mercury_mmc_options = '--bar' AssertLinter 'mmc', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('mmc') . ' --errorcheck-only --bar dummy' + \ ale#Escape('mmc') . ' --errorcheck-only --bar %s:t:r' diff --git a/test/command_callback/test_mypy_command_callback.vader b/test/command_callback/test_mypy_command_callback.vader index 3a26373f..1a0f5301 100644 --- a/test/command_callback/test_mypy_command_callback.vader +++ b/test/command_callback/test_mypy_command_callback.vader @@ -11,8 +11,9 @@ After: call ale#assert#TearDownLinterTest() Execute(The mypy callbacks should return the correct default values): + AssertLinterCwd g:dir AssertLinter 'mypy', - \ ale#path#CdString(g:dir) . ale#Escape('mypy') + \ ale#Escape('mypy') \ . ' --show-column-numbers' \ . ' --shadow-file %s %t %s' @@ -20,7 +21,7 @@ Execute(The mypy executable should be configurable, and escaped properly): let g:ale_python_mypy_executable = 'executable with spaces' AssertLinter 'executable with spaces', - \ ale#path#CdString(g:dir) . ale#Escape('executable with spaces') + \ ale#Escape('executable with spaces') \ . ' --show-column-numbers' \ . ' --shadow-file %s %t %s' @@ -28,62 +29,62 @@ Execute(The mypy command callback should let you set options): let g:ale_python_mypy_options = '--some-option' AssertLinter 'mypy', - \ ale#path#CdString(g:dir) . ale#Escape('mypy') + \ ale#Escape('mypy') \ . ' --some-option' \ . ' --show-column-numbers' \ . ' --shadow-file %s %t %s' Execute(The mypy command should switch directories to the detected project root): - silent execute 'file ' . fnameescape(g:dir . '/python_paths/no_virtualenv/subdir/foo/bar.py') + call ale#test#SetFilename('python_paths/no_virtualenv/subdir/foo/bar.py') + AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir') AssertLinter 'mypy', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir')) - \ . ale#Escape('mypy') + \ ale#Escape('mypy') \ . ' --show-column-numbers' \ . ' --shadow-file %s %t %s' Execute(The mypy callbacks should detect virtualenv directories and switch to the project root): - silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') + call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py') let b:executable = ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/mypy') + AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir') AssertLinter b:executable, - \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')) - \ . ale#Escape(b:executable) + \ ale#Escape(b:executable) \ . ' --show-column-numbers' \ . ' --shadow-file %s %t %s' Execute(The mypy callbacks should cd to directory containing mypy.ini if found): - silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_mypy_ini_and_pytest_ini/tests/testsubfolder/my_tests.py') + call ale#test#SetFilename('python_paths/with_mypy_ini_and_pytest_ini/tests/testsubfolder/my_tests.py') + AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/with_mypy_ini_and_pytest_ini') AssertLinter 'mypy', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_mypy_ini_and_pytest_ini')) - \ . ale#Escape('mypy') + \ ale#Escape('mypy') \ . ' --show-column-numbers' \ . ' --shadow-file %s %t %s' Execute(You should able able to use the global mypy instead): - silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') + call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py') let g:ale_python_mypy_use_global = 1 + AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir') AssertLinter 'mypy', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')) - \ . ale#Escape('mypy') + \ ale#Escape('mypy') \ . ' --show-column-numbers' \ . ' --shadow-file %s %t %s' Execute(Setting executable to 'pipenv' appends 'run mypy'): let g:ale_python_mypy_executable = 'path/to/pipenv' + AssertLinterCwd expand('#' . bufnr('') . ':p:h') AssertLinter 'path/to/pipenv', - \ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) - \ . ale#Escape('path/to/pipenv') . ' run mypy' + \ ale#Escape('path/to/pipenv') . ' run mypy' \ . ' --show-column-numbers --shadow-file %s %t %s' Execute(Pipenv is detected when python_mypy_auto_pipenv is set): - let g:ale_python_mypy_auto_pipenv = 1 call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py') + let g:ale_python_mypy_auto_pipenv = 1 + AssertLinterCwd expand('#' . bufnr('') . ':p:h') AssertLinter 'pipenv', - \ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) - \ . ale#Escape('pipenv') . ' run mypy --show-column-numbers --shadow-file %s %t %s' + \ ale#Escape('pipenv') . ' run mypy --show-column-numbers --shadow-file %s %t %s' diff --git a/test/command_callback/test_phpcs_command_callback.vader b/test/command_callback/test_phpcs_command_callback.vader index 48a599e4..35d59777 100644 --- a/test/command_callback/test_phpcs_command_callback.vader +++ b/test/command_callback/test_phpcs_command_callback.vader @@ -11,8 +11,8 @@ Execute(The local phpcs executable should be used): let g:executable = ale#path#Simplify(g:dir . '/../phpcs-test-files/project-with-phpcs/vendor/bin/phpcs') - AssertLinter g:executable, ale#path#BufferCdString(bufnr('')) - \ . ale#Escape(g:executable) + AssertLinterCwd '%s:h' + AssertLinter g:executable, ale#Escape(g:executable) \ . ' -s --report=emacs --stdin-path=%s' Execute(use_global should override local executable detection): @@ -20,27 +20,23 @@ Execute(use_global should override local executable detection): call ale#test#SetFilename('../phpcs-test-files/project-with-phpcs/foo/test.php') - AssertLinter 'phpcs', ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('phpcs') + AssertLinter 'phpcs', ale#Escape('phpcs') \ . ' -s --report=emacs --stdin-path=%s' Execute(Projects without local executables should use the global one): call ale#test#SetFilename('../phpcs-test-files/project-without-phpcs/foo/test.php') - AssertLinter 'phpcs', ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('phpcs') + AssertLinter 'phpcs', ale#Escape('phpcs') \ . ' -s --report=emacs --stdin-path=%s' Execute(User provided options should be used): let g:ale_php_phpcs_options = '--my-user-provided-option my-value' - AssertLinter 'phpcs', ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('phpcs') + AssertLinter 'phpcs', ale#Escape('phpcs') \ . ' -s --report=emacs --stdin-path=%s --my-user-provided-option my-value' Execute(The _standard option should be used): let g:ale_php_phpcs_standard = 'foobar' - AssertLinter 'phpcs', ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('phpcs') + AssertLinter 'phpcs', ale#Escape('phpcs') \ . ' -s --report=emacs --stdin-path=%s --standard=' . ale#Escape('foobar') diff --git a/test/command_callback/test_pydocstyle_command_callback.vader b/test/command_callback/test_pydocstyle_command_callback.vader index 511443a6..0a69c79a 100644 --- a/test/command_callback/test_pydocstyle_command_callback.vader +++ b/test/command_callback/test_pydocstyle_command_callback.vader @@ -6,35 +6,28 @@ After: call ale#assert#TearDownLinterTest() Execute(The pydocstyle command callback should return default string): - AssertLinter 'pydocstyle', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('pydocstyle') . ' %s:t' + AssertLinterCwd '%s:h' + AssertLinter 'pydocstyle', ale#Escape('pydocstyle') . ' %s:t' Execute(The pydocstyle command callback should allow options): let g:ale_python_pydocstyle_options = '--verbose' - AssertLinter 'pydocstyle', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('pydocstyle') . ' --verbose %s:t' + AssertLinter 'pydocstyle', ale#Escape('pydocstyle') . ' --verbose %s:t' Execute(The pydocstyle executable should be configurable): let g:ale_python_pydocstyle_executable = '~/.local/bin/pydocstyle' AssertLinter '~/.local/bin/pydocstyle', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('~/.local/bin/pydocstyle') . ' %s:t' + \ ale#Escape('~/.local/bin/pydocstyle') . ' %s:t' Execute(Setting executable to 'pipenv' appends 'run pydocstyle'): let g:ale_python_pydocstyle_executable = 'path/to/pipenv' AssertLinter 'path/to/pipenv', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('path/to/pipenv') . ' run pydocstyle %s:t' + \ ale#Escape('path/to/pipenv') . ' run pydocstyle %s:t' Execute(Pipenv is detected when python_pydocstyle_auto_pipenv is set): let g:ale_python_pydocstyle_auto_pipenv = 1 call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py') - AssertLinter 'pipenv', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('pipenv') . ' run pydocstyle %s:t' + AssertLinter 'pipenv', ale#Escape('pipenv') . ' run pydocstyle %s:t' diff --git a/test/command_callback/test_pylama_command_callback.vader b/test/command_callback/test_pylama_command_callback.vader index 0aea9a93..7f15bf4f 100644 --- a/test/command_callback/test_pylama_command_callback.vader +++ b/test/command_callback/test_pylama_command_callback.vader @@ -12,74 +12,65 @@ After: call ale#assert#TearDownLinterTest() -Execute(The pylama command callback should return a default): - AssertLinter 'pylama', - \ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) - \ . ale#Escape('pylama') . b:command_tail +Execute(The default pylama command should be correct): + AssertLinterCwd ale#path#Simplify(g:dir) + AssertLinter 'pylama', ale#Escape('pylama') . b:command_tail Execute(The option for disabling changing directories should work): let g:ale_python_pylama_change_directory = 0 + AssertLinterCwd '' AssertLinter 'pylama', ale#Escape('pylama') . b:command_tail Execute(The pylama executable should be configurable, and escaped properly): let g:ale_python_pylama_executable = 'executable with spaces' + AssertLinterCwd ale#path#Simplify(g:dir) AssertLinter 'executable with spaces', - \ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) - \ . ale#Escape('executable with spaces') . b:command_tail + \ ale#Escape('executable with spaces') . b:command_tail Execute(The pylama command callback should let you set options): let g:ale_python_pylama_options = '--some-option' - AssertLinter 'pylama', - \ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) - \ . ale#Escape('pylama') . ' --some-option' . b:command_tail + AssertLinterCwd ale#path#Simplify(g:dir) + AssertLinter 'pylama', ale#Escape('pylama') . ' --some-option' . b:command_tail Execute(The pylama command callback should switch directories to the detected project root): silent execute 'file ' . fnameescape(g:dir . '/python_paths/no_virtualenv/subdir/foo/bar.py') - AssertLinter 'pylama', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir')) - \ . ale#Escape('pylama') . b:command_tail + AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir') + AssertLinter 'pylama', ale#Escape('pylama') . b:command_tail Execute(The pylama command callback shouldn't detect virtualenv directories where they don't exist): - silent execute 'file ' . fnameescape(g:dir . '/python_paths/no_virtualenv/subdir/foo/bar.py') + call ale#test#SetFilename('python_paths/no_virtualenv/subdir/foo/bar.py') - AssertLinter 'pylama', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir')) - \ . ale#Escape('pylama') . b:command_tail + AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir') + AssertLinter 'pylama', ale#Escape('pylama') . b:command_tail Execute(The pylama command callback should detect virtualenv directories and switch to the project root): - silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') - + call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py') let b:executable = ale#path#Simplify( \ g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/pylama' \) - AssertLinter b:executable, - \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')) - \ . ale#Escape(b:executable) . b:command_tail + AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir') + AssertLinter b:executable, ale#Escape(b:executable) . b:command_tail Execute(You should able able to use the global pylama instead): - silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') + call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py') let g:ale_python_pylama_use_global = 1 - AssertLinter 'pylama', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')) - \ . ale#Escape('pylama') . b:command_tail + AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir') + AssertLinter 'pylama', ale#Escape('pylama') . b:command_tail Execute(Setting executable to 'pipenv' appends 'run pylama'): let g:ale_python_pylama_executable = 'path/to/pipenv' AssertLinter 'path/to/pipenv', - \ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) - \ . ale#Escape('path/to/pipenv') . ' run pylama' . b:command_tail + \ ale#Escape('path/to/pipenv') . ' run pylama' . b:command_tail Execute(Pipenv is detected when python_pylama_auto_pipenv is set): let g:ale_python_pylama_auto_pipenv = 1 call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py') - AssertLinter 'pipenv', - \ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) - \ . ale#Escape('pipenv') . ' run pylama' . b:command_tail + AssertLinter 'pipenv', ale#Escape('pipenv') . ' run pylama' . b:command_tail diff --git a/test/command_callback/test_pylint_command_callback.vader b/test/command_callback/test_pylint_command_callback.vader index 15f004b6..4b9a14a5 100644 --- a/test/command_callback/test_pylint_command_callback.vader +++ b/test/command_callback/test_pylint_command_callback.vader @@ -18,75 +18,64 @@ After: call ale#assert#TearDownLinterTest() Execute(The pylint callbacks should return the correct default values): - AssertLinter 'pylint', - \ ale#path#CdString(expand('%:p:h')) - \ . ale#Escape('pylint') . b:command_tail + AssertLinterCwd expand('%:p:h') + AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail Execute(Pylint should run with the --from-stdin in new enough versions): GivenCommandOutput ['pylint 2.4.0'] - AssertLinter 'pylint', - \ ale#path#CdString(expand('%:p:h')) - \ . ale#Escape('pylint') . b:command_tail[:-3] . '--from-stdin %s' + AssertLinterCwd expand('%:p:h') + AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail[:-3] . '--from-stdin %s' Execute(The option for disabling changing directories should work): let g:ale_python_pylint_change_directory = 0 + AssertLinterCwd '' AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail Execute(The pylint executable should be configurable, and escaped properly): let g:ale_python_pylint_executable = 'executable with spaces' - AssertLinter 'executable with spaces', - \ ale#path#CdString(expand('%:p:h')) - \ . ale#Escape('executable with spaces') . b:command_tail + AssertLinter 'executable with spaces', ale#Escape('executable with spaces') . b:command_tail Execute(The pylint command callback should let you set options): let g:ale_python_pylint_options = '--some-option' - AssertLinter 'pylint', - \ ale#path#CdString(expand('%:p:h')) - \ . ale#Escape('pylint') . ' --some-option' . b:command_tail + AssertLinter 'pylint', ale#Escape('pylint') . ' --some-option' . b:command_tail Execute(The pylint callbacks shouldn't detect virtualenv directories where they don't exist): - silent execute 'file ' . fnameescape(g:dir . '/python_paths/no_virtualenv/subdir/foo/bar.py') + call ale#test#SetFilename('python_paths/no_virtualenv/subdir/foo/bar.py') - AssertLinter 'pylint', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir')) - \ . ale#Escape('pylint') . b:command_tail + AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir') + AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail Execute(The pylint callbacks should detect virtualenv directories): - silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') - + call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py') let b:executable = ale#path#Simplify( \ g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/pylint' \) - AssertLinter b:executable, - \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')) - \ . ale#Escape(b:executable) . b:command_tail + AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir') + AssertLinter b:executable, ale#Escape(b:executable) . b:command_tail Execute(You should able able to use the global pylint instead): - silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') + call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py') let g:ale_python_pylint_use_global = 1 - AssertLinter 'pylint', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')) - \ . ale#Escape('pylint') . b:command_tail + AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir') + AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail Execute(Setting executable to 'pipenv' appends 'run pylint'): let g:ale_python_pylint_executable = 'path/to/pipenv' + let g:ale_python_pylint_use_global = 1 - AssertLinter 'path/to/pipenv', - \ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) - \ . ale#Escape('path/to/pipenv') . ' run pylint' + AssertLinter 'path/to/pipenv', ale#Escape('path/to/pipenv') . ' run pylint' \ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s' Execute(Pipenv is detected when python_pylint_auto_pipenv is set): let g:ale_python_pylint_auto_pipenv = 1 call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py') - AssertLinter 'pipenv', - \ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) - \ . ale#Escape('pipenv') . ' run pylint' + AssertLinterCwd expand('%:p:h') + AssertLinter 'pipenv', ale#Escape('pipenv') . ' run pylint' \ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s' diff --git a/test/command_callback/test_ruby_command_callback.vader b/test/command_callback/test_ruby_command_callback.vader index d957079d..b6bac14f 100644 --- a/test/command_callback/test_ruby_command_callback.vader +++ b/test/command_callback/test_ruby_command_callback.vader @@ -5,9 +5,9 @@ After: call ale#assert#TearDownLinterTest() Execute(The default command should be correct): - AssertLinter 'ruby', ale#Escape('ruby') . ' -w -c %t' + AssertLinter 'ruby', ale#Escape('ruby') . ' -w -c -T1 %t' Execute(The executable should be configurable): let g:ale_ruby_ruby_executable = 'foobar' - AssertLinter 'foobar', ale#Escape('foobar') . ' -w -c %t' + AssertLinter 'foobar', ale#Escape('foobar') . ' -w -c -T1 %t' diff --git a/test/command_callback/test_shellcheck_command_callback.vader b/test/command_callback/test_shellcheck_command_callback.vader index 9fb5303a..40995755 100644 --- a/test/command_callback/test_shellcheck_command_callback.vader +++ b/test/command_callback/test_shellcheck_command_callback.vader @@ -2,67 +2,63 @@ Before: call ale#assert#SetUpLinterTest('sh', 'shellcheck') call ale#test#SetFilename('test.sh') - let b:prefix = ale#path#BufferCdString(bufnr('')) let b:suffix = ' -f gcc -' After: unlet! b:is_bash - unlet! b:prefix unlet! b:suffix call ale#assert#TearDownLinterTest() Execute(The default shellcheck command should be correct): - AssertLinter 'shellcheck', b:prefix . ale#Escape('shellcheck') . b:suffix + AssertLinterCwd '%s:h' + AssertLinter 'shellcheck', ale#Escape('shellcheck') . b:suffix Execute(The option disabling changing directories should work): let g:ale_sh_shellcheck_change_directory = 0 + AssertLinterCwd '' AssertLinter 'shellcheck', ale#Escape('shellcheck') . b:suffix Execute(The shellcheck command should accept options): let b:ale_sh_shellcheck_options = '--foobar' - AssertLinter 'shellcheck', - \ b:prefix . ale#Escape('shellcheck') . ' --foobar' . b:suffix + AssertLinter 'shellcheck', ale#Escape('shellcheck') . ' --foobar' . b:suffix Execute(The shellcheck command should accept options and exclusions): let b:ale_sh_shellcheck_options = '--foobar' let b:ale_sh_shellcheck_exclusions = 'foo,bar' AssertLinter 'shellcheck', - \ b:prefix . ale#Escape('shellcheck') . ' --foobar -e foo,bar' . b:suffix + \ ale#Escape('shellcheck') . ' --foobar -e foo,bar' . b:suffix Execute(The shellcheck command should include the dialect): let b:is_bash = 1 - AssertLinter 'shellcheck', - \ b:prefix . ale#Escape('shellcheck') . ' -s bash' . b:suffix + AssertLinter 'shellcheck', ale#Escape('shellcheck') . ' -s bash' . b:suffix Execute(The shellcheck command should use ale_sh_shellcheck_dialect): let b:ale_sh_shellcheck_dialect = 'ksh93' - AssertLinter 'shellcheck', - \ b:prefix . ale#Escape('shellcheck') . ' -s ksh93' . b:suffix + AssertLinter 'shellcheck', ale#Escape('shellcheck') . ' -s ksh93' . b:suffix Execute(The shellcheck command should allow unspecified dialect): let b:ale_sh_shellcheck_dialect = '' - AssertLinter 'shellcheck', - \ b:prefix . ale#Escape('shellcheck') . b:suffix + AssertLinter 'shellcheck', ale#Escape('shellcheck') . b:suffix Execute(The shellcheck command should include the dialect before options and exclusions): let b:is_bash = 1 let b:ale_sh_shellcheck_options = '--foobar' let b:ale_sh_shellcheck_exclusions = 'foo,bar' - AssertLinter 'shellcheck', b:prefix . ale#Escape('shellcheck') + AssertLinter 'shellcheck', ale#Escape('shellcheck') \ . ' -s bash --foobar -e foo,bar' \ . b:suffix Execute(The -x option should be added when the version is new enough): AssertLinter 'shellcheck', [ \ ale#Escape('shellcheck') . ' --version', - \ b:prefix . ale#Escape('shellcheck') . b:suffix, + \ ale#Escape('shellcheck') . b:suffix, \] GivenCommandOutput [ @@ -73,13 +69,13 @@ Execute(The -x option should be added when the version is new enough): \] AssertLinter 'shellcheck', [ \ ale#Escape('shellcheck') . ' --version', - \ b:prefix . ale#Escape('shellcheck') . ' -x' . b:suffix, + \ ale#Escape('shellcheck') . ' -x' . b:suffix, \] " We should cache the version check GivenCommandOutput [] AssertLinter 'shellcheck', [ - \ b:prefix . ale#Escape('shellcheck') . ' -x' . b:suffix, + \ ale#Escape('shellcheck') . ' -x' . b:suffix, \] Execute(The -x option should not be added when the version is too old): @@ -91,7 +87,7 @@ Execute(The -x option should not be added when the version is too old): \] AssertLinter 'shellcheck', [ \ ale#Escape('shellcheck') . ' --version', - \ b:prefix . ale#Escape('shellcheck') . b:suffix, + \ ale#Escape('shellcheck') . b:suffix, \] Execute(The version check shouldn't be run again for old versions): @@ -103,8 +99,8 @@ Execute(The version check shouldn't be run again for old versions): \] AssertLinter 'shellcheck', [ \ ale#Escape('shellcheck') . ' --version', - \ b:prefix . ale#Escape('shellcheck') . b:suffix, + \ ale#Escape('shellcheck') . b:suffix, \] AssertLinter 'shellcheck', [ - \ b:prefix . ale#Escape('shellcheck') . b:suffix, + \ ale#Escape('shellcheck') . b:suffix, \] diff --git a/test/command_callback/test_staticcheck_command_callback.vader b/test/command_callback/test_staticcheck_command_callback.vader index 871a5510..993d9491 100644 --- a/test/command_callback/test_staticcheck_command_callback.vader +++ b/test/command_callback/test_staticcheck_command_callback.vader @@ -10,39 +10,26 @@ After: call ale#assert#TearDownLinterTest() Execute(The staticcheck callback should return the right defaults): - AssertLinter 'staticcheck', - \ ale#path#BufferCdString(bufnr('')) - \ . 'staticcheck ' - \ . ale#Escape(expand('%' . ':t')) + AssertLinterCwd '%s:h' + AssertLinter 'staticcheck', 'staticcheck %s:t' Execute(The staticcheck callback should use configured options): let b:ale_go_staticcheck_options = '-test' - AssertLinter 'staticcheck', - \ ale#path#BufferCdString(bufnr('')) - \ . 'staticcheck ' - \ . '-test ' . ale#Escape(expand('%' . ':t')) + AssertLinter 'staticcheck', 'staticcheck -test %s:t' Execute(The staticcheck `lint_package` option should use the correct command): let b:ale_go_staticcheck_lint_package = 1 - AssertLinter 'staticcheck', - \ ale#path#BufferCdString(bufnr('')) - \ . 'staticcheck .', + AssertLinterCwd '%s:h' + AssertLinter 'staticcheck', 'staticcheck .' Execute(The staticcheck callback should use the `GO111MODULE` option if set): let b:ale_go_go111module = 'off' - AssertLinter 'staticcheck', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Env('GO111MODULE', 'off') - \ . 'staticcheck ' - \ . ale#Escape(expand('%' . ':t')) + AssertLinter 'staticcheck', ale#Env('GO111MODULE', 'off') . 'staticcheck %s:t' " Test with lint_package option set let b:ale_go_staticcheck_lint_package = 1 - AssertLinter 'staticcheck', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Env('GO111MODULE', 'off') - \ . 'staticcheck .' + AssertLinter 'staticcheck', ale#Env('GO111MODULE', 'off') . 'staticcheck .' diff --git a/test/command_callback/test_tslint_command_callback.vader b/test/command_callback/test_tslint_command_callback.vader index cc5d2666..1b291d9f 100644 --- a/test/command_callback/test_tslint_command_callback.vader +++ b/test/command_callback/test_tslint_command_callback.vader @@ -6,22 +6,18 @@ After: call ale#assert#TearDownLinterTest() Execute(The default tslint command should be correct): - AssertLinter 'tslint', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('tslint') . ' --format json %t' + AssertLinterCwd '%s:h' + AssertLinter 'tslint', ale#Escape('tslint') . ' --format json %t' Execute(The rules directory option should be included if set): let b:ale_typescript_tslint_rules_dir = '/foo/bar' AssertLinter 'tslint', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('tslint') . ' --format json' + \ ale#Escape('tslint') . ' --format json' \ . ' -r ' . ale#Escape('/foo/bar') \ . ' %t' Execute(The executable should be configurable and escaped): let b:ale_typescript_tslint_executable = 'foo bar' - AssertLinter 'foo bar', - \ ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('foo bar') . ' --format json %t' + AssertLinter 'foo bar', ale#Escape('foo bar') . ' --format json %t' diff --git a/test/command_callback/test_vulture_command_callback.vader b/test/command_callback/test_vulture_command_callback.vader index bacf8f12..41a70045 100644 --- a/test/command_callback/test_vulture_command_callback.vader +++ b/test/command_callback/test_vulture_command_callback.vader @@ -11,58 +11,48 @@ After: call ale#assert#TearDownLinterTest() Execute(The vulture command callback should lint file directory by default): - AssertLinter 'vulture', - \ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) - \ . ale#Escape('vulture') . ' .' + AssertLinterCwd expand('#' . bufnr('') . ':p:h') + AssertLinter 'vulture', ale#Escape('vulture') . ' .' Execute(The vulture command callback should lint project root, when present): - silent execute 'file ' . fnameescape(g:dir . '/python_paths/no_virtualenv/subdir/foo/bar.py') + call ale#test#SetFilename('python_paths/no_virtualenv/subdir/foo/bar.py') - AssertLinter 'vulture', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir')) - \ . ale#Escape('vulture') . ' .' + AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir') + AssertLinter 'vulture', ale#Escape('vulture') . ' .' Execute(The option for disabling change directory works and only lints file): let g:ale_python_vulture_change_directory = 0 + AssertLinterCwd '' AssertLinter 'vulture', ale#Escape('vulture') . ' %s' Execute(The vulture executable should be configurable, and escaped properly): let g:ale_python_vulture_executable = 'executable with spaces' - AssertLinter 'executable with spaces', - \ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) - \ . ale#Escape('executable with spaces') . ' .' + AssertLinter 'executable with spaces', ale#Escape('executable with spaces') . ' .' Execute(The vulture command callback should let you set options): let g:ale_python_vulture_options = '--some-option' - AssertLinter 'vulture', - \ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) - \ . ale#Escape('vulture') . ' --some-option .' + AssertLinter 'vulture', ale#Escape('vulture') . ' --some-option .' Execute(The vulture command callback should detect virtualenv directories and switch to the project root): - silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') + call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py') let b:executable = ale#path#Simplify( \ g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/vulture' \) - AssertLinter b:executable, - \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')) - \ . ale#Escape(b:executable) . ' .' + AssertLinterCwd ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir') + AssertLinter b:executable, ale#Escape(b:executable) . ' .' Execute(You should able able to use the global vulture instead): - silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') + call ale#test#SetFilename('python_paths/with_virtualenv/subdir/foo/bar.py') let g:ale_python_vulture_use_global = 1 - AssertLinter 'vulture', - \ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir')) - \ . ale#Escape('vulture') . ' .' + AssertLinter 'vulture', ale#Escape('vulture') . ' .' Execute(Setting executable to 'pipenv' appends 'run vulture'): let g:ale_python_vulture_executable = 'path/to/pipenv' - AssertLinter 'path/to/pipenv', - \ ale#path#CdString(expand('#' . bufnr('') . ':p:h')) - \ . ale#Escape('path/to/pipenv') . ' run vulture' . ' .' + AssertLinter 'path/to/pipenv', ale#Escape('path/to/pipenv') . ' run vulture' . ' .' diff --git a/test/fixers/test_autoimport_fixer_callback.vader b/test/fixers/test_autoimport_fixer_callback.vader index 6952cbb8..bea448b5 100644 --- a/test/fixers/test_autoimport_fixer_callback.vader +++ b/test/fixers/test_autoimport_fixer_callback.vader @@ -28,8 +28,8 @@ Execute(The autoimport callback should return the correct default values): silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') AssertEqual \ { - \ 'command': ale#path#BufferCdString(bufnr('')) - \ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/autoimport')) . ' -', + \ 'cwd': '%s:h', + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/autoimport')) . ' -', \ }, \ ale#fixers#autoimport#Fix(bufnr('')) @@ -43,8 +43,8 @@ Execute(The autoimport callback should respect custom options): silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') AssertEqual \ { - \ 'command': ale#path#BufferCdString(bufnr('')) - \ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/autoimport')) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/autoimport')) \ . ' --multi-line=3 --trailing-comma -', \ }, \ ale#fixers#autoimport#Fix(bufnr('')) diff --git a/test/fixers/test_black_fixer_callback.vader b/test/fixers/test_black_fixer_callback.vader index 75864479..055f8783 100644 --- a/test/fixers/test_black_fixer_callback.vader +++ b/test/fixers/test_black_fixer_callback.vader @@ -1,30 +1,23 @@ Before: - Save g:ale_python_black_executable - Save g:ale_python_black_options + call ale#assert#SetUpFixerTest('python', 'black') - " Use an invalid global executable, so we don't match it. - let g:ale_python_black_executable = 'xxxinvalid' - let g:ale_python_black_options = '' - let g:ale_python_black_auto_pipenv = 0 - - call ale#test#SetDirectory('/testplugin/test/fixers') silent cd .. silent cd command_callback let g:dir = getcwd() - let b:bin_dir = has('win32') ? 'Scripts' : 'bin' After: - Restore + call ale#assert#TearDownFixerTest() + unlet! g:dir unlet! b:bin_dir - call ale#test#RestoreDirectory() - Execute(The black callback should return the correct default values): silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') AssertEqual - \ {'command': ale#path#BufferCdString(bufnr('')) . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/black')) . ' -'}, + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/black')) . ' -'}, \ ale#fixers#black#Fix(bufnr('')) Execute(The black callback should include options): @@ -40,6 +33,7 @@ Execute(The black callback should include --pyi for .pyi files): let g:ale_python_black_change_directory = 0 silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.pyi') + AssertEqual \ {'command': ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/black')) . ' --pyi -' }, \ ale#fixers#black#Fix(bufnr('')) @@ -48,7 +42,7 @@ Execute(Pipenv is detected when python_black_auto_pipenv is set): let g:ale_python_black_auto_pipenv = 1 let g:ale_python_black_change_directory = 0 - call ale#test#SetFilename('/testplugin/test/python_fixtures/pipenv/whatever.py') + call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py') AssertEqual \ {'command': ale#Escape('pipenv') . ' run black -'}, diff --git a/test/fixers/test_dhall_format_fixer_callback.vader b/test/fixers/test_dhall_format_fixer_callback.vader index 9bc17f7e..8d6c7651 100644 --- a/test/fixers/test_dhall_format_fixer_callback.vader +++ b/test/fixers/test_dhall_format_fixer_callback.vader @@ -6,7 +6,7 @@ Before: let g:ale_dhall_executable = 'odd-dhall' let g:ale_dhall_options = '--ascii' - call ale#assert#SetUpFixerTest('dhall-format', 'dhall-format') + call ale#assert#SetUpFixerTest('dhall', 'dhall-format') After: call ale#assert#TearDownFixerTest() diff --git a/test/fixers/test_dhall_freeze_fixer_callback.vader b/test/fixers/test_dhall_freeze_fixer_callback.vader index c8f820bb..c6e94ec1 100644 --- a/test/fixers/test_dhall_freeze_fixer_callback.vader +++ b/test/fixers/test_dhall_freeze_fixer_callback.vader @@ -7,7 +7,7 @@ Before: let g:ale_dhall_options = '--ascii' let g:ale_dhall_freeze_options = '--all' - call ale#assert#SetUpFixerTest('dhall-freeze', 'dhall-freeze') + call ale#assert#SetUpFixerTest('dhall', 'dhall-freeze') After: call ale#assert#TearDownFixerTest() diff --git a/test/fixers/test_dhall_lint_fixer_callback.vader b/test/fixers/test_dhall_lint_fixer_callback.vader index 82229363..5a1d6488 100644 --- a/test/fixers/test_dhall_lint_fixer_callback.vader +++ b/test/fixers/test_dhall_lint_fixer_callback.vader @@ -6,7 +6,7 @@ Before: let g:ale_dhall_executable = 'odd-dhall' let g:ale_dhall_options = '--ascii' - call ale#assert#SetUpFixerTest('dhall-lint', 'dhall-lint') + call ale#assert#SetUpFixerTest('dhall', 'dhall-lint') After: call ale#assert#TearDownFixerTest() diff --git a/test/fixers/test_eslint_fixer_callback.vader b/test/fixers/test_eslint_fixer_callback.vader index 50fc6672..48cafe78 100644 --- a/test/fixers/test_eslint_fixer_callback.vader +++ b/test/fixers/test_eslint_fixer_callback.vader @@ -17,9 +17,8 @@ Execute(The executable path should be correct): AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': - \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) - \ . (has('win32') ? 'node.exe ' : '') + \ 'cwd': ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'), + \ 'command': (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js')) \ . ' --fix %t', @@ -36,6 +35,7 @@ Execute(The ESLint fixer should use a config file option if set for old versions AssertFixer \ { \ 'read_temporary_file': 1, + \ 'cwd': '', \ 'command': ale#Escape('eslint') . ' -c /foo.cfg --fix %t', \ } @@ -44,6 +44,7 @@ Execute(The ESLint fixer should use a config file option if set for old versions AssertFixer \ { \ 'read_temporary_file': 1, + \ 'cwd': '', \ 'command': ale#Escape('eslint') . ' --bar -c /foo.cfg --fix %t', \ } @@ -52,6 +53,7 @@ Execute(The ESLint fixer should use a config file option if set for old versions AssertFixer \ { \ 'read_temporary_file': 1, + \ 'cwd': '', \ 'command': ale#Escape('eslint') . ' --config /foo.cfg --fix %t', \ } @@ -60,6 +62,7 @@ Execute(The ESLint fixer should use a config file option if set for old versions AssertFixer \ { \ 'read_temporary_file': 1, + \ 'cwd': '', \ 'command': ale#Escape('eslint') . ' --bar --config /foo.cfg --fix %t', \ } @@ -72,6 +75,7 @@ Execute(The ESLint fixer should use a -c file option if set for eslint_d): AssertFixer \ { \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', + \ 'cwd': '', \ 'command': ale#Escape('/bin/eslint_d') \ . ' -c /foo.cfg' \ . ' --stdin-filename %s --stdin --fix-to-stdout' @@ -82,6 +86,7 @@ Execute(The ESLint fixer should use a -c file option if set for eslint_d): AssertFixer \ { \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', + \ 'cwd': '', \ 'command': ale#Escape('/bin/eslint_d') \ . ' --bar -c /foo.cfg' \ . ' --stdin-filename %s --stdin --fix-to-stdout' @@ -92,6 +97,7 @@ Execute(The ESLint fixer should use a -c file option if set for eslint_d): AssertFixer \ { \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', + \ 'cwd': '', \ 'command': ale#Escape('/bin/eslint_d') \ . ' --config /foo.cfg' \ . ' --stdin-filename %s --stdin --fix-to-stdout' @@ -102,6 +108,7 @@ Execute(The ESLint fixer should use a -c file option if set for eslint_d): AssertFixer \ { \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', + \ 'cwd': '', \ 'command': ale#Escape('/bin/eslint_d') \ . ' --bar --config /foo.cfg' \ . ' --stdin-filename %s --stdin --fix-to-stdout' @@ -115,6 +122,7 @@ Execute(The ESLint fixer should use a config file option if set for new versions AssertFixer \ { \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', + \ 'cwd': '', \ 'command': ale#Escape('eslint') \ . ' -c /foo.cfg' \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json' @@ -125,6 +133,7 @@ Execute(The ESLint fixer should use a config file option if set for new versions AssertFixer \ { \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', + \ 'cwd': '', \ 'command': ale#Escape('eslint') \ . ' --bar -c /foo.cfg' \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json' @@ -135,6 +144,7 @@ Execute(The ESLint fixer should use a config file option if set for new versions AssertFixer \ { \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', + \ 'cwd': '', \ 'command': ale#Escape('eslint') \ . ' --config /foo.cfg' \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json' @@ -145,6 +155,7 @@ Execute(The ESLint fixer should use a config file option if set for new versions AssertFixer \ { \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', + \ 'cwd': '', \ 'command': ale#Escape('eslint') \ . ' --bar --config /foo.cfg' \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json' @@ -156,9 +167,8 @@ Execute(The lower priority configuration file in a nested directory should be pr AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': - \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) - \ . (has('win32') ? 'node.exe ' : '') + \ 'cwd': ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'), + \ 'command': (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/subdir-with-config/.eslintrc')) \ . ' --fix %t', @@ -172,9 +182,8 @@ Execute(--config in options should override configuration file detection for old AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': - \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) - \ . (has('win32') ? 'node.exe ' : '') + \ 'cwd': ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'), + \ 'command': (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' --config /foo.cfg' \ . ' --fix %t', @@ -185,9 +194,8 @@ Execute(--config in options should override configuration file detection for old AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': - \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) - \ . (has('win32') ? 'node.exe ' : '') + \ 'cwd': ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'), + \ 'command': (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' -c /foo.cfg' \ . ' --fix %t', @@ -199,9 +207,8 @@ Execute(package.json should be used as a last resort): AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': - \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) - \ . (has('win32') ? 'node.exe ' : '') + \ 'cwd': ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'), + \ 'command': (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js')) \ . ' --fix %t', @@ -212,9 +219,8 @@ Execute(package.json should be used as a last resort): AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': - \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files')) - \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/node_modules/.bin/eslint')) + \ 'cwd': ale#path#Simplify(g:dir . '/../eslint-test-files'), + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/node_modules/.bin/eslint')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/package.json')) \ . ' --fix %t', \ } @@ -229,9 +235,8 @@ Execute(The version check should be correct): \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' --version', \ { - \ 'command': - \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) - \ . (has('win32') ? 'node.exe ' : '') + \ 'cwd': ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'), + \ 'command': (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', @@ -240,9 +245,8 @@ Execute(The version check should be correct): AssertFixer [ \ { - \ 'command': - \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) - \ . (has('win32') ? 'node.exe ' : '') + \ 'cwd': ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'), + \ 'command': (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', @@ -255,9 +259,8 @@ Execute(--fix-dry-run should be used for 4.9.0 and up): GivenCommandOutput ['4.9.0'] AssertFixer \ { - \ 'command': - \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app')) - \ . (has('win32') ? 'node.exe ' : '') + \ 'cwd': ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'), + \ 'command': (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', @@ -269,9 +272,8 @@ Execute(--fix-to-stdout should be used for eslint_d): AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': - \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d')) - \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) + \ 'cwd': ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d'), + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/package.json')) \ . ' --fix %t', \ } @@ -281,9 +283,8 @@ Execute(--fix-to-stdout should be used for eslint_d): GivenCommandOutput ['v3.19.0 (eslint_d v4.2.0)'] AssertFixer \ { - \ 'command': - \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d')) - \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) + \ 'cwd': ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d'), + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) \ . ' --stdin-filename %s --stdin --fix-to-stdout', \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', \ } @@ -292,9 +293,8 @@ Execute(--fix-to-stdout should be used for eslint_d): GivenCommandOutput ['4.9.0'] AssertFixer \ { - \ 'command': - \ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d')) - \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) + \ 'cwd': ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d'), + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) \ . ' --stdin-filename %s --stdin --fix-to-stdout', \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', \ } diff --git a/test/fixers/test_isort_fixer_callback.vader b/test/fixers/test_isort_fixer_callback.vader index 3941f6dd..96632c8c 100644 --- a/test/fixers/test_isort_fixer_callback.vader +++ b/test/fixers/test_isort_fixer_callback.vader @@ -1,26 +1,17 @@ Before: - Save g:ale_python_isort_executable - Save g:ale_python_isort_options + call ale#assert#SetUpFixerTest('python', 'isort') - " Use an invalid global executable, so we don't match it. - let g:ale_python_isort_executable = 'xxxinvalid' - let g:ale_python_isort_options = '' - let g:ale_python_isort_auto_pipenv = 0 - - call ale#test#SetDirectory('/testplugin/test/fixers') silent cd .. silent cd command_callback let g:dir = getcwd() - let b:bin_dir = has('win32') ? 'Scripts' : 'bin' After: - Restore + call ale#assert#TearDownFixerTest() + unlet! g:dir unlet! b:bin_dir - call ale#test#RestoreDirectory() - Execute(The isort callback should return the correct default values): AssertEqual \ 0, @@ -29,8 +20,8 @@ Execute(The isort callback should return the correct default values): silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') AssertEqual \ { - \ 'command': ale#path#BufferCdString(bufnr('')) - \ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/isort')) . ' -', + \ 'cwd': '%s:h', + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/isort')) . ' -', \ }, \ ale#fixers#isort#Fix(bufnr('')) @@ -44,8 +35,8 @@ Execute(The isort callback should respect custom options): silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') AssertEqual \ { - \ 'command': ale#path#BufferCdString(bufnr('')) - \ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/isort')) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/isort')) \ . ' --multi-line=3 --trailing-comma -', \ }, \ ale#fixers#isort#Fix(bufnr('')) @@ -53,8 +44,11 @@ Execute(The isort callback should respect custom options): Execute(Pipenv is detected when python_isort_auto_pipenv is set): let g:ale_python_isort_auto_pipenv = 1 - call ale#test#SetFilename('/testplugin/test/python_fixtures/pipenv/whatever.py') + call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py') AssertEqual - \ {'command': ale#path#BufferCdString(bufnr('')) . ale#Escape('pipenv') . ' run isort -'}, + \ { + \ 'cwd': '%s:h', + \ 'command': ale#Escape('pipenv') . ' run isort -' + \ }, \ ale#fixers#isort#Fix(bufnr('')) diff --git a/test/fixers/test_prettier_eslint_fixer.callback.vader b/test/fixers/test_prettier_eslint_fixer.callback.vader index be8f04e3..9bd6baf7 100644 --- a/test/fixers/test_prettier_eslint_fixer.callback.vader +++ b/test/fixers/test_prettier_eslint_fixer.callback.vader @@ -73,8 +73,8 @@ Execute(The new --stdin-filepath option should be used when the version is new e GivenCommandOutput ['4.4.0'] AssertFixer \ { - \ 'command': ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('prettier-eslint') + \ 'cwd': '%s:h', + \ 'command': ale#Escape('prettier-eslint') \ . ' --eslint-config-path ' . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/.eslintrc.js')) \ . ' --stdin-filepath %s --stdin', \ } @@ -83,15 +83,15 @@ Execute(The version number should be cached): GivenCommandOutput ['4.4.0'] AssertFixer \ { - \ 'command': ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('prettier-eslint') + \ 'cwd': '%s:h', + \ 'command': ale#Escape('prettier-eslint') \ . ' --stdin-filepath %s --stdin', \ } GivenCommandOutput [] AssertFixer \ { - \ 'command': ale#path#BufferCdString(bufnr('')) - \ . ale#Escape('prettier-eslint') + \ 'cwd': '%s:h', + \ 'command': ale#Escape('prettier-eslint') \ . ' --stdin-filepath %s --stdin', \ } diff --git a/test/fixers/test_prettier_fixer_callback.vader b/test/fixers/test_prettier_fixer_callback.vader index b999071f..0857c4cb 100644 --- a/test/fixers/test_prettier_fixer_callback.vader +++ b/test/fixers/test_prettier_fixer_callback.vader @@ -62,8 +62,8 @@ Execute(--stdin-filepath should be used when prettier is new enough): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --no-semi' \ . ' --stdin-filepath %s --stdin', \ } @@ -74,16 +74,16 @@ Execute(The version number should be cached): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --stdin-filepath %s --stdin', \ } GivenCommandOutput [] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --stdin-filepath %s --stdin', \ } @@ -95,8 +95,8 @@ Execute(Should set --parser to `babylon` by default, < 1.16.0): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --parser babylon' \ . ' --stdin-filepath %s --stdin', \ } @@ -109,8 +109,8 @@ Execute(Should set --parser to `babel` by default, >= 1.16.0): GivenCommandOutput ['1.16.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --parser babel' \ . ' --stdin-filepath %s --stdin', \ } @@ -123,8 +123,8 @@ Execute(Should set --parser based on filetype, TypeScript): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --parser typescript' \ . ' --stdin-filepath %s --stdin', \ } @@ -137,8 +137,8 @@ Execute(Should set --parser based on filetype, CSS): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --parser css' \ . ' --stdin-filepath %s --stdin', \ } @@ -151,8 +151,8 @@ Execute(Should set --parser based on filetype, LESS): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --parser less' \ . ' --stdin-filepath %s --stdin', \ } @@ -165,8 +165,8 @@ Execute(Should set --parser based on filetype, SCSS): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --parser scss' \ . ' --stdin-filepath %s --stdin', \ } @@ -179,8 +179,8 @@ Execute(Should set --parser based on filetype, JSON): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --parser json' \ . ' --stdin-filepath %s --stdin', \ } @@ -193,8 +193,8 @@ Execute(Should set --parser based on filetype, JSON5): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --parser json5' \ . ' --stdin-filepath %s --stdin', \ } @@ -207,8 +207,8 @@ Execute(Should set --parser based on filetype, GraphQL): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --parser graphql' \ . ' --stdin-filepath %s --stdin', \ } @@ -221,8 +221,8 @@ Execute(Should set --parser based on filetype, Markdown): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --parser markdown' \ . ' --stdin-filepath %s --stdin', \ } @@ -235,8 +235,8 @@ Execute(Should set --parser based on filetype, Vue): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --parser vue' \ . ' --stdin-filepath %s --stdin', \ } @@ -249,8 +249,8 @@ Execute(Should set --parser based on filetype, YAML): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --parser yaml' \ . ' --stdin-filepath %s --stdin', \ } @@ -263,8 +263,8 @@ Execute(Should set --parser based on filetype, HTML): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --parser html' \ . ' --stdin-filepath %s --stdin', \ } @@ -277,8 +277,8 @@ Execute(Should set --parser based on filetype, Ruby): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --parser ruby' \ . ' --stdin-filepath %s --stdin', \ } @@ -291,8 +291,8 @@ Execute(Should set --parser based on first filetype of multiple filetypes): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --parser css' \ . ' --stdin-filepath %s --stdin', \ } @@ -305,8 +305,8 @@ Execute(Should set --parser for experimental language, Handlebars): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --parser glimmer' \ . ' --stdin-filepath %s --stdin', \ } @@ -317,8 +317,8 @@ Execute(Changes to directory where .prettierignore is found): GivenCommandOutput ['1.6.0'] AssertFixer \ { - \ 'command': ale#path#CdString(expand('%:p:h:h')) - \ . ale#Escape(g:ale_javascript_prettier_executable) + \ 'cwd': expand('%:p:h:h'), + \ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ . ' --stdin-filepath %s --stdin', \ } diff --git a/test/fixers/test_stylelint_fixer_callback.vader b/test/fixers/test_stylelint_fixer_callback.vader index 8fbd8a51..95f91f91 100644 --- a/test/fixers/test_stylelint_fixer_callback.vader +++ b/test/fixers/test_stylelint_fixer_callback.vader @@ -14,8 +14,8 @@ Execute(The stylelint callback should return the correct default values): AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': ale#path#BufferCdString(bufnr('')) - \ . (has('win32') ? 'node.exe ' : '') + \ 'cwd': '%s:h', + \ 'command': (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/stylelint/bin/stylelint.js')) \ . ' %t' \ . ' --fix', @@ -28,8 +28,8 @@ Execute(The stylelint callback should include custom stylelint options): AssertFixer \ { \ 'read_temporary_file': 1, - \ 'command': ale#path#BufferCdString(bufnr('')) - \ . (has('win32') ? 'node.exe ' : '') + \ 'cwd': '%s:h', + \ 'command': (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/stylelint/bin/stylelint.js')) \ . ' %t' \ . ' --cache' diff --git a/test/fixers/test_yamlfix_fixer_callback.vader b/test/fixers/test_yamlfix_fixer_callback.vader index 3ffda91e..75b9f0ad 100644 --- a/test/fixers/test_yamlfix_fixer_callback.vader +++ b/test/fixers/test_yamlfix_fixer_callback.vader @@ -1,12 +1,6 @@ Before: - Save g:ale_python_yamlfix_executable - Save g:ale_python_yamlfix_options + call ale#assert#SetUpFixerTest('yaml', 'yamlfix') - " Use an invalid global executable, so we don't match it. - let g:ale_python_yamlfix_executable = 'xxxinvalid' - let g:ale_python_yamlfix_options = '' - - call ale#test#SetDirectory('/testplugin/test/fixers') silent cd .. silent cd command_callback let g:dir = getcwd() @@ -14,11 +8,8 @@ Before: let b:bin_dir = has('win32') ? 'Scripts' : 'bin' After: - Restore - unlet! b:bin_dir - - call ale#test#RestoreDirectory() + call ale#assert#TearDownFixerTest() Execute(The yamlfix callback should return the correct default values): AssertEqual @@ -28,23 +19,19 @@ Execute(The yamlfix callback should return the correct default values): silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.yaml') AssertEqual \ { - \ 'command': ale#path#BufferCdString(bufnr('')) - \ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/yamlfix')) . ' -', + \ 'cwd': '%s:h', + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/yamlfix')) . ' -', \ }, \ ale#fixers#yamlfix#Fix(bufnr('')) Execute(The yamlfix callback should respect custom options): let g:ale_yaml_yamlfix_options = '--multi-line=3 --trailing-comma' - AssertEqual - \ 0, - \ ale#fixers#yamlfix#Fix(bufnr('')) - silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.yaml') AssertEqual \ { - \ 'command': ale#path#BufferCdString(bufnr('')) - \ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/yamlfix')) + \ 'cwd': '%s:h', + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/yamlfix')) \ . ' --multi-line=3 --trailing-comma -', \ }, \ ale#fixers#yamlfix#Fix(bufnr('')) diff --git a/test/test_ant_build_classpath_command.vader b/test/test_ant_build_classpath_command.vader index 5542a9d8..72a7688d 100644 --- a/test/test_ant_build_classpath_command.vader +++ b/test/test_ant_build_classpath_command.vader @@ -5,25 +5,23 @@ Before: Save $PATH let $PATH = ale#path#Simplify(g:dir . '/ant-test-files/bin') - let g:valid_project = 'ant-test-files/ant-project' - let g:invalid_project = 'ant-test-files/non-ant-project' - let g:command_tail = ' classpath' . ' -S' . ' -q' - After: Restore - unlet! g:command_tail - unlet! g:valid_project - unlet! g:invalid_project - call ale#test#RestoreDirectory() call ale#linter#Reset() Execute(Should return `cd '[dir]' && 'ant' classpath -S -q`): - call ale#test#SetFilename(valid_project . '/Main.java') + call ale#test#SetFilename('ant-test-files/ant-project/Main.java') AssertEqual - \ ale#path#CdString(ale#path#Simplify(g:dir . '/ant-test-files/ant-project')) - \ . ale#Escape('ant') - \ . g:command_tail, + \ [ + \ ale#path#Simplify(g:dir . '/ant-test-files/ant-project'), + \ ale#Escape('ant') . ' classpath' . ' -S' . ' -q', + \ ], \ ale#ant#BuildClasspathCommand(bufnr('')) + +Execute(Should return empty string if ant cannot be executed): + call ale#test#SetFilename('ant-test-files/not-an-ant-project/Main.java') + + AssertEqual ['', ''], ale#ant#BuildClasspathCommand(bufnr('')) diff --git a/test/test_c_flag_parsing.vader b/test/test_c_flag_parsing.vader index 319e10dd..4329b573 100644 --- a/test/test_c_flag_parsing.vader +++ b/test/test_c_flag_parsing.vader @@ -26,24 +26,30 @@ Execute(The make command should be correct): call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c') AssertEqual - \ ale#path#CdString(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project')) - \ . 'make -n --always-make', + \ [ + \ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'), + \ 'make -n --always-make', + \ ], \ ale#c#GetMakeCommand(bufnr('')) " You should be able to disable --always-make for a buffer. let b:ale_c_always_make = 0 AssertEqual - \ ale#path#CdString(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project')) - \ . 'make -n', + \ [ + \ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'), + \ 'make -n', + \ ], \ ale#c#GetMakeCommand(bufnr('')) Execute(Should recognize GNUmakefile as a makefile): call ale#test#SetFilename('test_c_projects/gnumakefile_project/file.c') AssertEqual - \ ale#path#CdString(ale#path#Simplify(g:dir. '/test_c_projects/gnumakefile_project')) - \ . 'make -n --always-make', + \ [ + \ ale#path#Simplify(g:dir. '/test_c_projects/gnumakefile_project'), + \ 'make -n --always-make', + \ ], \ ale#c#GetMakeCommand(bufnr('')) Execute(The CFlags parser should be able to parse include directives): diff --git a/test/test_eslint_executable_detection.vader b/test/test_eslint_executable_detection.vader deleted file mode 100644 index 3fed63da..00000000 --- a/test/test_eslint_executable_detection.vader +++ /dev/null @@ -1,100 +0,0 @@ -Before: - let g:ale_javascript_eslint_executable = 'eslint_d' - - call ale#test#SetDirectory('/testplugin/test') - - runtime ale_linters/javascript/eslint.vim - -After: - let g:ale_javascript_eslint_executable = 'eslint' - let g:ale_javascript_eslint_use_global = 0 - - call ale#test#RestoreDirectory() - call ale#linter#Reset() - -Execute(create-react-app directories should be detected correctly): - call ale#test#SetFilename('eslint-test-files/react-app/subdir/testfile.js') - - AssertEqual - \ ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'), - \ ale#handlers#eslint#GetExecutable(bufnr('')) - -Execute(use-global should override create-react-app detection): - let g:ale_javascript_eslint_use_global = 1 - - call ale#test#SetFilename('eslint-test-files/react-app/subdir/testfile.js') - - AssertEqual - \ 'eslint_d', - \ ale#handlers#eslint#GetExecutable(bufnr('')) - -Execute(other app directories should be detected correctly): - call ale#test#SetFilename('eslint-test-files/other-app/subdir/testfile.js') - - AssertEqual - \ ale#path#Simplify(g:dir . '/eslint-test-files/node_modules/.bin/eslint'), - \ ale#handlers#eslint#GetExecutable(bufnr('')) - -Execute(use-global should override other app directories): - let g:ale_javascript_eslint_use_global = 1 - - call ale#test#SetFilename('eslint-test-files/other-app/subdir/testfile.js') - - AssertEqual - \ 'eslint_d', - \ ale#handlers#eslint#GetExecutable(bufnr('')) - -Execute(eslint_d should be detected correctly): - call ale#test#SetFilename('eslint-test-files/app-with-eslint-d/testfile.js') - - AssertEqual - \ ale#path#Simplify(g:dir . '/eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d'), - \ ale#handlers#eslint#GetExecutable(bufnr('')) - -Execute(eslint.js executables should be run with node on Windows): - call ale#test#SetFilename('eslint-test-files/react-app/subdir/testfile.js') - - " We have to execute the file with node. - if has('win32') - AssertEqual - \ ale#path#CdString(ale#path#Simplify(g:dir . '/eslint-test-files/react-app')) - \ . ale#Escape('node.exe') . ' ' - \ . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) - \ . ' -f json --stdin --stdin-filename %s', - \ ale#handlers#eslint#GetCommand(bufnr('')) - else - AssertEqual - \ ale#path#CdString(ale#path#Simplify(g:dir . '/eslint-test-files/react-app')) - \ . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) - \ . ' -f json --stdin --stdin-filename %s', - \ ale#handlers#eslint#GetCommand(bufnr('')) - endif - -Execute(eslint.js should be run from containing project with eslint): - call ale#test#SetFilename('eslint-test-files/react-app/subdir-with-package-json/testfile.js') - - " We have to execute the file with node. - if has('win32') - AssertEqual - \ ale#path#CdString(ale#path#Simplify(g:dir . '/eslint-test-files/react-app')) - \ . ale#Escape('node.exe') . ' ' - \ . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) - \ . ' -f json --stdin --stdin-filename %s', - \ ale#handlers#eslint#GetCommand(bufnr('')) - else - AssertEqual - \ ale#path#CdString(ale#path#Simplify(g:dir . '/eslint-test-files/react-app')) - \ . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) - \ . ' -f json --stdin --stdin-filename %s', - \ ale#handlers#eslint#GetCommand(bufnr('')) - endif - -Execute(eslint.js executables can be run outside project dir): - " Set filename above eslint-test-files (which contains node_modules) - call ale#test#SetFilename('testfile.js') - - " cd "..." not present, since project root not found (from node_modules) - AssertEqual - \ ale#Escape(ale#handlers#eslint#GetExecutable(bufnr(''))) - \ . ' -f json --stdin --stdin-filename %s', - \ ale#handlers#eslint#GetCommand(bufnr('')) diff --git a/test/test_format_command.vader b/test/test_format_command.vader index 9d730fce..b0440dcd 100644 --- a/test/test_format_command.vader +++ b/test/test_format_command.vader @@ -25,12 +25,12 @@ After: Execute(FormatCommand should do nothing to basic command strings): AssertEqual \ ['', 'awesome-linter do something', 0], - \ ale#command#FormatCommand(bufnr('%'), '', 'awesome-linter do something', 0, v:null, []) + \ ale#command#FormatCommand(bufnr('%'), '', 'awesome-linter do something', 0, v:null, v:null, []) Execute(FormatCommand should handle %%, and ignore other percents): AssertEqual \ ['', '% %%d %%f %x %', 0], - \ ale#command#FormatCommand(bufnr('%'), '', '%% %%%d %%%f %x %', 0, v:null, []) + \ ale#command#FormatCommand(bufnr('%'), '', '%% %%%d %%%f %x %', 0, v:null, v:null, []) Execute(FormatCommand should convert %s to the current filename): AssertEqual @@ -39,10 +39,10 @@ Execute(FormatCommand should convert %s to the current filename): \ 'foo ' . ale#Escape(expand('%:p')) . ' bar ' . ale#Escape(expand('%:p')), \ 0, \ ], - \ ale#command#FormatCommand(bufnr('%'), '', 'foo %s bar %s', 0, v:null, []) + \ ale#command#FormatCommand(bufnr('%'), '', 'foo %s bar %s', 0, v:null, v:null, []) Execute(FormatCommand should convert %t to a new temporary filename): - let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %t', 0, v:null, []) + let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %t', 0, v:null, v:null, []) call CheckTempFile(g:result[0]) @@ -56,21 +56,21 @@ Execute(FormatCommand should convert %t to a new temporary filename): AssertEqual g:match[1], g:match[2] Execute(FormatCommand should not convert %t to a new temporary filename when the input is given as v:false): - let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %t', 0, v:false, []) + let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %t', 0, v:false, v:null, []) AssertEqual ['', 'foo %t bar %t', 0], g:result Execute(FormatCommand should signal that files are created when temporary files are needed): AssertEqual \ 1, - \ ale#command#FormatCommand(bufnr('%'), '', 'foo %t', 0, v:null, [])[2] + \ ale#command#FormatCommand(bufnr('%'), '', 'foo %t', 0, v:null, v:null, [])[2] AssertEqual \ 0, - \ ale#command#FormatCommand(bufnr('%'), '', 'foo %s', 0, v:null, [])[2] + \ ale#command#FormatCommand(bufnr('%'), '', 'foo %s', 0, v:null, v:null, [])[2] Execute(FormatCommand should let you combine %s and %t): - let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %s', 0, v:null, []) + let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %s', 0, v:null, v:null, []) call CheckTempFile(g:result[0]) @@ -87,30 +87,30 @@ Execute(FormatCommand should replace %e with the escaped executable): if has('win32') AssertEqual \ ['', 'foo foo', 0], - \ ale#command#FormatCommand(bufnr('%'), 'foo', '%e %e', 0, v:null, []) + \ ale#command#FormatCommand(bufnr('%'), 'foo', '%e %e', 0, v:null, v:null, []) AssertEqual \ ['', '"foo bar"', 0], - \ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null, []) + \ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null, v:null, []) AssertEqual \ ['', '%e %e', 0], - \ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, v:null, []) + \ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, v:null, v:null, []) else AssertEqual \ ['', '''foo'' ''foo''', 0], - \ ale#command#FormatCommand(bufnr('%'), 'foo', '%e %e', 0, v:null, []) + \ ale#command#FormatCommand(bufnr('%'), 'foo', '%e %e', 0, v:null, v:null, []) AssertEqual \ ['', '''foo bar''', 0], - \ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null, []) + \ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null, v:null, []) AssertEqual \ ['', '%e %e', 0], - \ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, v:null, []) + \ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, v:null, v:null, []) endif Execute(EscapeCommandPart should escape all percent signs): AssertEqual '%%s %%t %%%% %%s %%t %%%%', ale#engine#EscapeCommandPart('%s %t %% %s %t %%') Execute(EscapeCommandPart should pipe in temporary files appropriately): - let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo bar', 1, v:null, []) + let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo bar', 1, v:null, v:null, []) call CheckTempFile(g:result[0]) @@ -118,7 +118,7 @@ Execute(EscapeCommandPart should pipe in temporary files appropriately): Assert !empty(g:match), 'No match found! Result was: ' . g:result[1] AssertEqual ale#Escape(g:result[0]), g:match[1] - let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo bar %t', 1, v:null, []) + let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo bar %t', 1, v:null, v:null, []) call CheckTempFile(g:result[0]) @@ -133,10 +133,10 @@ Execute(FormatCommand should apply filename modifiers to the current file): \ . ' ' . ale#Escape(expand('%:p:h:t')) \ . ' ' . ale#Escape('txt') \ . ' ' . ale#Escape(expand('%:p:r')), - \ ale#command#FormatCommand(bufnr(''), '', '%s:h %s:t %s:h:t %s:e %s:r', 0, v:null, [])[1] + \ ale#command#FormatCommand(bufnr(''), '', '%s:h %s:t %s:h:t %s:e %s:r', 0, v:null, v:null, [])[1] Execute(FormatCommand should apply filename modifiers to the temporary file): - let g:result = ale#command#FormatCommand(bufnr(''), '', '%t:h %t:t %t:h:t %t:e %t:r', 0, v:null, []) + let g:result = ale#command#FormatCommand(bufnr(''), '', '%t:h %t:t %t:h:t %t:e %t:r', 0, v:null, v:null, []) AssertEqual \ ale#Escape(fnamemodify(g:result[0], ':h')) @@ -147,28 +147,40 @@ Execute(FormatCommand should apply filename modifiers to the temporary file): \ g:result[1] Execute(FormatCommand should apply filename mappings the current file): - let g:result = ale#command#FormatCommand(bufnr('%'), '', '%s', 0, v:null, [ + let g:result = ale#command#FormatCommand(bufnr('%'), '', '%s', 0, v:null, v:null, [ \ [expand('%:p:h'), '/foo/bar'], \]) Assert g:result[1] =~# '/foo/bar' Execute(FormatCommand should apply filename mappings to temporary files): - let g:result = ale#command#FormatCommand(bufnr('%'), '', '%t', 0, v:null, [ + let g:result = ale#command#FormatCommand(bufnr('%'), '', '%t', 0, v:null, v:null, [ \ [fnamemodify(tempname(), ':h:h'), '/foo/bar'] \]) Assert g:result[1] =~# '/foo/bar' Execute(FormatCommand should apply filename modifiers to mapped filenames): - let g:result = ale#command#FormatCommand(bufnr('%'), '', '%s:h', 0, v:null, [ + let g:result = ale#command#FormatCommand(bufnr('%'), '', '%s:h', 0, v:null, v:null, [ \ [expand('%:p:h'), '/foo/bar'], \]) AssertEqual ale#Escape('/foo/bar'), g:result[1] - let g:result = ale#command#FormatCommand(bufnr('%'), '', '%t:h:h:h', 0, v:null, [ + let g:result = ale#command#FormatCommand(bufnr('%'), '', '%t:h:h:h', 0, v:null, v:null, [ \ [fnamemodify(tempname(), ':h:h'), '/foo/bar'] \]) AssertEqual ale#Escape('/foo/bar'), g:result[1] + +Execute(FormatCommand should apply regular cwd paths): + AssertEqual + \ 'cd ' . (has('unix') ? '' : '/d ') . ale#Escape('/foo /bar') . ' && abc', + \ ale#command#FormatCommand(bufnr('%'), '', 'abc', 0, v:null, '/foo /bar', [])[1] + \ +Execute(FormatCommand should apply cwd subsitution and formatting): + call ale#test#SetFilename('foo.txt') + + AssertEqual + \ 'cd ' . (has('unix') ? '' : '/d ') . ale#Escape(getcwd()) . ' && abc', + \ ale#command#FormatCommand(bufnr('%'), '', 'abc', 0, v:null, '%s:h', [])[1] diff --git a/test/test_gradle_build_classpath_command.vader b/test/test_gradle_build_classpath_command.vader index 491c2bf0..e274797d 100644 --- a/test/test_gradle_build_classpath_command.vader +++ b/test/test_gradle_build_classpath_command.vader @@ -25,9 +25,11 @@ Execute(Should return 'gradlew' command if project includes gradle wapper): call ale#test#SetFilename('gradle-test-files/wrapped-project/src/main/kotlin/dummy.kt') AssertEqual - \ ale#path#CdString(ale#path#Simplify(g:dir . '/gradle-test-files/wrapped-project')) - \ . ale#Escape(ale#path#Simplify(g:dir . '/gradle-test-files/wrapped-project/gradlew')) + \ [ + \ ale#path#Simplify(g:dir . '/gradle-test-files/wrapped-project'), + \ ale#Escape(ale#path#Simplify(g:dir . '/gradle-test-files/wrapped-project/gradlew')) \ . g:command_tail, + \ ], \ ale#gradle#BuildClasspathCommand(bufnr('')) Execute(Should return 'gradle' command if project does not include gradle wapper): @@ -36,14 +38,15 @@ Execute(Should return 'gradle' command if project does not include gradle wapper \ . ale#path#Simplify(g:dir . '/gradle-test-files') AssertEqual - \ ale#path#CdString(ale#path#Simplify(g:dir . '/gradle-test-files/unwrapped-project')) - \ . ale#Escape('gradle') - \ . g:command_tail, + \ [ + \ ale#path#Simplify(g:dir . '/gradle-test-files/unwrapped-project'), + \ ale#Escape('gradle') . g:command_tail + \ ], \ ale#gradle#BuildClasspathCommand(bufnr('')) Execute(Should return empty string if gradle cannot be executed): call ale#test#SetFilename('gradle-test-files/non-gradle-project/src/main/kotlin/dummy.kt') AssertEqual - \ '', + \ ['', ''], \ ale#gradle#BuildClasspathCommand(bufnr('')) diff --git a/test/test_linter_defintion_processing.vader b/test/test_linter_defintion_processing.vader index d000b158..fa1b6786 100644 --- a/test/test_linter_defintion_processing.vader +++ b/test/test_linter_defintion_processing.vader @@ -89,6 +89,34 @@ Execute (PreProcess should allow command to be a callback): \ 'command': function('type'), \}) +Execute (PreProcess should throw when cwd is not a string): + AssertThrows call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 'SomeFunction', + \ 'executable': 'echo', + \ 'cwd': [], + \ 'command': 'echo', + \}) + AssertEqual '`cwd` must be a String or Function if defined', g:vader_exception + +Execute (PreProcess should allow cwd to be a callback): + call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 'SomeFunction', + \ 'executable': 'echo', + \ 'cwd': function('type'), + \ 'command': 'echo', + \}) + +Execute (PreProcess should allow cwd to be a string): + call ale#linter#PreProcess('testft', { + \ 'name': 'foo', + \ 'callback': 'SomeFunction', + \ 'executable': 'echo', + \ 'cwd': '/foo/bar', + \ 'command': 'echo', + \}) + Execute (PreProcess should when the output stream isn't a valid string): AssertThrows call ale#linter#PreProcess('testft', { \ 'name': 'foo', @@ -305,7 +333,7 @@ Execute(PreProcess should complain about invalid language values): \} AssertThrows call ale#linter#PreProcess('testft', g:linter) - AssertEqual '`language` must be a String or Funcref if defined', g:vader_exception + AssertEqual '`language` must be a String or Function if defined', g:vader_exception Execute(PreProcess should use the filetype as the language string by default): let g:linter = { diff --git a/test/test_maven_build_classpath_command.vader b/test/test_maven_build_classpath_command.vader index 2d8b38a5..633bb2a1 100644 --- a/test/test_maven_build_classpath_command.vader +++ b/test/test_maven_build_classpath_command.vader @@ -25,9 +25,11 @@ Execute(Should use 'mvnw' in classpath command if available): call ale#test#SetFilename('maven-test-files/maven-java-project/module1/src/main/java/dummy1.java') AssertEqual - \ ale#path#CdString(ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module1')) - \ . ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module1/' . g:expected_wrapper) - \ . ' dependency:build-classpath', + \ [ + \ ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module1'), + \ ale#Escape(ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module1/' . g:expected_wrapper)) + \ . ' dependency:build-classpath', + \ ], \ ale#maven#BuildClasspathCommand(bufnr('')) Execute(Should use 'mvn' in classpath command if it is executable and 'mvnw' is unavailable): @@ -36,13 +38,16 @@ Execute(Should use 'mvn' in classpath command if it is executable and 'mvnw' is \ . ale#path#Simplify(g:dir . '/maven-test-files') AssertEqual - \ ale#path#CdString(ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module2')) - \ . 'mvn dependency:build-classpath', + \ [ + \ ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module2'), + \ ale#Escape('mvn') + \ . ' dependency:build-classpath', + \ ], \ ale#maven#BuildClasspathCommand(bufnr('')) Execute(Should return empty string if maven cannot be executed): call ale#test#SetFilename('maven-test-files/non-maven-project/src/main/java/dummy.java') AssertEqual - \ '', + \ ['', ''], \ ale#maven#BuildClasspathCommand(bufnr('')) diff --git a/test/util/test_cd_string_commands.vader b/test/util/test_cd_string_commands.vader index 85c5065f..d854214a 100644 --- a/test/util/test_cd_string_commands.vader +++ b/test/util/test_cd_string_commands.vader @@ -10,11 +10,11 @@ Execute(CdString should output the correct command string): " We will check that escaping is done correctly for each platform. AssertEqual \ has('unix') ? 'cd ''/foo bar/baz'' && ' : 'cd /d "/foo bar/baz" && ', - \ ale#path#CdString('/foo bar/baz') + \ ale#command#CdString('/foo bar/baz') -Execute(BufferCdString should output the correct command string): +Execute(CdString handle substitution and formatting): call ale#test#SetFilename('foo.txt') AssertEqual \ has('unix') ? 'cd %s:h && ' : 'cd /d %s:h && ', - \ ale#path#BufferCdString(bufnr('')) + \ ale#command#CdString('%s:h')