diff --git a/.cargo/config.toml b/.cargo/config.toml index 35049cbc..184383a5 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +1,4 @@ [alias] +# We use this alias for task automation in the project. +# See README in xtask directory. xtask = "run --package xtask --" diff --git a/Cargo.lock b/Cargo.lock index 509eaf10..e52cca01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -258,18 +258,19 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.34" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff" +checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" dependencies = [ "clap_builder", + "clap_derive", ] [[package]] name = "clap_builder" -version = "4.5.34" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489" +checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" dependencies = [ "anstream", "anstyle", @@ -287,6 +288,18 @@ dependencies = [ "clap", ] +[[package]] +name = "clap_derive" +version = "4.5.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "clap_lex" version = "0.7.4" @@ -955,6 +968,12 @@ dependencies = [ "http 0.2.11", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -3634,6 +3653,10 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "xtask" version = "0.1.0" +dependencies = [ + "anyhow", + "clap", +] [[package]] name = "yoke" diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 337bfe3d..540a0c3b 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -2,5 +2,8 @@ name = "xtask" version = "0.1.0" edition = "2021" +publish = false [dependencies] +anyhow = "1.0.97" +clap = { version = "4.5.35", features = ["derive"] } diff --git a/xtask/README.md b/xtask/README.md new file mode 100644 index 00000000..706ac5fe --- /dev/null +++ b/xtask/README.md @@ -0,0 +1,9 @@ +# xtask + +The purpose of the xtask binary is to enable cross platform task automation +within the project (somewhat similar to how `npm run` is used in Node.js +projects to run scripts). Please see +[cargo xtask](https://github.com/matklad/cargo-xtask) for more information. + +To add support for a new task, add a new arm to the `match` in the +`execute_task` function, and add a new handler function that contains the logic. diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 8ec42909..954b22df 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,29 +1,60 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! This binary allows us to execute tasks within the project by running +//! `cargo xtask `. It can thus be used as a task automation tool. +//! For example instead of repeatedly running `cargo install` from the CLI +//! to install all the necessary tools for the project we can just run +//! `cargo xtask install-tools` and the logic defined here will install +//! the tools. + +use anyhow::{anyhow, Ok, Result}; +use clap::Parser; use std::{env, process::Command}; -type DynError = Box; - -fn main() { +fn main() -> Result<()> { if let Err(e) = execute_task() { eprintln!("{e}"); std::process::exit(-1); } + Ok(()) } -fn execute_task() -> Result<(), DynError> { - let task = env::args().nth(1); - match task.as_deref() { - Some("install-tools") => install_tools()?, +#[derive(Parser, Debug)] +#[command( + about = "Binary for executing tasks within the Comprehensive Rust project" +)] +struct Args { + #[arg(required = true, help = "The task to execute")] + task: String, +} + +fn execute_task() -> Result<()> { + let task = Args::parse().task; + match task.as_str() { + "install-tools" => install_tools()?, _ => { - return Err(Box::from(get_help_string(task.as_deref()))); + return Err(anyhow!(unrecognized_task_string(task.as_str()))); } } Ok(()) } -fn install_tools() -> Result<(), DynError> { +fn install_tools() -> Result<()> { println!("Installing project tools..."); - let install_args: Vec> = vec![ + let install_args = 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"], @@ -49,21 +80,17 @@ fn install_tools() -> Result<(), DynError> { args.join(" "), status.code().unwrap() ); - return Err(Box::from(error_message)); + return Err(anyhow!(error_message)); } } Ok(()) } -fn get_help_string(task: Option<&str>) -> String { - if let Some(t) = task { - format!( - "Unrecognized task '{t}'. Available tasks: +fn unrecognized_task_string(task: &str) -> String { + format!( + "Unrecognized task '{task}'. Available tasks: install-tools Installs the tools the project depends on." - ) - } else { - "Missing task. To execute a task run `cargo xtask [task]`.".to_string() - } + ) }