Skip to content

V0.1.3#9

Merged
arumes31 merged 7 commits into
mainfrom
v0.1.3
Jun 18, 2026
Merged

V0.1.3#9
arumes31 merged 7 commits into
mainfrom
v0.1.3

Conversation

@arumes31

@arumes31 arumes31 commented Jun 18, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Windows single-instance protection to prevent multiple app instances
    • Configurable sync direction (two-way, upload-only, download-only, mirror) and conflict resolution policies per folder pair
    • Quiet hours scheduling and metered network detection
    • Drive trash support for safer file deletion
    • Passphrase strength validation for enhanced security
    • Backup export for disaster recovery
    • Online-only file support to save local disk space
    • Enhanced UI: live activity tracking with ETA, search/filter, per-pair controls, desktop notifications
  • Bug Fixes

    • Database corruption quarantine and recovery
    • Delete/edit conflict detection to prevent data loss
    • TOCTOU protections during uploads
  • Improvements

    • Padded filename encryption and collision detection
    • Hash cache persistence across restarts
    • Long path support on Windows

@arumes31
arumes31 merged commit bc24447 into main Jun 18, 2026
1 of 3 checks passed
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a66ed5fe-a323-4b05-a8aa-d29c6084610d

📥 Commits

Reviewing files that changed from the base of the PR and between 4d2b39f and ac4a8b8.

📒 Files selected for processing (37)
  • README.md
  • cmd/gcrypt/main.go
  • cmd/gcrypt/singleinstance_other.go
  • cmd/gcrypt/singleinstance_windows.go
  • go.mod
  • internal/config/config.go
  • internal/config/config_test.go
  • internal/config/overlap_test.go
  • internal/crypto/filename.go
  • internal/crypto/filename_padding_test.go
  • internal/crypto/strength.go
  • internal/crypto/strength_test.go
  • internal/drive/client.go
  • internal/drive/store.go
  • internal/models/models.go
  • internal/service/backup.go
  • internal/service/fyneui.go
  • internal/service/fyneui_activity.go
  • internal/service/fyneui_issues.go
  • internal/service/fyneui_settings.go
  • internal/service/fyneui_theme.go
  • internal/service/setup.go
  • internal/sync/collision_test.go
  • internal/sync/conflict.go
  • internal/sync/engine.go
  • internal/sync/engine_gates_test.go
  • internal/sync/hashcache_test.go
  • internal/sync/ignore.go
  • internal/sync/manager.go
  • internal/sync/metered_other.go
  • internal/sync/metered_windows.go
  • internal/sync/platform_other.go
  • internal/sync/platform_windows.go
  • internal/sync/scanner.go
  • internal/sync/schedule.go
  • internal/sync/schedule_test.go
  • temp_clone

📝 Walkthrough

Walkthrough

This PR substantially extends the sync engine with bidirectional sync directions, a complete conflict-policy implementation (keep_local, keep_remote, keep_both, manual, auto LWW), quiet-hours and metered-network scheduling, padded filename encryption, passphrase-strength enforcement, a Windows single-instance guard, Drive client hardening (QuotaExceededError, modTime round-trip, TrashFile, changes-feed polling), SQLite store corruption recovery, and a major Fyne UI overhaul adding an Issues tab, per-pair folder controls, account/quota display, desktop notifications, and backup export.

Changes

Sync Engine, Config, Crypto, Drive & UI Feature Expansion

Layer / File(s) Summary
Config schema: direction, conflict policy, schedule, overlap
internal/config/config.go, internal/config/config_test.go, internal/config/overlap_test.go
Adds SyncDirection/ConflictPolicy types and constants, embeds ScheduleConfig into AppConfig, extends SyncPair with EffectiveDirection/EffectiveConflictPolicy (including ForwardOnly migration), adds PairsOverlap/CanAddPair/ValidateNoOverlap overlap detection, and updates Validate with validateHHMM for quiet-hours time strings; tests cover overlap scenarios and new validation errors.
Padded filename encryption & passphrase strength
internal/crypto/filename.go, internal/crypto/filename_padding_test.go, internal/crypto/strength.go, internal/crypto/strength_test.go, internal/service/setup.go
Adds EncryptFilenamePadded (v1 format: bucket-padded payload + version marker) and refactors DecryptFilename to auto-detect format; adds CheckPassphraseStrength enforcing length, denylist, character-class diversity, and wires it into RunSetup; tests cover round-trip, format compatibility, length-hiding, and passphrase cases.
Drive client & store extensions
internal/drive/client.go, internal/drive/store.go
Adds QuotaExceededError detection, modTime parameter to UploadFile/UpdateFile, AccountInfo/About, TrashFile, and ChangeItem/GetStartPageToken/ListChanges for the changes feed; extracts SQLite setup into openStore with PRAGMA quick_check and adds quarantineDB to rename corrupt DB files and retry on a fresh database.
Sync supporting primitives
internal/models/models.go, internal/sync/ignore.go, internal/sync/conflict.go, internal/sync/schedule.go, internal/sync/schedule_test.go, internal/sync/metered_*.go, internal/sync/platform_*.go, internal/sync/scanner.go, internal/sync/hashcache_test.go, go.mod
Adds SyncStatusOnlineOnly; extends built-in ignore patterns; introduces ConflictItem and thread-safe conflictQueue; adds IsQuietHours/ValidateScheduleTime; adds IsMeteredNetwork via Windows NLM COM and a no-op stub; adds longPath/availableDiskBytes with cross-platform stubs; extends Scanner with LoadHashCache/SaveHashCache/EmptyDirs; promotes golang.org/x/text to direct dependency.
Sync engine infrastructure
internal/sync/engine.go (fields, constants, enqueue, NewEngine), internal/sync/engine_gates_test.go, internal/sync/collision_test.go
Extends Engine with pendingBytes, largeUploadSem, changePageToken, conflictQueue, and encName helper; updates defaultWorkers and rate constants; refactors enqueueWork to track pendingBytes and adds enqueueDetached; warms hash cache in NewEngine; tests lock in per-direction gate behavior and collisionKey normalization.
Sync engine file operations
internal/sync/engine.go (upload/download/delete/conflict/worker/helpers)
Hardens uploadFile with long-path stat, encName, crash-recovery dedup lookup, TOCTOU size/mtime/hash guards, and large-upload semaphore; rewrites downloadFile with disk-space check, temp-file atomic rename, modtime restore, and re-hash; updates deleteRemote to use TrashFile with delete/edit conflict detection; adds upload-wins path in deleteLocal; rewrites resolveConflict for all conflict policies with conflictQueue integration; adds ListErrored/RetryFailed/PendingConflicts/ResolveConflictAction/OnlineOnlyCount/MakeAvailableOffline; gates worker on quiet hours and metered network.
Sync engine polling & reconcile
internal/sync/engine.go (poll, reconcile, collection)
Adds changePageToken-based pollOnce/pollChanges for incremental changes-feed polling; SyncNow forces full reconcile; reconcileRemote gains direction-aware early-exit, Unicode NFC+case-fold collision detection, online-only placeholder recording, two-way vs download-only conflict handling, and local-delete gating; collectRemoteFiles returns dirs for ensureLocalDirs; resolveRemoteDir/lookupRemoteDirID use encName.
Manager aggregation & overlap guard
internal/sync/manager.go
AddPair rejects overlapping pairs via config.PairsOverlap; adds ListErrored/RetryFailed/PendingConflicts/ResolveConflict/OnlineOnlyCount/MakeAvailableOffline as manager-level aggregation methods delegating to per-engine counterparts.
Service backup export
internal/service/backup.go
Adds ExportBackup that creates a destination directory at 0700, copies config.yaml and salt.bin with owner-only 0600 permissions via copyFileSecure, and removes partial copies on failure.
Fyne UI core: state, theme, tray/icon, account loop, notifications, progress
internal/service/fyneui.go, internal/service/fyneui_theme.go
Refactors FyneApp replacing isPaused with derived syncPaused(); adds brandTheme with custom accent colors; adds tightIcon/cropToGlyph/overlayBadge for badge-composited tray icons; adds accountLoop/refreshAccountInfo/applyAccountInfo polling Drive quota every 60s; adds maybeNotify for state-transition desktop notifications; rewrites refreshSummary with IEC units, ETA computation, byte-batch progress model, and signature-based refreshLiveTransfers; adds refreshPauseControls.
Fyne UI tabs: Activity filter, Issues tab, Settings & Folders overhaul
internal/service/fyneui_activity.go, internal/service/fyneui_issues.go, internal/service/fyneui_settings.go
Updates refreshActivity with activityFilter search and skip-refresh optimization; introduces buildIssuesTab/refreshIssues/buildConflictCard for errored transfers and manual conflicts; overhauls Settings tab with Account, Backup & recovery, Scheduling & network, and Security sections; reworks Folders tab with per-pair pairWidgets, folderFilter, per-folder Direction/ConflictPolicy/online-only/pad-filenames controls, Enabled checkbox with async manager wiring, and updatePairWidgets/applyPairWidgets for live metrics.
Windows single-instance guard & startup wiring
cmd/gcrypt/singleinstance_windows.go, cmd/gcrypt/singleinstance_other.go, cmd/gcrypt/main.go, README.md
Adds Windows session-scoped named-mutex guard (acquireSingleInstance) with no-op cross-platform stub; wires guard into main after the OpenGL relaunch handoff; updates upload_workers default (8→160) and throughput documentation in README.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant FyneUI
  participant SyncManager
  participant Engine
  participant DriveClient

  User->>FyneUI: Edit file locally
  FyneUI->>SyncManager: (polling interval / SyncNow)
  SyncManager->>Engine: pollChanges / reconcileRemote
  Engine->>DriveClient: ListChanges (changePageToken)
  DriveClient-->>Engine: ChangeItems
  Engine->>Engine: detectCollisions (NFC+case-fold)
  Engine->>Engine: resolveConflict (policy: auto/keep_local/keep_remote/keep_both/manual)
  alt manual policy
    Engine->>Engine: conflictQueue.Add(ConflictItem)
    Engine-->>FyneUI: PendingConflicts → Issues tab
    User->>FyneUI: Pick resolution button
    FyneUI->>SyncManager: ResolveConflict(pairID, path, policy)
    SyncManager->>Engine: ResolveConflictAction
  else auto/keep_local/keep_remote
    Engine->>DriveClient: UploadFile / UpdateFile (modTime)
    Engine->>Engine: TOCTOU hash verify
  end
  Engine-->>FyneUI: Activity / pendingBytes / ETA refresh
  FyneUI->>User: Progress bar + desktop notification
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • arumes31/gcrypt#7: Both PRs modify cmd/gcrypt/main.go startup wiring and internal/service/fyneui.go FyneApp/tray/window code, so this PR's single-instance guard and UI overhaul build directly on top of the same areas touched in PR #7.

Poem

🐇 A rabbit once managed just one way to sync,
Now two-way and mirror arrive in a blink!
Conflicts resolved with a card and three buttons,
Quiet hours respected — no nighttime disruptions.
Padded filenames hide lengths from the spies,
And one instance only — no duplicate ties! 🔐

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch v0.1.3

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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.

1 participant