Automatically run scripts from inside their directory with watchexec
Run Where I Made Ya
I use a bunch of
I cooked up this little script to take care of that with watchexec
2:
#!/bin/bash
The script sits at the top of Neopolitan's source tree. It kicks off a watchexec
process that keeps an eye on Python files. When one changes watchexec
runs it.
The key feature is that watchexec
does a cd
into the script's directory before running it. That means I can use relative file paths and they'll Just Work™.
What are all those flags?
You can run watchexec
from the command line. I like putting it in its own script. That way, I don't have to remember all these incantations:
-
watchexec
The command itself.
-
\
The backslash is used to break the overall
watchexec
command onto multiple lines. It gets used repeatedly. Things are a lot easier to work with that way than if everything was a single line the length of a novel. -
--project-origin .
watchexec
tries to set what it thinks is the root of a project. It causes issues when it gets things wrong. Using the--project-origin .
sets it to the current directory explicitly.I don't have a clear enough mental model of
watchexec
to know when it's necessary and when it's not. I always throw it in so I don't have to think about it. -
-c
Clears the screen before every run of the command.
A nice quality of life improvement knowing that you can scroll up and you won't end up looking at the output from a previous run.
-
-r
Restarts the target command if it's still running.
Neopolitan's scripts complete so fast this doesn't matter here. It's handy for things like Neopoligen3 that have longer build times.
-
-p
Postpone running the target command until the first change is detected.
Without this,
watchexec
fires off the target command as soon as it starts. That's fine/desirable in some cases. For this script, that would mean trying to use environmental variables before they are set. -
-e py
Tells
watchexec
what file extensions to watch for changes. In this case that'spy
for my Python files.You can add multiple extensions by separating them with a comma. For example, this would do
.py
and.rs
files:-e py,rs
-
--shell=bash
Tells
watchexec
to to usebash
to run the target command. -
--
the separator used to package up the command to run as a single argument surrounded by
'
characters. -
'
The opening single quote. Everything between it and the ending
'
constitutes the commandbash
runs when files change. -
FILE_PATH=" /"
This assemble the full path to the target Python script by combining two environmental variables that
watchexec
sets:and
It's worth pointing out that there are other environmental variables for file creation, renaming, etc. It would be a little safer to explicitly check to see if
is set. I'll add that if it ever becomes a problem.
-
&&
The
&&
gets used a few times. It makes sure that each part of the command chain only runs if the part before it succeeded. -
PARENT_DIR=""
Grabs the parent directory of the target script.
The double quotes nested inside another pair of double quotes always looks weird to me. That's just how bash does it. Without it, you run the risk of file paths wish spaces breaking things in unpredictable ways.
-
Change into the parent directory we just grabbed.
-
python3 "$FILE_PATH"
Call
python3
with the path to our script stored in$FILE_PATH
. This is what actually runs the script. -
'
Finally, close the single quote string to finish packaging everything up for
watchexec
.
Off And Running
It took half an hour to come up with this script. That's after hours spent figuring out different way to work with watchexec
over the years.
I'm happy to trade that time. It allows me to stay in the flow. Plus, I never have to spend that half hour again. I can just grab the script from here whenever I need it. If you end up using it, it'll be even more worth the time spent.
-a
Footnotes
A plain-text file format that's like Markdown on steroids
"a simple, standalone tool that watches a path and runs a command whenever it detects modifications."
Way more complicated than it sounds. Awesome when you learn how to turn it on properly.
The site builder I built that works with Neopolitan files. At the time of this writing it's got a bunch of stuff hard coded to my site. I'm working to remove that so other folks can play with it too.