1+ use std:: {
2+ fmt:: Write ,
3+ fs,
4+ io:: { BufRead , BufReader } ,
5+ path:: { Path , PathBuf } ,
6+ } ;
7+
18use clap:: Parser ;
29use color_eyre:: {
3- eyre:: { ensure, WrapErr } ,
10+ eyre:: { ensure, eyre , WrapErr } ,
411 Result ,
512} ;
6- use std :: { fs , path :: PathBuf } ;
13+ use regex :: Regex ;
714
815/// tokio-console dev tasks
916#[ derive( Debug , clap:: Parser ) ]
@@ -16,6 +23,9 @@ struct Args {
1623enum Command {
1724 /// Generate `console-api` protobuf bindings.
1825 GenProto ,
26+
27+ /// Check images needed for tokio-console docs.rs main page
28+ CheckDocsImages ,
1929}
2030
2131fn main ( ) -> Result < ( ) > {
@@ -27,6 +37,7 @@ impl Command {
2737 fn run ( & self ) -> Result < ( ) > {
2838 match self {
2939 Self :: GenProto => gen_proto ( ) ,
40+ Self :: CheckDocsImages => check_docs_rs_images ( ) ,
3041 }
3142 }
3243}
@@ -78,3 +89,68 @@ fn gen_proto() -> Result<()> {
7889 . compile_protos ( & proto_files[ ..] , & [ proto_dir] )
7990 . context ( "failed to compile protobuf files" )
8091}
92+
93+ fn check_docs_rs_images ( ) -> Result < ( ) > {
94+ eprintln ! ( "checking images for tokio-console docs.rs page..." ) ;
95+
96+ let base_dir = {
97+ let mut mydir = PathBuf :: from ( std:: env!( "CARGO_MANIFEST_DIR" ) ) ;
98+ ensure ! ( mydir. pop( ) , "manifest path should not be relative!" ) ;
99+ mydir
100+ } ;
101+
102+ let readme_path = base_dir. join ( "tokio-console/README.md" ) ;
103+ let file =
104+ fs:: File :: open ( & readme_path) . expect ( "couldn't open tokio-console README.md for reading" ) ;
105+
106+ let regex_line = line ! ( ) + 1 ;
107+ let re = Regex :: new (
108+ r"https://raw.githubusercontent.com/tokio-rs/console-/main/(assets/tokio-console-[\d\.]+\/\w+\.png)" ,
109+ )
110+ . expect ( "couldn't compile regex" ) ;
111+ let reader = BufReader :: new ( file) ;
112+ let mut readme_images = Vec :: new ( ) ;
113+ for line in reader. lines ( ) {
114+ let Ok ( line) = line else {
115+ break ;
116+ } ;
117+
118+ let Some ( image_match) = re. captures ( & line) else {
119+ continue ;
120+ } ;
121+
122+ let image_path = image_match. get ( 1 ) . unwrap ( ) . as_str ( ) ;
123+ readme_images. push ( image_path. to_string ( ) ) ;
124+ }
125+
126+ if readme_images. is_empty ( ) {
127+ let regex_file = file ! ( ) ;
128+ let readme_path = readme_path. to_string_lossy ( ) ;
129+ return Err ( eyre ! (
130+ "No images found in tokio-console README.md!\n \n \
131+ The README that was read is located at: {readme_path}\n \n \
132+ This probably means that there is a problem with the regex defined at \
133+ {regex_file}:{regex_line}."
134+ ) ) ;
135+ }
136+
137+ let mut missing = Vec :: new ( ) ;
138+ for image_path in & readme_images {
139+ if !Path :: new ( image_path) . exists ( ) {
140+ missing. push ( image_path. to_string ( ) ) ;
141+ }
142+ }
143+
144+ if missing. is_empty ( ) {
145+ eprintln ! ( "OK: verified existance of image files in README, count: {}" , readme_images. len( ) ) ;
146+
147+ Ok ( ( ) )
148+ } else {
149+ let mut error_buffer = "Tokio console README images missing:\n " . to_string ( ) ;
150+ for path in missing {
151+ writeln ! ( & mut error_buffer, " - {path}" ) ?;
152+ }
153+
154+ Err ( eyre ! ( "{}" , error_buffer) )
155+ }
156+ }
0 commit comments