| use std::env::args; |
| use std::fs::{File, create_dir_all}; |
| use std::io::{BufRead, BufReader, BufWriter, Write}; |
| use std::path::Path; |
| use std::process::{Command, exit}; |
| |
| fn get_themes<P: AsRef<Path>>(style_path: P) -> Vec<String> { |
| let mut ret = Vec::with_capacity(10); |
| |
| const BEGIN_THEME_MARKER: &'static str = "/* Begin theme: "; |
| const END_THEME_MARKER: &'static str = "/* End theme: "; |
| |
| let timestamp = |
| std::time::SystemTime::UNIX_EPOCH.elapsed().expect("time is after UNIX epoch").as_millis(); |
| |
| let mut in_theme = None; |
| create_dir_all("build/tmp").expect("failed to create temporary test directory"); |
| for line in BufReader::new(File::open(style_path).expect("read rustdoc.css failed")).lines() { |
| let line = line.expect("read line from rustdoc.css failed"); |
| let line = line.trim(); |
| if line.starts_with(BEGIN_THEME_MARKER) { |
| let theme_name = &line[BEGIN_THEME_MARKER.len()..].trim().trim_end_matches("*/").trim(); |
| let filename = format!("build/tmp/rustdoc.bootstrap.{timestamp}.{theme_name}.css"); |
| in_theme = Some(BufWriter::new( |
| File::create(&filename).expect("failed to create temporary test css file"), |
| )); |
| ret.push(filename); |
| } |
| if let Some(in_theme) = in_theme.as_mut() { |
| in_theme.write_all(line.as_bytes()).expect("write to temporary test css file"); |
| in_theme.write_all(b"\n").expect("write to temporary test css file"); |
| } |
| if line.starts_with(END_THEME_MARKER) { |
| in_theme = None; |
| } |
| } |
| ret |
| } |
| |
| fn main() { |
| let argv: Vec<String> = args().collect(); |
| |
| if argv.len() < 3 { |
| eprintln!("Needs rustdoc binary path"); |
| exit(1); |
| } |
| let rustdoc_bin = &argv[1]; |
| let style_path = &argv[2]; |
| let themes = get_themes(&style_path); |
| if themes.is_empty() { |
| eprintln!("No themes found in \"{}\"...", style_path); |
| exit(1); |
| } |
| let arg_name = "--check-theme".to_owned(); |
| let status = Command::new(rustdoc_bin) |
| .args(&themes.iter().flat_map(|t| vec![&arg_name, t].into_iter()).collect::<Vec<_>>()) |
| .status() |
| .expect("failed to execute child"); |
| if !status.success() { |
| exit(1); |
| } |
| } |