Skip to content

fix(aw-sync): default sync dir to documented data dir, migrate legacy ~/ActivityWatchSync - #667

Open
TimeToBuildBob wants to merge 5 commits into
ActivityWatch:masterfrom
TimeToBuildBob:fix/aw-sync-default-dir-data-dir
Open

fix(aw-sync): default sync dir to documented data dir, migrate legacy ~/ActivityWatchSync#667
TimeToBuildBob wants to merge 5 commits into
ActivityWatch:masterfrom
TimeToBuildBob:fix/aw-sync-default-dir-data-dir

Conversation

@TimeToBuildBob

@TimeToBuildBob TimeToBuildBob commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Problem

aw-sync's default sync location was ~/ActivityWatchSync, created in the user's
home directory. A stock install makes this visible immediately: aw-tauri's
first-run autostart module list ships { name = "aw-sync", args = "daemon" }, so a
fresh install runs the sync daemon and writes ~/ActivityWatchSync/<uuid>/test.db
without the user opting into sync at all — clashing with the documented data
directories (ActivityWatch/activitywatch#1418).

What changed

  • get_sync_dir() now defaults to data_dir()/activitywatch/aw-sync on desktop,
    matching aw-server's data_dir()/activitywatch/<component> convention
    (aw-server/src/dirs.rs::get_data_dir) and aw-sync's own config dir
    (config_dir()/activitywatch/aw-sync). Android keeps its app-scoped historical
    location, and the AW_SYNC_DIR / --sync-dir overrides are unchanged.
  • If ~/ActivityWatchSync already has content, that path is kept. aw-sync's
    transport is an external folder synchronizer (Syncthing/Dropbox/etc) watching
    that directory; auto-renaming it would disconnect existing setups, and a failed
    cross-device rename would start a fresh empty tree beside live data. New
    installs with no legacy dir get the documented location. An empty leftover of
    ~/ActivityWatchSync does not displace live data already in the documented
    dir. Existing users can delete the old folder or set AW_SYNC_DIR to switch.

Testing

Unit tests in aw-sync/src/dirs.rs cover the resolution paths:

  • prefers_existing_legacy_sync_dir
  • uses_documented_dir_when_no_legacy
  • prefers_legacy_even_if_documented_also_exists
  • empty_legacy_does_not_displace_populated_documented
cargo test -p aw-sync --lib   # 17 passed (incl. 4 new)
cargo clippy -p aw-sync       # no new lints in aw-sync

Closes ActivityWatch/activitywatch#1418

… ~/ActivityWatchSync

aw-sync's default sync location was `~/ActivityWatchSync`, which a stock
install (aw-tauri first-run autostarts `aw-sync daemon`) created in the
user's home directory, clashing with the documented data directories
(ActivityWatch/activitywatch#1418).

- get_sync_dir() now defaults to data_dir()/activitywatch/aw-sync on
  desktop, matching aw-server's data_dir()/activitywatch/<component>
  convention and aw-sync's own config dir. Android keeps its
  app-scoped historical location; AW_SYNC_DIR/--sync-dir overrides are
  unchanged.
- One-time migration moves an existing ~/ActivityWatchSync into the new
  location at daemon/CLI startup so synced data is preserved. It no-ops
  when an explicit location is set or no legacy dir exists, and refuses
  to auto-merge if both locations already have data (leaves both in
  place, logs a warning) rather than risk losing data.
- Adds unit tests for the migrate, no-op, and refuse-to-merge paths.

Closes ActivityWatch/activitywatch#1418

Git-Session-Id: fd9c
@greptile-apps

greptile-apps Bot commented Sep 1, 2026

Copy link
Copy Markdown

Greptile Summary

The PR changes aw-sync’s desktop default from ~/ActivityWatchSync to the platform data directory while retaining legacy roots intended to preserve existing external-folder transports.

  • Adds platform-aware default and legacy-directory resolution.
  • Updates CLI help and README documentation for the new selection behavior.
  • Adds regression coverage for legacy, documented, unreadable, and metadata-error states.

Confidence Score: 4/5

The PR should not merge until empty legacy directories reliably defer to the documented sync root without risking a split from temporarily unreadable documented state.

The resolver still returns an empty legacy directory whenever the documented directory is absent, empty, or unreadable, contradicting the new default and leaving a path that can separate synchronization from existing documented state.

Files Needing Attention: aw-sync/src/dirs.rs

Important Files Changed

Filename Overview
aw-sync/src/dirs.rs Implements and tests the new sync-root resolver, but its empty-legacy fallback can still select the legacy path contrary to the documented default and can redirect away from unreadable documented state.
aw-sync/src/main.rs Updates CLI help to describe the intended platform-data default and legacy-content fallback.
aw-sync/README.md Documents the platform data directory and retention of legacy directories that already contain data.

Reviews (5): Last reviewed commit: "fix(aw-sync): fail closed when legacy sy..." | Re-trigger Greptile

Comment thread aw-sync/src/dirs.rs Outdated
Comment thread aw-sync/src/dirs.rs Outdated
@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 52.17391% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.18%. Comparing base (656f3c9) to head (edb1879).
⚠️ Report is 98 commits behind head on master.

Files with missing lines Patch % Lines
aw-sync/src/dirs.rs 52.17% 11 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #667      +/-   ##
==========================================
+ Coverage   70.81%   79.18%   +8.36%     
==========================================
  Files          51       67      +16     
  Lines        2916     5789    +2873     
==========================================
+ Hits         2065     4584    +2519     
- Misses        851     1205     +354     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Auto-migration on startup had two failure modes Greptile flagged:
a failed cross-device rename left the daemon writing a fresh empty tree
beside live data, and a successful rename disconnected any Syncthing/
Dropbox transport still watching the old path.

New installs still default to data_dir()/activitywatch/aw-sync. If
~/ActivityWatchSync already exists, keep using it. AW_SYNC_DIR and
--sync-dir are unchanged.
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review

Comment thread aw-sync/src/dirs.rs Outdated
An empty leftover of the legacy default was enough to switch every
sync operation away from remote databases already in the documented
directory. Prefer the documented path when it has content and the
legacy dir does not.
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review

Comment thread aw-sync/src/dirs.rs Outdated
A read_dir error on the legacy path must not be treated as emptiness.
That silently switched the daemon onto the documented data dir while
Syncthing/Dropbox still watched the old path.
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review

Comment thread aw-sync/src/dirs.rs Outdated
Path::exists() maps IO/permission errors to false, which selected the
documented data dir and abandoned a Syncthing/Dropbox root we could not
stat. Use try_exists() and keep the legacy path on Err.
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review

Comment thread aw-sync/src/dirs.rs
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

Greptile convergence adjudication

Hit the review-attempt cap. Not retriggering Greptile.

Verified against: edb18794be6f537118ec2fe4a66a9d5fb7531821 (current head; Greptile last-reviewed this SHA). Our own reviewer has no open findings.

CI: all green (ubuntu, windows, macOS, Android, clippy, format, coverage). mergeable=MERGEABLE, mergeStateStatus=CLEAN.

Convergence: round_convergence.status=new_blocking, stable_rounds=0 (required 2). Five rounds, each with a new P1 on resolve_sync_dir. Classic diminishing-returns loop, not a leftover bug.

Fixed (already on this head)

Finding Class Where
Failed fs::rename (EXDEV) abandoned live sync state blocking dropped auto-rename in 630caae
Rename disconnected Syncthing/Dropbox transport blocking same; keep existing ~/ActivityWatchSync
Empty leftover legacy dir displaced populated documented dir blocking 68643b7
read_dir error treated as empty → silent switch blocking bcdd1ce (dir_has_entriesOption<bool>)
exists() mapped metadata error to absence blocking edb1879 (try_exists fail-closed)

Remaining (non-blocking)

Finding Class Dismissal
Empty ~/ActivityWatchSync still wins when documented is absent, empty, or unreadable accepted trade-off / product call Empty leftover already yields to a populated documented dir (empty_legacy_does_not_displace_populated_documented). Always-switch would disconnect a Syncthing/Dropbox root created from old docs and fail-open onto an unreadable documented dir. New installs with no leftover still get the platform data dir. Greptile withdrew this at 18:58Z (3907389302). Summary score stays 4/5 because the summary body was not re-edited after withdrawal.

This session: no code change. Resolved the six leftover Greptile threads (five outdated+fixed, one withdrawn). Did not retrigger review.

Domain risk (maintainer glance)

aw-sync default-dir selection:

  1. Fresh install, no leftover folder → documented data_dir()/activitywatch/aw-sync.
  2. Existing Syncthing/Dropbox watching ~/ActivityWatchSync → keep that path.
  3. Empty leftover + populated documented dir → documented (covered by test).

The product call in (remaining) is whether an empty leftover with no documented content should keep the old folder. I would keep it. Switching is a silent transport break for anyone who created the folder from old docs before the first sync.

Not auto-merging (cross-repo, no merge rights). Waiting on maintainer judgment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Folder created in home directory (clashes with documented location)

1 participant