Skip to main content

Directory synchronization tool using checksums

Project description

Dubler

Directory synchronization tool.

Note: The name "dubler" comes from Polish, where it means "a person replacing an actor in film or theater" (stunt double / stand-in). Just as a dubler stands in for an actor, this tool creates backup copies that can stand in for your original files — if something happens to the original, the backup is ready to take its place.

Features

  • Checksum-based comparison: Files are compared using SHA256 hashes
  • Multiple destinations: Sync to multiple directories at once
  • Idempotent: Running multiple times is safe - only copies missing or changed files
  • Failure tracking: Tracks failed files and allows re-running
  • Dry run mode: Preview changes before copying
  • JSON configuration: Store sync settings in a config file
  • Zero dependencies: Uses Python standard library only

Installation

# From PyPI
pip install dubler
# or with uv
uv pip install dubler

# From source
uv install

Usage

Command Line

# Basic sync
dubler --source /path/to/source --dest /path/to/dest1 --dest /path/to/dest2

# Dry run (preview without copying)
dubler -s /path/to/source -d /path/to/dest --dry-run

# Verbose output
dubler -s /path/to/source -d /path/to/dest -v

# Show failed files from previous runs
dubler --failed

# Clear failed files from state
dubler --clear-failed

Configuration File

Create a JSON config file (default: ~/.config/dubler/config.json):

{
  "source": "/path/to/source",
  "destinations": [
    "/path/to/dest1",
    "/path/to/dest2"
  ],
  "dry_run": false,
  "verbose": false
}

Then run without arguments:

dubler

Or specify a custom config file:

dubler --config /path/to/config.json

How It Works

  1. Scans the source directory recursively
  2. For each destination:
    • Compares files using SHA256 checksums
    • Copies files that don't exist or have different checksums
    • Tracks any failures in ~/.local/state/dubler/state.json
  3. Displays summary of copied, skipped, and failed files

State

The application stores data in standard XDG Base Directory locations:

  • ~/.config/dubler/config.json: Configuration file (optional)
  • ~/.local/state/dubler/state.json: Failed files from previous runs

Examples

# Sync photos to multiple backup drives
dubler -s ~/Pictures -d /Volumes/Backup1/Photos -d /Volumes/Backup2/Photos

# Preview what would be synced
dubler -s ~/Documents -d ~/Backup/Documents --dry-run -v

# After a failed run, see what failed
dubler --failed

# Fix the issue and run again (idempotent)
dubler -s ~/Documents -d ~/Backup/Documents

Releasing

The project uses automatic versioning based on git tags via setuptools_scm.

Creating a Release

Use the release helper script:

# Bump patch version (bug fixes)
uv run python scripts/release.py patch

# Bump minor version (new features)
uv run python scripts/release.py minor

# Bump major version (breaking changes)
uv run python scripts/release.py major

# Or specify exact version
uv run python scripts/release.py patch --version 1.2.3

This will:

  1. Create and push a git tag (e.g., v1.0.0)
  2. Trigger the GitHub Actions release workflow
  3. Automatically create a published release with:
    • Release notes from commits
    • Installation instructions
    • Full changelog link
  4. Publish to PyPI

Manual Release (Alternative)

# Create and push tag manually
git tag v1.0.0
git push origin v1.0.0

Version Format

Tags must follow semantic versioning: vX.Y.Z

  • X = Major version (breaking changes)
  • Y = Minor version (new features, backwards compatible)
  • Z = Patch version (bug fixes, backwards compatible)

Conventional Commits

This project uses conventional commit messages. See AGENTS.md for guidelines.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dubler-1.0.0.tar.gz (22.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dubler-1.0.0-py3-none-any.whl (8.8 kB view details)

Uploaded Python 3

File details

Details for the file dubler-1.0.0.tar.gz.

File metadata

  • Download URL: dubler-1.0.0.tar.gz
  • Upload date:
  • Size: 22.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for dubler-1.0.0.tar.gz
Algorithm Hash digest
SHA256 fc72ce954f7cab58d41ca29e337678c984a80d2fe59f60c8414f569f8f201763
MD5 74dc9a42097810621d493df550a56c22
BLAKE2b-256 e25e7ee3c9050697a751d8fff6984e91b5ced840017a99c0795511323067cafa

See more details on using hashes here.

File details

Details for the file dubler-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: dubler-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 8.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for dubler-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 934d08cbd53797cde7ce9862a1c4b6e67de0605e349ac88dbf3b9344dcf824ac
MD5 19238e63db9e3c3a683ef26d154d64cb
BLAKE2b-256 511a2bfd27d2b8ad3806cedf3667dfefbf576b5a0a22b394e264ae558740479d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page