mirror of
https://github.com/dense-analysis/ale.git
synced 2025-12-08 21:44:47 +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
|
function! ale_linters#python#jedils#GetCommand(buffer) abort
|
||||||
let l:executable = ale_linters#python#jedils#GetExecutable(a:buffer)
|
let l:executable = ale_linters#python#jedils#GetExecutable(a:buffer)
|
||||||
|
|
||||||
let l:exec_args = l:executable =~? 'pipenv$'
|
let l:exec_args = l:executable =~? 'pipenv$'
|
||||||
\ ? ' run jedi-language-server'
|
\ ? ' 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
|
endfunction
|
||||||
|
|
||||||
call ale#linter#Define('python', {
|
call ale#linter#Define('python', {
|
||||||
|
|||||||
@@ -37,12 +37,16 @@ endfunction
|
|||||||
|
|
||||||
function! ale_linters#python#pylsp#GetCommand(buffer) abort
|
function! ale_linters#python#pylsp#GetCommand(buffer) abort
|
||||||
let l:executable = ale_linters#python#pylsp#GetExecutable(a:buffer)
|
let l:executable = ale_linters#python#pylsp#GetExecutable(a:buffer)
|
||||||
|
|
||||||
let l:exec_args = l:executable =~? 'pipenv\|poetry$'
|
let l:exec_args = l:executable =~? 'pipenv\|poetry$'
|
||||||
\ ? ' run pylsp'
|
\ ? ' 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
|
endfunction
|
||||||
|
|
||||||
call ale#linter#Define('python', {
|
call ale#linter#Define('python', {
|
||||||
|
|||||||
@@ -64,12 +64,16 @@ endfunction
|
|||||||
|
|
||||||
function! ale_linters#python#pyright#GetCommand(buffer) abort
|
function! ale_linters#python#pyright#GetCommand(buffer) abort
|
||||||
let l:executable = ale_linters#python#pyright#GetExecutable(a:buffer)
|
let l:executable = ale_linters#python#pyright#GetExecutable(a:buffer)
|
||||||
|
|
||||||
let l:exec_args = l:executable =~? 'pipenv\|poetry$'
|
let l:exec_args = l:executable =~? 'pipenv\|poetry$'
|
||||||
\ ? ' run pyright'
|
\ ? ' 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
|
endfunction
|
||||||
|
|
||||||
call ale#linter#Define('python', {
|
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.
|
" Description: Functions for integrating with Python linters.
|
||||||
|
|
||||||
call ale#Set('python_auto_pipenv', '0')
|
call ale#Set('python_auto_pipenv', '0')
|
||||||
@@ -96,6 +96,24 @@ function! ale#python#FindVirtualenv(buffer) abort
|
|||||||
return $VIRTUAL_ENV
|
return $VIRTUAL_ENV
|
||||||
endfunction
|
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.
|
" 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
|
" First search on a virtualenv for Python, if nothing is found, try the global
|
||||||
" command. Returns an empty string if cannot find the executable
|
" 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.
|
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*
|
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.
|
" Enable automatic detection of poetry for Python linters.
|
||||||
let g:ale_python_auto_poetry = get(g:, 'ale_python_auto_poetry', 0)
|
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.
|
" This variable can be overridden to set the GO111MODULE environment variable.
|
||||||
let g:ale_go_go111module = get(g:, 'ale_go_go111module', '')
|
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:
|
Before:
|
||||||
call ale#assert#SetUpLinterTest('python', 'pylsp')
|
call ale#assert#SetUpLinterTest('python', 'pylsp')
|
||||||
|
Save b:ale_python_auto_virtualenv
|
||||||
|
|
||||||
let b:bin_dir = has('win32') ? 'Scripts' : 'bin'
|
let b:bin_dir = has('win32') ? 'Scripts' : 'bin'
|
||||||
|
|
||||||
After:
|
After:
|
||||||
unlet! b:bin_dir
|
unlet! b:bin_dir
|
||||||
|
unlet! b:venv_bin
|
||||||
|
unlet! b:sep
|
||||||
unlet! b:executable
|
unlet! b:executable
|
||||||
|
|
||||||
call ale#assert#TearDownLinterTest()
|
call ale#assert#TearDownLinterTest()
|
||||||
@@ -40,6 +43,17 @@ Execute(The pylsp executable should be run from the virtualenv path):
|
|||||||
AssertEqual ale#Escape(b:executable),
|
AssertEqual ale#Escape(b:executable),
|
||||||
\ ale_linters#python#pylsp#GetCommand(bufnr(''))
|
\ 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):
|
Execute(You should be able to override the pylsp virtualenv lookup):
|
||||||
call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py')
|
call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py')
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
Before:
|
Before:
|
||||||
call ale#assert#SetUpLinterTest('python', 'pyright')
|
call ale#assert#SetUpLinterTest('python', 'pyright')
|
||||||
|
Save b:ale_python_auto_virtualenv
|
||||||
|
|
||||||
let b:bin_dir = has('win32') ? 'Scripts' : 'bin'
|
let b:bin_dir = has('win32') ? 'Scripts' : 'bin'
|
||||||
|
|
||||||
After:
|
After:
|
||||||
unlet! b:bin_dir
|
unlet! b:bin_dir
|
||||||
|
unlet! b:venv_bin
|
||||||
|
unlet! b:sep
|
||||||
unlet! b:executable
|
unlet! b:executable
|
||||||
|
|
||||||
call ale#assert#TearDownLinterTest()
|
call ale#assert#TearDownLinterTest()
|
||||||
@@ -132,6 +135,17 @@ Execute(The pyright callbacks should detect virtualenv directories):
|
|||||||
|
|
||||||
AssertLinter b:executable, ale#Escape(b:executable) . ' --stdio'
|
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'):
|
Execute(Setting executable to 'pipenv' should append 'run pyright'):
|
||||||
call ale#test#SetFilename('../test-files')
|
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