smaug-lib 0.5.0

The library for interacting with Smaug projects
Documentation
use crate::dependency;
use crate::{config, source::Source};
use config::{Config, DependencyOptions};
use dependency::Dependency;
use log::*;
use semver::VersionReq;
use std::collections::HashMap;
use std::path::PathBuf;

#[derive(Clone, Default)]
pub struct Resolver {
    pub requirements: Vec<Dependency>,
    pub source_map: HashMap<String, Box<dyn Source>>,
    pub installs: Vec<Install>,
    pub requires: Vec<String>,
}

#[derive(Clone, Debug, Default)]
pub struct Install {
    pub from: PathBuf,
    pub to: PathBuf,
}

impl Resolver {
    pub fn install(&mut self, destination: PathBuf) -> std::io::Result<Vec<Dependency>> {
        info!("Installing Dependencies\n");

        let reqs = self.requirements.clone();
        let sources = self.source_map.clone();

        for dependency in reqs.iter() {
            let source = sources.get(&dependency.name).unwrap();

            if source.installed(dependency, &destination) {
                info!("{} is already installed", dependency.name);
            } else {
                info!("Installing {}", dependency.name);
                source.install(dependency, &destination)?;
            }

            source.update_resolver(self, dependency, &destination);
        }

        info!("");

        Ok(reqs)
    }

    pub fn add_source(&mut self, name: String, source: Box<dyn Source>) {
        self.source_map.entry(name).or_insert(source);
    }

    pub fn add_requirement(&mut self, dependency: Dependency) {
        self.requirements.push(dependency);
    }
}

pub fn new_from_config(config: &Config) -> Resolver {
    let mut resolver = Resolver::default();

    for (name, dependency_options) in config.dependencies.iter() {
        let name = String::from(name);
        let version = match dependency_options {
            DependencyOptions::Registry { version, .. } => version.clone(),
            _ => VersionReq::any().to_string(),
        };

        debug!("{:?}", dependency_options);
        let source = crate::source::from_dependency_options(dependency_options)
            .expect("could not create source");
        let dependency = Dependency {
            name: name.clone(),
            version,
        };

        resolver.add_requirement(dependency.clone());
        resolver.add_source(dependency.name, source);
    }

    resolver
}