use std::ffi::OsStr;
use std::path::{Path, PathBuf};
use parse_git_url::GitUrl;
use crate::error::SheepError;
pub fn repo_path<P: AsRef<Path>>(repo_url: &str, directory: P) -> Result<PathBuf, SheepError> {
let repo_name = repo_name(repo_url)?;
let path_parts = [
directory.as_ref().as_os_str(),
OsStr::new(&repo_name)
];
Ok(path_parts.iter().collect::<PathBuf>())
}
fn repo_name(repo_url: &str) -> Result<String, SheepError> {
let git_url = GitUrl::parse(repo_url)?;
if git_url.name.is_empty() {
Err(SheepError::new("no repo name found in git url"))
} else {
Ok(git_url.name)
}
}
#[cfg(test)]
mod test {
use std::path::Path;
use crate::repo::path;
#[test]
fn repo_path_invalid_url() {
path::repo_path("invalid", Path::new("/dir"))
.expect_err("failed to emit error for invalid URL");
}
#[test]
fn repo_path_https_url() {
let path = path::repo_path("https://github.com/ncipollo/sheepit.git",
Path::new("/dir"))
.expect("failed to parse ssh url");
assert_eq!(Path::new("/dir/sheepit"), path.as_path())
}
#[test]
fn repo_path_ssh_url() {
let path = path::repo_path("git@github.com:ncipollo/sheepit.git",
Path::new("/dir"))
.expect("failed to parse ssh url");
assert_eq!(Path::new("/dir/sheepit"), path.as_path())
}
}