|
| 1 | +# cargo xtask |
| 2 | + |
| 3 | +cargo-xtask is way to add free-form automation to a Rust project, a-la `make` or bespoke bash scripts. |
| 4 | + |
| 5 | +The two distinguishing features of xtask are: |
| 6 | + |
| 7 | +* It doesn't require any other binaries besides `cargo` and `rustc`, it fully bootstraps from them |
| 8 | +* Unlike bash, it is cross platform |
| 9 | + |
| 10 | +## How Does It Work? |
| 11 | + |
| 12 | +cargo-xtask is a polyfill for [cargo workflows](http://aturon.github.io/tech/2018/04/05/workflows/) feature. |
| 13 | +It is a way to extend stock, stable cargo with custom commands (`xtasks`), written in Rust. |
| 14 | + |
| 15 | +This polyfill doesn't need any code, just a particular configuration of a cargo project. |
| 16 | +This repository serves as a specification of such configuration. |
| 17 | + |
| 18 | +## Defining xtasks |
| 19 | + |
| 20 | +In the root of the project repository, there should be an `xtask` directory, which is a cargo crate with one binary target. |
| 21 | +In the root of the project, there should be a `./cargo/config` file with the following entry: |
| 22 | + |
| 23 | +```toml |
| 24 | +[alias] |
| 25 | +xtask = "run --manifest-path ./xtask/Cargo.toml" |
| 26 | +``` |
| 27 | + |
| 28 | +Example directory layout: |
| 29 | + |
| 30 | +``` |
| 31 | +/my-project |
| 32 | + .git |
| 33 | + .gitignore |
| 34 | + .cargo/ |
| 35 | + config |
| 36 | + Cargo.toml |
| 37 | + src/ |
| 38 | + lib.rs |
| 39 | + xtask/ |
| 40 | + Cargo.toml |
| 41 | + src/ |
| 42 | + main.rs |
| 43 | +``` |
| 44 | + |
| 45 | +Both `xtask` directory and `./cargo/config` should be committed to the version control system. |
| 46 | + |
| 47 | +The `xtask` binary should expect at least one positional argument, which is a name of the task to be executed. |
| 48 | +Tasks are implemented in Rust, and can use arbitrary crates from crates.io. |
| 49 | +Tasks can execute `cargo` (it is advisable to use `CARGO` environmental variable to get the right `cargo`). |
| 50 | + |
| 51 | +The `xtask` crate may or may not be a part of the main workspace. |
| 52 | + |
| 53 | +## Using xtasks |
| 54 | + |
| 55 | +Use `cargo xtask task-name` command to run the task. |
| 56 | + |
| 57 | +Example: |
| 58 | +``` |
| 59 | +cargo xtask deploy |
| 60 | +``` |
| 61 | + |
| 62 | +Note that this doesn't require any additional setup besides cloning the repository, and will automatically build the `xtask` binary on the first run. |
| 63 | + |
| 64 | +## Not Using xtasks |
| 65 | + |
| 66 | +xtasks are entirely optional, and you don't have to use them! |
| 67 | +In particular, if, for your purposes, `cargo build` and `cargo test` are enough, don't use xtasks. |
| 68 | +If you prefer to write a short bash script, and don't need to support windows, there's no need to use xtasks either. |
| 69 | + |
| 70 | +## Standard xtasks |
| 71 | + |
| 72 | +The following specifies the names and behaviors of some common xtasks, to help establish common conventions. |
| 73 | +If you feel an important common task is missing, feel free to submit a PR! |
| 74 | + |
| 75 | +### `cargo xtask`, `cargo xtask --help` |
| 76 | + |
| 77 | +When run without argument or with the `--help` argument, `xtask` should print a help message which lists available tasks and contains the link to this specification. |
| 78 | + |
| 79 | +### `cargo xtask ci` |
| 80 | + |
| 81 | +This task should run `cargo test` and any additional checks that are required on CI, like checking formatting, running `miri` test, checking links in the documentation. |
| 82 | +The CI configuration should generally look like this: |
| 83 | + |
| 84 | +```yaml |
| 85 | +script: |
| 86 | + - cargo xtask ci |
| 87 | +``` |
| 88 | +
|
| 89 | +The expectation is that, if `cargo xtask ci` passes locally, the CI will be green as well. |
| 90 | + |
| 91 | +You don't need this task if `cargo test` is enough for your purposes. |
| 92 | + |
| 93 | +### `cargo xtask dist` |
| 94 | + |
| 95 | +This should *package* the software and produce a set of distributable artifacts. |
| 96 | +Artifacts should be placed into `./target/dist` directory. |
| 97 | +The precise meaning of artifacts is not defined, but, for a CLI tool, you can expect the binary itself (build in release mode and stripped), man pages and shell completion files. |
| 98 | +The `dist` command should clean the `./target/dist` directory before populating it with artifacts. |
| 99 | +It is expected that the `dist` command calls `cargo build --release` internally. |
| 100 | + |
| 101 | +### `cargo xtask codegen` |
| 102 | + |
| 103 | +This command should run code generation, which happens outside of `build.rs`. |
| 104 | +For example, if you are writing a gPRC server, and would like to commit the generated code into the repository (so that the clients don't have to have `protoc` installed), you can implement code generation as `cargo xtask codegen`. |
| 105 | + |
| 106 | +## Tooling |
| 107 | + |
| 108 | +There's no specific tooling to support xtasks at the moment. |
| 109 | +If you write tools or libraries for xtasks, send a PR to this document. |
| 110 | +Some possible ideas: |
| 111 | + |
| 112 | +* cargo subcomand to generate `xtask` template |
| 113 | +* implementations of common xtasks, like "check that code is formatted with rustfmt" or "build completions for a clap app", as libraries. |
| 114 | + |
| 115 | +## Background |
| 116 | + |
| 117 | +To my knowledge, the idea of xtasks was first introduced in [this post](https://matklad.github.io/2018/01/03/make-your-own-make.html). |
| 118 | +In some sense, the present document just specifies some conventions around original idea. |
| 119 | + |
| 120 | +The name `xtask` is chosen so as not to conflict with potential future built-in cargo feature for tasks. |
0 commit comments