Create an xtask crate for workspace task automation
Initially covering: * Building docs * Nightly CI jobs
This commit is contained in:
@@ -1,2 +1,5 @@
|
||||
[alias]
|
||||
xtask = "run --package xtask --"
|
||||
|
||||
[doc.extern-map.registries]
|
||||
crates-io = "https://docs.rs/"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -1,2 +1,4 @@
|
||||
[workspace]
|
||||
members = ["crates/*"]
|
||||
members = ["crates/*", "xtask"]
|
||||
# xtask should only be compiled when invoked explicitly
|
||||
default-members = ["crates/*"]
|
||||
|
||||
@@ -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"
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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(())
|
||||
}
|
||||
Reference in New Issue
Block a user