summaryrefslogtreecommitdiff
path: root/ofborg/tickborg/src/evalchecker.rs
blob: ac1b4f8d3906cc51f4df9290f5e3c8e7ca15b12d (plain)
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
use std::fs::File;
use std::io::Write;
use std::path::Path;
use std::process::Command;

/// A generic check that can be run against a checkout
pub struct EvalChecker {
    name: String,
    command: String,
    args: Vec<String>,
}

impl EvalChecker {
    pub fn new(name: &str, command: &str, args: Vec<String>) -> EvalChecker {
        EvalChecker {
            name: name.to_owned(),
            command: command.to_owned(),
            args,
        }
    }

    pub fn name(&self) -> &str {
        &self.name
    }

    pub fn execute(&self, path: &Path) -> Result<File, File> {
        let output = Command::new(&self.command)
            .args(&self.args)
            .current_dir(path)
            .output();

        let tmp = tempfile::NamedTempFile::new().expect("Failed to create temp file");
        let tmp_path = tmp.into_temp_path().to_path_buf();

        match output {
            Ok(result) => {
                let mut f = File::create(&tmp_path).expect("Failed to create output file");
                f.write_all(&result.stdout).ok();
                f.write_all(&result.stderr).ok();
                drop(f);
                let file = File::open(&tmp_path).expect("Failed to open output file");
                if result.status.success() {
                    Ok(file)
                } else {
                    Err(file)
                }
            }
            Err(e) => {
                let mut f = File::create(&tmp_path).expect("Failed to create output file");
                write!(f, "Failed to execute {}: {}", self.command, e).ok();
                drop(f);
                Err(File::open(&tmp_path).expect("Failed to open output file"))
            }
        }
    }

    pub fn cli_cmd(&self) -> String {
        let mut cli = vec![self.command.clone()];
        cli.append(&mut self.args.clone());
        cli.join(" ")
    }
}