mirror of
https://github.com/dense-analysis/ale.git
synced 2025-12-07 21:24:33 +08:00
#2172 Auto PATH with ale_python_auto_virtualenv
Automatically set `PATH` for some Python linters that seem to need it when g:ale_python_auto_virtualenv or b:ale_python_auto_virtualenv is `1`.
This commit is contained in:
@@ -16,12 +16,16 @@ endfunction
|
||||
|
||||
function! ale_linters#python#jedils#GetCommand(buffer) abort
|
||||
let l:executable = ale_linters#python#jedils#GetExecutable(a:buffer)
|
||||
|
||||
let l:exec_args = l:executable =~? 'pipenv$'
|
||||
\ ? ' run jedi-language-server'
|
||||
\ : ''
|
||||
let l:env_string = ''
|
||||
|
||||
return ale#Escape(l:executable) . l:exec_args
|
||||
if ale#Var(a:buffer, 'python_auto_virtualenv')
|
||||
let l:env_string = ale#python#AutoVirtualenvEnvString(a:buffer)
|
||||
endif
|
||||
|
||||
return l:env_string . ale#Escape(l:executable) . l:exec_args
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('python', {
|
||||
|
||||
@@ -37,12 +37,16 @@ endfunction
|
||||
|
||||
function! ale_linters#python#pylsp#GetCommand(buffer) abort
|
||||
let l:executable = ale_linters#python#pylsp#GetExecutable(a:buffer)
|
||||
|
||||
let l:exec_args = l:executable =~? 'pipenv\|poetry$'
|
||||
\ ? ' run pylsp'
|
||||
\ : ''
|
||||
let l:env_string = ''
|
||||
|
||||
return ale#Escape(l:executable) . l:exec_args . ale#Pad(ale#Var(a:buffer, 'python_pylsp_options'))
|
||||
if ale#Var(a:buffer, 'python_auto_virtualenv')
|
||||
let l:env_string = ale#python#AutoVirtualenvEnvString(a:buffer)
|
||||
endif
|
||||
|
||||
return l:env_string . ale#Escape(l:executable) . l:exec_args . ale#Pad(ale#Var(a:buffer, 'python_pylsp_options'))
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('python', {
|
||||
|
||||
@@ -64,12 +64,16 @@ endfunction
|
||||
|
||||
function! ale_linters#python#pyright#GetCommand(buffer) abort
|
||||
let l:executable = ale_linters#python#pyright#GetExecutable(a:buffer)
|
||||
|
||||
let l:exec_args = l:executable =~? 'pipenv\|poetry$'
|
||||
\ ? ' run pyright'
|
||||
\ : ''
|
||||
let l:env_string = ''
|
||||
|
||||
return ale#Escape(l:executable) . l:exec_args . ' --stdio'
|
||||
if ale#Var(a:buffer, 'python_auto_virtualenv')
|
||||
let l:env_string = ale#python#AutoVirtualenvEnvString(a:buffer)
|
||||
endif
|
||||
|
||||
return l:env_string . ale#Escape(l:executable) . l:exec_args . ' --stdio'
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('python', {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Author: w0rp <dev@w0rp.com>
|
||||
" Description: Functions for integrating with Python linters.
|
||||
|
||||
call ale#Set('python_auto_pipenv', '0')
|
||||
@@ -96,6 +96,24 @@ function! ale#python#FindVirtualenv(buffer) abort
|
||||
return $VIRTUAL_ENV
|
||||
endfunction
|
||||
|
||||
" Automatically determine virtualenv environment variables and build
|
||||
" a string of them to prefix linter commands with.
|
||||
function! ale#python#AutoVirtualenvEnvString(buffer) abort
|
||||
let l:venv_dir = ale#python#FindVirtualenv(a:buffer)
|
||||
let l:sep = has('win32') ? ';' : ':'
|
||||
|
||||
if !empty(l:venv_dir)
|
||||
let l:vars = [
|
||||
\ ['PATH', ale#path#Simplify(l:venv_dir . '/bin') . l:sep . $PATH],
|
||||
\]
|
||||
|
||||
" We don't need a space between var as ale#Env adds one.
|
||||
return join(map(l:vars, 'ale#Env(v:val[0], v:val[1])'), '')
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" Given a buffer number and a command name, find the path to the executable.
|
||||
" First search on a virtualenv for Python, if nothing is found, try the global
|
||||
" command. Returns an empty string if cannot find the executable
|
||||
|
||||
@@ -20,6 +20,17 @@ g:ale_python_auto_poetry *g:ale_python_auto_poetry*
|
||||
if true. This is overridden by a manually-set executable.
|
||||
|
||||
|
||||
g:ale_python_auto_virtualenv *g:ale_python_auto_virtualenv*
|
||||
*b:ale_python_auto_virtualenv*
|
||||
Type: |Number|
|
||||
Default: `0`
|
||||
|
||||
If set to `1`, ALE will automatically set environment variables for commands
|
||||
such as `PATH` to attempt to make the experience of running Python linters
|
||||
via virtualenv easier, without the need for another plugin or some
|
||||
specialised setup.
|
||||
|
||||
|
||||
===============================================================================
|
||||
ALE Python Project Root Behavior *ale-python-root*
|
||||
|
||||
|
||||
@@ -178,6 +178,10 @@ let g:ale_python_auto_pipenv = get(g:, 'ale_python_auto_pipenv', 0)
|
||||
" Enable automatic detection of poetry for Python linters.
|
||||
let g:ale_python_auto_poetry = get(g:, 'ale_python_auto_poetry', 0)
|
||||
|
||||
" Enable automatic adjustment of environment variables for Python linters.
|
||||
" The variables are set based on ALE's virtualenv detection.
|
||||
let g:ale_python_auto_virtualenv = get(g:, 'ale_python_auto_virtualenv', 0)
|
||||
|
||||
" This variable can be overridden to set the GO111MODULE environment variable.
|
||||
let g:ale_go_go111module = get(g:, 'ale_go_go111module', '')
|
||||
|
||||
|
||||
47
test/linter/test_jedils.vader
Normal file
47
test/linter/test_jedils.vader
Normal file
@@ -0,0 +1,47 @@
|
||||
Before:
|
||||
call ale#assert#SetUpLinterTest('python', 'jedils')
|
||||
Save b:ale_python_auto_virtualenv
|
||||
|
||||
let b:bin_dir = has('win32') ? 'Scripts' : 'bin'
|
||||
|
||||
After:
|
||||
unlet! b:bin_dir
|
||||
unlet! b:venv_bin
|
||||
unlet! b:sep
|
||||
unlet! b:executable
|
||||
|
||||
call ale#assert#TearDownLinterTest()
|
||||
|
||||
Execute(The jedi-language-server command callback should return default string):
|
||||
call ale#test#SetFilename('./foo.py')
|
||||
|
||||
AssertLinter 'jedi-language-server', ale#Escape('jedi-language-server')
|
||||
|
||||
Execute(The jedi-language-server executable should be configurable):
|
||||
let g:ale_python_jedils_executable = '~/.local/bin/jedi-language-server'
|
||||
|
||||
AssertLinter '~/.local/bin/jedi-language-server' , ale#Escape('~/.local/bin/jedi-language-server')
|
||||
|
||||
Execute(virtualenv vars should be used when ale_python_auto_virtualenv = 1):
|
||||
let b:ale_python_auto_virtualenv = 1
|
||||
call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py')
|
||||
|
||||
let b:venv_bin = ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir)
|
||||
let b:sep = has('win32') ? ';' : ':'
|
||||
let b:executable = ale#path#Simplify(b:venv_bin . '/jedi-language-server')
|
||||
|
||||
AssertLinter b:executable, ale#Env('PATH', b:venv_bin . b:sep . $PATH)
|
||||
\ . ale#Escape(b:executable)
|
||||
|
||||
Execute(You should be able to override the jedi-language-server virtualenv lookup):
|
||||
call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py')
|
||||
|
||||
let g:ale_python_jedils_use_global = 1
|
||||
|
||||
AssertLinter 'jedi-language-server', ale#Escape('jedi-language-server')
|
||||
|
||||
Execute(Setting executable to 'pipenv' appends 'run jedi-language-server'):
|
||||
let g:ale_python_jedils_executable = 'path/to/pipenv'
|
||||
call ale#test#SetFilename('../test-files/dummy')
|
||||
|
||||
AssertLinter 'path/to/pipenv', ale#Escape('path/to/pipenv') . ' run jedi-language-server'
|
||||
@@ -1,10 +1,13 @@
|
||||
Before:
|
||||
call ale#assert#SetUpLinterTest('python', 'pylsp')
|
||||
Save b:ale_python_auto_virtualenv
|
||||
|
||||
let b:bin_dir = has('win32') ? 'Scripts' : 'bin'
|
||||
|
||||
After:
|
||||
unlet! b:bin_dir
|
||||
unlet! b:venv_bin
|
||||
unlet! b:sep
|
||||
unlet! b:executable
|
||||
|
||||
call ale#assert#TearDownLinterTest()
|
||||
@@ -40,6 +43,17 @@ Execute(The pylsp executable should be run from the virtualenv path):
|
||||
AssertEqual ale#Escape(b:executable),
|
||||
\ ale_linters#python#pylsp#GetCommand(bufnr(''))
|
||||
|
||||
Execute(virtualenv vars should be used when ale_python_auto_virtualenv = 1):
|
||||
let b:ale_python_auto_virtualenv = 1
|
||||
call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py')
|
||||
|
||||
let b:venv_bin = ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir)
|
||||
let b:sep = has('win32') ? ';' : ':'
|
||||
let b:executable = ale#path#Simplify(b:venv_bin . '/pylsp')
|
||||
|
||||
AssertLinter b:executable, ale#Env('PATH', b:venv_bin . b:sep . $PATH)
|
||||
\ . ale#Escape(b:executable)
|
||||
|
||||
Execute(You should be able to override the pylsp virtualenv lookup):
|
||||
call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py')
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
Before:
|
||||
call ale#assert#SetUpLinterTest('python', 'pyright')
|
||||
Save b:ale_python_auto_virtualenv
|
||||
|
||||
let b:bin_dir = has('win32') ? 'Scripts' : 'bin'
|
||||
|
||||
After:
|
||||
unlet! b:bin_dir
|
||||
unlet! b:venv_bin
|
||||
unlet! b:sep
|
||||
unlet! b:executable
|
||||
|
||||
call ale#assert#TearDownLinterTest()
|
||||
@@ -132,6 +135,17 @@ Execute(The pyright callbacks should detect virtualenv directories):
|
||||
|
||||
AssertLinter b:executable, ale#Escape(b:executable) . ' --stdio'
|
||||
|
||||
Execute(virtualenv vars should be used when ale_python_auto_virtualenv = 1):
|
||||
let b:ale_python_auto_virtualenv = 1
|
||||
call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py')
|
||||
|
||||
let b:venv_bin = ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir)
|
||||
let b:sep = has('win32') ? ';' : ':'
|
||||
let b:executable = ale#path#Simplify(b:venv_bin . '/pyright-langserver')
|
||||
|
||||
AssertLinter b:executable, ale#Env('PATH', b:venv_bin . b:sep . $PATH)
|
||||
\ . ale#Escape(b:executable) . ' --stdio'
|
||||
|
||||
Execute(Setting executable to 'pipenv' should append 'run pyright'):
|
||||
call ale#test#SetFilename('../test-files')
|
||||
|
||||
|
||||
0
test/test-files/python/with_virtualenv/env/bin/jedi-language-server
vendored
Executable file
0
test/test-files/python/with_virtualenv/env/bin/jedi-language-server
vendored
Executable file
Reference in New Issue
Block a user