2020-05-31 17:45:35 +00:00
|
|
|
use anyhow::Result;
|
2020-07-09 15:35:49 +00:00
|
|
|
use git2::{
|
|
|
|
Cred, CredentialType, Direction, FetchOptions, PushOptions, RemoteCallbacks, Repository,
|
|
|
|
Signature,
|
|
|
|
};
|
2020-07-09 15:31:09 +00:00
|
|
|
use std::path::Path;
|
2020-05-31 17:45:35 +00:00
|
|
|
|
2020-07-09 15:31:09 +00:00
|
|
|
pub const TAGS: &'static [&'static str] = &["refs/tags/*:refs/tags/*"];
|
|
|
|
|
|
|
|
pub fn pull(repo: &Repository, token: String, what: &[&str]) -> Result<()> {
|
|
|
|
let mut remote = repo.find_remote("origin")?;
|
2020-07-09 15:35:49 +00:00
|
|
|
let mut fo = FetchOptions::new();
|
2020-07-09 15:31:09 +00:00
|
|
|
|
2020-07-09 17:06:07 +00:00
|
|
|
remote.connect_auth(Direction::Fetch, Some(callbacks(token.clone())), None)?;
|
|
|
|
fo.remote_callbacks(callbacks(token));
|
2020-07-09 15:31:09 +00:00
|
|
|
remote.fetch(what, Some(&mut fo), None)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-07-09 17:06:07 +00:00
|
|
|
fn callbacks<'a>(token: String) -> RemoteCallbacks<'a> {
|
2020-07-09 15:35:49 +00:00
|
|
|
let mut callbacks = RemoteCallbacks::new();
|
2020-07-09 17:06:07 +00:00
|
|
|
callbacks.credentials(move |_u, _username, allowed_types| {
|
2020-07-09 15:35:49 +00:00
|
|
|
if allowed_types.contains(CredentialType::SSH_KEY) {
|
2020-07-09 15:31:09 +00:00
|
|
|
let user = "git";
|
2020-07-09 15:35:49 +00:00
|
|
|
Cred::ssh_key_from_agent(user)
|
2020-07-09 15:31:09 +00:00
|
|
|
} else {
|
2020-07-09 17:06:07 +00:00
|
|
|
Cred::userpass_plaintext(&token, "x-oauth-basic")
|
2020-07-09 15:31:09 +00:00
|
|
|
}
|
|
|
|
});
|
2020-07-09 17:06:07 +00:00
|
|
|
callbacks
|
|
|
|
}
|
2020-07-09 15:31:09 +00:00
|
|
|
|
2020-07-09 17:06:07 +00:00
|
|
|
pub fn push(repo: &Repository, token: String, what: &[&str]) -> Result<()> {
|
|
|
|
let mut remote = repo.find_remote("origin")?;
|
|
|
|
|
|
|
|
remote.connect_auth(Direction::Push, Some(callbacks(token.clone())), None)?;
|
2020-07-09 15:31:09 +00:00
|
|
|
|
2020-07-09 17:06:07 +00:00
|
|
|
let mut po = PushOptions::new();
|
|
|
|
po.remote_callbacks(callbacks(token));
|
2020-07-09 15:31:09 +00:00
|
|
|
remote.push(what, Some(&mut po))?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-07-09 15:35:49 +00:00
|
|
|
pub fn commit(repo: &Repository, sig: &Signature, msg: &str, files: &[&str]) -> Result<()> {
|
2020-07-09 15:31:09 +00:00
|
|
|
let mut index = repo.index()?;
|
|
|
|
for file in files {
|
|
|
|
index.add_path(Path::new(file))?;
|
|
|
|
}
|
|
|
|
|
|
|
|
let oid = index.write_tree()?;
|
|
|
|
let tree = repo.find_tree(oid)?;
|
|
|
|
repo.commit(Some("HEAD"), &sig, &sig, &msg, &tree, &[])?;
|
|
|
|
|
2020-05-31 18:13:14 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-07-09 15:35:49 +00:00
|
|
|
pub fn tag_version(repo: &Repository, sig: &Signature, tag: String, desc: String) -> Result<()> {
|
2020-05-31 18:13:14 +00:00
|
|
|
let obj = repo.revparse_single("HEAD")?;
|
|
|
|
repo.tag(&tag, &obj, &sig, &desc, false)?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-07-09 15:31:09 +00:00
|
|
|
pub fn has_tag(repo: &Repository, tag: String) -> Result<bool> {
|
2020-05-31 17:45:35 +00:00
|
|
|
let tags = repo.tag_names(Some(&tag))?;
|
|
|
|
|
|
|
|
for tag_obj in tags.iter() {
|
|
|
|
if tag_obj.is_none() {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
let tag_name = tag_obj.unwrap();
|
2020-07-09 17:06:07 +00:00
|
|
|
log::debug!("tag: {}", tag_name.to_string());
|
2020-05-31 17:45:35 +00:00
|
|
|
if tag == tag_name.to_string() {
|
|
|
|
return Ok(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use anyhow::Result;
|
|
|
|
use git2::*;
|
2020-07-09 15:31:09 +00:00
|
|
|
use std::{fs::File, io::Write};
|
2020-05-31 17:45:35 +00:00
|
|
|
use tempfile::tempdir;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn has_tag() -> Result<()> {
|
|
|
|
const TAG: &'static str = "0.1.0";
|
|
|
|
let dir = tempdir()?;
|
|
|
|
let repo = Repository::init(&dir)?;
|
|
|
|
let mut fout = File::create(&dir.path().join("VERSION"))?;
|
|
|
|
write!(fout, "{}", TAG)?;
|
|
|
|
drop(fout);
|
|
|
|
|
2020-05-31 18:13:14 +00:00
|
|
|
let sig = &Signature::now("Gitea Release Tool", "gitea-release@tulpa.dev")?;
|
2020-07-09 15:31:09 +00:00
|
|
|
super::commit(&repo, &sig, "test commit please ignore", &["VERSION"])?;
|
2020-07-09 17:06:07 +00:00
|
|
|
super::tag_version(&repo, &sig, TAG.into(), format!("version {}", TAG))?;
|
2020-05-31 18:13:14 +00:00
|
|
|
assert!(super::has_tag(&repo, TAG.into())?);
|
2020-05-31 17:45:35 +00:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|