nur - the simple nu based task runner
nur is a simple, yet very powerful task runner. It borrows ideas from b5
and just, but uses nu scripting
to define the tasks. This allows for very powerful, yet well structured tasks.
Warning / disclaimer
In its current state nur is more or less a proof of concept. I wanted to put it out there, so
I may receive some feedback. But I am not using this in some production setup myself yet. So feel
free to poke around with this, but be aware this is far from being finished, stable or anything.
Also this is my first ever rust project and parts of the code are currently more like helping me
out to get to know rust. Meaning: There might be dragons!
Usage example
nur allows you to execute tasks define in a file called nurfile. It will look through your
current working directory and all its parents to look for this file. When it has found the nurfile
it will change to the directory the file was found in and then source the file into nu script.
You can define tasks like this:
def "nur hello" [
name: string = "world",
] {
print $"hello {name}"
}
The important bit is that you define your tasks as subcommands for "nur". If you then execute
nur hello it will print "hello world", meaning it did execute the task hello in your nurfile.
You can also use nur --help to get some details on how to use nur and nur --help hello to
see what this hello task accepts as parameters.
Note: In the future you should be able to use something like nur hello --name max to pass parameters
to your tasks - but this still needs to be implemented.
Your tasks then can do whatever you want them to do in nu script. This allows for very structured
usage of for example docker to run/manage your project needs. But it can also just execute simple
commands like you would normally do in your shell (like npm ci or something). nur is not tight
to any programming language, packaging system or anything. As in the end the nurfile if just a
normal nu script you can put into this whatever you like.
See nu custom commands for details on how to define
tasks and at least read through the nu quick tour to
understand some basics about nu scripting.
Why + some history
For me nur is the next logical step after I created b5. b5 is based on running bash code and
allowing users to do this in a somewhat ordered matter. Initially b5 even was just some bash script,
but then eventually I figured bash is just not enough to handle my requirements. So I switched to
using Python, but b5 was still based on bash, as it would generate bash code and then just execute
the code. One issue I always had with this approach was that again bash isn't that nice to write
complex things without introducing issues everywhere. Look for example at parameter handling.
Then along came just, which did implement its own language you could use to write your justfile.
This language was inspired by what a Makefile would look like, still without the issued Makefile's
impose when using those as your task runner. Also it did include a very nice way to define task arguments,
parse those, care about validation etc. Still the way just works is either to execute the task line
by line (and not having any context between those commands) or define some script language to execute
the full command (meaning using something like bash again). So just - at least for me - is a great
step forward, but still not what I had in mind when creating b5 and what I would like to do with a
task runner.
Then I came across nu, especially the nu shell. This did become my default shell after a while and
I am using it as of now. nu feels nicely designed, has a very structured way to execute command and
also handle their "response" data (stdout/err) - as everything is structured data here. This is way
better than the original UNIX approach of always parsing text data. Also nu allows you to have simple
functions, that - as with just - handle argument parsing for you. So this did look like the perfect
combination for something like a task runner.
Of course you could just define some nu functions to completely create a task runner, that would
already be better than b5 or just. But this would also mean that every dev using this task runner
would need to switch to nu first. So I decided to try the hard route and create my own rust based
cli tool that would parse a nu script and then execute tasks defined in this script.
This is what you are seeing here. nur will load the nurfile defined in your project directory and
then allows you to execute tasks from this file. As it is its own binary you can easily use nur from
bash, zsh and possibly even PowerShell - whatever you prefer. Still you will be able to have the nu
superpowers inside your defined tasks.
About the name
nur stands for "nu run". Basically it should be "nu run task", which would lead to "nurt" - but then I
decided for just "nur" as:
nuris very fast to type (one less character 💪)nuris the reverse ofrun, which I like as a side effect 🥳- and then as a nice addon: You could translate "just" to "nur" in german 😂
Contributing
If you want to contribute to this project, feel free to just fork the project, create a dev branch in your fork and then create a pull request (PR). If you are unsure about whether your changes really suit the project please create an issue first, to talk about this.