v1.4.0 - Incremental Update Mode + First PyPI Release
Release v1.4.0
What's Changed
✨ New Features
- Incremental update mode:
dazzlesum updatenow rehashes only changed files instead of silently performing a full create (theupdate_modeparameter was previously dead code). On a library-scale tree, an unchanged rescan is stat-bound: minutes instead of hours. - Per-machine state cache: one SQLite file (
.dazzle-cache.sqlite) at the shadow root records each file's (size, mtime) at last hash. Disposable accelerator — the.shasummanifests remain the only durable record. Never sync or commit it. - Resilio-safe change detection: comparison is stat equality against recorded state, not "is mtime newer" — content synced in carrying older origin mtimes is still detected.
update --dirs-from FILE|-: external change detectors (git hooks, filesystem watchers) can nominate suspect folders; anything that prints folder names can drive an incremental update.update --bootstrap hash|trust: adopt an existing manifest tree with full re-verification or by seeding the cache without rehashing.update --paranoidandupdate --keep-missing; per-run stats report (unchanged / rehashed / added / removed / rewritten / failed).dazzlesum --detailed-help updatetopic.
🐛 Bug Fixes
--excludepatterns now prune directory traversal, not just file matching. Previously the walker descended into excluded directories (.git,.private,.sync, …) and checksummed their contents (v1.3.6 fixed this for the progress counter but not the walk itself).- Windows junction detection no longer spawns a
dir /ALsubprocess per non-junction directory (~60 ms per folder — hours at scale), and directories reached through a junction ancestor are no longer misclassified as junctions (which silently skipped whole trees). --dirs-frominput is BOM-tolerant (PowerShell pipes prepend a UTF-8 BOM to stdin; Windows editors add one to files).
📝 Documentation
- README: refreshed badge row (live PyPI version, release date, platform); documented the standalone no-install path (copy
dazzlesum.py, run directly); canonicalized URLs on the DazzleTools org. - Human test checklist for the feature at
tests/checklists/v1.4.0__Feature__incremental-update-mode.md, including the executed-run record.
🧰 Maintenance
.shasumwrites are atomic (temp + rename); update rewrites a manifest only when its content actually changed, keeping unchanged manifests byte-identical.- PyPI publishing workflow: publishing a GitHub Release triggers an automatic upload via trusted publishing (OIDC, no stored tokens); manual dispatch and local
twine uploadremain available.scripts/check_dist_no_leak.pyblocks any artifact containingprivate/paths or local state files. - 30 new automated tests (update semantics incl. the older-mtime sync case, BOM regressions, junction detection with a real NTFS junction, traversal pruning at both call sites).
🔄 Breaking Changes
- None.
updatesemantics changed from "silent full create" to true incremental — strictly what the command always documented.
Installation
Install from PyPI
pip install dazzlesumOr clone and install
git clone https://github.com/DazzleTools/dazzlesum.git
cd dazzlesum
pip install -e .Or standalone
Copy dazzlesum.py anywhere and run it directly — single file, stdlib only.
Full Changelog: v1.3.6...v1.4.0