fix(sync): replace cryptic sigil counters with readable output (#86)

* fix(sync): replace cryptic sigil counters with readable output

Problem: sync summaries used unexplained sigils (`+/-/~` and `!`) that
conveyed no meaning, mixed symbol and prose formats across operations,
and `gcal push` silently swallowed failures with no aggregate counter.

Solution: replace all summary `log.info` calls with a shared
`fmt_counts` helper that formats `N label` pairs separated by ` | `,
suppresses zero counts, and falls back to "nothing to do". Add a
`failed` counter to `gcal.push` to surface errors previously only
emitted as individual warnings.

* ci: format
This commit is contained in:
Barrett Ruth 2026-03-06 13:26:23 -05:00
parent 9de53f2bb3
commit bc902abd07
2 changed files with 64 additions and 27 deletions

View file

@ -154,6 +154,21 @@ local function unlink_remote(task, extra, now_ts)
task.modified = now_ts task.modified = now_ts
end end
---@param parts {[1]: integer, [2]: string}[]
---@return string
local function fmt_counts(parts)
local items = {}
for _, p in ipairs(parts) do
if p[1] > 0 then
table.insert(items, p[1] .. ' ' .. p[2])
end
end
if #items == 0 then
return 'nothing to do'
end
return table.concat(items, ' | ')
end
---@param callback fun(access_token: string): nil ---@param callback fun(access_token: string): nil
local function with_token(callback) local function with_token(callback)
oauth.async(function() oauth.async(function()
@ -176,7 +191,7 @@ function M.push()
local s = require('pending').store() local s = require('pending').store()
local now_ts = os.date('!%Y-%m-%dT%H:%M:%SZ') --[[@as string]] local now_ts = os.date('!%Y-%m-%dT%H:%M:%SZ') --[[@as string]]
local created, updated, deleted = 0, 0, 0 local created, updated, deleted, failed = 0, 0, 0, 0
for _, task in ipairs(s:tasks()) do for _, task in ipairs(s:tasks()) do
local extra = task._extra or {} local extra = task._extra or {}
@ -197,6 +212,7 @@ function M.push()
delete_event(access_token, cal_id --[[@as string]], event_id --[[@as string]]) delete_event(access_token, cal_id --[[@as string]], event_id --[[@as string]])
if del_err then if del_err then
log.warn('gcal delete failed: ' .. del_err) log.warn('gcal delete failed: ' .. del_err)
failed = failed + 1
else else
unlink_remote(task, extra, now_ts) unlink_remote(task, extra, now_ts)
deleted = deleted + 1 deleted = deleted + 1
@ -214,6 +230,7 @@ function M.push()
local upd_err = update_event(access_token, cal_id, event_id, task) local upd_err = update_event(access_token, cal_id, event_id, task)
if upd_err then if upd_err then
log.warn('gcal update failed: ' .. upd_err) log.warn('gcal update failed: ' .. upd_err)
failed = failed + 1
else else
updated = updated + 1 updated = updated + 1
end end
@ -221,10 +238,12 @@ function M.push()
local lid, lid_err = find_or_create_calendar(access_token, cat, calendars) local lid, lid_err = find_or_create_calendar(access_token, cat, calendars)
if lid_err or not lid then if lid_err or not lid then
log.warn('gcal calendar failed: ' .. (lid_err or 'unknown')) log.warn('gcal calendar failed: ' .. (lid_err or 'unknown'))
failed = failed + 1
else else
local new_id, create_err = create_event(access_token, lid, task) local new_id, create_err = create_event(access_token, lid, task)
if create_err then if create_err then
log.warn('gcal create failed: ' .. create_err) log.warn('gcal create failed: ' .. create_err)
failed = failed + 1
elseif new_id then elseif new_id then
if not task._extra then if not task._extra then
task._extra = {} task._extra = {}
@ -245,7 +264,12 @@ function M.push()
if buffer.bufnr() and vim.api.nvim_buf_is_valid(buffer.bufnr()) then if buffer.bufnr() and vim.api.nvim_buf_is_valid(buffer.bufnr()) then
buffer.render(buffer.bufnr()) buffer.render(buffer.bufnr())
end end
log.info(string.format('Google Calendar pushed — +%d ~%d -%d', created, updated, deleted)) log.info('gcal push: ' .. fmt_counts({
{ created, 'added' },
{ updated, 'updated' },
{ deleted, 'removed' },
{ failed, 'failed' },
}))
end) end)
end end

View file

@ -195,6 +195,21 @@ local function unlink_remote(task, now_ts)
task.modified = now_ts task.modified = now_ts
end end
---@param parts {[1]: integer, [2]: string}[]
---@return string
local function fmt_counts(parts)
local items = {}
for _, p in ipairs(parts) do
if p[1] > 0 then
table.insert(items, p[1] .. ' ' .. p[2])
end
end
if #items == 0 then
return 'nothing to do'
end
return table.concat(items, ' | ')
end
---@param task pending.Task ---@param task pending.Task
---@return table ---@return table
local function task_to_gtask(task) local function task_to_gtask(task)
@ -450,9 +465,12 @@ function M.push()
if buffer.bufnr() and vim.api.nvim_buf_is_valid(buffer.bufnr()) then if buffer.bufnr() and vim.api.nvim_buf_is_valid(buffer.bufnr()) then
buffer.render(buffer.bufnr()) buffer.render(buffer.bufnr())
end end
log.info( log.info('gtasks push: ' .. fmt_counts({
string.format('Google Tasks pushed — +%d ~%d -%d !%d', created, updated, deleted, failed) { created, 'added' },
) { updated, 'updated' },
{ deleted, 'deleted' },
{ failed, 'failed' },
}))
end) end)
end end
@ -474,15 +492,12 @@ function M.pull()
if buffer.bufnr() and vim.api.nvim_buf_is_valid(buffer.bufnr()) then if buffer.bufnr() and vim.api.nvim_buf_is_valid(buffer.bufnr()) then
buffer.render(buffer.bufnr()) buffer.render(buffer.bufnr())
end end
log.info( log.info('gtasks pull: ' .. fmt_counts({
string.format( { created, 'added' },
'Google Tasks pulled — +%d ~%d !%d, unlinked: %d', { updated, 'updated' },
created, { unlinked, 'unlinked' },
updated, { failed, 'failed' },
failed, }))
unlinked
)
)
end) end)
end end
@ -506,19 +521,17 @@ function M.sync()
if buffer.bufnr() and vim.api.nvim_buf_is_valid(buffer.bufnr()) then if buffer.bufnr() and vim.api.nvim_buf_is_valid(buffer.bufnr()) then
buffer.render(buffer.bufnr()) buffer.render(buffer.bufnr())
end end
log.info( log.info('gtasks sync — push: ' .. fmt_counts({
string.format( { pushed_create, 'added' },
'Google Tasks synced — push: +%d ~%d -%d !%d, pull: +%d ~%d !%d, unlinked: %d', { pushed_update, 'updated' },
pushed_create, { pushed_delete, 'deleted' },
pushed_update, { pushed_failed, 'failed' },
pushed_delete, }) .. ' pull: ' .. fmt_counts({
pushed_failed, { pulled_create, 'added' },
pulled_create, { pulled_update, 'updated' },
pulled_update, { unlinked, 'unlinked' },
pulled_failed, { pulled_failed, 'failed' },
unlinked }))
)
)
end) end)
end end