use std::path::Path;
use git2::build::RepoBuilder;
use git2::{Error, Oid, Repository};
/// TODO support SSH repository_url - we assume that the repository URL starts with HTTPS
/// TODO support git submodules
pub fn clone
(
repository_url: &str,
into_dir: P,
credentials: &Option,
) -> Result
where
P: AsRef,
{
let final_repository_url = match credentials {
Some(c) => format!(
"https://{}:{}@{}",
c.login,
c.password,
repository_url.replace("https://", "")
),
None => repository_url.to_string(),
};
RepoBuilder::new().clone(final_repository_url.as_str(), into_dir.as_ref())
}
pub fn checkout(repo: &Repository, commit_id: &str, repo_url: &str) -> Result<(), Error> {
let oid = match Oid::from_str(&commit_id) {
Err(e) => {
let x = git2::Error::from_str(
format!(
"Error while trying to validate commit ID {} on repository {}: {}",
&commit_id, &repo_url, &e
)
.as_ref(),
);
return Err(x);
}
Ok(o) => o,
};
let _ = match repo.find_commit(oid) {
Err(e) => {
let mut x = git2::Error::from_str(
format!(
"Commit ID {} on repository {} was not found",
&commit_id, &repo_url
)
.as_ref(),
);
x.set_code(e.code());
x.set_class(e.class());
return Err(x);
}
Ok(c) => c,
};
let obj = match repo.revparse_single(&commit_id) {
Err(e) => {
let x = git2::Error::from_str(
format!(
"Wasn't able to use git object commit ID {} on repository {}: {}",
&commit_id, &repo_url, &e
)
.as_ref(),
);
return Err(x);
}
Ok(o) => o,
};
let _ = repo.checkout_tree(&obj, None);
repo.set_head(&("refs/heads/".to_owned() + &commit_id))
}
pub fn checkout_submodules(repo: &Repository) -> Result<(), Error> {
match repo.submodules() {
Ok(submodules) => {
for mut submodule in submodules {
info!(
"getting submodule {:?} from {:?}",
submodule.name(),
submodule.url()
);
match submodule.update(true, None) {
Err(e) => return Err(e),
_ => (),
}
}
}
Err(err) => return Err(err),
}
Ok(())
}
pub struct Credentials {
pub login: String,
pub password: String,
}