# Path synchronization - Core recipes # CONFIGURE THESE FOR YOUR SETUP: SOURCE := "/path/to/source" # Primary location (source for cloud backup) TARGET := "/path/to/target" # Secondary location # Cloud backup configuration CLOUD_REMOTE := "your-cloud-remote" # Any rclone remote CLOUD_PATH := "/usync" # Path in cloud storage CLOUD_MOUNT_PATH := "~/cloud-mount" # Local mount point (default: home directory) # Install dependencies for openSUSE install-deps: sudo zypper install -y rclone unison # Fast sync between paths (unison) sync-paths: unison -ui text paths # Slow sync to cloud storage (from source) sync-cloud: check-rclone mount-cloud rclone sync -P --checkers 32 --transfers 32 --buffer-size 128M --retries 3 --order-by 'size,ascending' {{SOURCE}}/usync {{CLOUD_REMOTE}}:{{CLOUD_PATH}} just unmount-cloud # Dry run to cloud (safety check) sync-cloud-dry: check-rclone mount-cloud rclone sync -P --checkers 32 --transfers 32 --buffer-size 128M --retries 3 --order-by 'size,ascending' --dry-run {{SOURCE}}/usync {{CLOUD_REMOTE}}:{{CLOUD_PATH}} just unmount-cloud # Mount management (uses configurable mount point) mount-cloud: @mountpoint {{CLOUD_MOUNT_PATH}} 2>/dev/null && echo "Cloud storage already mounted" || (mkdir -p {{CLOUD_MOUNT_PATH}} && rclone mount {{CLOUD_REMOTE}}: --vfs-cache-mode full --daemon {{CLOUD_MOUNT_PATH}} && echo "✓ Cloud storage mounted at {{CLOUD_MOUNT_PATH}}") unmount-cloud: fusermount -u {{CLOUD_MOUNT_PATH}} # Verify rclone remote exists check-rclone: @rclone config show {{CLOUD_REMOTE}} >/dev/null 2>&1 || (echo "Error: rclone remote '{{CLOUD_REMOTE}}' not found. Run 'rclone config' first." && exit 1) @echo "✓ rclone remote '{{CLOUD_REMOTE}}' configured" # Verify both paths are accessible check: @test -d {{SOURCE}} || (echo "Source path not found: {{SOURCE}}" && exit 1) @test -d {{TARGET}} || (echo "Target path not found: {{TARGET}}" && exit 1) @echo "✓ Both paths accessible" @test -w {{SOURCE}} || (echo "Source path not writable" && exit 1) @test -w {{TARGET}} || (echo "Target path not writable" && exit 1) @echo "✓ Both paths writable" # Create usync directories if they don't exist setup: @mkdir -p {{SOURCE}}/usync {{TARGET}}/usync @echo "✓ Usync directories created" @just create-unison-profile # Create unison profile for non-interactive syncing create-unison-profile: @mkdir -p ~/.unison @sed -e "s|TEMPLATE_SOURCE|{{SOURCE}}|g" -e "s|TEMPLATE_TARGET|{{TARGET}}|g" -e "s|TEMPLATE_HOME_DIR|$(echo $HOME)|g" unison-profile.prf > ~/.unison/paths.prf @echo "✓ Unison profile created at ~/.unison/paths.prf" # Status check (default) status: @echo "=== Path Status ===" @echo "Source path: $(test -d {{SOURCE}}/usync && echo "$(ls -1 {{SOURCE}}/usync/ 2>/dev/null | wc -l) folders, $(du -sh {{SOURCE}}/usync 2>/dev/null | cut -f1)" || echo "missing")" @echo "Target path: $(test -d {{TARGET}}/usync && echo "$(ls -1 {{TARGET}}/usync/ 2>/dev/null | wc -l) folders, $(du -sh {{TARGET}}/usync 2>/dev/null | cut -f1)" || echo "missing")" @echo "Cloud storage ({{CLOUD_REMOTE}}): $(mountpoint {{CLOUD_MOUNT_PATH}} >/dev/null 2>&1 && echo "mounted" || echo "not mounted")" @echo "Unison profile: $(test -f ~/.unison/paths.prf && echo "exists" || echo "missing")" default: just status