Skip to content

Commit

Permalink
feat: showing live logs in the buffer (#136)
Browse files Browse the repository at this point in the history
  • Loading branch information
wojciech-kulik committed Apr 14, 2024
1 parent 9b33fd3 commit 3fd5b2e
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 20 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ vim.keymap.set("n", "<leader>xa", "<cmd>XcodebuildCodeActions<cr>", { desc = "Sh
open_command = "silent botright 20split {path}", -- command used to open logs panel. You must use {path} variable to load the log file
logs_formatter = "xcbeautify --disable-colored-output", -- command used to format logs, you can use "" to skip formatting
only_summary = false, -- if true logs won't be displayed, just xcodebuild.nvim summary
live_logs = true, -- if true logs will be updated in real-time
show_warnings = true, -- show warnings in logs summary
notify = function(message, severity) -- function to show notifications from this module (like "Build Failed")
vim.notify(message, severity)
Expand Down
14 changes: 14 additions & 0 deletions doc/xcodebuild.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ M.setup({options}) *xcodebuild.setup*
open_command = "silent botright 20split {path}", -- command used to open logs panel. You must use {path} variable to load the log file
logs_formatter = "xcbeautify --disable-colored-output", -- command used to format logs, you can use "" to skip formatting
only_summary = false, -- if true logs won't be displayed, just xcodebuild.nvim summary
live_logs = true, -- if true logs will be updated in real-time
show_warnings = true, -- show warnings in logs summary
notify = function(message, severity) -- function to show notifications from this module (like "Build Failed")
vim.notify(message, severity)
Expand Down Expand Up @@ -1556,6 +1557,19 @@ Key bindings:
- Press `q` to close the panel


M.clear() *xcodebuild.xcode_logs.panel.clear*
Clears the logs buffer.


*xcodebuild.xcode_logs.panel.append_log_lines*
M.append_log_lines({lines}, {format})
Appends {lines} to the logs buffer.

Parameters: ~
{lines} (string[])
{format} (boolean|nil) default = true


*xcodebuild.xcode_logs.panel.set_logs*
M.set_logs({report}, {isTesting}, {callback})
Processes {report} and shows logs in the panel.
Expand Down
1 change: 1 addition & 0 deletions lua/xcodebuild/core/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ local defaults = {
open_command = "silent botright 20split {path}", -- command used to open logs panel. You must use {path} variable to load the log file
logs_formatter = "xcbeautify --disable-colored-output", -- command used to format logs, you can use "" to skip formatting
only_summary = false, -- if true logs won't be displayed, just xcodebuild.nvim summary
live_logs = true, -- if true logs will be updated in real-time
show_warnings = true, -- show warnings in logs summary
notify = function(message, severity) -- function to show notifications from this module (like "Build Failed")
vim.notify(message, severity)
Expand Down
2 changes: 2 additions & 0 deletions lua/xcodebuild/helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,12 @@ function M.update_readonly_buffer(bufnr, updateFoo)
return
end

vim.api.nvim_buf_set_option(bufnr, "readonly", false)
vim.api.nvim_buf_set_option(bufnr, "modifiable", true)
updateFoo()
vim.api.nvim_buf_set_option(bufnr, "modifiable", false)
vim.api.nvim_buf_set_option(bufnr, "modified", false)
vim.api.nvim_buf_set_option(bufnr, "readonly", true)
end

return M
1 change: 1 addition & 0 deletions lua/xcodebuild/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ end
--- open_command = "silent botright 20split {path}", -- command used to open logs panel. You must use {path} variable to load the log file
--- logs_formatter = "xcbeautify --disable-colored-output", -- command used to format logs, you can use "" to skip formatting
--- only_summary = false, -- if true logs won't be displayed, just xcodebuild.nvim summary
--- live_logs = true, -- if true logs will be updated in real-time
--- show_warnings = true, -- show warnings in logs summary
--- notify = function(message, severity) -- function to show notifications from this module (like "Build Failed")
--- vim.notify(message, severity)
Expand Down
2 changes: 2 additions & 0 deletions lua/xcodebuild/project/builder.lua
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ function M.build_project(opts, callback)
if code == CANCELLED_CODE then
notifications.send_build_finished(appdata.report, buildId, true)
events.build_finished(opts.buildForTesting or false, false, true, {})
logsParser.clear()
logsPanel.append_log_lines({ "", "Build cancelled" }, false)
return
end

Expand Down
13 changes: 8 additions & 5 deletions lua/xcodebuild/tests/runner.lua
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ function M.run_tests(testsToRun, opts)
helpers.clear_state()
diagnostics.clear_marks()

local logsParser = require("xcodebuild.xcode_logs.parser")
local quickfix = require("xcodebuild.core.quickfix")
local logsPanel = require("xcodebuild.xcode_logs.panel")
local coverage = require("xcodebuild.code_coverage.coverage")

local show_finish = function()
notifications.send_tests_finished(appdata.report, false)
end
Expand All @@ -153,7 +158,6 @@ function M.run_tests(testsToRun, opts)
local process_coverage = function()
if config.code_coverage.enabled then
notifications.send_progress("Gathering coverage...")
local coverage = require("xcodebuild.code_coverage.coverage")

if not appdata.report.xcresultFilepath then
notifications.send_warning("Could not find xcresult file. Code coverage won't be displayed.")
Expand All @@ -170,7 +174,6 @@ function M.run_tests(testsToRun, opts)
end

local on_stdout = function(_, output)
local logsParser = require("xcodebuild.xcode_logs.parser")
appdata.report = logsParser.parse_logs(output)
notifications.show_tests_progress(appdata.report)

Expand All @@ -190,16 +193,15 @@ function M.run_tests(testsToRun, opts)
appdata.report.failedTestsCount,
true
)
logsParser.clear()
logsPanel.append_log_lines({ "", "Tests cancelled" }, false)
return
end

if config.restore_on_start then
appdata.write_report(appdata.report)
end

local quickfix = require("xcodebuild.core.quickfix")
local logsPanel = require("xcodebuild.xcode_logs.panel")

testSearch.load_targets_map()
quickfix.set(appdata.report)
diagnostics.refresh_all_test_buffers(appdata.report)
Expand All @@ -219,6 +221,7 @@ function M.run_tests(testsToRun, opts)
-- Test Explorer also builds for testing
M.show_test_explorer(function()
testExplorer.start_tests(testsToRun)
logsParser.clear()

M.currentJobId = xcode.run_tests({
on_exit = on_exit,
Expand Down
77 changes: 62 additions & 15 deletions lua/xcodebuild/xcode_logs/panel.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ local appdata = require("xcodebuild.project.appdata")
local config = require("xcodebuild.core.config").options.logs
local testSearch = require("xcodebuild.tests.search")
local events = require("xcodebuild.broadcasting.events")
local helpers = require("xcodebuild.helpers")

local M = {}

Expand Down Expand Up @@ -56,8 +57,14 @@ end
local function format_logs(lines, callback)
if config.only_summary then
callback({})
elseif config.logs_formatter and string.len(config.logs_formatter) > 0 then
elseif config.logs_formatter and config.logs_formatter ~= "" then
local logs_filepath = appdata.original_logs_filepath

if config.logs_formatter:find("xcbeautify") and vim.fn.executable("xcbeautify") == 0 then
callback(lines)
return
end

local command = "cat '" .. logs_filepath .. "' | " .. config.logs_formatter

vim.fn.jobstart(command, {
Expand All @@ -78,21 +85,14 @@ local function refresh_logs_content()
return
end

vim.api.nvim_buf_set_option(bufnr, "modifiable", true)
vim.api.nvim_buf_set_option(bufnr, "readonly", false)

util.focus_buffer(bufnr)
vim.cmd("silent e!")

local linesNumber = #vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
vim.api.nvim_win_set_cursor(winnr, { linesNumber, 0 })
vim.api.nvim_win_call(winnr, function()
vim.cmd("silent e!")
vim.cmd("normal! G")
end)

if not config.auto_focus then
vim.cmd("wincmd p")
if config.auto_focus then
util.focus_buffer(bufnr)
end

vim.api.nvim_buf_set_option(bufnr, "modifiable", false)
vim.api.nvim_buf_set_option(bufnr, "readonly", true)
end

---Inserts test results into the {prettyOutput}.
Expand Down Expand Up @@ -235,6 +235,53 @@ local function open_test_file(tests)
end
end

---Clears the logs buffer.
function M.clear()
local bufnr, _ = get_buf_and_win_of_logs()
if not bufnr then
return
end

helpers.update_readonly_buffer(bufnr, function()
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {})
end)
end

---Appends {lines} to the logs buffer.
---@param lines string[]
---@param format boolean|nil default = true
function M.append_log_lines(lines, format)
local bufnr, winnr = get_buf_and_win_of_logs()
if not bufnr then
return
end

if format == nil then
format = true
end

if config.logs_formatter and config.logs_formatter ~= "" and format then
if config.logs_formatter:find("xcbeautify") then
if vim.fn.executable("xcbeautify") ~= 0 then
lines = vim.fn.systemlist(config.logs_formatter, table.concat(lines, "\n"))
end
else
lines = vim.fn.systemlist(config.logs_formatter, table.concat(lines, "\n"))
end
end

helpers.update_readonly_buffer(bufnr, function()
local currentBuf = vim.api.nvim_get_current_buf()
vim.api.nvim_buf_set_lines(bufnr, -1, -1, false, lines)

if bufnr ~= currentBuf and winnr then
vim.api.nvim_win_call(winnr, function()
vim.cmd("normal! G")
end)
end
end)
end

---Processes {report} and shows logs in the panel.
---It also writes the logs to the file.
---{callback} is called after the processing is finished.
Expand Down Expand Up @@ -296,7 +343,7 @@ function M.open_logs(scrollToBottom)
vim.api.nvim_win_set_cursor(0, { #lines, 0 })
end

if not config.auto_focus then
if not config.auto_focus and winnr == vim.api.nvim_get_current_win() then
vim.cmd("wincmd p")
end
end
Expand Down
17 changes: 17 additions & 0 deletions lua/xcodebuild/xcode_logs/parser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -513,17 +513,34 @@ end
---@param logLines string[] Xcode log lines.
---@return ParsedReport
function M.parse_logs(logLines)
local newLines = {}
local logsPanel = require("xcodebuild.xcode_logs.panel")
if not next(output) then
logsPanel.clear()
end

for _, line in ipairs(logLines) do
process_line(line)
end

if next(output) and next(logLines) then
output[#output] = output[#output] .. logLines[1]
newLines = { output[#output] }
table.remove(logLines, 1)
end

for _, line in ipairs(logLines) do
table.insert(output, line)
table.insert(newLines, line)
end

-- skip the last line (it will be joined in the next iteration)
if next(newLines) then
table.remove(newLines, #newLines)
end

if require("xcodebuild.core.config").options.logs.live_logs then
logsPanel.append_log_lines(newLines)
end

---@type ParsedReport
Expand Down

0 comments on commit 3fd5b2e

Please sign in to comment.