1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-05-16 23:55:42 +02:00

Xtask improvements (#2707)

Some minor improvements to an already-merged PR (#2688) on the task
automation via xtask. Main ones being:

- Adding more explanatory comments about what the xtask package is and
what it does
- Using Clap for CLI arg parsing
- Using Anyhow for error handling

---------

Co-authored-by: Eric Githinji <egithinji@google.com>
This commit is contained in:
Eric Githinji 2025-04-07 13:18:49 +03:00 committed by GitHub
parent 43cf3fb616
commit 0085748d17
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 87 additions and 23 deletions

View File

@ -1,2 +1,4 @@
[alias] [alias]
# We use this alias for task automation in the project.
# See README in xtask directory.
xtask = "run --package xtask --" xtask = "run --package xtask --"

31
Cargo.lock generated
View File

@ -258,18 +258,19 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.34" version = "4.5.35"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff" checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive",
] ]
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.34" version = "4.5.35"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489" checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@ -287,6 +288,18 @@ dependencies = [
"clap", "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]] [[package]]
name = "clap_lex" name = "clap_lex"
version = "0.7.4" version = "0.7.4"
@ -955,6 +968,12 @@ dependencies = [
"http 0.2.11", "http 0.2.11",
] ]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.3.9" version = "0.3.9"
@ -3634,6 +3653,10 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
[[package]] [[package]]
name = "xtask" name = "xtask"
version = "0.1.0" version = "0.1.0"
dependencies = [
"anyhow",
"clap",
]
[[package]] [[package]]
name = "yoke" name = "yoke"

View File

@ -2,5 +2,8 @@
name = "xtask" name = "xtask"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
publish = false
[dependencies] [dependencies]
anyhow = "1.0.97"
clap = { version = "4.5.35", features = ["derive"] }

9
xtask/README.md Normal file
View File

@ -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.

View File

@ -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 <task>`. 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}; use std::{env, process::Command};
type DynError = Box<dyn std::error::Error>; fn main() -> Result<()> {
fn main() {
if let Err(e) = execute_task() { if let Err(e) = execute_task() {
eprintln!("{e}"); eprintln!("{e}");
std::process::exit(-1); std::process::exit(-1);
} }
Ok(())
} }
fn execute_task() -> Result<(), DynError> { #[derive(Parser, Debug)]
let task = env::args().nth(1); #[command(
match task.as_deref() { about = "Binary for executing tasks within the Comprehensive Rust project"
Some("install-tools") => install_tools()?, )]
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(()) Ok(())
} }
fn install_tools() -> Result<(), DynError> { fn install_tools() -> Result<()> {
println!("Installing project tools..."); println!("Installing project tools...");
let install_args: Vec<Vec<&str>> = vec![ let install_args = vec![
// The --locked flag is important for reproducible builds. It also // The --locked flag is important for reproducible builds. It also
// avoids breakage due to skews between mdbook and mdbook-svgbob. // avoids breakage due to skews between mdbook and mdbook-svgbob.
vec!["mdbook", "--locked", "--version", "0.4.44"], vec!["mdbook", "--locked", "--version", "0.4.44"],
@ -49,21 +80,17 @@ fn install_tools() -> Result<(), DynError> {
args.join(" "), args.join(" "),
status.code().unwrap() status.code().unwrap()
); );
return Err(Box::from(error_message)); return Err(anyhow!(error_message));
} }
} }
Ok(()) Ok(())
} }
fn get_help_string(task: Option<&str>) -> String { fn unrecognized_task_string(task: &str) -> String {
if let Some(t) = task { format!(
format!( "Unrecognized task '{task}'. Available tasks:
"Unrecognized task '{t}'. Available tasks:
install-tools Installs the tools the project depends on." install-tools Installs the tools the project depends on."
) )
} else {
"Missing task. To execute a task run `cargo xtask [task]`.".to_string()
}
} }