Bug fixes, new features and test suite#102
Conversation
At least on Ubuntu 24.04, `pip` would error out with `error: externally-managed-environment`. According to the following SO, the proper way for an application that should be globally available, is to use `pipx` instead. See https://stackoverflow.com/a/78652149/37706
Replace [px]* with [a-z] to match all vim swap extensions (.swo, .swn, .swm, etc.) not just .swp and .swx. Signed-off-by: Eric Villard <dev@eviweb.fr>
Signed-off-by: Eric Villard <dev@eviweb.fr>
inotify fires both created and modified events when a file is created. Previously on_created was entirely skipped for InotifyObserver, which caused two bugs: - files moved into a watched directory did not trigger the command (joh#68) - WHEN_CHANGED_EVENT was never set to file_created on Linux (joh#76) Fix: track recently created paths in a set and skip the redundant modified event, instead of ignoring created events entirely.
last_run was recorded after subprocess.call(), so any file change occurring during command execution had mtime > last_run and triggered a re-run. Also the comparison used < instead of <=. Fix: record last_run before subprocess.call() so that changes during execution are correctly ignored on the next event.
Add modern pyproject.toml with build-system configuration. Remove obsolete subprocess32 from requirements (Python 2 only). A wheel can now be built with: python3 -m build
-k: kill the currently running command before restarting it,
useful for long-running processes (servers, watchers).
Uses SIGTERM with 5s timeout fallback to SIGKILL.
-d DELAY: wait DELAY seconds before running the command,
coalescing rapid successive changes into a single run.
Uses threading.Timer, each new event resets the timer.
Covers: is_interested(), event handlers, debounce, run_command, CLI parsing. Also documents regex bug in backup file exclusion (.~$)." Signed-off-by: Eric Villard <dev@eviweb.fr>
Replace set with dict (path -> timestamp). On each on_modified, purge entries older than 1s before checking. Handles the case where on_modified never fires after on_created (e.g. empty file creation). Signed-off-by: Eric Villard <dev@eviweb.fr>
r'.~$' matched any char before ~ due to unescaped dot. Corrected to r'\.~$' to match only literal dot (e.g. file.py~). Signed-off-by: Eric Villard <dev@eviweb.fr>
New option -p PATTERN (glob) restricts reactions to files whose basename matches the pattern. Can be repeated for multiple patterns. No -p means watch all files (existing behavior preserved). Uses fnmatch for glob matching (*, ?, [...] supported). Pattern check is applied in is_interested() after exclude rules, so excluded files (vim swap, .git, etc.) are never triggered regardless of patterns. Examples: when-changed -r -p '*.py' src/ make test when-changed -r -p '*.py' -p '*.yml' src/ make lint Signed-off-by: Eric Villard <dev@eviweb.fr>
|
Fantastic, thank you for all this work! Given the amount of changes, I'm going to need some time to review, so please bear with me :) |
|
You're welcome. |
|
Hello again, and sorry for taking so long to review this PR. As far as I can see, the PR is a bundle of many unrelated changes. This means that any issues found during review will block all other changes from being merged. I would much prefer to review each change in separate PRs. Could you please split this work into smaller, self-contained PRs and submit them separately? Thank you :-) |
This PR addresses several open issues and adds new features.
Bug fixes
[px]*with[a-z]in vim swap file exclusion regexto cover all extensions (
.swo,.swn, etc.)WHEN_CHANGED_EVENTis now correctly set tofile_createdon Linux — previously
on_createdwas entirely skipped forInotifyObserverthe command — was broken by the same inotify workaround as On created event not correctly handled on linux #76
-1no longer re-runs the command when a file changesduring execution —
last_runis now recorded beforesubprocess.Popeninstead of after
'.~$'→'\.~$')_recently_createdgrowing unboundedly — replacedsetwith adict(path → timestamp) with TTL-based purgeNew features
-kflag: kill the running command before restarting it,useful for long-running processes. Uses
SIGTERMwith 5s timeoutfallback to
SIGKILL-d DELAYflag: debounce rapid successive changes,coalescing them into a single run after DELAY seconds
-p PATTERNflag: filter watched files by glob pattern(e.g.
*.py). Can be repeated for multiple patterns. No-ppreservesexisting behavior (watch everything)
pyproject.tomlto enable wheel builds (python3 -m build)piptopipx(PR Recommendpipxto install, instead ofpip#100)Tests
is_interested()and exclusion patternson_created,on_modified,on_moved,on_deleted)run_command()including-1,-k, quiet mode-ppattern filtering