Development
cargo build --all-targetsThe workspace is one library crate (proton_drive_sync_engine) backing proton-syncd and
proton-sync, plus the desktop-app members under gui/. Edition 2024 is required.
Validation suite
Section titled “Validation suite”Run this before opening or updating a pull request — CI enforces it:
cargo fmt --all -- --checkcargo clippy --all-targets --all-features -- -D warningscargo test --all-targets --all-featuresclippy runs with -D warnings, so any warning is a build failure. Keep cargo fmt clean.
Focused tests
Section titled “Focused tests”cargo test sync::tests # planner unit tests (src/sync.rs)cargo test proton::tests # remote JSON parsing / CLI wrappercargo test events::tests # volume-events delta parsing + refresh logiccargo test reconstruct::tests # base ⊕ delta remote-map reconstructioncargo test daemon::tests # reconciliation with injected fakescargo test --test dry_run_cli # dry-run integration testcargo test --test ipc_cli # control-socket integration testcargo test computes_empty_file_sha1 # a single test by name substringThe testing pattern
Section titled “The testing pattern”The daemon is generic over its client (Daemon<C: ProtonClient>), so tests inject fake
ProtonClient implementations — including one that fails uploads to exercise the
checkpoint-commit invariant (completed actions stay committed; the failed action is never
recorded) — and reconciliation is tested without a real Proton Drive.
The planner in src/sync.rs is pure and tested directly with in-memory maps.
Prefer adding regression tests next to the logic you change: planner tests in
src/sync.rs, and boundary tests where external paths first enter the engine (remote JSON
parsing, local scanning, conflict targets). When you change a safety boundary, add a test at
the boundary that first accepts the external path.
Live tests (opt-in, #[ignore])
Section titled “Live tests (opt-in, #[ignore])”Several tests exercise a real authenticated Proton Drive account. They are #[ignore] by
default and mostly read-only. The read-only smoke test:
PROTON_SYNC_LIVE_REMOTE_ROOT=/Drive/RemoteFolder \ cargo test --test proton_live --all-features -- --ignored# Set PROTON_SYNC_LIVE_CLI=/path/to/proton-drive if it isn't on PATH.There are also #[ignore] live checks for the volume-events detection path
(tests/events_live.rs) and an id-identity gate (tests/events_identity_live.rs) that must
pass before trusting event-driven reconcile on a given account. Mutating live scenarios must
follow the safety gates in
docs/live-e2e-test-plan.md.
Where changes usually start
Section titled “Where changes usually start”- Sync behavior almost always starts in
src/sync.rs(the pure planner). Add planner regression tests there. - Runtime/loop behavior is in
src/daemon.rs. - Remote parsing is in
src/proton.rs; change detection insrc/events.rsandsrc/reconstruct.rs. - The desktop app’s data layer is
gui/gui-core(pure Rust, unit-testable standalone); the Tauri shell isgui/src-tauri; the webview frontend isgui/src.
See the repo’s CLAUDE.md for the architecture map and the invariants to preserve, and the
ADRs for the non-obvious decisions.
Contributing
Section titled “Contributing”Format, lint, and test before pushing. Keep changes focused, add tests near the code you touch, and preserve the documented invariants — commit-after-side-effects, path-safety at boundaries, non-destructive-on-unknown-digests, and selective-sync-applies-everywhere.