Fix #1716 - Replace tempdir() with a wrapper to preserve TMPDIR
This commit is contained in:
parent
6ef31073dd
commit
ac0abc7c1f
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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...
|
||||
|
@ -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)
|
||||
|
@ -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'
|
||||
|
@ -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.
|
||||
|
@ -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().
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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 = {}
|
||||
|
@ -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',
|
||||
\ ])
|
||||
|
@ -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"
|
||||
|
@ -1,4 +0,0 @@
|
||||
Execute($TMPDIR should be set to a default value if unset):
|
||||
if has('unix')
|
||||
AssertEqual '/tmp', $TMPDIR
|
||||
endif
|
13
test/test_tmpdir_wrapper.vader
Normal file
13
test/test_tmpdir_wrapper.vader
Normal 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
|
@ -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 = ''
|
||||
|
Loading…
Reference in New Issue
Block a user