Create an xtask crate for workspace task automation

Initially covering:

* Building docs
* Nightly CI jobs
This commit is contained in:
Jonas Platte
2022-03-02 18:43:45 +01:00
parent b276087969
commit b7a4ca4cff
7 changed files with 161 additions and 9 deletions
+3
View File
@@ -1,2 +1,5 @@
[alias]
xtask = "run --package xtask --"
[doc.extern-map.registries]
crates-io = "https://docs.rs/"
+2 -8
View File
@@ -67,14 +67,8 @@ jobs:
- name: Clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: --all-targets -- -D warnings
- name: Clippy without default features
uses: actions-rs/cargo@v1
with:
command: clippy
args: --all-targets --no-default-features --features native-tls,warp -- -D warnings
command: run
args: -p xtask -- ci clippy
check-wasm:
name: checking WASM builds
+1
View File
@@ -24,6 +24,7 @@ jobs:
- name: Load cache
uses: Swatinem/rust-cache@v1
# Keep in sync with xtask docs
- name: Build docs
uses: actions-rs/cargo@v1
env:
+3 -1
View File
@@ -1,2 +1,4 @@
[workspace]
members = ["crates/*"]
members = ["crates/*", "xtask"]
# xtask should only be compiled when invoked explicitly
default-members = ["crates/*"]
+11
View File
@@ -0,0 +1,11 @@
[package]
name = "xtask"
version = "0.1.0"
edition = "2021"
publish = false
[dependencies]
clap = { version = "3.1.3", features = ["derive"] }
serde = { version = "1.0.136", features = ["derive"] }
serde_json = "1.0.79"
xshell = "0.1.17"
+86
View File
@@ -0,0 +1,86 @@
use std::{env, path::PathBuf};
use clap::{Args, Subcommand};
use serde::Deserialize;
use xshell::{cmd, pushd};
use crate::{build_docs, DenyWarnings, Result};
#[derive(Args)]
pub struct CiArgs {
#[clap(subcommand)]
cmd: Option<CiCommand>,
}
#[derive(Subcommand)]
enum CiCommand {
/// Check style
Style,
/// Check for typos
Typos,
/// Check clippy lints
Clippy,
/// Check documentation
Docs,
}
impl CiArgs {
pub fn run(self) -> Result<()> {
let _p = pushd(&workspace_root()?)?;
match self.cmd {
Some(cmd) => match cmd {
CiCommand::Style => check_style(),
CiCommand::Typos => check_typos(),
CiCommand::Clippy => check_clippy(),
CiCommand::Docs => check_docs(),
},
None => {
check_style()?;
check_clippy()?;
check_typos()?;
check_docs()?;
Ok(())
}
}
}
}
fn check_style() -> Result<()> {
cmd!("rustup run nightly cargo fmt -- --check").run()?;
Ok(())
}
fn check_typos() -> Result<()> {
// FIXME: Print install instructions if command-not-found (needs an xshell
// change: https://github.com/matklad/xshell/issues/46)
cmd!("typos").run()?;
Ok(())
}
fn check_clippy() -> Result<()> {
cmd!("rustup run nightly cargo clippy --all-targets -- -D warnings").run()?;
cmd!(
"rustup run nightly cargo clippy --all-targets
--no-default-features --features native-tls,warp
-- -D warnings"
)
.run()?;
Ok(())
}
fn check_docs() -> Result<()> {
build_docs([], DenyWarnings::Yes)
}
fn workspace_root() -> Result<PathBuf> {
#[derive(Deserialize)]
struct Metadata {
workspace_root: PathBuf,
}
let cargo = env::var("CARGO").unwrap_or_else(|_| "cargo".to_owned());
let metadata_json = cmd!("{cargo} metadata --no-deps --format-version 1").read()?;
Ok(serde_json::from_str::<Metadata>(&metadata_json)?.workspace_root)
}
+55
View File
@@ -0,0 +1,55 @@
mod ci;
use ci::CiArgs;
use clap::{Parser, Subcommand};
use xshell::cmd;
type Result<T, E = Box<dyn std::error::Error>> = std::result::Result<T, E>;
#[derive(Parser)]
struct Xtask {
#[clap(subcommand)]
cmd: Command,
}
#[derive(Subcommand)]
enum Command {
/// Run continuous integration checks
Ci(CiArgs),
/// Build the SDKs documentation
Doc {
/// Opens the docs in a browser after the operation
#[clap(long)]
open: bool,
},
}
fn main() -> Result<()> {
match Xtask::parse().cmd {
Command::Ci(ci) => ci.run(),
Command::Doc { open } => build_docs(open.then(|| "--open"), DenyWarnings::No),
}
}
enum DenyWarnings {
Yes,
No,
}
fn build_docs(
extra_args: impl IntoIterator<Item = &'static str>,
deny_warnings: DenyWarnings,
) -> Result<()> {
let mut rustdocflags = "--enable-index-page -Zunstable-options --cfg docsrs".to_owned();
if let DenyWarnings::Yes = deny_warnings {
rustdocflags += " -Dwarnings";
}
// Keep in sync with .github/workflows/docs.yml
cmd!("rustup run nightly cargo doc --no-deps --workspace --features docsrs -Zrustdoc-map")
.env("RUSTDOCFLAGS", rustdocflags)
.args(extra_args)
.run()?;
Ok(())
}