Package: r3build
r3build, a smart file watcherPrefacer3build[rìːbíld]is yet another smart file watcher that helps you develop something.
The most notable thing is the simple and powerful configuration system. It will enable you to install a
minimal watcher for the first step and also to grow the watcher to handle a wide range of file events.Install$ pip install r3buildHow to use (Case 1: one-shot build)The first one introduces a combination of simple event detection and a "one-shot" task.
When you edit your code and save it, r3build invokes a make target detecting that file event.Writer3build.tomlin your project directory.$ cat r3build.toml
[[job]]
name = "Build them all"
type = "make"
when = ["modified"]
glob = ["*.c", "*.h"]
glob_exclude = ["extra/*", "extra/**/*"]This means that "when .c or .h files are modified, runmake, but ignore all files inextradirectory."Another example:$ cat r3build.toml
[[job]]
name = "Run it"
type = "command"
command = "python -m foobar"
when = ["modified"]
glob = ["./foobar/*.py", "./foobar/**/*.py"]This means that "when a Python code infoobarpackage is edited, run__main__.pyin the package."Invoke r3build. This watches what you edit.$ r3buildAlternatively:$ python -m r3buildEdit your code as you want, and enjoy them being built / run automatically.How to use (Case 2: auto-reloading)Let me introduce "auto-reloading" use-case for the second one.Say you're building a great asynchronous system withCelery.
While the most popular way to reload Celery is to usewatchdog,
r3build has advantages to it;No longer have to write one-liners and double-hyphensManage all auto-reload tasks in one placeNot only Celery, r3build is capable of restarting any process of course.Writer3build.tomlin your project directory.$ cat r3build.toml
[[job]]
name = "Run celery"
type = "daemon"
command = "celery worker --app=app.entrypoint"
when = ["created", "modified"]
regex = ".+\.py$"This means that:r3build launches Celery as a child processWhen .py files are created or modified, restart already running CelerySuppressing std* is also available.$ cat r3build.toml
[[job]]
name = "Run celery"
type = "daemon"
command = "celery worker --app=app.entrypoint"
when = ["created", "modified"]
regex = ".+\.py$"
stdout = false
stderr = trueInvoke r3build.$ r3buildWatch it restart as you write code. Voila!How to use (verbose)The configuration file,r3build.toml, defines how it watches, runs, and builds the code.
Other than that, it also defines all behavior of r3build like if it outputs the logs to console and how to filter events.
(For details, please refer tothe skeleton (template)placed in the root of this repository.)Here's an example ofr3build.tomlto runmakeevery time you edit your C code:[[job]]
name = "Build them all"
type = "make"The[[job]]line means that it's an item injobarray. Thenameconfig means that the name of thisjobis "Build them all". The lasttypeconfig means that this job invokesmakecommand when this it gets triggered.The example is enough for r3build to watch your code while it'll accept ALL file events
that occur to your code -- when they are "created", "deleted", "moved" and "modified".Here's an additional example to "filter" the events; thewhenkey.[[job]]
name = "Build them all"
type = "make"
when = ["modified"]As a result, the job will only be triggered when your code is being edit (modified).
Seethe skeletonfor the available values.You'll notice that it triggers not only for.cand.hbut all files.
It's super-easy to filter them only for.cand.hcode. Here's how:[[job]]
name = "Build them all"
type = "make"
when = ["modified"]
glob = ["*.c", "*.h"]You would already understood the most part ofr3build.toml.
Here's one more thing to good to know. "Exclude" keys.[[job]]
name = "Build them all"
type = "make"
when = ["modified"]
glob = ["*.c", "*.h"]
glob_exclude = ["extra/*", "extra/**/*"]Theglob_excludeconfiguration will ignore the changes occurred inextradirectory.Spec of r3build.tomlSeer3build.skeleton.tomlfor available configurations.The full example of r3build.toml is not yet described but simpler examples are inexamples.Environment variablesFollowing variables are added when jobs get launched. Seeexamplesfor usage.$R3_EVENT: event typemoveddeletedcreatedmodified$R3_FILENAME: file name$R3_IS_DIRECTORY: if it's a directory or not0: Not directory1: DirectoryQ&AQ. I wrote regex rules but nothing happens even it's modified... How to debug it?Enabling Verbose mode with-vflag or enabling all logs will provide a way to analyze it.$ r3build -v[log]
all = true-vandlog.all = trueare equivalent.Q. Where are the specs of regex and glob rules?We userepackagefor regex
andfnmatchcase()fromfnmatchpackagefor glob. Please refer those documents.Q. Can I merge r3build.toml and pyproject.toml or any other TOML documents?Yes, it should be possible if the keys in document root don't collide with the another document.
r3build doesn't care other thanlog,event, andjobkeys.Confirmed platformsPython 3.8.3 + Debian Linux 10 (Buster)Python 3.8.3 + macOS 10.14.6 MojavePython 3.8.3 + macOS 10.15.4 CatalinaIt should work on any platform with Python 3.7+.MotivationI used to usejoh/when-changed. This was enough to watch changes. But when it comes to complex detection, like "run make when I edit C code but ignore intermediate files," I had to write dirty grep filter to get rid of garbages.To achieve the smart detection, I thought of a well-structured configuration file that describes its behavior and finally I got the concept of r3build.ContributeSeeherefor contribution rules.License and CopyrightMIT LicenseCopyright (c) 2020 Takumi Sueda