performance for null-ls cache path detection

async call inside null-ls
bugfix fish/bash/zsh GoTestFile
pull/298/head
ray-x 1 year ago
parent 0912de62af
commit b7f7110d01

@ -240,20 +240,25 @@ function M.make(...)
if vim.fn.empty(vim.fn.glob(args[#args])) == 0 then -- pkg name in args
changed = true
if value:find("FAIL") == nil then
local p = extract_filepath(value)
if p then
local p, fn, ln= extract_filepath(value, package_path)
if p == true then -- path existed, but need to attach the pkg name
-- log(fn, ln, package_path, package_path:gsub('%.%.%.', ''))
-- remove ... in package path
value = package_path:gsub('%.%.%.', '') .. util.ltrim(value)
end
end
else
local p = extract_filepath(value)
if p then
local p, n = extract_filepath(value)
log(p, n, #lines)
if p == true then
failed = true
value = p .. util.ltrim(value)
value = n .. util.ltrim(value)
changed = true
log(value)
end
end
trace(value)
log(value, #lines)
table.insert(lines, value)
if itemn == 1 and failed and changed then
itemn = #lines

@ -508,9 +508,10 @@ M.get_test_cases = function()
end
return tests[1]
end
tests = vim.fn.join(tests, '\\|')
utils.log(tests)
return tests
local sep = '|'
local testsstr = vim.fn.join(tests, sep)
utils.log(tests, testsstr)
return testsstr, tests
end
M.test_file = function(...)
@ -572,10 +573,7 @@ M.test_file = function(...)
end
table.insert(cmd_args, '-run')
local sh = vim.o.shell
if sh:find('fish') then
tests = "'" .. tests .. "'"
end
tests = "'" .. tests .. "'"
table.insert(cmd_args, tests) -- shell script | is a pipe
table.insert(cmd_args, relpath)

@ -32,18 +32,22 @@ local function handler()
end
local verbose = true
local failure = {}
if #msgs > 160 then -- lua is still slow
if #msgs > 100 then -- lua is slow
log('reduce')
verbose = false
local fname = vfn.expand('%:t:r')
local reduce = {}
for _, m in pairs(msgs) do
local f = m:find(fname)
local n = m:find('fail') or m:find('FAIL') or m:find('panic')
if f or n then
table.insert(reduce, m)
end
if n then
table.insert(failure, 'failed:' .. m)
local other = m:find('=== PAUSE')
if not other then
local f = m:find(fname)
local n = m:find('fail') or m:find('FAIL') or m:find('panic')
if f or n then
table.insert(reduce, m)
elseif n then
table.insert(failure, 'failed:' .. m)
end
end
end
msgs = reduce
@ -52,97 +56,105 @@ local function handler()
-- the output is jsonencoded
local output = ''
local json_decode = vfn.json_decode
local qf = {}
local panic = {} -- store failed or panic info
for i, m in pairs(msgs) do
log(i, m)
for idx, m in pairs(msgs) do
-- log(idx)
if vfn.empty(m) == 0 then
local entry = vfn.json_decode(m)
-- log(entry)
if entry.Action == 'run' then
package = entry.Package
if m:find('--- PASS') or m:find('--- SKIP') or m:find('=== RUN') then
output = ''
elseif entry.Action == 'output' then
package = entry.Package
if vfn.empty(entry.Output) == 0 then
local ma = vfn.matchlist(entry.Output, [[\v\s*(\w+.+\.go):(\d+):]])
if ma[2] then
log(ma)
filename = package .. utils.sep() .. ma[2]
if vfn.filereadable(filename) == 0 then
filename = vfn.fnamemodify(vfn.expand('%:h'), ':~:.') .. utils.sep() .. ma[2]
end
line = ma[3]
end
if not verbose then
output = entry.Output
else
local entry = json_decode(m)
entry = entry or {}
-- log(entry)
if entry.Action == 'run' then
package = entry.Package
output = ''
elseif entry.Action == 'output' then
package = entry.Package
if vfn.empty(entry.Output) == 1 or false then
output = ''
else
output = output .. (entry.Output or '')
log(idx, entry)
entry.Output = utils.trim(entry.Output)
entry.Output = entry.Output:gsub('\t', ' ')
local found = false
local fname
local lnum
found, fname, lnum = extract_filepath(entry.Output, package)
if fname then
filename = fname
line = lnum
end
-- log(found, filename, lnum)
if found == true then
local pkg_path = require('go.gotest').get_test_path() .. utils.sep()
output = pkg_path .. utils.ltrim(entry.Output)
else -- not found or format is correct
if #output > 1 then
output = output .. (entry.Output or '')
else
output = output .. (entry.Output or '')
end
end
if entry.Output:find('FAIL') or entry.Output:find('panic') then
table.insert(panic, entry.Output)
end
log(idx, filename, output or 'nil')
end
if entry.Output:find('FAIL') or entry.Output:find('panic') then
table.insert(panic, entry.Output)
elseif entry.Action == 'pass' or entry.Action == 'skip' then
-- log(entry)
-- reset
output = ''
elseif entry.Action == 'fail' and vfn.empty(output) == 0 then
log(idx, entry, filename, output)
if filename and filename:find(vfn.expand('%:t:r')) then -- can be output from other files
table.insert(diags, {
file = filename,
row = tonumber(line),
col = 1,
message = output,
severity = severities.error,
source = 'go test',
})
end
log(output or 'nil')
end
elseif entry.Action == 'pass' or entry.Action == 'skip' then
-- log(entry)
-- reset
output = ''
elseif entry.Action == 'fail' and vfn.empty(output) == 0 then
-- log(entry)
if filename and filename:find(vfn.expand('%:t:r')) then -- can be output from other files
table.insert(diags, {
file = filename,
row = tonumber(line),
col = 1,
message = output,
severity = severities.error,
source = 'go test',
})
end
local qflines = vim.split(output, '\n')
for i, value in ipairs(qflines) do
if vim.fn.empty(value) == 0 then
local p = extract_filepath(value)
if p then
value = p .. utils.ltrim(value)
local qflines = vim.split(output, '\n')
for i, value in ipairs(qflines) do
if vim.fn.empty(value) == 0 then
-- local p, _ = extract_filepath(value)
-- if p then
-- value = pkg_path .. utils.ltrim(value)
-- log(value)
-- end
qflines[i] = value
end
qflines[i] = value
end
-- log(qflines)
vim.list_extend(qf, qflines)
output = ''
elseif entry.Action == 'fail' then -- empty output
-- log(idx, entry)
-- reset
local plines = ''
if #panic > 0 then
plines = table.concat(panic, '')
end
end
log(qflines)
vim.list_extend(qf, qflines)
output = ''
elseif entry.Action == 'fail' then -- empty output
-- log(entry)
-- reset
local plines = ''
if #panic > 0 then
plines = table.concat(panic, '')
end
vim.notify(
'go test failed package: '
.. entry.Package
.. 'test: '
.. (entry.Test or '')
.. '\n please check quickfix!\n'
.. plines,
vim.log.levels.WARN
)
end
end
if #qf > 0 then
local efm = require('go.gotest').efm()
vfn.setqflist({}, ' ', { title = 'gotest', lines = qf, efm = efm })
end
end
log(diags)
if not verbose and #failure > 0 then
vim.notify(
'go test failed package: ' .. package .. '\n please check quickfix!',
vim.log.levels.WARN
)
if #qf > 0 then
local efm = require('go.gotest').efm()
vfn.setqflist({}, ' ', { title = 'gotest', lines = qf, efm = efm })
log(qf, efm)
end
log(diags)
vim.notify('go test failed: ' .. '\n please check quickfix!\n', vim.log.levels.WARN)
-- local ok, d = pcall(vfn.json_decode, msg)
return done(diags)
end
@ -250,6 +262,7 @@ return {
vim.notify('failed to load null-ls', vim.log.levels.WARN)
return
end
local pkg_path = ''
return h.make_builtin({
name = 'gotest',
@ -262,20 +275,19 @@ return {
local gt = require('go.gotest')
local a = { 'test', '-json' }
local tests = gt.get_test_cases()
-- log(tests)
log(tests)
local pkg = require('go.gotest').get_test_path()
if not tests or not tests[1] then
pkg_path = pkg
if vfn.empty(tests) == 1 then
table.insert(a, pkg)
else
tests = tests[1]
local sh = vim.o.shell
table.insert(a, '-run')
table.insert(a, tests)
table.insert(a, pkg)
end
-- log(a)
log(a)
return a
end,
method = methods.internal.DIAGNOSTICS_ON_SAVE,
@ -293,7 +305,7 @@ return {
-- end
return true
end,
on_output = handler(),
on_output = handler(pkg_path),
},
factory = h.generator_factory,
})

@ -177,7 +177,8 @@ util.check_same = function(tbl1, tbl2)
end
util.map = function(modes, key, result, options)
options = util.merge({ noremap = true, silent = false, expr = false, nowait = false }, options or {})
options =
util.merge({ noremap = true, silent = false, expr = false, nowait = false }, options or {})
local buffer = options.buffer
options.buffer = nil
@ -245,6 +246,8 @@ util.log = function(...)
local info = debug.getinfo(2, 'Sl')
str = str .. info.short_src .. ':' .. info.currentline
local _, ms = vim.loop.gettimeofday()
str = string.format('[%s %d] %s', os.date(), ms, str)
for i, v in ipairs(arg) do
if type(v) == 'table' then
str = str .. ' |' .. tostring(i) .. ': ' .. vim.inspect(v) .. '\n'
@ -370,16 +373,16 @@ function util.load_plugin(name, modulename)
if has_packer or has_lazy then
-- packer installed
if has_packer then
local loader = require('packer').loader
if not pkg[name] or not pkg[name].loaded then
util.log('packer loader ' .. name)
vim.cmd('packadd ' .. name) -- load with default
if pkg[name] ~= nil then
loader(name)
local loader = require('packer').loader
if not pkg[name] or not pkg[name].loaded then
util.log('packer loader ' .. name)
vim.cmd('packadd ' .. name) -- load with default
if pkg[name] ~= nil then
loader(name)
end
end
end
else
require('lazy').load({plugins =name})
require('lazy').load({ plugins = name })
end
else
util.log('packadd ' .. name)
@ -425,7 +428,8 @@ end
-- end
function util.relative_to_cwd(name)
local rel = fn.isdirectory(name) == 0 and fn.fnamemodify(name, ':h:.') or fn.fnamemodify(name, ':.')
local rel = fn.isdirectory(name) == 0 and fn.fnamemodify(name, ':h:.')
or fn.fnamemodify(name, ':.')
if rel == '.' then
return '.'
else
@ -790,63 +794,79 @@ end
local namepath = {}
util.extract_filepath = function(msg)
util.extract_filepath = function(msg, pkg_path)
msg = msg or ''
-- util.log(msg)
--[[ or [[ findAllSubStr_test.go:234: Error inserting caseResult1: operation error DynamoDB: PutItem, exceeded maximum number of attempts]]
-- or 'path/path2/filename.go:50:11: Error invaild
-- or /home/ray/go/src/github/sample/app/driver.go:342 +0x19e5
local pos, _ = msg:find([[[%w_%-%./]+%.go:%d+:]])
if not pos then
pos, _ = msg:find([[[%w_%-%./]+%.go:%d+ ]]) -- test failure with panic
end
local pos2
if not pos then
local ma = fn.matchlist(msg, [[\v\s*(\w+.+\.go):(\d+):]])
ma = ma or fn.matchlist(msg, [[\v\s*(\w+.+\.go):(\d+)]])
local filename, lnum
if ma[2] then
util.log(ma)
filename = ma[2]
lnum = ma[3]
else
return
end
pos2 = msg:find(':')
local s = msg:sub(1, pos2 - 1)
util.log('fname : ', s)
if vim.fn.filereadable(s) == 1 then
util.log('filename', s)
util.log('fname : ' .. (filename or 'nil') .. ':' .. (lnum or '-1'))
if namepath[filename] then
-- if name is same, no need to update path
return (namepath[filename] ~= filename), namepath[filename], lnum
end
if vim.fn.filereadable(filename) == 1 then
util.log('filename', filename)
-- no need to extract path, already quickfix format
return
namepath[filename] = filename
return false, filename, lnum
end
if not pos2 then
util.log('incorrect format', msg)
return
if pkg_path then
local pn = pkg_path:gsub('%.%.%.', '')
local fname = pn .. util.sep() .. filename
if vim.fn.filereadable(fname) == 1 then
namepath[filename] = fname
util.log('fname with pkg_name', fname)
return true, fname, lnum
end
end
pos2 = msg:find(':')
local fname = msg:sub(pos, pos2 - 1)
local fname = fn.fnamemodify(fn.expand('%:h'), ':~:.') .. util.sep() .. ma[2]
util.log(fname, namepath[fname])
if namepath[fname] ~= nil then
return namepath[fname]
end
if vim.fn.filereadable(fname) == 1 then
return
namepath[filename] = fname
return true, fname, lnum
end
if namepath[filename] ~= nil then
util.log(namepath[filename])
return namepath[filename], lnum
end
if vim.fn.executable('find') == 0 then
return
return false, fname, lnum
end
-- note: slow operations
local cmd = 'find ./ -type f -name ' .. fname
local cmd = 'find ./ -type f -name ' .. filename
local path = vim.fn.systemlist(cmd)
if vim.v.shell_error ~= 0 then
util.warn('find failed ' .. cmd .. vim.inspect(path))
return
end
for _, value in pairs(path) do
local st, _ = value:find(fname)
local st, _ = value:find(filename)
if st then
-- find cmd returns `./path/path2/filename.go`, the leading './' is not needed for quickfix
local p = value:sub(1, st - 1)
util.log(value, st, p)
namepath[st] = p
return p
namepath[filename] = p
return true, p, lnum
end
end
-- nothing... we will not check this file again
namepath[filename] = filename
end
return util

Loading…
Cancel
Save