support pulling, refactor git module

This commit is contained in:
Cadey Ratio 2020-07-09 11:31:09 -04:00
parent 2c098d4f23
commit bc608f7ddc
3 changed files with 96 additions and 22 deletions

View File

@ -11,10 +11,11 @@ pub(crate) async fn run(
let repo = git2::Repository::open(".")?;
let tag = tag.unwrap_or(version::read_version("VERSION".into())?);
let desc = changelog::read(fname.clone(), tag.clone())?;
let sig = git2::Signature::now(&common.username, &common.email)?;
if !git::has_tag(&repo, tag.clone())? {
git::tag_version(&repo, tag.clone(), desc.clone())?;
let _ = git::push_tags(&repo);
git::tag_version(&repo, tag.clone(), desc.clone(), &sig)?;
let _ = git::push(&repo, common.token.clone(), git::TAGS);
} else
/* The tag already exists */
{

View File

@ -9,18 +9,30 @@ pub(crate) struct Common {
/// The gitea server to connect to
#[structopt(short, long, env = "GITEA_SERVER")]
pub server: String,
/// The gitea token to authenticate with
#[structopt(long, env = "GITEA_TOKEN")]
pub token: String,
/// The gitea user to authenticate as
#[structopt(short, long, env = "GITEA_AUTH_USER")]
pub auth_user: String,
/// The owner of the gitea repo
#[structopt(short, long, env = "GITEA_OWNER")]
pub owner: String,
/// The gitea repo to operate on
#[structopt(short, long, env = "GITEA_REPO")]
pub repo: String,
/// Git signature email
#[structopt(long, short = "E", env = "SIGNATURE_EMAIL", default_value = "domo@tulpa.dev")]
pub email: String,
/// Git signature username
#[structopt(long, short = "U", env = "SIGNATURE_NAME", default_value = "Domo Arigato")]
pub username: String,
}
#[derive(StructOpt, Debug, Clone)]
@ -29,12 +41,15 @@ pub(crate) struct DroneEnv {
/// push URL
#[structopt(long, env = "DRONE_GIT_HTTP_URL")]
pub push_url: String,
/// repo owner
#[structopt(long, env = "DRONE_REPO_OWNER")]
pub owner: String,
/// repo name
#[structopt(long, env = "DRONE_REPO_NAME")]
pub repo: String,
/// branch
#[structopt(long, env = "DRONE_REPO_BRANCH")]
pub branch: String,
@ -43,18 +58,30 @@ pub(crate) struct DroneEnv {
/// auth username
#[structopt(long, env = "PLUGIN_AUTH_USERNAME")]
pub auth_user: String,
/// Gitea server
#[structopt(long, env = "PLUGIN_GITEA_SERVER")]
pub server: String,
/// Gitea token
#[structopt(long, env = "PLUGIN_GITEA_TOKEN")]
pub token: String,
/// CHANGELOG path
#[structopt(long, env = "PLUGIN_CHANGELOG_PATH", default_value = "./CHANGELOG.md")]
pub changelog_path: PathBuf,
/// Default branch name
#[structopt(long, env = "PLUGIN_DEFAULT_BRANCH")]
pub default_branch: Option<String>,
/// Git signature email
#[structopt(long, short = "E", env = "PLUGIN_SIGNATURE_EMAIL", default_value = "domo@tulpa.dev")]
pub email: String,
/// Git signature username
#[structopt(long, short = "U", env = "PLUGIN_SIGNATURE_NAME", default_value = "Domo Arigato")]
pub username: String,
}
impl Into<Common> for DroneEnv {
@ -65,6 +92,8 @@ impl Into<Common> for DroneEnv {
auth_user: self.auth_user,
owner: self.owner,
repo: self.repo,
email: self.email,
username: self.username,
}
}
}

View File

@ -1,22 +1,77 @@
use anyhow::Result;
use git2::{Repository, Signature};
use std::path::Path;
pub(crate) fn push_tags(repo: &Repository) -> Result<()> {
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")?;
remote.connect(git2::Direction::Push)?;
remote.push(&["refs/tags/*:refs/tags/*"], None)?;
let mut fo = git2::FetchOptions::new();
let mut callbacks = git2::RemoteCallbacks::new();
callbacks.credentials(|_u, _username, allowed_types| {
if allowed_types.contains(git2::CredentialType::SSH_KEY) {
let user = "git";
git2::Cred::ssh_key_from_agent(user)
} else {
git2::Cred::userpass_plaintext(&token, "")
}
});
fo.remote_callbacks(callbacks);
remote.connect(git2::Direction::Fetch)?;
remote.fetch(what, Some(&mut fo), None)?;
Ok(())
}
pub(crate) fn tag_version(repo: &Repository, tag: String, desc: String) -> Result<()> {
let sig = &Signature::now("Gitea Release Tool", "gitea-release@tulpa.dev")?;
pub fn push(repo: &Repository, token: String, what: &[&str]) -> Result<()> {
let mut remote = repo.find_remote("origin")?;
let mut po = git2::PushOptions::new();
let mut callbacks = git2::RemoteCallbacks::new();
callbacks.credentials(|_u, _username, allowed_types| {
if allowed_types.contains(git2::CredentialType::SSH_KEY) {
let user = "git";
git2::Cred::ssh_key_from_agent(user)
} else {
git2::Cred::userpass_plaintext(&token, "")
}
});
po.remote_callbacks(callbacks);
remote.connect(git2::Direction::Push)?;
remote.push(what, Some(&mut po))?;
Ok(())
}
pub fn commit(
repo: &Repository,
sig: &git2::Signature,
msg: &str,
files: &[&str],
) -> Result<()> {
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, &[])?;
Ok(())
}
pub fn tag_version(repo: &Repository, tag: String, desc: String, sig: &git2::Signature) -> Result<()> {
let obj = repo.revparse_single("HEAD")?;
repo.tag(&tag, &obj, &sig, &desc, false)?;
Ok(())
}
pub(crate) fn has_tag(repo: &Repository, tag: String) -> Result<bool> {
pub fn has_tag(repo: &Repository, tag: String) -> Result<bool> {
let tags = repo.tag_names(Some(&tag))?;
for tag_obj in tags.iter() {
@ -37,7 +92,7 @@ pub(crate) fn has_tag(repo: &Repository, tag: String) -> Result<bool> {
mod tests {
use anyhow::Result;
use git2::*;
use std::{fs::File, io::Write, path::Path};
use std::{fs::File, io::Write};
use tempfile::tempdir;
#[test]
@ -48,22 +103,11 @@ mod tests {
let mut fout = File::create(&dir.path().join("VERSION"))?;
write!(fout, "{}", TAG)?;
drop(fout);
let mut index = repo.index()?;
index.add_path(Path::new("VERSION"))?;
let oid = index.write_tree()?;
let tree = repo.find_tree(oid)?;
let sig = &Signature::now("Gitea Release Tool", "gitea-release@tulpa.dev")?;
repo.commit(
Some("HEAD"),
&sig,
&sig,
"test commit please ignore",
&tree,
&[],
)?;
super::commit(&repo, &sig, "test commit please ignore", &["VERSION"])?;
super::tag_version(&repo, TAG.into(), format!("version {}", TAG))?;
super::tag_version(&repo, TAG.into(), format!("version {}", TAG), &sig)?;
assert!(super::has_tag(&repo, TAG.into())?);
Ok(())