fix commit
This commit is contained in:
@@ -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 }
|
||||
|
@@ -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?
|
||||
|
@@ -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();
|
||||
|
@@ -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(())
|
||||
}
|
||||
}
|
||||
|
@@ -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>;
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
|
@@ -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<()>;
|
||||
}
|
||||
|
||||
|
@@ -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)]
|
||||
|
@@ -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(())
|
||||
|
Reference in New Issue
Block a user