fix commit

This commit is contained in:
2022-11-27 01:56:07 +01:00
parent 9f2bc08429
commit 4345f9c39b
26 changed files with 2441 additions and 68 deletions

View File

@@ -6,6 +6,8 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
gitea_client = { path = "../gitea_client" }
async-trait = { workspace = true }
eyre = { workspace = true }
tokio = { workspace = true }

View File

@@ -27,9 +27,13 @@ impl Executor for DefaultExecutor {
action_path: PathBuf,
action: Action,
) -> eyre::Result<()> {
tracing::trace!(
victim_path = victim_path.to_string_lossy().to_string(),
"execute"
);
let bin = self.builder.build(action_path, action.clone()).await?;
match action {
Action::Go { entry } => {
Action::Go { .. } => {
GolangExecutor::new()
.execute(GolangExecutorOpts { bin, victim_path })
.await?

View File

@@ -1,19 +1,29 @@
use std::{path::PathBuf, sync::Arc};
use eyre::ContextCompat;
use git2::{Cred, PushOptions, RemoteCallbacks, Repository};
use tokio::sync::Mutex;
use crate::{schema::models::GitPushBranch, storage::DynStorageEngine};
use crate::storage::DynStorageEngine;
use super::GitProvider;
#[derive(Clone, Debug)]
pub struct LocalGitProviderOptions {
pub http_auth: Option<String>,
}
pub struct LocalGitProvider {
storage_engine: DynStorageEngine,
options: LocalGitProviderOptions,
}
impl LocalGitProvider {
pub fn new(storage_engine: DynStorageEngine) -> Self {
Self { storage_engine }
pub fn new(options: LocalGitProviderOptions, storage_engine: DynStorageEngine) -> Self {
Self {
storage_engine,
options,
}
}
}
@@ -22,20 +32,37 @@ impl GitProvider for LocalGitProvider {
async fn clone_from_url(&self, url: String) -> eyre::Result<(PathBuf, Repository)> {
tracing::debug!(url, "allocating dir");
let dir = self.storage_engine.allocate_dir().await?;
let options = self.options.clone();
let dirpath = dir.clone().path();
let repo = tokio::task::spawn_blocking(move || {
let mut callbacks = RemoteCallbacks::new();
callbacks.credentials(|url, username_from_url, _allowed_types| {
tracing::debug!(username_from_url, url, "pulling key from ssh-agent");
Cred::ssh_key_from_agent(username_from_url.unwrap())
if let Some(auth) = &options.http_auth {
tracing::trace!(auth, "authenticating");
let (user, pass) = auth
.split_once(":")
.ok_or("http_auth is not formatted correctly")
.unwrap();
Cred::userpass_plaintext(user, pass)
} else {
let username = username_from_url
.context("could not find username_from_url")
.unwrap();
Cred::ssh_key_from_agent(username)
}
});
let mut fo = git2::FetchOptions::new();
fo.remote_callbacks(callbacks);
let checkout_builder = git2::build::CheckoutBuilder::new();
let mut builder = git2::build::RepoBuilder::new();
builder.fetch_options(fo);
builder.fetch_options(fo).with_checkout(checkout_builder);
tracing::debug!(
url,
@@ -54,7 +81,7 @@ impl GitProvider for LocalGitProvider {
async fn create_branch(
&self,
repo: Arc<Mutex<Repository>>,
branch: &GitPushBranch,
branch_name: &String,
) -> eyre::Result<()> {
let repo = repo.lock().await;
@@ -64,7 +91,7 @@ impl GitProvider for LocalGitProvider {
.ok_or(eyre::anyhow!("could not get access to target commit"))?;
let head_commit = repo.find_commit(head_commit_oid)?;
let newbranch = repo.branch(
&branch.name.to_lowercase().replace(" ", "-"),
&branch_name.to_lowercase().replace(" ", "-"),
&head_commit,
true,
)?;
@@ -82,13 +109,23 @@ impl GitProvider for LocalGitProvider {
async fn push_branch(
&self,
repo: Arc<Mutex<Repository>>,
branch: &GitPushBranch,
branch_name: &String,
) -> eyre::Result<()> {
let repo = repo.lock().await;
let options = self.options.clone();
tracing::trace!("pulling signature from local git");
let signature = repo.signature()?;
for rev in repo.revwalk()? {
let rev = rev?;
let commit = repo.find_commit(rev)?;
let summary = commit
.summary()
.ok_or(eyre::anyhow!("could not find commit"))?;
tracing::info!(summary, "summary")
}
tracing::trace!("fetching index and adding changed files to working tree");
let mut index = repo.index()?;
index.add_all(&["."], git2::IndexAddOption::DEFAULT, None)?;
@@ -104,10 +141,10 @@ impl GitProvider for LocalGitProvider {
tracing::trace!("writing commit object");
repo.commit(
None,
Some("HEAD"),
&signature,
&signature,
branch.name.to_lowercase().replace(" ", "-").as_str(),
branch_name.to_lowercase().replace(" ", "-").as_str(),
&tree,
&[&parents],
)?;
@@ -121,7 +158,19 @@ impl GitProvider for LocalGitProvider {
let mut remote_callbacks = RemoteCallbacks::new();
remote_callbacks.credentials(|url, username_from_url, _allowed_types| {
tracing::debug!(username_from_url, url, "pulling key from ssh-agent");
Cred::ssh_key_from_agent(username_from_url.unwrap())
if let Some(auth) = &options.http_auth {
tracing::trace!(auth, "authenticating");
let (user, pass) = auth
.split_once(":")
.ok_or("http_auth is not formatted correctly")
.unwrap();
Cred::userpass_plaintext(user, pass)
} else {
let username = username_from_url.unwrap();
Cred::ssh_key_from_agent(username)
}
});
let mut push_options = PushOptions::new();

View File

@@ -1,7 +1,76 @@
pub struct DefaultGiteaClient {}
use std::sync::Arc;
use async_trait::async_trait;
use gitea_client::{builder::GiteaClientBuilder, models::CreatePullRequestOption};
use super::GiteaClient;
pub struct DefaultGiteaClientOptions {
pub url: String,
pub basicauth: Option<String>,
}
pub struct DefaultGiteaClient {
gitea_client: Arc<gitea_client::client::GiteaClient>,
}
impl DefaultGiteaClient {
pub fn new() -> Self {
Self {}
pub fn new(options: &DefaultGiteaClientOptions) -> Self {
let mut gitea = GiteaClientBuilder::new().set_base_path(&options.url);
if let Some(basicauth) = options.basicauth.clone() {
if let Some((username, password)) = basicauth.split_once(":") {
gitea = gitea.set_basic_auth(username.into(), Some(password.into()));
}
}
Self {
gitea_client: Arc::new(gitea.build()),
}
}
}
#[async_trait]
impl GiteaClient for DefaultGiteaClient {
async fn get_clone_url(&self, owner: String, repo_name: String) -> eyre::Result<String> {
let repo = self
.gitea_client
.repository()
.get(&owner, &repo_name)
.await?;
let clone_url = repo
.ssh_url
.ok_or(eyre::anyhow!("clone_url is not set for repository"))?;
Ok(clone_url)
}
async fn create_pull_request(
&self,
owner: &String,
repo_name: &String,
pull_request_name: &String,
) -> eyre::Result<()> {
self.gitea_client
.repository()
.create_pull_request(
&owner,
&repo_name,
Some(CreatePullRequestOption {
assignee: None,
assignees: None,
base: Some("main".into()),
body: None,
due_date: None,
head: Some(pull_request_name.to_lowercase().replace(" ", "-")),
labels: None,
milestone: None,
title: Some(pull_request_name.clone()),
}),
)
.await?;
Ok(())
}
}

View File

@@ -1,17 +1,42 @@
pub mod client;
pub mod provider;
use std::sync::Arc;
use std::{path::PathBuf, sync::Arc};
use async_trait::async_trait;
use git2::Repository;
use tokio::sync::Mutex;
pub trait GiteaClient {}
use crate::schema::models::GitPushPullRequest;
#[async_trait]
pub trait GiteaClient {
async fn get_clone_url(&self, owner: String, repo_name: String) -> eyre::Result<String>;
async fn create_pull_request(
&self,
owner: &String,
repo_name: &String,
pull_request_name: &String,
) -> eyre::Result<()>;
}
pub type DynGiteaClient = Arc<dyn GiteaClient + Send + Sync>;
#[async_trait]
pub trait GiteaProvider {
async fn clone_from_qualified(repo: String) -> eyre::Result<String>;
async fn clone_from_qualified(&self, repo: String) -> eyre::Result<(PathBuf, Repository)>;
async fn create_branch(
&self,
repo: Arc<Mutex<Repository>>,
branch: &GitPushPullRequest,
) -> eyre::Result<()>;
async fn create_pull_request(
&self,
repo: Arc<Mutex<Repository>>,
repo_name: &String,
pull_request: &GitPushPullRequest,
) -> eyre::Result<()>;
}
pub type DynGiteaProvider = Arc<dyn GiteaProvider + Send + Sync>;

View File

@@ -1,12 +1,16 @@
use async_trait::async_trait;
use std::{path::PathBuf, sync::Arc};
use crate::{git::DynGitProvider, storage::DynStorageEngine};
use async_trait::async_trait;
use git2::Repository;
use tokio::sync::Mutex;
use crate::{git::DynGitProvider, schema::models::GitPushPullRequest, storage::DynStorageEngine};
use super::{DynGiteaClient, GiteaProvider};
pub struct DefaultGiteaProvider {
git_provider: DynGitProvider,
storage_engine: DynStorageEngine,
_storage_engine: DynStorageEngine,
gitea_client: DynGiteaClient,
}
@@ -18,7 +22,7 @@ impl DefaultGiteaProvider {
) -> Self {
Self {
git_provider,
storage_engine,
_storage_engine: storage_engine,
gitea_client,
}
}
@@ -26,7 +30,50 @@ impl DefaultGiteaProvider {
#[async_trait]
impl GiteaProvider for DefaultGiteaProvider {
async fn clone_from_qualified(repo: String) -> eyre::Result<String> {
todo!()
async fn clone_from_qualified(&self, repo: String) -> eyre::Result<(PathBuf, Repository)> {
let (owner, repo_name) = repo
.split_once("/")
.ok_or(eyre::anyhow!("repo is not a valid format"))?;
let clone_url = self
.gitea_client
.get_clone_url(owner.into(), repo_name.into())
.await?;
let (path, repo) = self.git_provider.clone_from_url(clone_url).await?;
Ok((path, repo))
}
async fn create_branch(
&self,
repo: Arc<Mutex<Repository>>,
pull_request: &GitPushPullRequest,
) -> eyre::Result<()> {
tracing::trace!("creating branch");
self.git_provider
.create_branch(repo, &pull_request.name)
.await
}
async fn create_pull_request(
&self,
repo: Arc<Mutex<Repository>>,
repo_name: &String,
pull_request: &GitPushPullRequest,
) -> eyre::Result<()> {
let (owner, repo_name) = repo_name
.split_once("/")
.ok_or(eyre::anyhow!("repo is not a valid format"))?;
tracing::trace!("push_branch");
self.git_provider
.push_branch(repo, &pull_request.name)
.await?;
tracing::trace!("create_pull_request");
self.gitea_client
.create_pull_request(&owner.into(), &repo_name.into(), &pull_request.name)
.await
}
}

View File

@@ -15,12 +15,12 @@ pub trait GitProvider {
async fn create_branch(
&self,
repo: Arc<Mutex<Repository>>,
branch: &GitPushBranch,
branch_name: &String,
) -> eyre::Result<()>;
async fn push_branch(
&self,
repo: Arc<Mutex<Repository>>,
branch: &GitPushBranch,
branch_name: &String,
) -> eyre::Result<()>;
}

View File

@@ -25,12 +25,14 @@ pub struct Git {
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct GitHubPush {
pub branch: GitPushPullRequest,
#[serde(rename = "pull-request")]
pub pull_request: GitPushPullRequest,
}
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct GiteaPush {
pub branch: GitPushPullRequest,
#[serde(rename = "pull-request")]
pub pull_request: GitPushPullRequest,
}
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]

View File

@@ -43,7 +43,7 @@ pub async fn execute_shell(cmd: String, path: Option<PathBuf>) -> eyre::Result<(
});
while let Some(line) = reader.next_line().await? {
tracing::trace!("something: {}", line)
tracing::trace!("{}", line)
}
Ok(())