75 lines
3.2 KiB
Markdown
75 lines
3.2 KiB
Markdown
|
|
# calcalist
|
||
|
|
|
||
|
|
Aggregates events between CalDAV, Google Calendar and iCal feeds. `README.md` is
|
||
|
|
the user-facing guide; the design rationale lives in the module doc comments,
|
||
|
|
beside the code it governs.
|
||
|
|
|
||
|
|
These conventions were `SPECS.md`'s, which has been retired now the roadmap is
|
||
|
|
finished. Git history holds it, and `TODO.md`, if the record is ever wanted.
|
||
|
|
|
||
|
|
## Development
|
||
|
|
|
||
|
|
Use devbox for dependency management and scripts. Use jj for version control
|
||
|
|
(colocated with git).
|
||
|
|
|
||
|
|
- `devbox run fmt` — format.
|
||
|
|
- `devbox run check` — format check, clippy with warnings denied, and tests.
|
||
|
|
This is the gate; jj has no commit step to hang a hook off, since the working
|
||
|
|
copy is itself a commit.
|
||
|
|
- `devbox run test` — tests only.
|
||
|
|
|
||
|
|
Keep `/target` in `.gitignore`: jj snapshots the working copy on every command,
|
||
|
|
with no staging step.
|
||
|
|
|
||
|
|
The integration tests in `tests/` need `radicale` and `pimsync`, both of which
|
||
|
|
devbox provides. Outside that shell they report what is missing and pass.
|
||
|
|
|
||
|
|
## Coding style
|
||
|
|
|
||
|
|
- Simple, readable, idiomatic.
|
||
|
|
- Explicit types for public APIs and important fields.
|
||
|
|
- Prefer immutable data structures.
|
||
|
|
- No global mutable state.
|
||
|
|
- No speculative features or dependencies.
|
||
|
|
- Keep functions short and single-purpose; extract helpers to avoid nesting.
|
||
|
|
- File and module naming: `snake_case.rs`. Types and traits: `PascalCase`.
|
||
|
|
Functions, variables and fields: `snake_case`. Constants:
|
||
|
|
`SCREAMING_SNAKE_CASE`.
|
||
|
|
- Run `devbox run check` before describing a change.
|
||
|
|
- Comment only when intent is not obvious from the code.
|
||
|
|
- Prefer composition and traits over deep type hierarchies.
|
||
|
|
|
||
|
|
## Decisions already taken
|
||
|
|
|
||
|
|
Settled after real design work. Reopen only with new information, not from
|
||
|
|
first principles.
|
||
|
|
|
||
|
|
**No configuration web interface.** Designed in full, then dropped. Its audience
|
||
|
|
would be people who find TOML hard — but every user must first create a Google
|
||
|
|
Cloud project, configure a consent screen and put a secret in a keyring, which
|
||
|
|
is a far higher bar than editing the config. Anyone who clears it can edit the
|
||
|
|
file; anyone who cannot never reaches the file. `doctor`, `status` and
|
||
|
|
`discover` cover what the interface was actually for.
|
||
|
|
|
||
|
|
**Bring-your-own OAuth client, not a shipped verified one.** Verification for
|
||
|
|
the Calendar scope needs a domain you own — a `github.io` address is rejected —
|
||
|
|
and Calendar API quota is per Cloud project, with charges announced for
|
||
|
|
exceeding it. A shipped client would pool every user's syncing into the
|
||
|
|
publisher's project, and their bill. Shipping an *unverified* shared client is
|
||
|
|
worse still: the 100-new-user cap is permanent for the project's lifetime.
|
||
|
|
|
||
|
|
**pimsync cannot reach Google, and never will.** It has no REST storage, and its
|
||
|
|
config exposes only HTTP Basic auth, which Google's CalDAV endpoint rejected in
|
||
|
|
March 2025. The Google leg is calcalist's own in every design.
|
||
|
|
|
||
|
|
**The config file is never machine-rewritten.** It is the portable,
|
||
|
|
hand-editable artefact. Anything that writes it must preserve comments,
|
||
|
|
ordering and omitted defaults — `toml::to_string` on the `Serialize` derive
|
||
|
|
does none of those things.
|
||
|
|
|
||
|
|
## Known gap
|
||
|
|
|
||
|
|
A failing `pimsync sync` stops the whole CalDAV leg. Unlike the Google side this
|
||
|
|
cannot be narrowed: pimsync is one process covering every pair, and a failure
|
||
|
|
does not say which pair it belongs to.
|