smaug_lib/sources/
git_source.rs1use crate::dependency::Dependency;
2use crate::source::Source;
3use crate::sources::dir_source::DirSource;
4use git2::build::CheckoutBuilder;
5use git2::build::RepoBuilder;
6use git2::FetchOptions;
7use git2::Oid;
8use log::*;
9use std::path::Path;
10
11#[derive(Clone, Debug)]
12pub struct GitSource {
13 pub repo: String,
14 pub branch: Option<String>,
15 pub rev: Option<String>,
16 pub tag: Option<String>,
17}
18
19impl Source for GitSource {
20 fn install(&self, dependency: &Dependency, path: &Path) -> std::io::Result<()> {
21 let destination = crate::smaug::cache_dir().join(dependency.clone().name);
22 trace!(
23 "Installing git repository {} to {}",
24 self.repo,
25 destination.display()
26 );
27
28 if destination.exists() {
29 trace!("Removing directory {}", destination.to_str().unwrap());
30 rm_rf::ensure_removed(destination.clone()).unwrap();
31 }
32
33 let fetch = FetchOptions::new();
34 let checkout = CheckoutBuilder::new();
35
36 let mut builder = RepoBuilder::new();
37 builder.fetch_options(fetch);
38 builder.with_checkout(checkout);
39
40 debug!("Repository: {}", self.repo);
41 if self.branch.is_some() {
42 debug!("Branch: {}", self.branch.as_ref().unwrap());
43 builder.branch(self.branch.as_ref().unwrap().as_str());
44 }
45
46 trace!(
47 "Cloning git repository to {}",
48 destination.to_str().unwrap()
49 );
50 let repository = builder.clone(&self.repo, destination.as_path()).unwrap();
51
52 if self.rev.is_some() {
53 let revision = self.rev.clone().unwrap();
54 debug!("Revision: {}", revision);
55 let mut checkout = CheckoutBuilder::new();
56 let object = repository
57 .find_object(
58 Oid::from_str(revision.as_str()).expect("Could not find the revision"),
59 None,
60 )
61 .unwrap();
62 repository
63 .reset(&object, git2::ResetType::Hard, Some(&mut checkout))
64 .unwrap();
65 }
66
67 if self.tag.is_some() {
68 let tag = self.tag.clone().unwrap();
69 let mut checkout = CheckoutBuilder::new();
70
71 let rev = repository
72 .revparse_single(&tag)
73 .expect("Couldn't parse tag");
74
75 repository
76 .reset(&rev, git2::ResetType::Hard, Some(&mut checkout))
77 .unwrap();
78 }
79
80 let cached = repository.path().parent().expect("No parent dir");
81
82 DirSource {
83 path: cached.to_path_buf(),
84 }
85 .install(dependency, path)
86 }
87}