feat(sync): backend interface + CLI refactor (#42)
* refactor(sync): extract backend interface, adapt gcal module
Problem: :Pending sync hardcodes Google Calendar — M.sync() does
pcall(require, 'pending.sync.gcal') and calls gcal.sync() directly.
The config has a flat gcal field. This prevents adding new sync backends
without modifying init.lua.
Solution: Define a backend interface contract (name, auth, sync, health
fields), refactor :Pending sync to dispatch via require('pending.sync.'
.. backend_name), add sync table to config with legacy gcal migration,
rename gcal.authorize to gcal.auth, add gcal.health for checkhealth,
and add tab completion for backend names and actions.
* docs(sync): update vimdoc for backend interface
Problem: Vimdoc documents :Pending sync as a bare command that pushes
to Google Calendar, with no mention of backends or the sync table config.
Solution: Update :Pending sync section to show {backend} [{action}]
syntax with examples, add SYNC BACKENDS section documenting the interface
contract, update config example to use sync.gcal, document legacy gcal
migration, and update health check description.
* test(sync): add backend dispatch tests
Problem: No test coverage for sync dispatch logic, config migration,
or gcal module interface conformance.
Solution: Add spec/sync_spec.lua with tests for: bare sync errors,
empty backend errors, unknown backend errors, unknown action errors,
default-to-sync routing, explicit sync/auth routing, legacy gcal config
migration, explicit sync.gcal precedence, and gcal module interface
fields (name, auth, sync, health).
This commit is contained in:
parent
85cf0d42ed
commit
306e11aee6
7 changed files with 327 additions and 36 deletions
|
|
@ -2,6 +2,9 @@
|
|||
---@field calendar? string
|
||||
---@field credentials_path? string
|
||||
|
||||
---@class pending.SyncConfig
|
||||
---@field gcal? pending.GcalConfig
|
||||
|
||||
---@class pending.Keymaps
|
||||
---@field close? string|false
|
||||
---@field toggle? string|false
|
||||
|
|
@ -32,6 +35,7 @@
|
|||
---@field drawer_height? integer
|
||||
---@field debug? boolean
|
||||
---@field keymaps pending.Keymaps
|
||||
---@field sync? pending.SyncConfig
|
||||
---@field gcal? pending.GcalConfig
|
||||
|
||||
---@class pending.config
|
||||
|
|
@ -65,6 +69,7 @@ local defaults = {
|
|||
next_task = ']t',
|
||||
prev_task = '[t',
|
||||
},
|
||||
sync = {},
|
||||
}
|
||||
|
||||
---@type pending.Config?
|
||||
|
|
@ -77,6 +82,10 @@ function M.get()
|
|||
end
|
||||
local user = vim.g.pending or {}
|
||||
_resolved = vim.tbl_deep_extend('force', defaults, user)
|
||||
if _resolved.gcal and not (_resolved.sync and _resolved.sync.gcal) then
|
||||
_resolved.sync = _resolved.sync or {}
|
||||
_resolved.sync.gcal = _resolved.gcal
|
||||
end
|
||||
return _resolved
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue