mapm-cli 6.1.0

The command-line implementation of mapm
use crate::utils::dirs::{scripts_dir, template_dir};
use crate::utils::{msg, preview};

use colour::*;
use mapm::problem::Problem;
use std::process::Command;
use std::{env, fs};

pub fn contest(fetch_res: &mapm::contest::ContestFetchResult) {
    match fetch_res {
        Ok(contest) => {
            if let Err(errs) = contest.check_template() {
                for problem_err in errs.problem_errs {
                    e_red_ln!("Errors for problem `{}`:", problem_err.name);
                    for err in &problem_err.errs {
                        msg::print_err(err);
                    }
                }
                for contest_err in errs.contest_errs {
                    msg::print_err(&contest_err);
                }
            }
            let contest_res = contest.compile(template_dir());
            if let Some(err) = contest_res.err {
                msg::print_err(&err);
            };
            for result in contest_res.latexmk_results {
                match result {
                    Ok(msg) => println!("{}", msg),
                    Err(err) => {
                        e_red_ln!("{}", err);
                    }
                }
            }
        }
        Err(errs) => {
            for err in errs.contest_errs.iter() {
                msg::print_err(err);
                quit::with_code(exitcode::DATAERR);
            }
            for problem_err in errs.problem_errs.iter() {
                e_red_ln!("Errors for problem `{}`:", problem_err.name);
                for err in &problem_err.errs {
                    msg::print_err(err);
                }
            }
        }
    }
}

pub fn exec_script(script_name: &str) {
    let script_path = scripts_dir().join(script_name);
    if script_path.exists() {
        if cfg!(windows) {
            Command::new("powershell")
                .arg(
                    fs::read_to_string(script_path)
                        .expect("Could not read post-build script file to string"),
                )
                .spawn()
                .expect("Could not execute post-build script");
        } else if cfg!(unix) {
            Command::new("sh")
                .arg(script_path)
                .spawn()
                .expect("Could not execute post-build script");
        }
    }
}

pub fn preview(problem: &Problem) {
    let cwd = env::current_dir().expect("Could not get current directory");
    let cache_dir = dirs::cache_dir().expect("Could not find cache directory");
    let preview_dir = cache_dir.join("mapm").join(&problem.name);
    if !preview_dir.is_dir() {
        fs::create_dir_all(&preview_dir).expect("Could not create directory");
    }
    env::set_current_dir(&preview_dir).expect("Could not set working directory");
    let contest = preview::preview_contest(problem);
    if let Err(errs) = contest.check_template() {
        for problem_err in errs.problem_errs {
            e_red_ln!("Errors for problem `{}`:", problem_err.name);
            for err in &problem_err.errs {
                msg::print_err(err);
            }
        }
        for contest_err in errs.contest_errs {
            msg::print_err(&contest_err);
        }
    }
    let compile_results = contest.compile(template_dir());
    if let Some(err) = compile_results.err {
        msg::print_err(&err);
    }
    for latexmk_result in compile_results.latexmk_results {
        match latexmk_result {
            Ok(latexmk_result) => println!("{}", latexmk_result),
            Err(latexmk_result) => {
                e_red_ln!("{}", latexmk_result);
            }
        }
    }
    exec_script("preview");
    env::set_current_dir(&cwd).expect("Could not set working directory");
}

pub fn preview_all(problems: &[Problem]) {
    let cwd = env::current_dir().expect("Could not get current directory");
    let cache_dir = dirs::cache_dir().expect("Could not find cache directory");
    let preview_all_dir = cache_dir.join("mapm").join("preview-all");
    if !preview_all_dir.is_dir() {
        fs::create_dir_all(&preview_all_dir).expect("Could not create directory");
    }
    env::set_current_dir(&preview_all_dir).expect("Could not set working directory");
    let contest = preview::preview_all_contest(problems);
    if let Err(errs) = contest.check_template() {
        for problem_err in errs.problem_errs {
            e_red_ln!("Errors for problem `{}`:", problem_err.name);
            for err in &problem_err.errs {
                msg::print_err(err);
            }
        }
        for contest_err in errs.contest_errs {
            msg::print_err(&contest_err);
        }
    }
    let compile_results = contest.compile(template_dir());
    if let Some(err) = compile_results.err {
        msg::print_err(&err);
    }
    for latexmk_result in compile_results.latexmk_results {
        match latexmk_result {
            Ok(latexmk_result) => println!("{}", latexmk_result),
            Err(latexmk_result) => {
                e_red_ln!("{}", latexmk_result);
            }
        }
    }
    exec_script("preview-all");
    env::set_current_dir(&cwd).expect("Could not set working directory");
}