Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eslint fixer does not change directory (unlike eslint checker) and therefore cannot find plugins #3094

Closed
hjwp opened this issue Apr 3, 2020 · 3 comments · Fixed by #3096
Labels

Comments

@hjwp
Copy link
Contributor

hjwp commented Apr 3, 2020

Information

VIM version

VIM - Vi IMproved 8.1 (2018 May 18, compiled Mar 19 2020 13:12:18)
Included patches: 1-875, 878, 884, 948, 1046, 1365-1368, 1382, 1401

Operating System: ubuntu 19.10

What went wrong

I've been trying to configure eslint for a react/typescript project. Got the linter working, but not the fixer. my javascript files are in a subfolder of my main project root.

Reproducing the bug

  • in a subfolder of an existing project, start a create-react-app project
  • from the top-level folder, use vim to open a file with errors
  • note errors are suggested, linting/checking works.
  • but run :ALEFix and nothing happens.

here's what i think is happening: the checker does a cd to the folder that contains node_modules and the .eslintrc.js. but when it gets run as a fixer, it does not do that CD.

(finished - exit code 1) ['/bin/zsh', '-c', 'cd ''/home/harry/workspace/casper/ui'' && ''/home/harry/workspace/casper/ui/node_modules/eslint/bin/eslint.js'' -f json --stdin --stdin-filename ''/home/harry/workspace/casper/ui/src/App.test.tsx'' < ''/tmp/vZQ7KPK/1/App.test.tsx''']

vs

(finished - exit code 2) ['/bin/zsh', '-c', '''/home/harry/workspace/casper/ui/node_modules/eslint/bin/eslint.js'' --stdin-filename ''/home/harry/workspace/casper/ui/src/App.test.tsx'' --stdin --fix-dry-run --format=json < ''/tmp/vZQ7KPK/2/App.test.tsx''']

rerunning the above manually gives

ESLint couldn't find the plugin "eslint-plugin-react".

if I cd into the ui directory, then it runs ok.

:ALEInfo

 Current Filetype: typescript
Available Linters: ['eslint', 'standard', 'tslint', 'tsserver', 'typecheck', 'xo']
  Enabled Linters: ['eslint', 'standard', 'tslint', 'tsserver', 'typecheck', 'xo']
 Suggested Fixers: 
  'eslint' - Apply eslint --fix to a file.
  'prettier' - Apply prettier to a file.
  'remove_trailing_lines' - Remove all blank lines at the end of a file.
  'trim_whitespace' - Remove all trailing whitespace characters at the end of every line.
  'tslint' - Fix typescript files with tslint --fix.
  'xo' - Fix JavaScript/TypeScript files using xo --fix.
 Linter Variables:

let g:ale_typescript_standard_executable = 'standard'
let g:ale_typescript_standard_options = ''
let g:ale_typescript_standard_use_global = 0
let g:ale_typescript_tslint_config_path = ''
let g:ale_typescript_tslint_executable = 'tslint'
let g:ale_typescript_tslint_ignore_empty_files = 0
let g:ale_typescript_tslint_rules_dir = ''
let g:ale_typescript_tslint_use_global = 0
let g:ale_typescript_tsserver_config_path = ''
let g:ale_typescript_tsserver_executable = 'tsserver'
let g:ale_typescript_tsserver_use_global = 0
let g:ale_typescript_xo_executable = 'xo'
let g:ale_typescript_xo_options = ''
let g:ale_typescript_xo_use_global = 0
 Global Variables:

let g:ale_cache_executable_check_failures = v:null
let g:ale_change_sign_column_color = 0
let g:ale_command_wrapper = ''
let g:ale_completion_delay = v:null
let g:ale_completion_enabled = 0
let g:ale_completion_max_suggestions = v:null
let g:ale_echo_cursor = 1
let g:ale_echo_msg_error_str = 'Error'
let g:ale_echo_msg_format = '%code: %%s'
let g:ale_echo_msg_info_str = 'Info'
let g:ale_echo_msg_warning_str = 'Warning'
let g:ale_enabled = 1
let g:ale_fix_on_save = 0
let g:ale_fixers = {'typescript': ['eslint'], '*': ['remove_trailing_lines'], 'javascript': ['eslint'], 'python': ['black']}
let g:ale_history_enabled = 1
let g:ale_history_log_output = 1
let g:ale_keep_list_window_open = 0
let g:ale_lint_delay = 200
let g:ale_lint_on_enter = 1
let g:ale_lint_on_filetype_changed = 1
let g:ale_lint_on_insert_leave = 1
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'normal'
let g:ale_linter_aliases = {}
let g:ale_linters = {}
let g:ale_linters_explicit = 0
let g:ale_list_vertical = 0
let g:ale_list_window_size = 10
let g:ale_loclist_msg_format = '%code: %%s'
let g:ale_lsp_root = {}
let g:ale_max_buffer_history_size = 20
let g:ale_max_signs = -1
let g:ale_maximum_file_size = v:null
let g:ale_open_list = 0
let g:ale_pattern_options = v:null
let g:ale_pattern_options_enabled = v:null
let g:ale_set_balloons = 0
let g:ale_set_highlights = 1
let g:ale_set_loclist = 1
let g:ale_set_quickfix = 0
let g:ale_set_signs = 1
let g:ale_sign_column_always = 0
let g:ale_sign_error = '>>'
let g:ale_sign_info = '--'
let g:ale_sign_offset = 1000000
let g:ale_sign_style_error = '>>'
let g:ale_sign_style_warning = '--'
let g:ale_sign_warning = '--'
let g:ale_sign_highlight_linenrs = 0
let g:ale_statusline_format = v:null
let g:ale_type_map = {}
let g:ale_use_global_executables = v:null
let g:ale_virtualtext_cursor = 0
let g:ale_warn_about_trailing_blank_lines = 1
let g:ale_warn_about_trailing_whitespace = 1
  Command History:

(executable check - success) /home/harry/workspace/casper/ui/node_modules/eslint/bin/eslint.js
(finished - exit code 1) ['/bin/zsh', '-c', 'cd ''/home/harry/workspace/casper/ui'' && ''/home/harry/workspace/casper/ui/node_modules/eslint/bin/eslint.js'' -f json --stdin --stdin-filename ''/home/harry/workspace/casper/ui/src/App.test.tsx'' < ''/tmp/vZQ7KPK/1/App.test.tsx''']

<<<OUTPUT STARTS>>>
[{"filePath":"/home/harry/workspace/casper/ui/src/App.test.tsx","messages":[{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'ReactTestUtils' is defined but never used.","line":7,"column":8,"nodeType":"Identifier","endLine":7,"endColumn":22}, TRIMMED \n"}]
<<<OUTPUT ENDS>>>

(executable check - failure) standard
(executable check - failure) tslint
(executable check - success) /home/harry/workspace/casper/ui/node_modules/.bin/tsserver
(started) ['/bin/zsh', '-c', '''/home/harry/workspace/casper/ui/node_modules/.bin/tsserver''']
(executable check - failure) typecheck
(executable check - failure) xo
(finished - exit code 0) ['/bin/zsh', '-c', '''/home/harry/workspace/casper/ui/node_modules/eslint/bin/eslint.js'' --version']

<<<OUTPUT STARTS>>>
v6.8.0
<<<OUTPUT ENDS>>>

(finished - exit code 2) ['/bin/zsh', '-c', '''/home/harry/workspace/casper/ui/node_modules/eslint/bin/eslint.js'' --stdin-filename ''/home/harry/workspace/casper/ui/src/App.test.tsx'' --stdin --fix-dry-run --format=json < ''/tmp/vZQ7KPK/2/App.test.tsx''']
(finished - exit code 1) ['/bin/zsh', '-c', 'cd ''/home/harry/workspace/casper/ui'' && ''/home/harry/workspace/casper/ui/node_modules/eslint/bin/eslint.js'' -f json --stdin --stdin-filename ''/home/harry/workspace/casper/ui/src/App.test.tsx'' < ''/tmp/vZQ7KPK/3/App.test.tsx''']

<<<OUTPUT STARTS>>>
[{"filePath":"/home/harry/workspace/casper/ui/src/App.test.tsx","messages":[{"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'ReactTestUtils' is defined but never used.","line":7,"column":8,"nodeType":"Identifier","endLine":7,"endColumn":22},TRIMMED"}]
<<<OUTPUT ENDS>>>

(executable check - failure) standard
(executable check - failure) tslint
(executable check - failure) typecheck
(executable check - failure) xo
(finished - exit code 2) ['/bin/zsh', '-c', '''/home/harry/workspace/casper/ui/node_modules/eslint/bin/eslint.js'' --stdin-filename ''/home/harry/workspace/casper/ui/src/App.test.tsx'' --stdin --fix-dry-run --format=json < ''/tmp/vZQ7KPK/4/App.test.tsx''']
@hjwp hjwp added the bug label Apr 3, 2020
@RyanSquared
Copy link
Member

diff --git a/autoload/ale/fixers/eslint.vim b/autoload/ale/fixers/eslint.vim
index 62e692b1..2dbf5f30 100644
--- a/autoload/ale/fixers/eslint.vim
+++ b/autoload/ale/fixers/eslint.vim
@@ -3,7 +3,12 @@
 
 function! ale#fixers#eslint#Fix(buffer) abort
     let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
-    let l:command = ale#node#Executable(a:buffer, l:executable)
+
+    let l:modules_dir = ale#path#FindNearestDirectory(a:buffer, 'node_modules')
+    let l:project_dir = !empty(l:modules_dir) ? fnamemodify(l:modules_dir, ':h:h') : ''
+    let l:cd_command = !empty(l:project_dir) ? ale#path#CdString(l:project_dir) : ''
+
+    let l:command = l:cd_command . ale#node#Executable(a:buffer, l:executable)
     \   . ' --version'
 
     return ale#semver#RunWithVersionCheck(

I was going to suggest the above patch, but I think it might be a bit more complicated. Can you try it out anyways?

To apply it, save the patch, and run git apply the_file.patch.

@hjwp
Copy link
Contributor Author

hjwp commented Apr 4, 2020

I think I actually hacked together something more or less exactly like that. iirc it didn't quite work. not at a proper computer rn but will take a look on monday...

@hjwp
Copy link
Contributor Author

hjwp commented Apr 4, 2020

had a bash ⬆️ will add tests if i get a spare moment, and can figure them out.

kevinoid added a commit to kevinoid/ale that referenced this issue Apr 5, 2020
To match the ESLint linter, as changed in 9ee57d4 (which I forgot to
apply to the fixer, whoops).

Fixes: dense-analysis#3094
Closes: dense-analysis#3095

Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
@w0rp w0rp closed this as completed in #3096 Jul 1, 2020
w0rp pushed a commit that referenced this issue Jul 1, 2020
* Split eslint#GetCdString from eslint#GetCommand

Move the code for finding the project root and building the cd string
into a separate function so that it can be reused in the eslint fixer.

Signed-off-by: Kevin Locke <kevin@kevinlocke.name>

* Run ESLint fixer from project root dir

To match the ESLint linter, as changed in 9ee57d4 (which I forgot to
apply to the fixer, whoops).

Fixes: #3094
Closes: #3095

Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
w0rp pushed a commit that referenced this issue Jul 1, 2020
* Split eslint#GetCdString from eslint#GetCommand

Move the code for finding the project root and building the cd string
into a separate function so that it can be reused in the eslint fixer.

Signed-off-by: Kevin Locke <kevin@kevinlocke.name>

* Run ESLint fixer from project root dir

To match the ESLint linter, as changed in 9ee57d4 (which I forgot to
apply to the fixer, whoops).

Fixes: #3094
Closes: #3095

Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants