1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//! Configuration

use std::collections::BTreeMap;

use crate::{error::Error, repo::GitRepository};

/// A more user-friendly config object
pub type GitConfig = BTreeMap<String, String>;

/// Config key for the user email
pub const USER_EMAIL: &str = "user.email";

/// Config key for the user name
pub const USER_NAME: &str = "user.name";

/// Returns the repo config
///
/// The config is the config which can be applied taking into
/// account the hierarchy which exists between the global config,
/// and the local/repo config overwriting the global config.
pub fn get_config(repo: &GitRepository) -> Result<GitConfig, Error> {
    let git2_cfg = repo.config().unwrap();

    let mut cfg = BTreeMap::new();
    git2_cfg.entries(None).into_iter().for_each(|entries| {
        // NB: this loop is over the types of config, starting from the most generic one (global => local)
        entries
            .for_each(|entry| {
                // NB: this loop is for each entry in the config file
                // let level = entry.level();
                let name = entry.name().unwrap().to_string();
                let value = entry.value().unwrap_or("").to_string();
                // eprintln!("{:?} {} {}", level, name, value);
                cfg.insert(name, value);
            })
            .unwrap();
    });

    Ok(cfg)
}

/// Retrieves the repo origin url
pub fn get_origin_url(repo: &GitRepository, origin_name: &str) -> Result<Option<String>, Error> {
    let cfg = get_config(repo)?;
    let key = format!("remote.{}.url", origin_name);
    Ok(cfg.get(key.as_str()).map(|s| s.to_string()))
}

#[cfg(test)]
mod tests {
    use crate::repo::discover_repo;

    // Note this useful idiom: importing names from outer (for mod tests) scope.
    use super::*;

    #[test]
    fn test_cfg() {
        let cwd = std::env::current_dir().unwrap();
        let repo = discover_repo(&cwd).unwrap();
        let cfg = get_config(&repo).unwrap();
        for (k, v) in cfg.iter() {
            eprintln!("{}: {}", k, v);
        }
    }
}