mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 03:05:11 -07:00
refactor: rewrite virtualenv healthcheck in lua
This is required to remove the vimscript checkhealth functions.
This commit is contained in:
parent
3c724fe1f3
commit
5ed7ede1f5
@ -90,79 +90,6 @@ function! s:disabled_via_loaded_var(provider) abort
|
|||||||
return 0
|
return 0
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Resolves Python executable path by invoking and checking `sys.executable`.
|
|
||||||
function! s:python_exepath(invocation) abort
|
|
||||||
return s:normalize_path(system(fnameescape(a:invocation)
|
|
||||||
\ . ' -c "import sys; sys.stdout.write(sys.executable)"'))
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Checks that $VIRTUAL_ENV Python executables are found at front of $PATH in
|
|
||||||
" Nvim and subshells.
|
|
||||||
function! s:check_virtualenv() abort
|
|
||||||
call health#report_start('Python virtualenv')
|
|
||||||
if !exists('$VIRTUAL_ENV')
|
|
||||||
call health#report_ok('no $VIRTUAL_ENV')
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
let errors = []
|
|
||||||
" Keep hints as dict keys in order to discard duplicates.
|
|
||||||
let hints = {}
|
|
||||||
" The virtualenv should contain some Python executables, and those
|
|
||||||
" executables should be first both on Nvim's $PATH and the $PATH of
|
|
||||||
" subshells launched from Nvim.
|
|
||||||
let bin_dir = has('win32') ? '/Scripts' : '/bin'
|
|
||||||
let venv_bins = glob($VIRTUAL_ENV . bin_dir . '/python*', v:true, v:true)
|
|
||||||
" XXX: Remove irrelevant executables found in bin/.
|
|
||||||
let venv_bins = filter(venv_bins, 'v:val !~# "python-config"')
|
|
||||||
if len(venv_bins)
|
|
||||||
for venv_bin in venv_bins
|
|
||||||
let venv_bin = s:normalize_path(venv_bin)
|
|
||||||
let py_bin_basename = fnamemodify(venv_bin, ':t')
|
|
||||||
let nvim_py_bin = s:python_exepath(exepath(py_bin_basename))
|
|
||||||
let subshell_py_bin = s:python_exepath(py_bin_basename)
|
|
||||||
if venv_bin !=# nvim_py_bin
|
|
||||||
call add(errors, '$PATH yields this '.py_bin_basename.' executable: '.nvim_py_bin)
|
|
||||||
let hint = '$PATH ambiguities arise if the virtualenv is not '
|
|
||||||
\.'properly activated prior to launching Nvim. Close Nvim, activate the virtualenv, '
|
|
||||||
\.'check that invoking Python from the command line launches the correct one, '
|
|
||||||
\.'then relaunch Nvim.'
|
|
||||||
let hints[hint] = v:true
|
|
||||||
endif
|
|
||||||
if venv_bin !=# subshell_py_bin
|
|
||||||
call add(errors, '$PATH in subshells yields this '
|
|
||||||
\.py_bin_basename . ' executable: '.subshell_py_bin)
|
|
||||||
let hint = '$PATH ambiguities in subshells typically are '
|
|
||||||
\.'caused by your shell config overriding the $PATH previously set by the '
|
|
||||||
\.'virtualenv. Either prevent them from doing so, or use this workaround: '
|
|
||||||
\.'https://vi.stackexchange.com/a/34996'
|
|
||||||
let hints[hint] = v:true
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
else
|
|
||||||
call add(errors, 'no Python executables found in the virtualenv '.bin_dir.' directory.')
|
|
||||||
endif
|
|
||||||
|
|
||||||
let msg = '$VIRTUAL_ENV is set to: '.$VIRTUAL_ENV
|
|
||||||
if len(errors)
|
|
||||||
if len(venv_bins)
|
|
||||||
let msg .= "\nAnd its ".bin_dir.' directory contains: '
|
|
||||||
\.join(map(venv_bins, "fnamemodify(v:val, ':t')"), ', ')
|
|
||||||
endif
|
|
||||||
let conj = "\nBut "
|
|
||||||
for error in errors
|
|
||||||
let msg .= conj.error
|
|
||||||
let conj = "\nAnd "
|
|
||||||
endfor
|
|
||||||
let msg .= "\nSo invoking Python may lead to unexpected results."
|
|
||||||
call health#report_warn(msg, keys(hints))
|
|
||||||
else
|
|
||||||
call health#report_info(msg)
|
|
||||||
call health#report_info('Python version: '
|
|
||||||
\.system('python -c "import platform, sys; sys.stdout.write(platform.python_version())"'))
|
|
||||||
call health#report_ok('$VIRTUAL_ENV provides :!python.')
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:check_ruby() abort
|
function! s:check_ruby() abort
|
||||||
call health#report_start('Ruby provider (optional)')
|
call health#report_start('Ruby provider (optional)')
|
||||||
|
|
||||||
@ -372,7 +299,6 @@ function! s:check_perl() abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! health#provider2#check() abort
|
function! health#provider2#check() abort
|
||||||
call s:check_virtualenv()
|
|
||||||
call s:check_ruby()
|
call s:check_ruby()
|
||||||
call s:check_node()
|
call s:check_node()
|
||||||
call s:check_perl()
|
call s:check_perl()
|
||||||
|
@ -489,7 +489,7 @@ local function python()
|
|||||||
if not is_blank(pyenv_root) then
|
if not is_blank(pyenv_root) then
|
||||||
venv_root = pyenv_root
|
venv_root = pyenv_root
|
||||||
else
|
else
|
||||||
venv_root = vim.fs.basename(venv)
|
venv_root = vim.fs.dirname(venv)
|
||||||
end
|
end
|
||||||
|
|
||||||
if vim.startswith(vim.fn.resolve(python_exe), venv_root .. '/') then
|
if vim.startswith(vim.fn.resolve(python_exe), venv_root .. '/') then
|
||||||
@ -571,9 +571,96 @@ local function python()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Resolves Python executable path by invoking and checking `sys.executable`.
|
||||||
|
local function python_exepath(invocation)
|
||||||
|
return vim.fs.normalize(
|
||||||
|
system(vim.fn.fnameescape(invocation) .. ' -c "import sys; sys.stdout.write(sys.executable)"')
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Checks that $VIRTUAL_ENV Python executables are found at front of $PATH in
|
||||||
|
-- Nvim and subshells.
|
||||||
|
local function virtualenv()
|
||||||
|
start('Python virtualenv')
|
||||||
|
if not os.getenv('VIRTUAL_ENV') then
|
||||||
|
ok('no $VIRTUAL_ENV')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local errors = {}
|
||||||
|
-- Keep hints as dict keys in order to discard duplicates.
|
||||||
|
local hints = {}
|
||||||
|
-- The virtualenv should contain some Python executables, and those
|
||||||
|
-- executables should be first both on Nvim's $PATH and the $PATH of
|
||||||
|
-- subshells launched from Nvim.
|
||||||
|
local bin_dir = (iswin and '/Scripts' or '/bin')
|
||||||
|
local venv_bins = vim.fn.glob(os.getenv('VIRTUAL_ENV') .. bin_dir .. '/python*', true, true)
|
||||||
|
-- XXX: Remove irrelevant executables found in bin/.
|
||||||
|
venv_bins = vim.fn.filter(venv_bins, 'v:val !~# "python-config"')
|
||||||
|
if vim.tbl_coun(venv_bins) > 0 then
|
||||||
|
for _, venv_bin in pairs(venv_bins) do
|
||||||
|
venv_bin = vim.fs.normalize(venv_bin)
|
||||||
|
local py_bin_basename = vim.fs.basename(venv_bin)
|
||||||
|
local nvim_py_bin = python_exepath(vim.fn.exepath(py_bin_basename))
|
||||||
|
local subshell_py_bin = python_exepath(py_bin_basename)
|
||||||
|
if venv_bin ~= nvim_py_bin then
|
||||||
|
errors[#errors + 1] = '$PATH yields this '
|
||||||
|
.. py_bin_basename
|
||||||
|
.. ' executable: '
|
||||||
|
.. nvim_py_bin
|
||||||
|
local hint = '$PATH ambiguities arise if the virtualenv is not '
|
||||||
|
.. 'properly activated prior to launching Nvim. Close Nvim, activate the virtualenv, '
|
||||||
|
.. 'check that invoking Python from the command line launches the correct one, '
|
||||||
|
.. 'then relaunch Nvim.'
|
||||||
|
hints[hint] = true
|
||||||
|
end
|
||||||
|
if venv_bin ~= subshell_py_bin then
|
||||||
|
errors[#errors + 1] = '$PATH in subshells yields this '
|
||||||
|
.. py_bin_basename
|
||||||
|
.. ' executable: '
|
||||||
|
.. subshell_py_bin
|
||||||
|
local hint = '$PATH ambiguities in subshells typically are '
|
||||||
|
.. 'caused by your shell config overriding the $PATH previously set by the '
|
||||||
|
.. 'virtualenv. Either prevent them from doing so, or use this workaround: '
|
||||||
|
.. 'https://vi.stackexchange.com/a/34996'
|
||||||
|
hints[hint] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
errors[#errors + 1] = 'no Python executables found in the virtualenv '
|
||||||
|
.. bin_dir
|
||||||
|
.. ' directory.'
|
||||||
|
end
|
||||||
|
|
||||||
|
local msg = '$VIRTUAL_ENV is set to: ' .. os.getenv('VIRTUAL_ENV')
|
||||||
|
if vim.tbl_count(errors) > 0 then
|
||||||
|
if vim.tbl_count(venv_bins) > 0 then
|
||||||
|
msg = msg
|
||||||
|
.. '\nAnd its '
|
||||||
|
.. bin_dir
|
||||||
|
.. ' directory contains: '
|
||||||
|
.. vim.fn.join(vim.fn.map(venv_bins, [[fnamemodify(v:val, ':t')]]), ', ')
|
||||||
|
end
|
||||||
|
local conj = '\nBut '
|
||||||
|
for _, err in ipairs(errors) do
|
||||||
|
msg = msg .. conj .. err
|
||||||
|
conj = '\nAnd '
|
||||||
|
end
|
||||||
|
msg = msg .. '\nSo invoking Python may lead to unexpected results.'
|
||||||
|
warn(msg, vim.fn.keys(hints))
|
||||||
|
else
|
||||||
|
info(msg)
|
||||||
|
info(
|
||||||
|
'Python version: '
|
||||||
|
.. system('python -c "import platform, sys; sys.stdout.write(platform.python_version())"')
|
||||||
|
)
|
||||||
|
ok('$VIRTUAL_ENV provides :!python.')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function M.check()
|
function M.check()
|
||||||
clipboard()
|
clipboard()
|
||||||
python()
|
python()
|
||||||
|
virtualenv()
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
Loading…
Reference in New Issue
Block a user