fix: install dependencies

This commit is contained in:
Christian Clason 2023-05-31 09:19:16 +02:00
parent 9c0a99819c
commit cd2c826972
8 changed files with 207 additions and 131 deletions

View file

@ -74,12 +74,11 @@ end
---@return string[]
function M.installed_parsers()
local install_dir = M.get_install_dir('parser')
local install_dir = M.get_install_dir('queries')
local installed = {} --- @type string[]
for f in vim.fs.dir(install_dir) do
local lang = assert(f:match('(.*)%..*'))
installed[#installed + 1] = lang
installed[#installed + 1] = f
end
return installed
@ -139,6 +138,14 @@ function M.norm_languages(languages, skip)
end, languages) --[[@as string[] ]]
end
if not (skip and skip.dependencies) then
for _, lang in pairs(languages) do
if parsers.configs[lang].requires then
vim.list_extend(languages, parsers.configs[lang].requires)
end
end
end
return languages
end

View file

@ -1,4 +1,5 @@
local install = require('nvim-treesitter.install')
local parsers = require('nvim-treesitter.parsers')
local config = require('nvim-treesitter.config')
local util = require('nvim-treesitter.util')
local tsq = vim.treesitter.query
@ -123,14 +124,25 @@ function M.check()
-- Installation dependency checks
install_health()
-- Parser installation checks
local languages = config.installed_parsers()
local parser_installation = { 'Parser/Features' .. string.rep(' ', 9) .. 'H L F I J' }
for _, parser_name in pairs(config.installed_parsers()) do
local out = ' - ' .. parser_name .. string.rep(' ', 20 - #parser_name)
for _, query_group in pairs(M.bundled_queries) do
local status, err = query_status(parser_name, query_group)
out = out .. status .. ' '
if err then
table.insert(error_collection, { parser_name, query_group, err })
for _, lang in pairs(languages) do
local parser = parsers.configs[lang]
local out = ' - ' .. lang .. string.rep(' ', 20 - #lang)
if parser.install_info then
for _, query_group in pairs(M.bundled_queries) do
local status, err = query_status(lang, query_group)
out = out .. status .. ' '
if err then
table.insert(error_collection, { lang, query_group, err })
end
end
end
if parser.requires then
for _, p in pairs(parser.requires) do
if not vim.list_contains(languages, p) then
table.insert(error_collection, { lang, 'queries', 'dependency ' .. p .. ' missing' })
end
end
end
table.insert(parser_installation, vim.fn.trim(out, ' ', 2))

View file

@ -449,74 +449,76 @@ local function install_lang(lang, cache_dir, install_dir, force, generate_from_g
end
end
local cc = M.select_executable(M.compilers)
if not cc then
cc_err()
return
end
local logger = log.new('install/' .. lang)
local err
local repo = get_parser_install_info(lang)
local project_name = 'tree-sitter-' .. lang
local logger = log.new('install/' .. lang)
generate_from_grammar = repo.requires_generate_from_grammar or generate_from_grammar
if generate_from_grammar and vim.fn.executable('tree-sitter') ~= 1 then
logger:error('tree-sitter CLI not found: `tree-sitter` is not executable')
end
if generate_from_grammar and vim.fn.executable('node') ~= 1 then
logger:error('Node JS not found: `node` is not executable')
end
local revision = repo.revision or get_target_revision(lang)
local maybe_local_path = fs.normalize(repo.url)
local from_local_path = vim.fn.isdirectory(maybe_local_path) == 1
if from_local_path then
repo.url = maybe_local_path
end
if not from_local_path then
util.delete(fs.joinpath(cache_dir, project_name))
local project_dir = fs.joinpath(cache_dir, project_name)
revision = revision or repo.branch or 'master'
if can_download_tar(repo) then
do_download_tar(logger, repo, project_name, cache_dir, revision, project_dir)
else
do_download_git(logger, repo, project_name, cache_dir, revision, project_dir)
if repo then
local cc = M.select_executable(M.compilers)
if not cc then
cc_err()
return
end
end
local compile_location = get_compile_location(repo, cache_dir, project_name, from_local_path)
local project_name = 'tree-sitter-' .. lang
if generate_from_grammar then
do_generate_from_grammar(logger, repo, compile_location)
end
generate_from_grammar = repo.requires_generate_from_grammar or generate_from_grammar
logger:info('Compiling parser')
local r = do_compile(repo, cc, compile_location)
if r.exit_code > 0 then
logger:error('Error during compilation: ' .. vim.inspect(r.stderr))
end
if generate_from_grammar and vim.fn.executable('tree-sitter') ~= 1 then
logger:error('tree-sitter CLI not found: `tree-sitter` is not executable')
end
local parser_lib_name = fs.joinpath(install_dir, lang) .. '.so'
if generate_from_grammar and vim.fn.executable('node') ~= 1 then
logger:error('Node JS not found: `node` is not executable')
end
local err = uv_copyfile(fs.joinpath(compile_location, 'parser.so'), parser_lib_name)
a.main()
if err then
logger:error(err)
end
local revision = repo.revision or get_target_revision(lang)
local revfile = fs.joinpath(config.get_install_dir('parser-info') or '', lang .. '.revision')
util.write_file(revfile, revision or '')
local maybe_local_path = fs.normalize(repo.url)
local from_local_path = vim.fn.isdirectory(maybe_local_path) == 1
if from_local_path then
repo.url = maybe_local_path
end
if not from_local_path then
util.delete(fs.joinpath(cache_dir, project_name))
if not from_local_path then
util.delete(fs.joinpath(cache_dir, project_name))
local project_dir = fs.joinpath(cache_dir, project_name)
revision = revision or repo.branch or 'master'
if can_download_tar(repo) then
do_download_tar(logger, repo, project_name, cache_dir, revision, project_dir)
else
do_download_git(logger, repo, project_name, cache_dir, revision, project_dir)
end
end
local compile_location = get_compile_location(repo, cache_dir, project_name, from_local_path)
if generate_from_grammar then
do_generate_from_grammar(logger, repo, compile_location)
end
logger:info('Compiling parser')
local r = do_compile(repo, cc, compile_location)
if r.exit_code > 0 then
logger:error('Error during compilation: ' .. vim.inspect(r.stderr))
end
local parser_lib_name = fs.joinpath(install_dir, lang) .. '.so'
err = uv_copyfile(fs.joinpath(compile_location, 'parser.so'), parser_lib_name)
a.main()
if err then
logger:error(err)
end
local revfile = fs.joinpath(config.get_install_dir('parser-info') or '', lang .. '.revision')
util.write_file(revfile, revision or '')
if not from_local_path then
util.delete(fs.joinpath(cache_dir, project_name))
end
end
local queries = fs.joinpath(config.get_install_dir('queries'), lang)
@ -527,7 +529,7 @@ local function install_lang(lang, cache_dir, install_dir, force, generate_from_g
if err then
logger:error(err)
end
logger:info('Parser installed')
logger:info('Language installed')
end
--- Throttles a function using the first argument as an ID
@ -617,7 +619,7 @@ local function install(languages, options, _callback)
a.join(max_jobs, nil, tasks)
if #tasks > 1 then
a.main()
log.info('Installed %d/%d parsers', done, #tasks)
log.info('Installed %d/%d languages', done, #tasks)
end
end
@ -650,34 +652,35 @@ end, 2)
local function uninstall_lang(lang, parser, queries)
local logger = log.new('uninstall/' .. lang)
logger:debug('Uninstalling ' .. lang)
if vim.fn.filereadable(parser) ~= 1 then
return
if vim.fn.filereadable(parser) == 1 then
logger:debug('Unlinking ' .. parser)
local perr = uv_unlink(parser)
a.main()
if perr then
log.error(perr)
end
end
logger:debug('Unlinking ' .. parser)
local perr = uv_unlink(parser)
a.main()
if vim.fn.isdirectory(queries) == 1 then
logger:debug('Unlinking ' .. queries)
local qerr = uv_unlink(queries)
a.main()
if perr then
log.error(perr)
if qerr then
logger:error(qerr)
end
end
logger:debug('Unlinking ' .. queries)
local qerr = uv_unlink(queries)
a.main()
if qerr then
logger:error(qerr)
end
logger:info('Parser uninstalled')
logger:info('Language uninstalled')
end
--- @param languages string[]|string
--- @param _options? UpdateOptions
--- @param _callback fun()
M.uninstall = a.sync(function(languages, _options, _callback)
languages = config.norm_languages(languages or 'all', { missing = true })
languages = config.norm_languages(languages or 'all', { missing = true, dependencies = true })
local parser_dir = config.get_install_dir('parser')
local query_dir = config.get_install_dir('queries')
@ -701,7 +704,7 @@ M.uninstall = a.sync(function(languages, _options, _callback)
a.join(max_jobs, nil, tasks)
if #tasks > 1 then
a.main()
log.info('Uninstalled %d/%d parsers', done, #tasks)
log.info('Uninstalled %d/%d languages', done, #tasks)
end
end, 2)

View file

@ -12,6 +12,7 @@
---@field install_info InstallInfo
---@field filetype string[]
---@field maintainers string[]
---@field requires string[]
---@field tier integer|nil
---@field readme_note string|nil
@ -44,6 +45,7 @@ M.configs = {
generate_requires_npm = true,
},
maintainers = { '@dlvandenberg' },
requires = { 'html', 'html_tags' },
tier = 4,
},
@ -63,6 +65,7 @@ M.configs = {
files = { 'src/parser.c', 'src/scanner.c' },
},
maintainers = { '@ObserverOfTime' },
requires = { 'cpp' },
},
asm = {
@ -80,6 +83,7 @@ M.configs = {
files = { 'src/parser.c', 'src/scanner.c' },
},
maintainers = { '@virchau13' },
requires = { 'html', 'html_tags' },
},
authzed = {
@ -309,6 +313,7 @@ M.configs = {
generate_requires_npm = true,
},
maintainers = { '@theHamsta' },
requires = { 'c' },
},
css = {
@ -326,6 +331,7 @@ M.configs = {
location = 'csv',
},
maintainers = { '@amaanq' },
requires = { 'tsv' },
tier = 2,
},
@ -336,6 +342,7 @@ M.configs = {
generate_requires_npm = true,
},
maintainers = { '@theHamsta' },
requires = { 'cpp' },
},
cue = {
@ -476,6 +483,12 @@ M.configs = {
tier = 4,
},
ecma = {
maintainers = { '@steelsojka' },
readme_note = 'queries required by javascript, typescript, tsx, qmljs',
tier = 3,
},
editorconfig = {
install_info = {
url = 'https://github.com/ValdezFOmar/tree-sitter-editorconfig',
@ -539,6 +552,7 @@ M.configs = {
url = 'https://github.com/tree-sitter/tree-sitter-embedded-template',
files = { 'src/parser.c' },
},
tier = 4,
},
enforce = {
@ -796,6 +810,7 @@ M.configs = {
generate_requires_npm = true,
},
maintainers = { '@theHamsta' },
requires = { 'c' },
},
gn = {
@ -925,6 +940,7 @@ M.configs = {
url = 'https://github.com/slackhq/tree-sitter-hack',
files = { 'src/parser.c', 'src/scanner.c' },
},
tier = 4,
},
hare = {
@ -941,6 +957,7 @@ M.configs = {
files = { 'src/parser.c', 'src/scanner.c' },
},
maintainers = { '@mrcjkb' },
tier = 3,
},
haskell_persistent = {
@ -985,6 +1002,7 @@ M.configs = {
generate_requires_npm = true,
},
maintainers = { '@winston0410' },
requires = { 'json' },
},
hlsl = {
@ -994,6 +1012,7 @@ M.configs = {
generate_requires_npm = true,
},
maintainers = { '@theHamsta' },
requires = { 'cpp' },
},
hlsplaylist = {
@ -1023,12 +1042,18 @@ M.configs = {
tier = 4,
},
html_tags = {
maintainers = { '@TravonteD' },
readme_note = 'queries required by html, astro, vue, svelte',
},
html = {
install_info = {
url = 'https://github.com/tree-sitter/tree-sitter-html',
files = { 'src/parser.c', 'src/scanner.c' },
},
maintainers = { '@TravonteD' },
requires = { 'html_tags' },
},
htmldjango = {
@ -1118,6 +1143,7 @@ M.configs = {
generate_requires_npm = true,
},
maintainers = { '@fab4100' },
requires = { 'c' },
},
janet_simple = {
@ -1151,6 +1177,7 @@ M.configs = {
files = { 'src/parser.c', 'src/scanner.c' },
},
maintainers = { '@steelsojka' },
requires = { 'ecma', 'jsx' },
},
jinja = {
@ -1214,7 +1241,7 @@ M.configs = {
generate_requires_npm = true,
},
maintainers = { '@WhyNotHugo' },
readme_note = 'JSON with comments',
requires = { 'json' },
},
jsonnet = {
@ -1225,6 +1252,11 @@ M.configs = {
maintainers = { '@nawordar' },
},
jsx = {
maintainers = { '@steelsojka' },
readme_note = 'queries required by javascript, tsx',
},
julia = {
install_info = {
url = 'https://github.com/tree-sitter/tree-sitter-julia',
@ -1370,8 +1402,8 @@ M.configs = {
url = 'https://github.com/MunifTanjim/tree-sitter-lua',
files = { 'src/parser.c', 'src/scanner.c' },
},
tier = 1,
maintainers = { '@muniftanjim' },
tier = 1,
},
luadoc = {
@ -1397,6 +1429,7 @@ M.configs = {
files = { 'src/parser.c', 'src/scanner.c' },
},
maintainers = { '@amaanq' },
requires = { 'lua' },
},
m68k = {
@ -1423,6 +1456,7 @@ M.configs = {
},
maintainers = { '@MDeiml' },
readme_note = 'basic highlighting',
requires = { 'markdown_inline' },
tier = 1,
},
@ -1475,8 +1509,8 @@ M.configs = {
files = { 'src/parser.c' },
requires_generate_from_grammar = true,
},
tier = 4,
maintainers = { '@artagnon' },
tier = 4,
},
muttrc = {
@ -1511,6 +1545,7 @@ M.configs = {
url = 'https://github.com/nickel-lang/tree-sitter-nickel',
files = { 'src/parser.c', 'src/scanner.c' },
},
tier = 4,
},
nim = {
@ -1519,6 +1554,7 @@ M.configs = {
files = { 'src/parser.c', 'src/scanner.c' },
},
maintainers = { '@aMOPel' },
requires = { 'nim_format_string' },
tier = 3,
},
@ -1553,8 +1589,8 @@ M.configs = {
files = { 'src/parser.c', 'src/scanner.cc' },
use_makefile = true,
},
tier = 4,
maintainers = { '@JoeyGrajciar', '@vhyrro' },
tier = 4,
},
nqc = {
@ -1581,6 +1617,7 @@ M.configs = {
files = { 'src/parser.c' },
},
maintainers = { '@amaanq' },
requires = { 'c' },
},
objdump = {
@ -1608,6 +1645,7 @@ M.configs = {
location = 'grammars/interface',
},
maintainers = { '@undu' },
requires = { 'ocaml' },
},
ocamllex = {
@ -1826,6 +1864,7 @@ M.configs = {
location = 'psv',
},
maintainers = { '@amaanq' },
requires = { 'tsv' },
tier = 2,
},
@ -1895,6 +1934,7 @@ M.configs = {
files = { 'src/parser.c', 'src/scanner.c' },
},
maintainers = { '@Decodetalkers' },
requires = { 'ecma' },
},
query = {
@ -2120,6 +2160,8 @@ M.configs = {
files = { 'src/parser.c', 'src/scanner.c' },
},
maintainers = { '@elianiva' },
requires = { 'css' },
tier = 3,
},
sflog = {
@ -2314,6 +2356,7 @@ M.configs = {
files = { 'src/parser.c', 'src/scanner.c' },
},
maintainers = { '@amaanq' },
requires = { 'html_tags' },
tier = 2,
},
@ -2421,6 +2464,8 @@ M.configs = {
location = 'dialects/terraform',
},
maintainers = { '@MichaHoffmann' },
requires = { 'hcl' },
tier = 3,
},
textproto = {
@ -2501,6 +2546,7 @@ M.configs = {
generate_requires_npm = true,
},
maintainers = { '@steelsojka' },
requires = { 'ecma', 'jsx', 'typescript' },
},
turtle = {
@ -2527,6 +2573,7 @@ M.configs = {
generate_requires_npm = true,
},
maintainers = { '@steelsojka' },
requires = { 'ecma' },
},
typespec = {
@ -2684,6 +2731,7 @@ M.configs = {
branch = 'main',
},
maintainers = { '@WhyNotHugo', '@lucario387' },
requires = { 'html_tags' },
tier = 2,
},
@ -2737,6 +2785,7 @@ M.configs = {
location = 'xml',
},
maintainers = { '@ObserverOfTime' },
requires = { 'dtd' },
tier = 2,
},