#task #build #cargo #subcommand #make

bin+lib cargo-task

Ultra-Lightweight Zero-Dependency Rust Cargo Task Runner

13 releases

0.0.13 Oct 25, 2021
0.0.12 Jan 13, 2021
0.0.11 Dec 21, 2020
0.0.10 Oct 14, 2020

#86 in Cargo plugins

41 downloads per month


1.5K SLoC

Crates.io Crates.io


Ultra-Lightweight Zero-Dependency Rust Cargo Task Runner.

  • Platform Agnostic - runs on any platform that cargo runs on.
  • Zero-Dependency - the task manager itself installs almost instantly.
  • Rust Task Logic - stop writing separate bash and powershell scripts.
  • Take a look at the '.cargo-task' directory in this repo for examples.
cargo install -f cargo-task
cargo help task

Creating cargo-task automation tasks.

cargo task ct-init
cd .cargo-task
cargo new --bin my-task
cd ..
cargo task my-task
  • cargo task ct-init - creates the .cargo-task directory and .gitignore.
  • cargo task my-task - runs the crate named my-task defined in the .cargo-task directory.

It's that simple!

Script-like single file tasks.

If you don't want to commit a whole directory / Cargo.toml etc... you can specify cargo-task tasks as single files.

Just create a file in your .cargo-task directory named something like my-task.ct.rs and write it as you would a main.rs.

This will also create a my-task cargo task. You can even specify cargo crate dependencies via AtAt directive @ct-cargo-deps@ (see below).

Customizing how tasks are executed.

cargo-task uses a metadata format called AtAt - because it uses @ signs:

@ct-default@ true @@

Some things to know about AtAt:

  • protocol: @key@ value @@.
  • the first @ for the key must be the first character on a line.
  • the value is terminated by a two ats, "@@".
  • the value can contain newlines or be on a single line.
  • you probably want it in a rust comment block : )

These directives will be read from your main.rs file when parsing the .cargo-task crates.

Default tasks.

@ct-default@ true @@

Default tasks will be executed if the task list is empty on cargo task invocations.

Bootstrap tasks.

@ct-bootstrap@ true @@

Bootstrap tasks will always be executed before any task-list tasks. Also, the cargo-task metadata will be reloaded after bootstrap tasks are executed. You can use this to download / install / configure additional tasks.

Cargo dependencies.

num_cpus = "1"
serde = { version = "1", features = [ "derive" ] }

Write them just as you would in your Cargo.toml.

Task dependencies.


A whitespace delimited list of tasks that must be run prior to the current task. Can be on a single line or multiple lines.

Minimum cargo-task version.

@ct-min-version@ 0.0.7 @@

Require at least a minimum version of cargo-task to prompt users to upgrade if you are depending on features. Note, this directive works well when combined with @ct-bootstrap@

The magic cargo_task_util dependency.

This module will be available at the root of your crate during build time. To include it, simply add a mod directive in your main.rs file. A crate dependency with the same pub contents of this module will be available to your crate a run-time. The dependency is automatically added to script-type tasks.

To add it to crate-type tasks simply include the dependency in your Cargo.toml:

cargo_task_util = "*"
@ct-default@ true @@

use cargo_task_util::*;

fn main() {
    // cargo task metadata env helper
    let env = ct_env();

    // print out some cool cargo-task metadata
    // (this does the same thing as `cargo task ct-meta`)
    println!("{:#?}", env);

    // also includes cargo-task special log helpers
    ct_warn!("ahh, a warning! {:?}", std::time::SystemTime::now());

Configuring tasks and the cargo_task_util crate for direct execution.

So, you want to run your cargo tasks directly? The cargo_task_util crate is generated into your .cargo-task directory, but is ignored from git by a .cargo-task/.gitignore file. You can delete the .gitignore lines to check the crate into version control.

Due to a windows pathing quirk, we need to use a workspace-level [patch] directive to make this dependency work.

If you want a root workspace Cargo.toml, you can create one at the root of your project, and include all your crates, and your task crates.

If, instead, you want to keep the task crates in a separate workspace, you can put a workspace Cargo.toml file in your .cargo-task directory. (You will also need to remove that line from your .cargo-task/.gitignore)

This example is for a .cargo-task/Cargo.toml workspace. If your workspace root is a different directory, you'll have to adjust the paths.

members = [

cargo_task_util = { path = "cargo_task_util" }

Exporting environment variables to configure other tasks.

cargo_task_util::CTEnv also includes a utility for exporting environment variables.

If you just use the rust std::env::set_var function, the variable will be set for the current task execution, but no other tasks will see it.

Instead you can use cargo_task_util::CTEnv::set_env function.

You probably want to do this in a "bootstrap" task so it is available to other tasks that are run later.

@ct-bootstrap@ true @@

mod cargo_task_util;
use cargo_task_util::*;

fn main() {
    // cargo task metadata env helper
    let env = ct_env();

    // set a variable that will be available in other tasks.
    env.set_env("MY_VARIABLE", "MY_VALUE");

No runtime deps