async_gitlib/
repo_clone.rs

1use async_std::task::spawn_blocking;
2use git2::{Error, FetchOptions, RemoteCallbacks};
3use git2::build::{RepoBuilder};
4use std::path::PathBuf;
5
6pub struct RepoClone {
7    bare: bool,
8    branch: String,
9}
10
11impl RepoClone {
12
13    pub fn bare(&self) -> bool {
14        self.bare
15    }
16
17    pub fn set_bare(&mut self, bare: bool) {
18        self.bare = bare;
19    }
20
21    pub fn branch(&self) -> &str {
22        &self.branch
23    }
24
25    pub fn set_branch<S>(&mut self, branch: S)
26        where
27        S: Into<String>,
28    {
29        self.branch = branch.into();
30    }
31
32    pub async fn clone<S, T>(&self, source: S, target: T) -> Result<(), Error>
33        where
34        S: Into<String>,
35        T: Into<PathBuf>,
36    {
37        let source = source.into();
38        let target = target.into();
39        let bare = self.bare.clone();
40        let branch = self.branch.clone();
41
42        spawn_blocking(move || {
43
44            let callbacks = RemoteCallbacks::new();
45            // callbacks.transfer_progress(|progress| {
46            //     println!("=> total_objects: {:?}", progress.total_objects()); // total
47            //     println!("=> indexed_objects: {:?}", progress.indexed_objects()); // current
48            //     println!("=> received_bytes: {:?}", progress.received_bytes());
49            //     true
50            // });
51            // callbacks.credentials(|_url, username_from_url, _allowed_types| {
52            //     Cred::ssh_key(
53            //         username_from_url.unwrap(),
54            //         None,
55            //         std::path::Path::new(&format!("{}/.ssh/id_rsa", env::var("HOME").unwrap())),
56            //         None,
57            //     )
58            // });
59            // callbacks.certificate_check(|cert, data| {});
60
61            let mut fo = FetchOptions::new();
62            fo.remote_callbacks(callbacks);
63
64            let mut builder = RepoBuilder::new();
65            builder.bare(bare);
66            builder.branch(&branch);
67            builder.fetch_options(fo);
68            builder.clone(&source, &target)?;
69
70            Ok(())
71        }).await
72    }
73}
74
75impl Default for RepoClone {
76
77    fn default() -> Self {
78        Self {
79            bare: false,
80            branch: String::from("master"),
81        }
82    }
83}
84
85#[cfg(test)]
86mod tests {
87    use super::*;
88    use tempfile::TempDir;
89
90    #[async_std::test]
91    async fn clones_public() {
92        let source = "https://github.com/xpepermint/async-gitlib";
93        let target = TempDir::new().unwrap().path().to_owned();
94        let clone = RepoClone::default();
95        clone.clone(source, &target).await.unwrap();
96        assert!(target.join("Cargo.toml").exists());
97    }
98}