smaug_lib/
source.rs

1use url_source::UrlSource;
2
3use crate::resolver::Install;
4use crate::sources::file_source::FileSource;
5use crate::sources::registry_source::RegistrySource;
6use crate::{config::DependencyOptions, sources::git_source::GitSource};
7use crate::{dependency::Dependency, sources::url_source};
8use crate::{resolver::Resolver, sources::dir_source::DirSource};
9use log::*;
10use std::path::Path;
11
12pub trait Source: SourceClone {
13    fn install(&self, dependency: &Dependency, path: &Path) -> std::io::Result<()>;
14
15    fn installed(&self, dependency: &Dependency, destination: &Path) -> bool {
16        let destination = destination.join(dependency.clone().name);
17        destination.exists()
18    }
19
20    fn update_resolver(
21        &self,
22        resolver: &mut Resolver,
23        dependency: &Dependency,
24        destination: &Path,
25    ) {
26        let project_dir = destination.parent().unwrap();
27        let destination = destination.join(dependency.clone().name);
28        let config_path = destination.join("Smaug.toml");
29        let config = crate::config::load(&config_path).expect("Could not find Smaug.toml");
30        debug!("Package config: {:?}", config);
31        let package = config.package.expect("No package configuration found.");
32
33        for (from, to) in package.installs {
34            let install_source = from.to_path(destination.as_path());
35            let install_destination = to.to_path(project_dir);
36
37            let install = Install {
38                from: install_source,
39                to: install_destination,
40            };
41
42            resolver.installs.push(install);
43        }
44
45        let mut requires = package
46            .requires
47            .iter()
48            .map(|require| {
49                let package_file = require.to_path(destination.clone());
50                trace!("Checking package file {:?}", package_file);
51
52                if package_file.exists() {
53                    trace!("package file exists");
54                    format!("smaug/{}/{}", dependency.name, require)
55                } else {
56                    trace!("package file does not exists");
57                    require.to_string()
58                }
59            })
60            .collect();
61        resolver.requires.append(&mut requires);
62    }
63}
64
65pub trait SourceClone {
66    fn clone_box(&self) -> Box<dyn Source>;
67}
68
69pub fn from_dependency_options(options: &DependencyOptions) -> Option<Box<dyn Source>> {
70    match options {
71        DependencyOptions::Git {
72            repo,
73            branch,
74            rev,
75            tag,
76        } => Some(Box::new(GitSource {
77            repo: repo.clone(),
78            branch: branch.clone(),
79            rev: rev.clone(),
80            tag: tag.clone(),
81        })),
82        DependencyOptions::Dir { dir: path } => Some(Box::new(DirSource {
83            path: path.to_path_buf(),
84        })),
85        DependencyOptions::File { file: path } => Some(Box::new(FileSource {
86            path: path.to_path_buf(),
87        })),
88        DependencyOptions::Url { url } => Some(Box::new(UrlSource {
89            url: url.to_string(),
90        })),
91        DependencyOptions::Registry { version } => Some(Box::new(RegistrySource {
92            version: version.to_string(),
93        })),
94    }
95}
96
97impl<T> SourceClone for T
98where
99    T: 'static + Source + Clone,
100{
101    fn clone_box(&self) -> Box<dyn Source> {
102        Box::new(self.clone())
103    }
104}
105
106impl Clone for Box<dyn Source> {
107    fn clone(&self) -> Box<dyn Source> {
108        self.clone_box()
109    }
110}