boltbuild 0.1.0

BoltBuild is a programmable build system.
Documentation
use crate::command::{CommandOutput, SerializedHash};
use crate::context::TOOLS_DIR;
use crate::environment::{Environment, ReadWriteEnvironment};
use crate::node::Node;
use blake3::Hasher;
use std::iter::zip;
use std::sync::{Arc, Mutex};

impl CommandOutput {
    pub(crate) fn hash(
        &self,
        options: Option<&Environment>,
        envs: &[Arc<Mutex<ReadWriteEnvironment>>],
        tools: &Vec<Node>,
    ) -> std::io::Result<(
        SerializedHash,
        SerializedHash,
        SerializedHash,
        SerializedHash,
    )> {
        let hash1 = {
            let mut hasher = Hasher::new();
            for file in &self.stored_hash.file_dependencies {
                if file.is_file() {
                    hasher.update(file.as_os_str().as_encoded_bytes());
                    hasher.update_reader(std::fs::File::open(file)?)?;
                } else {
                    hasher.update("!file_not_found!".as_bytes());
                    hasher.update(file.as_os_str().as_encoded_bytes());
                }
            }
            SerializedHash(hasher.finalize())
        };

        let hash2 = {
            let mut hasher = Hasher::new();
            for file in tools {
                hasher.update(file.path().as_os_str().as_encoded_bytes());
                if let Ok(file) = std::fs::File::open(file.path()) {
                    hasher.update_reader(file)?;
                } else if let Some(file) = TOOLS_DIR.get_file(file.path()) {
                    hasher.update(file.contents());
                } else {
                    hasher.update("!file_not_found!".as_bytes());
                }
            }
            SerializedHash(hasher.finalize())
        };

        let hash3 = {
            let mut hasher = Hasher::new();
            if let Some(env) = options {
                for env_var in &self.stored_hash.option_dependencies {
                    env.get_raw(env_var.as_str()).hash(&mut hasher);
                }
            }
            SerializedHash(hasher.finalize())
        };

        let hash4 = {
            let mut hasher = Hasher::new();
            for (vars, env_arc) in zip(self.stored_hash.variable_dependencies.iter(), envs.iter()) {
                let env = env_arc.lock().unwrap();
                for var in vars {
                    env.get_raw(var.as_str()).hash(&mut hasher);
                }
            }
            SerializedHash(hasher.finalize())
        };

        Ok((hash1, hash2, hash3, hash4))
    }
}