Fix #1716 - Replace tempdir() with a wrapper to preserve TMPDIR

This commit is contained in:
w0rp 2018-07-12 13:05:59 +01:00
parent 1fc3a1563b
commit 7d66293bbc
No known key found for this signature in database
GPG key ID: 0FC1ECAA8C81CD83
18 changed files with 145 additions and 133 deletions

View file

@ -29,7 +29,7 @@ function! ale_linters#cs#mcsc#GetCommand(buffer) abort
\ : ''
" register temporary module target file with ale
let l:out = tempname()
let l:out = ale#util#Tempname()
call ale#engine#ManageFile(a:buffer, l:out)
" The code is compiled as a module and the output is redirected to a

View file

@ -10,7 +10,7 @@ endfunction
function! ale_linters#cuda#nvcc#GetCommand(buffer) abort
" Unused: use ale#util#nul_file
" let l:output_file = tempname() . '.ii'
" let l:output_file = ale#util#Tempname() . '.ii'
" call ale#engine#ManageFile(a:buffer, l:output_file)
return ale#Escape(ale_linters#cuda#nvcc#GetExecutable(a:buffer))

View file

@ -128,14 +128,7 @@ function! ale_linters#elm#make#HandleElm018Line(line, output) abort
endfunction
function! ale_linters#elm#make#FileIsBuffer(path) abort
let l:is_windows = has('win32')
let l:temp_dir = l:is_windows ? $TMP : $TMPDIR
if has('win32')
return a:path[0:len(l:temp_dir) - 1] is? l:temp_dir
else
return a:path[0:len(l:temp_dir) - 1] is# l:temp_dir
endif
return ale#path#IsTempName(a:path)
endfunction
function! ale_linters#elm#make#ParseMessage(message) abort

View file

@ -3,7 +3,7 @@
let g:ale_erlang_erlc_options = get(g:, 'ale_erlang_erlc_options', '')
function! ale_linters#erlang#erlc#GetCommand(buffer) abort
let l:output_file = tempname()
let l:output_file = ale#util#Tempname()
call ale#engine#ManageFile(a:buffer, l:output_file)
return 'erlc -o ' . ale#Escape(l:output_file)

View file

@ -20,7 +20,7 @@ function! ale_linters#thrift#thrift#GetCommand(buffer) abort
let l:generators = ['cpp']
endif
let l:output_dir = tempname()
let l:output_dir = ale#util#Tempname()
call mkdir(l:output_dir)
call ale#engine#ManageDirectory(a:buffer, l:output_dir)

View file

@ -7,7 +7,7 @@ if !exists('g:ale_verilog_verilator_options')
endif
function! ale_linters#verilog#verilator#GetCommand(buffer) abort
let l:filename = tempname() . '_verilator_linted.v'
let l:filename = ale#util#Tempname() . '_verilator_linted.v'
" Create a special filename, so we can detect it in the handler.
call ale#engine#ManageFile(a:buffer, l:filename)

View file

@ -13,7 +13,7 @@ function! s:TemporaryFilename(buffer) abort
" Create a temporary filename, <temp_dir>/<original_basename>
" The file itself will not be created by this function.
return tempname() . (has('win32') ? '\' : '/') . l:filename
return ale#util#Tempname() . (has('win32') ? '\' : '/') . l:filename
endfunction
" Given a command string, replace every...

View file

@ -98,7 +98,7 @@ endfunction
" Create a new temporary directory and manage it in one go.
function! ale#engine#CreateDirectory(buffer) abort
let l:temporary_directory = tempname()
let l:temporary_directory = ale#util#Tempname()
" Create the temporary directory for the file, unreadable by 'other'
" users.
call mkdir(l:temporary_directory, '', 0750)

View file

@ -2,7 +2,7 @@
" Description: Error handling for the format GHC outputs.
" Remember the directory used for temporary files for Vim.
let s:temp_dir = fnamemodify(tempname(), ':h')
let s:temp_dir = fnamemodify(ale#util#Tempname(), ':h')
" Build part of a regular expression for matching ALE temporary filenames.
let s:temp_regex_prefix =
\ '\M'

View file

@ -84,7 +84,7 @@ function! ale#path#IsAbsolute(filename) abort
return a:filename[:0] is# '/' || a:filename[1:2] is# ':\'
endfunction
let s:temp_dir = ale#path#Simplify(fnamemodify(tempname(), ':h'))
let s:temp_dir = ale#path#Simplify(fnamemodify(ale#util#Tempname(), ':h'))
" Given a filename, return 1 if the file represents some temporary file
" created by Vim.

View file

@ -277,6 +277,25 @@ function! ale#util#InSandbox() abort
return 0
endfunction
function! ale#util#Tempname() abort
let l:clear_tempdir = 0
if has('unix') && empty($TMPDIR)
let l:clear_tempdir = 1
let $TMPDIR = '/tmp'
endif
try
let l:name = tempname() " no-custom-checks
finally
if l:clear_tempdir
let $TMPDIR = ''
endif
endtry
return l:name
endfunction
" Given a single line, or a List of lines, and a single pattern, or a List
" of patterns, return all of the matches for the lines(s) from the given
" patterns, using matchlist().

View file

@ -111,6 +111,9 @@ these are reported with ALE's `custom-linting-rules` script. See
* Don't use the `shellescape()` function. It doesn't escape arguments properly
on Windows. Use `ale#Escape()` instead, which will avoid escaping where it
isn't needed, and generally escape arguments better on Windows.
* Don't use the `tempname()` function. It doesn't work when `$TMPDIR` isn't
set. Use `ale#util#Tempname()` instead, which temporarily sets `$TMPDIR`
appropriately where needed.
Apply the following guidelines when writing Vader test files.

View file

@ -35,12 +35,6 @@ endif
" Set this flag so that other plugins can use it, like airline.
let g:loaded_ale = 1
" Set the TMPDIR environment variable if it is not set automatically.
" This can automatically fix some environments.
if has('unix') && empty($TMPDIR)
let $TMPDIR = '/tmp'
endif
" This global variable is used internally by ALE for tracking information for
" each buffer which linters are being run against.
let g:ale_buffer_info = {}

View file

@ -1,10 +1,7 @@
Before:
let b:tmp = has('win32') ? substitute($TMP, '\\', '\\\\', 'g') : $TMPDIR
runtime ale_linters/elm/make.vim
After:
unlet! b:tmp
unlet! g:config_error_lines
call ale#linter#Reset()
@ -22,12 +19,12 @@ Execute(The elm-make handler should parse Elm 0.19 general problems correctly):
\ }
\ ],
\ ale_linters#elm#make#Handle(347, [
\ '{
\ "type": "error",
\ "path": "' . b:tmp . '/Module.elm",
\ "title": "UNKNOWN IMPORT",
\ "message": ["error details\n\n", { "string": "styled details" }]
\ }'
\ json_encode({
\ 'type': 'error',
\ 'path': ale#util#Tempname() . '/Module.elm',
\ 'title': 'UNKNOWN IMPORT',
\ 'message': ["error details\n\n", { 'string': 'styled details' }]
\ }),
\ ])
Execute(The elm-make handler should parse Elm 0.19 compilation errors correctly):
@ -47,7 +44,7 @@ Execute(The elm-make handler should parse Elm 0.19 compilation errors correctly)
\ 'end_lnum': 407,
\ 'end_col': 17,
\ 'type': 'E',
\ 'text': "error details 2",
\ 'text': 'error details 2',
\ },
\ {
\ 'lnum': 406,
@ -55,35 +52,35 @@ Execute(The elm-make handler should parse Elm 0.19 compilation errors correctly)
\ 'end_lnum': 406,
\ 'end_col': 93,
\ 'type': 'E',
\ 'text': "error details 3",
\ 'text': 'error details 3',
\ },
\ ],
\ ale_linters#elm#make#Handle(347, [
\ '{
\ "type": "compile-errors",
\ "errors": [
\ json_encode({
\ 'type': 'compile-errors',
\ 'errors': [
\ {
\ "path": "' . b:tmp . '/Module.elm",
\ "problems": [
\ 'path': ale#util#Tempname() . '/Module.elm',
\ 'problems': [
\ {
\ "title": "TYPE MISMATCH",
\ "message": ["error details 1\n\n", { "string": "styled details" }],
\ "region": { "start": { "line": 404, "column": 1 }, "end": { "line": 408, "column": 18 } }
\ 'title': 'TYPE MISMATCH',
\ 'message': ["error details 1\n\n", { 'string': 'styled details' }],
\ 'region': { 'start': { 'line': 404, 'column': 1 }, 'end': { 'line': 408, 'column': 18 } }
\ },
\ {
\ "title": "TYPE MISMATCH",
\ "message": ["error details 2"],
\ "region": { "start": {"line": 406, "column": 5}, "end": {"line": 407, "column": 17 } }
\ 'title': 'TYPE MISMATCH',
\ 'message': ['error details 2'],
\ 'region': { 'start': {'line': 406, 'column': 5}, 'end': {'line': 407, 'column': 17 } }
\ },
\ {
\ "title": "TYPE MISMATCH",
\ "message": ["error details 3"],
\ "region": { "start": { "line": 406, "column": 5}, "end": {"line": 406, "column": 93 } }
\ 'title': 'TYPE MISMATCH',
\ 'message': ['error details 3'],
\ 'region': { 'start': { 'line': 406, 'column': 5}, 'end': {'line': 406, 'column': 93 } }
\ }
\ ]
\ }
\ ]
\ }'
\ }),
\ ])
Execute(The elm-make handler should handle errors in Elm 0.19 imported modules):
@ -109,33 +106,33 @@ Execute(The elm-make handler should handle errors in Elm 0.19 imported modules):
\ },
\ ],
\ ale_linters#elm#make#Handle(347, [
\ '{
\ "type": "error",
\ "path": "src/Module.elm",
\ "title": "UNKNOWN IMPORT",
\ "message": ["error details\n\n", { "string": "styled details" }]
\ }',
\ '{
\ "type": "error",
\ "path": null,
\ "title": "UNKNOWN IMPORT",
\ "message": ["error details\n\n", { "string": "styled details" }]
\ }',
\ '{
\ "type": "compile-errors",
\ "errors": [
\ json_encode({
\ 'type': 'error',
\ 'path': 'src/Module.elm',
\ 'title': 'UNKNOWN IMPORT',
\ 'message': ["error details\n\n", { 'string': 'styled details' }]
\ }),
\ json_encode({
\ 'type': 'error',
\ 'path': v:null,
\ 'title': 'UNKNOWN IMPORT',
\ 'message': ["error details\n\n", { 'string': 'styled details' }]
\ }),
\ json_encode({
\ 'type': 'compile-errors',
\ 'errors': [
\ {
\ "path": "src/Module.elm",
\ "problems": [
\ 'path': 'src/Module.elm',
\ 'problems': [
\ {
\ "title": "TYPE MISMATCH",
\ "message": ["error details\n\n", { "string": "styled details" }],
\ "region": { "start": { "line": 404, "column": 1 }, "end": { "line": 408, "column": 18 } }
\ 'title': 'TYPE MISMATCH',
\ 'message': ["error details\n\n", { 'string': 'styled details' }],
\ 'region': { 'start': { 'line': 404, 'column': 1 }, 'end': { 'line': 408, 'column': 18 } }
\ }
\ ]
\ }
\ ]
\ }'
\ }),
\ ])
@ -182,45 +179,45 @@ Execute(The elm-make handler should parse Elm 0.18 compilation errors correctly)
\ },
\ ],
\ ale_linters#elm#make#Handle(347, [
\ '[
\ json_encode([
\ {
\ "tag": "unused import",
\ "overview": "warning overview",
\ "details": "warning details",
\ "region": {"start": { "line": 33, "column": 1 }, "end": { "line": 33, "column": 19 } },
\ "type": "warning",
\ "file": "' . b:tmp . '/Module.elm"
\ 'tag': 'unused import',
\ 'overview': 'warning overview',
\ 'details': 'warning details',
\ 'region': {'start': { 'line': 33, 'column': 1 }, 'end': { 'line': 33, 'column': 19 } },
\ 'type': 'warning',
\ 'file': ale#util#Tempname() . '/Module.elm',
\ }
\ ]',
\ '[
\ ]),
\ json_encode([
\ {
\ "tag": "TYPE MISMATCH",
\ "overview": "error overview 1",
\ "subregion": { "start": { "line": 406, "column": 5 }, "end": { "line": 408, "column": 18 } },
\ "details": "error details 1",
\ "region": { "start": { "line": 404, "column": 1 }, "end": { "line": 408, "column": 18 } },
\ "type": "error",
\ "file":"' . b:tmp . '/Module.elm"
\ 'tag': 'TYPE MISMATCH',
\ 'overview': 'error overview 1',
\ 'subregion': { 'start': { 'line': 406, 'column': 5 }, 'end': { 'line': 408, 'column': 18 } },
\ 'details': 'error details 1',
\ 'region': { 'start': { 'line': 404, 'column': 1 }, 'end': { 'line': 408, 'column': 18 } },
\ 'type': 'error',
\ 'file': ale#util#Tempname() . '/Module.elm',
\ },
\ {
\ "tag": "TYPE MISMATCH",
\ "overview": "error overview 2",
\ "subregion": { "start": { "line": 407, "column": 12 }, "end": { "line": 407, "column": 17 } },
\ "details": "error details 2",
\ "region": { "start": { "line": 406, "column": 5}, "end": { "line": 407, "column": 17 } },
\ "type":"error",
\ "file":"' . b:tmp . '/Module.elm"
\ 'tag': 'TYPE MISMATCH',
\ 'overview': 'error overview 2',
\ 'subregion': { 'start': { 'line': 407, 'column': 12 }, 'end': { 'line': 407, 'column': 17 } },
\ 'details': 'error details 2',
\ 'region': { 'start': { 'line': 406, 'column': 5}, 'end': { 'line': 407, 'column': 17 } },
\ 'type':'error',
\ 'file': ale#util#Tempname() . '/Module.elm',
\ },
\ {
\ "tag": "TYPE MISMATCH",
\ "overview": "error overview 3",
\ "subregion": { "start": { "line": 406, "column": 88 }, "end": { "line": 406, "column": 93 } },
\ "details": "error details 3",
\ "region": { "start": { "line": 406, "column": 5 }, "end": { "line": 406, "column": 93 } },
\ "type":"error",
\ "file":"' . b:tmp . '/Module.elm"
\ 'tag': 'TYPE MISMATCH',
\ 'overview': 'error overview 3',
\ 'subregion': { 'start': { 'line': 406, 'column': 88 }, 'end': { 'line': 406, 'column': 93 } },
\ 'details': 'error details 3',
\ 'region': { 'start': { 'line': 406, 'column': 5 }, 'end': { 'line': 406, 'column': 93 } },
\ 'type':'error',
\ 'file': ale#util#Tempname() . '/Module.elm',
\ }
\ ]'
\ ]),
\ ])
Execute(The elm-make handler should handle errors in Elm 0.18 imported modules):
@ -229,29 +226,29 @@ Execute(The elm-make handler should handle errors in Elm 0.18 imported modules):
\ {
\ 'lnum': 1,
\ 'type': 'E',
\ 'text': "src/Module.elm:33 - error overview",
\ 'text': 'src/Module.elm:33 - error overview',
\ 'detail': "src/Module.elm:33 ----------\n\nerror overview\n\nerror details"
\ }
\ ],
\ ale_linters#elm#make#Handle(347, [
\ '[
\ json_encode([
\ {
\ "tag": "unused import",
\ "overview": "warning overview",
\ "details": "warning details",
\ "region": {"start": { "line": 33, "column": 1 }, "end": { "line": 33, "column": 19 } },
\ "type": "warning",
\ "file": "src/Module.elm"
\ 'tag': 'unused import',
\ 'overview': 'warning overview',
\ 'details': 'warning details',
\ 'region': {'start': { 'line': 33, 'column': 1 }, 'end': { 'line': 33, 'column': 19 } },
\ 'type': 'warning',
\ 'file': 'src/Module.elm',
\ },
\ {
\ "tag": "type error",
\ "overview": "error overview",
\ "details": "error details",
\ "region": {"start": { "line": 33, "column": 1 }, "end": { "line": 33, "column": 19 } },
\ "type": "error",
\ "file": "src/Module.elm"
\ 'tag': 'type error',
\ 'overview': 'error overview',
\ 'details': 'error details',
\ 'region': {'start': { 'line': 33, 'column': 1 }, 'end': { 'line': 33, 'column': 19 } },
\ 'type': 'error',
\ 'file': 'src/Module.elm',
\ }
\ ]',
\ ]),
\ ])
" Generic
@ -275,21 +272,21 @@ Execute(The elm-make handler should put an error on the first line if a line can
\ },
\ ],
\ ale_linters#elm#make#Handle(347, [
\ '{
\ "type": "compile-errors",
\ "errors": [
\ json_encode({
\ 'type': 'compile-errors',
\ 'errors': [
\ {
\ "path": "' . b:tmp . '/Module.elm",
\ "problems": [
\ 'path': ale#util#Tempname() . '/Module.elm',
\ 'problems': [
\ {
\ "title": "TYPE MISMATCH",
\ "message": ["error details 1\n\n", { "string": "styled details" }],
\ "region": { "start": { "line": 404, "column": 1 }, "end": { "line": 408, "column": 18 } }
\ 'title': 'TYPE MISMATCH',
\ 'message': ["error details 1\n\n", { 'string': 'styled details' }],
\ 'region': { 'start': { 'line': 404, 'column': 1 }, 'end': { 'line': 408, 'column': 18 } }
\ }
\ ]
\ }
\ ]
\ }',
\ }),
\ 'Not JSON',
\ 'Also not JSON',
\ ])

View file

@ -87,6 +87,7 @@ check_errors $'\t' 'Use four spaces, not tabs'
check_errors 'let g:ale_\w\+_\w\+_args =' 'Name your option g:ale_<filetype>_<lintername>_options instead'
check_errors 'shellescape(' 'Use ale#Escape instead of shellescape'
check_errors 'simplify(' 'Use ale#path#Simplify instead of simplify'
check_errors 'tempname(' 'Use ale#util#Tempname instead of tempname'
check_errors "expand(['\"]%" "Use expand('#' . a:buffer . '...') instead. You might get a filename for the wrong buffer."
check_errors 'getcwd()' "Do not use getcwd(), as it could run from the wrong buffer. Use expand('#' . a:buffer . ':p:h') instead."
check_errors '==#' "Use 'is#' instead of '==#'. 0 ==# 'foobar' is true"

View file

@ -1,4 +0,0 @@
Execute($TMPDIR should be set to a default value if unset):
if has('unix')
AssertEqual '/tmp', $TMPDIR
endif

View file

@ -0,0 +1,13 @@
Before:
Save $TMPDIR
After:
Restore
Execute(ale#util#Tempname should create files in /tmp if $TMPDIR isn't set):
if has('unix')
let $TMPDIR = ''
Assert ale#util#Tempname() =~# '^/tmp'
" We should unlet the environment variable again.
AssertEqual '', $TMPDIR
endif

View file

@ -35,7 +35,3 @@ set ttimeoutlen=0
execute 'set encoding=utf-8'
let g:mapleader=','
" Clear the TMPDIR value for tests.
" The plugin should set this to /tmp by default, which we will test.
let $TMPDIR = ''