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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use std::fs;
use std::path::Path;

use url::Url;

/// Validate repository url.
///
/// Notes:
/// * Relative URLs without base (scp-like syntax) are not supported.
///
///   e.g. `[user@]host.xz:path/to/repo.git` or `[user@]host.xz:~/path/to/repo.git`
pub fn validate_repo_url(url: &str) -> Result<(), String> {
    match Url::parse(url) {
        Ok(_parsed) => Ok(()),
        Err(err) => return Err(format!("{}", err.to_string())),
    }
}

/// Get repository server (host[:port]) from repository url.
pub fn repo_server_from_url(url: &str) -> Result<String, String> {
    let parsed = match Url::parse(url) {
        Ok(parsed) => parsed,
        Err(err) => return Err(format!("{}", err.to_string())),
    };
    let host = parsed.host_str().unwrap();
    let port = parsed.port();
    // URL scheme is ignored.
    let server = match port {
        None => host.to_owned(),
        _ => host.to_owned() + ":" + &port.unwrap().to_string(),
    };
    Ok(server.to_string())
}

/// Convert repository url to relative repository directory.
pub fn repo_url_to_relpath(url: &str) -> Result<String, String> {
    let parsed = match Url::parse(url) {
        Ok(parsed) => parsed,
        Err(err) => return Err(format!("{}", err.to_string())),
    };
    let host = parsed.host_str().unwrap();
    let port = parsed.port();
    let path = parsed.path();
    let relpath = match port {
        None => host.to_owned() + path,
        _ => host.to_owned() + ":" + &port.unwrap().to_string() + path,
    };
    // TODO bare repository needs ".git" suffix?
    Ok(relpath.trim_right_matches(".git").to_string())
}

/// Delete repository relative path.
pub fn delete_repo_relpath(relpath: &Path) {
    let local_relpath = relpath.to_str().unwrap();
    if relpath.is_dir() {
        // Delete repo directory
        println!(
            "Found repository directory '{}'. Try to delete it...",
            &local_relpath
        );
        match fs::remove_dir_all(relpath) {
            Ok(_) => {
                println!(
                    "Local repository directory '{}' is deleted.",
                    &local_relpath
                );
                println!("Please manually delete repository from metadata file.");
            }
            Err(err) => println!(
                "Failed to delete repository directory '{}' because of: {}",
                &local_relpath,
                err.to_string()
            ),
        }
    } else if relpath.exists() {
        // Delete it whatever.
        println!(
            "The repository path '{}' is not a directory. Try to delete it whatever...",
            &local_relpath
        );
        match fs::remove_file(relpath) {
            Ok(_) => {
                println!("Local repository path '{}' is deleted.", &local_relpath);
                println!("Please manually delete repository from metadata file.");
            }
            Err(err) => println!(
                "Failed to delete repository path '{}' because of: {}",
                &local_relpath,
                err.to_string()
            ),
        }
    } else {
        // Repo directory does not exist.
        println!(
            "The repository directory '{}' does not exists.",
            &local_relpath
        );
    }
}

/// Generate http proxy url.
pub fn gen_proxy_url(scheme: &str, host: &str, port: u16) -> String {
    let proxy_url = scheme.to_owned() + "://" + host + ":" + &port.to_string();
    proxy_url.to_string()
}

/// Generate alternative url for vcs.
pub fn gen_alternative_url(vcs: &str, url: &str) -> Option<String> {
    if vcs == "git" {
        let alternative_url = if url.ends_with(".git") {
            url.trim_right_matches(".git").to_string()
        } else {
            url.to_string() + ".git"
        };
        Some(alternative_url)
    } else {
        // Other vcs unsupported now.
        None
    }
}