1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
use std::fs; use std::path; use std::process; use regex::Regex; use crate::args::Args; use crate::command::Command; use crate::config::Config; use crate::error::ErrorHandleable; use crate::message::Messageable; pub struct Runner { args: Args, config: Config, file_regex: Regex, } impl Runner { pub fn new(args: Args, config: Config) -> Self { let pattern = config.file_name.replace("{}", r"([^\.]+)"); let file_regex = regex::Regex::new(&pattern).handle_error(&format!( "Failed to parse a regular expression: {}", pattern )); Runner { args, config, file_regex, } } pub fn run(&self, file_name: &str) -> Option<process::ExitStatus> { self.match_file(&file_name).map(|task_name| { Self::notify_detection(&file_name); Self::create_test_directory(&self.args.test_directory); let path = self.args.test_directory.join(task_name); let url = self.config.task_url.replace("{}", task_name); let command = format!( "timeout {} {}", self.args.timeout, self.config.command.replace("{}", task_name) ); if !path.exists() { let exit_status = Self::download(&url, &path); if !exit_status.success() { return exit_status; } } Self::test(&command, &path) }) } fn notify_detection(file_name: &str) { println!(); format!("Detected change in file '{}' ", file_name) .info_message() .show(); } fn match_file<'a>(&self, file_name: &'a str) -> Option<&'a str> { self.file_regex .captures(file_name) .and_then(|caps| caps.get(1)) .map(|m| m.as_str()) } fn create_test_directory(path: &path::Path) { fs::create_dir_all(path).handle_error(&format!( "Failed to create a directory: {}", path.to_string_lossy() )); } fn download(url: &str, path: &path::Path) -> process::ExitStatus { Command::new("oj") .arg("download") .arg("--directory") .arg(&path.to_string_lossy()) .arg(url) .show() .run() } fn test(command: &str, path: &path::Path) -> process::ExitStatus { Command::new("oj") .arg("test") .arg("--command") .arg(command) .arg("--directory") .arg(&path.to_string_lossy()) .show() .run() } }