entr is a command line utility for running arbitrary commands when files change.
Just for clarification - I did not contribute to this project. I just happen to find it useful.
Yes, yes you already have all this with guard, live-reload, guardian, watcher, watchy, watch, bouncy, bounce, bouncer, sir-loads-alot, loady, loadup, springy, trampoline, hot-rocket1 etc. but
entr is worth a look. Why? Well it has a few criteria that make it compelling,
- It's not locked into a particular use case, language or ecosystem
- It has no external dependencies
- It works on more than just Linux
- It's command line friendly (works with pipes)
So lets just see it in action,
You can either build it from source or if you're using a mac you an use brew
brew update && brew install entr
What you want to do is get a list of files you are interested in i.e. ones that should trigger "something" when they change. This can be something as simple as
ls or as convoluted as
find . -iname '*.cr' -not -path './.crystal/*' something like. One way or another a command that spits out a file list is the first part.
Next you pipe this into
entr with the command you want to run.
ls -d * | entr make
In this case when a file listed by
make will be ran.
This is good enough for many use cases but there are always edge cases. One good example is live reloading a web server. In this case the process that you spawn typically blocks until killed which would cause issues with the above command. To cater for this use case
entr gives us the
ls -d * | entr -r lein ring server-headless
entr will attempt to terminate then running process prior to starting it again.
We also have the
-c option. This does nothing more than clear the screen before running the command.
entr provides the ability to pass a special argument,
/_, into the command it is configured to run. This argument will be replaced with the path to the first file that has changed. This is useful when you specifically need to execute the changed file, for example, when working with data loading scripts,
ls ./data/*.js | entr mongo < /_
entr is nice and simple with no external dependencies and not specific to any particular technology stack.
1: I may have made some or all of these up.