Skip to content

Commit 91f6de6

Browse files
egithinjiEric Githinji
andauthored
Xtask (#2688)
### Background Comprehensive Rust requires a number of tools to be installed (e.g. mdbook and mdbook-course). As mentioned in #2509 (and discussed in #2469) it would be nice to have a cross platform command for installing these dependencies. Currently these are installed using a shell script (`install-mdbook.sh`) but this isn't truly cross platform e.g. for Windows users. ### Xtask [xtask](https://github.com/matklad/cargo-xtask) outlines an approach for automating tasks in a Rust project. It involves using cargo's aliasing feature to allow us to run commands like `cargo xtask <some task>` to perform adhoc tasks via a Rust binary that we might otherwise need a shell script for. In this PR we add support for a `cargo xtask install-tools` command that will replace the `install-mdbook.sh` script and install the dependent tools. We can potentially extend it to support for other tasks e.g. `cargo xtask fmt`. --------- Co-authored-by: Eric Githinji <egithinji@google.com>
1 parent 01176e0 commit 91f6de6

File tree

8 files changed

+84
-13
lines changed

8 files changed

+84
-13
lines changed

.cargo/config.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[alias]
2+
xtask = "run --package xtask --"

.github/workflows/install-mdbook/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ runs:
66
using: composite
77
steps:
88
- name: Install mdbook
9-
run: ./install-mdbook.sh
9+
run: cargo xtask install-tools
1010
shell: bash
1111

1212
- name: Install dependencies for mdbook-pandoc

Cargo.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@ members = [
2929
"src/unsafe-rust",
3030
"src/user-defined-types",
3131
"third_party/cxx/blobstore",
32+
"xtask",
3233
]
3334
resolver = "2"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ cd comprehensive-rust
7171
Then install these tools with:
7272

7373
```shell
74-
bash install-mdbook.sh
74+
cargo xtask install-tools
7575
```
7676

7777
Run

install-mdbook.sh

Lines changed: 0 additions & 11 deletions
This file was deleted.

xtask/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "xtask"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]

xtask/src/main.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use std::{env, process::Command};
2+
3+
type DynError = Box<dyn std::error::Error>;
4+
5+
fn main() {
6+
if let Err(e) = execute_task() {
7+
eprintln!("{e}");
8+
std::process::exit(-1);
9+
}
10+
}
11+
12+
fn execute_task() -> Result<(), DynError> {
13+
let task = env::args().nth(1);
14+
match task.as_deref() {
15+
Some("install-tools") => install_tools()?,
16+
_ => {
17+
return Err(Box::from(get_help_string(task.as_deref())));
18+
}
19+
}
20+
Ok(())
21+
}
22+
23+
fn install_tools() -> Result<(), DynError> {
24+
println!("Installing project tools...");
25+
26+
let install_args: Vec<Vec<&str>> = vec![
27+
// The --locked flag is important for reproducible builds. It also
28+
// avoids breakage due to skews between mdbook and mdbook-svgbob.
29+
vec!["mdbook", "--locked", "--version", "0.4.44"],
30+
vec!["mdbook-svgbob", "--locked", "--version", "0.2.1"],
31+
vec!["mdbook-pandoc", "--locked", "--version", "0.9.3"],
32+
vec!["mdbook-i18n-helpers", "--locked", "--version", "0.3.5"],
33+
vec!["i18n-report", "--locked", "--version", "0.2.0"],
34+
// These packages are located in this repository
35+
vec!["--path", "mdbook-exerciser", "--locked"],
36+
vec!["--path", "mdbook-course", "--locked"],
37+
];
38+
39+
for args in &install_args {
40+
let status = Command::new(env!("CARGO"))
41+
.arg("install")
42+
.args(args)
43+
.status()
44+
.expect("Failed to execute cargo install");
45+
46+
if !status.success() {
47+
let error_message = format!(
48+
"Command 'cargo install {}' exited with status code: {}",
49+
args.join(" "),
50+
status.code().unwrap()
51+
);
52+
return Err(Box::from(error_message));
53+
}
54+
}
55+
56+
Ok(())
57+
}
58+
59+
fn get_help_string(task: Option<&str>) -> String {
60+
if let Some(t) = task {
61+
format!(
62+
"Unrecognized task '{t}'. Available tasks:
63+
64+
install-tools Installs the tools the project depends on."
65+
)
66+
} else {
67+
"Missing task. To execute a task run `cargo xtask [task]`.".to_string()
68+
}
69+
}

0 commit comments

Comments
 (0)