Run ESLint fixer from project root, where possible (#3096)

* 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 9ee57d43 (which I forgot to
apply to the fixer, whoops).

Fixes: #3094
Closes: #3095

Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
This commit is contained in:
Kevin Locke 2020-07-01 16:00:21 +00:00 committed by w0rp
parent 1428c7b29e
commit d8143885a4
No known key found for this signature in database
GPG key ID: 0FC1ECAA8C81CD83
3 changed files with 50 additions and 22 deletions

View file

@ -53,7 +53,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
" Use --fix-to-stdout with eslint_d " Use --fix-to-stdout with eslint_d
if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0]) if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0])
return { return {
\ 'command': ale#node#Executable(a:buffer, l:executable) \ 'command': ale#handlers#eslint#GetCdString(a:buffer)
\ . ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options) \ . ale#Pad(l:options)
\ . ' --stdin-filename %s --stdin --fix-to-stdout', \ . ' --stdin-filename %s --stdin --fix-to-stdout',
\ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput',
@ -63,7 +64,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
" 4.9.0 is the first version with --fix-dry-run " 4.9.0 is the first version with --fix-dry-run
if ale#semver#GTE(a:version, [4, 9, 0]) if ale#semver#GTE(a:version, [4, 9, 0])
return { return {
\ 'command': ale#node#Executable(a:buffer, l:executable) \ 'command': ale#handlers#eslint#GetCdString(a:buffer)
\ . ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options) \ . ale#Pad(l:options)
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
@ -71,7 +73,8 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
endif endif
return { return {
\ 'command': ale#node#Executable(a:buffer, l:executable) \ 'command': ale#handlers#eslint#GetCdString(a:buffer)
\ . ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options) \ . ale#Pad(l:options)
\ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '') \ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '')
\ . ' --fix %t', \ . ' --fix %t',

View file

@ -37,11 +37,9 @@ function! ale#handlers#eslint#GetExecutable(buffer) abort
\]) \])
endfunction endfunction
function! ale#handlers#eslint#GetCommand(buffer) abort " Given a buffer, return a command prefix string which changes directory
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer) " as necessary for running ESLint.
function! ale#handlers#eslint#GetCdString(buffer) abort
let l:options = ale#Var(a:buffer, 'javascript_eslint_options')
" ESLint 6 loads plugins/configs/parsers from the project root " ESLint 6 loads plugins/configs/parsers from the project root
" By default, the project root is simply the CWD of the running process. " 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 " https://github.com/eslint/rfcs/blob/master/designs/2018-simplified-package-loading/README.md
@ -50,9 +48,16 @@ function! ale#handlers#eslint#GetCommand(buffer) abort
" Note: If node_modules not present yet, can't load local deps anyway. " Note: If node_modules not present yet, can't load local deps anyway.
let l:modules_dir = ale#path#FindNearestDirectory(a:buffer, 'node_modules') 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: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) : ''
return l:cd_command return !empty(l:project_dir) ? ale#path#CdString(l:project_dir) : ''
endfunction
function! ale#handlers#eslint#GetCommand(buffer) abort
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
let l:options = ale#Var(a:buffer, 'javascript_eslint_options')
return ale#handlers#eslint#GetCdString(a:buffer)
\ . ale#node#Executable(a:buffer, l:executable) \ . ale#node#Executable(a:buffer, l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -f json --stdin --stdin-filename %s' \ . ' -f json --stdin --stdin-filename %s'

View file

@ -13,7 +13,9 @@ Execute(The executable path should be correct):
AssertFixer AssertFixer
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': (has('win32') ? 'node.exe ' : '') \ 'command':
\ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'))
\ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . 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')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js'))
\ . ' --fix %t', \ . ' --fix %t',
@ -150,7 +152,9 @@ Execute(The lower priority configuration file in a nested directory should be pr
AssertFixer AssertFixer
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': (has('win32') ? 'node.exe ' : '') \ 'command':
\ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'))
\ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . 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')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/subdir-with-config/.eslintrc'))
\ . ' --fix %t', \ . ' --fix %t',
@ -164,7 +168,9 @@ Execute(--config in options should override configuration file detection for old
AssertFixer AssertFixer
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': (has('win32') ? 'node.exe ' : '') \ 'command':
\ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'))
\ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' --config /foo.cfg' \ . ' --config /foo.cfg'
\ . ' --fix %t', \ . ' --fix %t',
@ -175,7 +181,9 @@ Execute(--config in options should override configuration file detection for old
AssertFixer AssertFixer
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': (has('win32') ? 'node.exe ' : '') \ 'command':
\ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'))
\ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' -c /foo.cfg' \ . ' -c /foo.cfg'
\ . ' --fix %t', \ . ' --fix %t',
@ -187,7 +195,9 @@ Execute(package.json should be used as a last resort):
AssertFixer AssertFixer
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': (has('win32') ? 'node.exe ' : '') \ 'command':
\ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'))
\ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . 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')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js'))
\ . ' --fix %t', \ . ' --fix %t',
@ -199,7 +209,8 @@ Execute(package.json should be used as a last resort):
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': \ 'command':
\ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/node_modules/.bin/eslint')) \ 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'))
\ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/package.json')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/package.json'))
\ . ' --fix %t', \ . ' --fix %t',
\ } \ }
@ -214,7 +225,9 @@ 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')) \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' --version', \ . ' --version',
\ { \ {
\ 'command': (has('win32') ? 'node.exe ' : '') \ 'command':
\ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'))
\ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . 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', \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
@ -223,7 +236,9 @@ Execute(The version check should be correct):
AssertFixer [ AssertFixer [
\ { \ {
\ 'command': (has('win32') ? 'node.exe ' : '') \ 'command':
\ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'))
\ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . 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', \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
@ -236,7 +251,9 @@ Execute(--fix-dry-run should be used for 4.9.0 and up):
GivenCommandOutput ['4.9.0'] GivenCommandOutput ['4.9.0']
AssertFixer AssertFixer
\ { \ {
\ 'command': (has('win32') ? 'node.exe ' : '') \ 'command':
\ ale#path#CdString(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app'))
\ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . 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', \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
@ -249,7 +266,8 @@ Execute(--fix-to-stdout should be used for eslint_d):
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': \ 'command':
\ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) \ 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'))
\ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/package.json')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/package.json'))
\ . ' --fix %t', \ . ' --fix %t',
\ } \ }
@ -260,7 +278,8 @@ Execute(--fix-to-stdout should be used for eslint_d):
AssertFixer AssertFixer
\ { \ {
\ 'command': \ 'command':
\ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) \ 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'))
\ . ' --stdin-filename %s --stdin --fix-to-stdout', \ . ' --stdin-filename %s --stdin --fix-to-stdout',
\ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput',
\ } \ }
@ -270,7 +289,8 @@ Execute(--fix-to-stdout should be used for eslint_d):
AssertFixer AssertFixer
\ { \ {
\ 'command': \ 'command':
\ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) \ 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'))
\ . ' --stdin-filename %s --stdin --fix-to-stdout', \ . ' --stdin-filename %s --stdin --fix-to-stdout',
\ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput',
\ } \ }