I find myself in a need of a simple cli tool when working on my Rust projects. However, I am on a pretty deep level of yak-shaving now, so I am afraid that I’ll get a stackoverflow if try write to write this tool myself
So, I’ll just through in the idea here, and hope that somebody picks it up and runs with it =)
When developing Rust code, I often have to run repetetive tasks. The example of such tasks are
- generate some files to
src/(build.rs is not applicable here, b/c I want to commit the results of codegen)
- add a new test data file with a specified format: for example, add files
- check that each file with
.rsextension starts with a license preamble
- build and package a rust application
- automatically update changelog file
Currently, I use
just (a simpler and more sane
make) for this, but I don’t quite like two things about this solution:
- it relies on shell, and I am bad at shell scripting,
- shells are bad at being cross-platform.
What I would really love is the ability to write this “scripts” in Rust…
Here is a short specification of the proposed solution
By convention, all custom tasks are defined as a binary crate in the
tasks subdirectory. For example, the layout for the frobnicator project might look like this:
frobnicator/ Cargo.toml src/ lib.rs tasks/ Cargo.toml # this is **not** a member of workspace src/ main.rs # this is the binary capable of executing all the tasks
The bare-bones way to run
generate-test taks would look like this than:
$ cargo --manifest-path ./tasks/Cargo.toml run -- generate-test --name "foo"
To run tasks in a convenient way, a special subcommand,
cargo task is provided. So, the actual invocation looks like
$ cargo task generate-test --name "foo"
The job of
- find out the workspace root and
cargo build --manifest-path ./tasksto build the tasks crate
- run the resulting
tasksbinary, forwaring all the command-line arguments.
Bike shedding: should this be
cargo do instead of
cargo task? Or maybe even
cargo x, to mirror
./x.py? Or maybe a fancy
In principle, it is possible to write arbitrary code in the
tasks/src/main.rs. However a “shell-like scripting support library” would be most useful! Here are some tasks that this library might do:
- reexport file crate API to make reading and wriing files easily
- reexport other utilites to make it easy to read config files and env variables.
- provide a way to conveniently launch subprocesses, with few lines of code and with automatic panicking on non-zero return code a-la
- provide pure-rust implementations of common shell utilites as functions, like
- provide automatic command rounting, with a strong convention over configuration API. That is, be simpler and less flexible than clap, the only way to define commands and options should be via serde.
- provide a convenient way to shell out back to Cargo.
That’s about it for specification I guess?
As I’ve said, I don’t have enough time/desire to make this dream a reality, but, if someone else creates at least a bare bones version of it (basically, creates a repo with CI and implementation of
cargo task), I promise I’ll use this thing for my project and will contribute stuff, necessary for me personally