1
use std::collections::HashSet;
2

            
3
use git2::Repository;
4

            
5
/// Get a list of remotes for a repository. If there are no remotes, return an
6
/// empty HashSet.
7
4
fn list_remotes(repo: &Repository) -> HashSet<String> {
8
4
    let mut remotes = HashSet::new();
9
4
    if let Ok(remote_list) = repo.remotes() {
10
4
        for remote in remote_list.into_iter().flatten() {
11
2
            remotes.insert(remote.to_string());
12
2
        }
13
    }
14
4
    remotes
15
4
}
16

            
17
/// Get a list of remote prefixes for a repository. If there are no remotes,
18
/// return an empty HashSet.
19
4
pub fn list_remote_prefixes(repo: &Repository) -> HashSet<String> {
20
4
    let mut prefixes = HashSet::new();
21
4
    for remote in list_remotes(repo) {
22
2
        prefixes.insert(as_prefix(remote));
23
2
    }
24
4
    prefixes
25
4
}
26

            
27
/// Return remote as prefix. If it does not end in a slash, add one.
28
/// e.g. "origin" -> "origin/"
29
/// e.g. "origin/" -> "origin/"
30
6
fn as_prefix(remote: String) -> String {
31
6
    if remote.ends_with('/') {
32
2
        remote.to_string()
33
    } else {
34
4
        format!("{}/", remote)
35
    }
36
6
}
37

            
38
#[cfg(test)]
39
mod tests {
40
    use super::*;
41

            
42
    #[test]
43
2
    fn test_as_prefix() {
44
2
        assert_eq!(as_prefix("origin".to_string()), "origin/");
45
2
        assert_eq!(as_prefix("origin/".to_string()), "origin/");
46
2
    }
47

            
48
    #[test]
49
2
    fn test_list_remote_prefixes() {
50
2
        // GIVEN a repository with remotes
51
2
        let (_testdir, repo) = crate::test_utilities::create_mock_repo();
52
2
        let remote = "origin";
53
2
        let remote_prefix = format!("{}/", remote);
54
2
        repo.remote(remote, "https://example.com").unwrap();
55
2

            
56
2
        // WHEN the remote prefixes are listed
57
2
        let actual = list_remote_prefixes(&repo);
58
2

            
59
2
        // THEN it should match the expected remote prefix
60
2
        assert_eq!(actual.len(), 1);
61
2
        assert!(actual.contains(&remote_prefix));
62
2
    }
63

            
64
    #[test]
65
2
    fn test_list_remote_prefixes_empty() {
66
2
        // GIVEN a repository without remotes
67
2
        let (_testdir, repo) = crate::test_utilities::create_mock_repo();
68
2

            
69
2
        // WHEN the remote prefixes are listed
70
2
        let actual = list_remote_prefixes(&repo);
71
2

            
72
2
        // THEN it should be empty
73
2
        assert!(actual.is_empty());
74
2
    }
75
}