acataluddi / rerun2

Rerun a given command (eg tests) on filesystem events

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

rerun2

Save rerun2 on your PATH, and invoke it using:

rerun COMMAND

It runs COMMAND every time there's a filesystem modify event within your current directory (recursive). For example, it can re-run tests every time you hit 'save' in your editor. Or it can re-generate rendered output (html, SVG, etc) every time you save the source (e.g. Markdown or GraphViz dot).

COMMAND needs to be a single parameter to rerun, hence if it contains spaces, either quote the whole thing:

rerun "ls ~"

or escape them:

rerun ls\ ~

Things one might like about it:

  • It uses inotify, so is more responsive than polling. Fabulous for running sub-millisecond unit tests, or rendering Graphviz dot files, every time you hit 'save'.
  • Because it's so fast, you don't have to bother telling it to ignore large subdirs (like node_modules) just for performance reasons.
  • It's extra super responsive, because it only calls inotifywait once, on startup, instead of running it, and incurring the expensive hit of establishing watches, on every iteration.
  • It's just a few lines of Bash
  • Because it's Bash, it interprets commands you pass it exactly as if you had typed them at a Bash prompt. (Presumably this is less cool if you use another shell).
  • It doesn't lose events that happen while COMMAND is executing, unlike most of the other inotify solutions on this page.
  • On the first event, it enters a 'dead period' for 0.15 seconds, during which other events are ignored, before COMMAND is run exactly once. This is so that the flurry of events caused by the create-write-move dance which Vi or Emacs does when saving a buffer don't cause multiple laborious executions of a possibly slow-running test suite. Any events which then occur while COMMAND is executing are not ignored - they will cause a second dead period and subsequent execution.

Things one might dislike about it:

  • It uses inotify to recieve filesystem events, so won't work outside of Linux. For a cross-platform solution, consider this project's precursor, https://github.com/tartley/rerun (see below).
  • Because it uses inotify, it will barf on trying to watch directories containing more files than the max number of user inotify watches. By default, this seems to be set to around 5,000 to 8,000 on different machines I use, but is easy to increase. See https://unix.stackexchange.com/questions/13751/kernel-inotify-watch-limit-reached
  • If you are editing files on your host, but executing rerun2 on a VM with those files mounted in the VM, then rerun2 won't see any events. You must either start editing files within the VM, or else use my other project, https://github.com/tartley/rerun (see below).
  • It fails to execute commands containing Bash aliases. I could swear that this used to work. In principle, because this is Bash, not executing COMMAND in a subshell, I'd expect this to work. I'd love to hear If anyone knows why it doesn't. Many of the other solutions on this page can't execute such commands either.
  • Personally I wish I was able to hit a key in the terminal it's running in to manually cause an extra execution of COMMAND. Could I add this somehow, simply? A concurrently running while read -n1 loop which also calls execute?
  • Right now I've coded it to clear the terminal and print the executed COMMAND on each iteration. Some folks might like to add command-line flags to turn things like this off, etc. But this would increase size and complexity many-fold.

Alternatives

This project is the successor to a Python program I wrote:

https://github.com/tartley/rerun

which polls for filesystem changes rather than using events. So this rerun works on all operating systems, works on mounted filesystems in VMs. In practice I've never seen it be more than a couple hundred milliseconds, even on what I consider large projects (e.g. including the Django source).

About

Rerun a given command (eg tests) on filesystem events

License:MIT License


Languages

Language:Shell 100.0%