smaug_lib/
resolver.rs

1use crate::dependency;
2use crate::{config, source::Source};
3use config::{Config, DependencyOptions};
4use dependency::Dependency;
5use log::*;
6use semver::VersionReq;
7use std::collections::HashMap;
8use std::path::PathBuf;
9
10#[derive(Clone, Default)]
11pub struct Resolver {
12    pub requirements: Vec<Dependency>,
13    pub source_map: HashMap<String, Box<dyn Source>>,
14    pub installs: Vec<Install>,
15    pub requires: Vec<String>,
16}
17
18#[derive(Clone, Debug, Default)]
19pub struct Install {
20    pub from: PathBuf,
21    pub to: PathBuf,
22}
23
24impl Resolver {
25    pub fn install(&mut self, destination: PathBuf) -> std::io::Result<Vec<Dependency>> {
26        info!("Installing Dependencies\n");
27
28        let reqs = self.requirements.clone();
29        let sources = self.source_map.clone();
30
31        for dependency in reqs.iter() {
32            let source = sources.get(&dependency.name).unwrap();
33
34            if source.installed(dependency, &destination) {
35                info!("{} is already installed", dependency.name);
36            } else {
37                info!("Installing {}", dependency.name);
38                source.install(dependency, &destination)?;
39            }
40
41            source.update_resolver(self, dependency, &destination);
42        }
43
44        info!("");
45
46        Ok(reqs)
47    }
48
49    pub fn add_source(&mut self, name: String, source: Box<dyn Source>) {
50        self.source_map.entry(name).or_insert(source);
51    }
52
53    pub fn add_requirement(&mut self, dependency: Dependency) {
54        self.requirements.push(dependency);
55    }
56}
57
58pub fn new_from_config(config: &Config) -> Resolver {
59    let mut resolver = Resolver::default();
60
61    for (name, dependency_options) in config.dependencies.iter() {
62        let name = String::from(name);
63        let version = match dependency_options {
64            DependencyOptions::Registry { version, .. } => version.clone(),
65            _ => VersionReq::any().to_string(),
66        };
67
68        debug!("{:?}", dependency_options);
69        let source = crate::source::from_dependency_options(dependency_options)
70            .expect("could not create source");
71        let dependency = Dependency {
72            name: name.clone(),
73            version,
74        };
75
76        resolver.add_requirement(dependency.clone());
77        resolver.add_source(dependency.name, source);
78    }
79
80    resolver
81}