mirror of
https://github.com/dense-analysis/ale.git
synced 2026-01-31 07:05:31 +08:00
Close #2556 - Support filename mapping
ALE now supports mapping files between different systems for running linters and fixers with Docker, in virtual machines, in servers, etc.
This commit is contained in:
@@ -6,6 +6,7 @@ Before:
|
||||
Save g:ale_lint_on_save
|
||||
Save g:ale_echo_cursor
|
||||
Save g:ale_command_wrapper
|
||||
Save g:ale_filename_mappings
|
||||
|
||||
silent! cd /testplugin/test/fix
|
||||
|
||||
@@ -19,6 +20,7 @@ Before:
|
||||
let g:ale_fixers = {
|
||||
\ 'testft': [],
|
||||
\}
|
||||
let g:ale_filename_mappings = {}
|
||||
|
||||
let g:pre_success = 0
|
||||
let g:post_success = 0
|
||||
@@ -72,6 +74,10 @@ Before:
|
||||
return {'command': 'cat %t <(echo d)'}
|
||||
endfunction
|
||||
|
||||
function EchoFilename(buffer, lines) abort
|
||||
return {'command': 'echo %s'}
|
||||
endfunction
|
||||
|
||||
function RemoveLastLine(buffer, lines) abort
|
||||
return ['a', 'b']
|
||||
endfunction
|
||||
@@ -155,6 +161,7 @@ After:
|
||||
delfunction CatLineDeferred
|
||||
delfunction ReplaceWithTempFile
|
||||
delfunction CatWithTempFile
|
||||
delfunction EchoFilename
|
||||
delfunction RemoveLastLine
|
||||
delfunction RemoveLastLineOneArg
|
||||
delfunction TestCallback
|
||||
@@ -209,6 +216,23 @@ Expect(The first function should be used):
|
||||
^b
|
||||
^c
|
||||
|
||||
Execute(Should apply filename mpapings):
|
||||
" The command echos %s, and we'll map the current path so we can check
|
||||
" that ALEFix applies filename mappings, end-to-end.
|
||||
let g:ale_filename_mappings = {
|
||||
\ 'echo_filename': [
|
||||
\ [expand('%:p:h'), '/some/fake/path'],
|
||||
\ ],
|
||||
\}
|
||||
|
||||
call ale#fix#registry#Add('echo_filename', 'EchoFilename', [], 'echo filename')
|
||||
let g:ale_fixers.testft = ['echo_filename']
|
||||
ALEFix
|
||||
call ale#test#FlushJobs()
|
||||
|
||||
Expect(The mapped filename should be printed):
|
||||
/some/fake/path/test.txt
|
||||
|
||||
Execute(ALEFix should apply simple functions in a chain):
|
||||
let g:ale_fixers.testft = ['AddCarets', 'Capitalize']
|
||||
ALEFix
|
||||
|
||||
62
test/test_filename_mapping.vader
Normal file
62
test/test_filename_mapping.vader
Normal file
@@ -0,0 +1,62 @@
|
||||
Before:
|
||||
Save g:ale_filename_mappings
|
||||
Save b:ale_filename_mappings
|
||||
|
||||
let g:ale_filename_mappings = {}
|
||||
unlet! b:ale_filename_mappings
|
||||
|
||||
After:
|
||||
Restore
|
||||
|
||||
Execute(ale#GetFilenameMappings should return the correct mappings for given linters/fixers):
|
||||
let g:ale_filename_mappings = {'a': [['foo', 'bar']], 'b': [['baz', 'foo']]}
|
||||
|
||||
AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), 'a')
|
||||
AssertEqual [['baz', 'foo']], ale#GetFilenameMappings(bufnr(''), 'b')
|
||||
AssertEqual [], ale#GetFilenameMappings(bufnr(''), 'c')
|
||||
|
||||
let b:ale_filename_mappings = {'b': [['abc', 'xyz']]}
|
||||
|
||||
AssertEqual [], ale#GetFilenameMappings(bufnr(''), 'a')
|
||||
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), 'b')
|
||||
AssertEqual [], ale#GetFilenameMappings(bufnr(''), 'c')
|
||||
|
||||
Execute(ale#GetFilenameMappings should return Lists set for use with all tools):
|
||||
let g:ale_filename_mappings = [['foo', 'bar']]
|
||||
|
||||
AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), 'a')
|
||||
AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), '')
|
||||
AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), v:null)
|
||||
|
||||
let b:ale_filename_mappings = [['abc', 'xyz']]
|
||||
|
||||
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), 'a')
|
||||
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), '')
|
||||
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), v:null)
|
||||
|
||||
Execute(ale#GetFilenameMappings should let you use * as a fallback):
|
||||
let g:ale_filename_mappings = {'a': [['foo', 'bar']], '*': [['abc', 'xyz']]}
|
||||
|
||||
AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), 'a')
|
||||
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), 'b')
|
||||
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), '')
|
||||
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), v:null)
|
||||
|
||||
Execute(ale#filename_mapping#Invert should invert filename mappings):
|
||||
AssertEqual
|
||||
\ [['b', 'a'], ['y', 'x']],
|
||||
\ ale#filename_mapping#Invert([['a', 'b'], ['x', 'y']])
|
||||
\
|
||||
Execute(ale#filename_mapping#Map return the filename as-is if there are no mappings):
|
||||
AssertEqual
|
||||
\ '/foo//bar',
|
||||
\ ale#filename_mapping#Map('/foo//bar', [['/bar', '/data/']])
|
||||
|
||||
Execute(ale#filename_mapping#Map should map filenames):
|
||||
AssertEqual
|
||||
\ '/data/bar',
|
||||
\ ale#filename_mapping#Map('/foo//bar', [
|
||||
\ ['/data', '/baz'],
|
||||
\ ['/foo', '/data'],
|
||||
\ ['/foo', '/xyz'],
|
||||
\ ])
|
||||
@@ -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, [])
|
||||
|
||||
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, [])
|
||||
|
||||
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, [])
|
||||
|
||||
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, [])
|
||||
|
||||
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, [])
|
||||
|
||||
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, [])[2]
|
||||
|
||||
AssertEqual
|
||||
\ 0,
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', 'foo %s', 0, v:null)[2]
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', 'foo %s', 0, 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, [])
|
||||
|
||||
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, [])
|
||||
AssertEqual
|
||||
\ ['', '"foo bar"', 0],
|
||||
\ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null)
|
||||
\ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null, [])
|
||||
AssertEqual
|
||||
\ ['', '%e %e', 0],
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, v:null)
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, 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, [])
|
||||
AssertEqual
|
||||
\ ['', '''foo bar''', 0],
|
||||
\ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null)
|
||||
\ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null, [])
|
||||
AssertEqual
|
||||
\ ['', '%e %e', 0],
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, v:null)
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, 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, [])
|
||||
|
||||
call CheckTempFile(g:result[0])
|
||||
|
||||
@@ -118,10 +118,24 @@ 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, [])
|
||||
|
||||
call CheckTempFile(g:result[0])
|
||||
|
||||
let g:match = matchlist(g:result[1], '\v^foo bar (.*)$')
|
||||
Assert !empty(g:match), 'No match found! Result was: ' . g:result[1]
|
||||
AssertEqual ale#Escape(g:result[0]), g:match[1]
|
||||
|
||||
Execute(FormatCommand should apply filename mappings the current file):
|
||||
let g:result = ale#command#FormatCommand(bufnr('%'), '', '%s', 1, 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', 1, v:null, [
|
||||
\ [fnamemodify(tempname(), ':h:h'), '/foo/bar']
|
||||
\])
|
||||
|
||||
Assert g:result[1] =~# '/foo/bar'
|
||||
|
||||
@@ -1,7 +1,50 @@
|
||||
Before:
|
||||
Save g:ale_filename_mappings
|
||||
|
||||
let g:ale_filename_mappings = {}
|
||||
|
||||
After:
|
||||
unlet! b:temp_name
|
||||
unlet! b:other_bufnr
|
||||
|
||||
Restore
|
||||
|
||||
|
||||
Execute(FixLocList should map filenames):
|
||||
" Paths converted back into temporary filenames shouldn't be included.
|
||||
let g:ale_filename_mappings = {
|
||||
\ 'linter2': [['/xxx', '/data']],
|
||||
\ 'linter1': [
|
||||
\ ['/bar', '/data/special'],
|
||||
\ ['/foo', '/data'],
|
||||
\ [
|
||||
\ ale#path#Simplify(fnamemodify(ale#util#Tempname(), ':h:h')),
|
||||
\ '/x-tmp',
|
||||
\ ],
|
||||
\ ],
|
||||
\}
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ '/foo/file.txt',
|
||||
\ v:null,
|
||||
\ '/bar/file.txt',
|
||||
\ ],
|
||||
\ map(
|
||||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'linter1',
|
||||
\ 0,
|
||||
\ [
|
||||
\ {'text': 'x', 'lnum': 1, 'filename': '/data/file.txt'},
|
||||
\ {'text': 'x', 'lnum': 1, 'filename': '/x-tmp/file.txt'},
|
||||
\ {'text': 'x', 'lnum': 1, 'filename': '/data/special/file.txt'},
|
||||
\ ],
|
||||
\ ),
|
||||
\ 'get(v:val, ''filename'', v:null)',
|
||||
\ )
|
||||
|
||||
|
||||
Given foo (Some file with lines to count):
|
||||
foo12345678
|
||||
bar12345678
|
||||
@@ -37,7 +80,7 @@ Execute(FixLocList should set all the default values correctly):
|
||||
\ 'nr': -1,
|
||||
\ 'linter_name': 'foobar',
|
||||
\ },
|
||||
\],
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
@@ -58,7 +101,7 @@ Execute(FixLocList should use the values we supply):
|
||||
\ 'nr': 42,
|
||||
\ 'linter_name': 'foobar',
|
||||
\ },
|
||||
\],
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
@@ -87,7 +130,7 @@ Execute(FixLocList should set items with lines beyond the end to the last line):
|
||||
\ 'nr': -1,
|
||||
\ 'linter_name': 'foobar',
|
||||
\ },
|
||||
\],
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
@@ -108,7 +151,7 @@ Execute(FixLocList should move line 0 to line 1):
|
||||
\ 'nr': -1,
|
||||
\ 'linter_name': 'foobar',
|
||||
\ },
|
||||
\],
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
@@ -130,7 +173,7 @@ Execute(FixLocList should convert line and column numbers correctly):
|
||||
\ 'nr': -1,
|
||||
\ 'linter_name': 'foobar',
|
||||
\ },
|
||||
\],
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
@@ -164,7 +207,7 @@ Execute(FixLocList should pass on end_col values):
|
||||
\ 'nr': -1,
|
||||
\ 'linter_name': 'foobar',
|
||||
\ },
|
||||
\],
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
@@ -202,7 +245,7 @@ Execute(FixLocList should pass on end_lnum values):
|
||||
\ 'nr': -1,
|
||||
\ 'linter_name': 'foobar',
|
||||
\ },
|
||||
\],
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
@@ -227,7 +270,7 @@ Execute(FixLocList should allow subtypes to be set):
|
||||
\ 'nr': -1,
|
||||
\ 'linter_name': 'foobar',
|
||||
\ },
|
||||
\],
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
@@ -289,7 +332,7 @@ Execute(FixLocList should accept filenames):
|
||||
\ 'nr': -1,
|
||||
\ 'linter_name': 'foobar',
|
||||
\ },
|
||||
\],
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
@@ -327,7 +370,7 @@ Execute(FixLocList should interpret temporary filenames as being the current buf
|
||||
\ 'nr': -1,
|
||||
\ 'linter_name': 'foobar',
|
||||
\ },
|
||||
\],
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(
|
||||
\ bufnr(''),
|
||||
\ 'foobar',
|
||||
@@ -352,7 +395,7 @@ Execute(The error code should be passed on):
|
||||
\ 'linter_name': 'foobar',
|
||||
\ 'code': 'some-code'
|
||||
\ },
|
||||
\],
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
@@ -385,7 +428,7 @@ Execute(FixLocList should mark problems as coming from other sources if requeste
|
||||
\ 'linter_name': 'foobar',
|
||||
\ 'from_other_source': 1,
|
||||
\ },
|
||||
\],
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
@@ -407,7 +450,7 @@ Execute(character positions should be converted to byte positions):
|
||||
\ {'lnum': 1, 'bufnr': bufnr(''), 'col': 7, 'end_col': 13, 'end_lnum': 1, 'linter_name': 'foobar', 'nr': -1, 'type': 'E', 'vcol': 0, 'text': 'a'},
|
||||
\ {'lnum': 1, 'bufnr': bufnr(''), 'col': 7, 'end_col': 17, 'end_lnum': 2, 'linter_name': 'foobar', 'nr': -1, 'type': 'E', 'vcol': 0, 'text': 'a'},
|
||||
\ {'lnum': 2, 'bufnr': bufnr(''), 'col': 17, 'linter_name': 'foobar', 'nr': -1, 'type': 'E', 'vcol': 0, 'text': 'a'},
|
||||
\],
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
|
||||
Reference in New Issue
Block a user