From 91f6de64df79c8014452dc57936754eb542ee73f Mon Sep 17 00:00:00 2001 From: Eric Githinji <51313777+egithinji@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:24:08 +0300 Subject: [PATCH] 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 ` 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 --- .cargo/config.toml | 2 + .github/workflows/install-mdbook/action.yml | 2 +- Cargo.lock | 4 ++ Cargo.toml | 1 + README.md | 2 +- install-mdbook.sh | 11 ---- xtask/Cargo.toml | 6 ++ xtask/src/main.rs | 69 +++++++++++++++++++++ 8 files changed, 84 insertions(+), 13 deletions(-) create mode 100644 .cargo/config.toml delete mode 100755 install-mdbook.sh create mode 100644 xtask/Cargo.toml create mode 100644 xtask/src/main.rs diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 00000000..35049cbc --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[alias] +xtask = "run --package xtask --" diff --git a/.github/workflows/install-mdbook/action.yml b/.github/workflows/install-mdbook/action.yml index d46db758..a0869d00 100644 --- a/.github/workflows/install-mdbook/action.yml +++ b/.github/workflows/install-mdbook/action.yml @@ -6,7 +6,7 @@ runs: using: composite steps: - name: Install mdbook - run: ./install-mdbook.sh + run: cargo xtask install-tools shell: bash - name: Install dependencies for mdbook-pandoc diff --git a/Cargo.lock b/Cargo.lock index c407cc3a..1d8551b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3740,6 +3740,10 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +[[package]] +name = "xtask" +version = "0.1.0" + [[package]] name = "yoke" version = "0.7.5" diff --git a/Cargo.toml b/Cargo.toml index 2452ca07..9402942f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,5 +29,6 @@ members = [ "src/unsafe-rust", "src/user-defined-types", "third_party/cxx/blobstore", + "xtask", ] resolver = "2" diff --git a/README.md b/README.md index db7ca963..1315de59 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ cd comprehensive-rust Then install these tools with: ```shell -bash install-mdbook.sh +cargo xtask install-tools ``` Run diff --git a/install-mdbook.sh b/install-mdbook.sh deleted file mode 100755 index abd81258..00000000 --- a/install-mdbook.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -# The --locked flag is important for reproducible builds. It also -# avoids breakage due to skews between mdbook and mdbook-svgbob. -cargo install mdbook --locked --version 0.4.44 -cargo install mdbook-svgbob --locked --version 0.2.1 -cargo install mdbook-pandoc --locked --version 0.9.3 -cargo install mdbook-i18n-helpers --locked --version 0.3.5 -cargo install i18n-report --locked --version 0.2.0 -# these packages are located in this repository -cargo install --path mdbook-exerciser --locked -cargo install --path mdbook-course --locked diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml new file mode 100644 index 00000000..337bfe3d --- /dev/null +++ b/xtask/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "xtask" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/xtask/src/main.rs b/xtask/src/main.rs new file mode 100644 index 00000000..8ec42909 --- /dev/null +++ b/xtask/src/main.rs @@ -0,0 +1,69 @@ +use std::{env, process::Command}; + +type DynError = Box; + +fn main() { + if let Err(e) = execute_task() { + eprintln!("{e}"); + std::process::exit(-1); + } +} + +fn execute_task() -> Result<(), DynError> { + let task = env::args().nth(1); + match task.as_deref() { + Some("install-tools") => install_tools()?, + _ => { + return Err(Box::from(get_help_string(task.as_deref()))); + } + } + Ok(()) +} + +fn install_tools() -> Result<(), DynError> { + println!("Installing project tools..."); + + let install_args: Vec> = vec![ + // The --locked flag is important for reproducible builds. It also + // avoids breakage due to skews between mdbook and mdbook-svgbob. + vec!["mdbook", "--locked", "--version", "0.4.44"], + vec!["mdbook-svgbob", "--locked", "--version", "0.2.1"], + vec!["mdbook-pandoc", "--locked", "--version", "0.9.3"], + vec!["mdbook-i18n-helpers", "--locked", "--version", "0.3.5"], + vec!["i18n-report", "--locked", "--version", "0.2.0"], + // These packages are located in this repository + vec!["--path", "mdbook-exerciser", "--locked"], + vec!["--path", "mdbook-course", "--locked"], + ]; + + for args in &install_args { + let status = Command::new(env!("CARGO")) + .arg("install") + .args(args) + .status() + .expect("Failed to execute cargo install"); + + if !status.success() { + let error_message = format!( + "Command 'cargo install {}' exited with status code: {}", + args.join(" "), + status.code().unwrap() + ); + return Err(Box::from(error_message)); + } + } + + Ok(()) +} + +fn get_help_string(task: Option<&str>) -> String { + if let Some(t) = task { + format!( + "Unrecognized task '{t}'. Available tasks: + +install-tools Installs the tools the project depends on." + ) + } else { + "Missing task. To execute a task run `cargo xtask [task]`.".to_string() + } +}