From 30119064143c0afa1a5e46e587defd03ac4b6d46 Mon Sep 17 00:00:00 2001 From: Hayden Stainsby Date: Wed, 23 Oct 2024 16:17:07 +0200 Subject: [PATCH] use xtask to check docs images Rather than using a bash script, let's do things properly and validate the presence of the images in the Tokio Console README.md file with an xtask operation. This commit intentially has an error in the regex to check that the CI step is working. --- .github/workflows/ci.yml | 17 ++++---- xtask/Cargo.toml | 1 + xtask/src/main.rs | 83 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 91 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db5e5df80..cadd41fb9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -108,14 +108,15 @@ jobs: - name: Checkout sources uses: actions/checkout@v4 - - name: Check tokio-console README images - run: > - for filename in - $(grep 'https://raw.githubusercontent.com/tokio-rs/console/main/assets' tokio-console/ README.md - | perl -n -e '/(tokio-console-[\d\.]+\/\w+\.png)/; print "$1\n"' - ); do - ls -l assets/$filename; - done + - name: Install ${{ matrix.rust }} toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + + - uses: Swatinem/rust-cache@v2 + + - name: Run xtask check-docs-images + run: cargo run --bin xtask -- check-docs-images grpc_web: name: gRPC-web Example diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 74fc81d88..1296c6380 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -12,3 +12,4 @@ tonic-build = { version = "0.12", default-features = false, features = [ ] } clap = { version = "~4.5.4", features = ["derive"] } color-eyre = "0.6" +regex = "1.11.0" diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 1483690b2..63701821c 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,9 +1,16 @@ +use std::{ + fmt::Write, + fs, + io::{BufRead, BufReader}, + path::{Path, PathBuf}, +}; + use clap::Parser; use color_eyre::{ - eyre::{ensure, WrapErr}, + eyre::{ensure, eyre, WrapErr}, Result, }; -use std::{fs, path::PathBuf}; +use regex::Regex; /// tokio-console dev tasks #[derive(Debug, clap::Parser)] @@ -16,6 +23,9 @@ struct Args { enum Command { /// Generate `console-api` protobuf bindings. GenProto, + + /// Check images needed for tokio-console docs.rs main page + CheckDocsImages, } fn main() -> Result<()> { @@ -27,6 +37,7 @@ impl Command { fn run(&self) -> Result<()> { match self { Self::GenProto => gen_proto(), + Self::CheckDocsImages => check_docs_rs_images(), } } } @@ -78,3 +89,71 @@ fn gen_proto() -> Result<()> { .compile_protos(&proto_files[..], &[proto_dir]) .context("failed to compile protobuf files") } + +fn check_docs_rs_images() -> Result<()> { + eprintln!("checking images for tokio-console docs.rs page..."); + + let base_dir = { + let mut mydir = PathBuf::from(std::env!("CARGO_MANIFEST_DIR")); + ensure!(mydir.pop(), "manifest path should not be relative!"); + mydir + }; + + let readme_path = base_dir.join("tokio-console/README.md"); + let file = + fs::File::open(&readme_path).expect("couldn't open tokio-console README.md for reading"); + + let regex_line = line!() + 1; + let re = Regex::new( + r"https://raw.githubusercontent.com/tokio-rs/console-/main/(assets/tokio-console-[\d\.]+\/\w+\.png)", + ) + .expect("couldn't compile regex"); + let reader = BufReader::new(file); + let mut readme_images = Vec::new(); + for line in reader.lines() { + let Ok(line) = line else { + break; + }; + + let Some(image_match) = re.captures(&line) else { + continue; + }; + + let image_path = image_match.get(1).unwrap().as_str(); + readme_images.push(image_path.to_string()); + } + + if readme_images.is_empty() { + let regex_file = file!(); + let readme_path = readme_path.to_string_lossy(); + return Err(eyre!( + "No images found in tokio-console README.md!\n\n\ + The README that was read is located at: {readme_path}\n\n\ + This probably means that there is a problem with the regex defined at \ + {regex_file}:{regex_line}." + )); + } + + let mut missing = Vec::new(); + for image_path in &readme_images { + if !Path::new(image_path).exists() { + missing.push(image_path.to_string()); + } + } + + if missing.is_empty() { + eprintln!( + "OK: verified existance of image files in README, count: {}", + readme_images.len() + ); + + Ok(()) + } else { + let mut error_buffer = "Tokio console README images missing:\n".to_string(); + for path in missing { + writeln!(&mut error_buffer, " - {path}")?; + } + + Err(eyre!("{}", error_buffer)) + } +}