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}