with builder

This commit is contained in:
2022-11-22 23:12:10 +01:00
parent b7a0e0b96e
commit 367fa16fd7
12 changed files with 254 additions and 13 deletions

View File

@@ -0,0 +1,36 @@
use std::{path::PathBuf, sync::Arc};
use async_trait::async_trait;
use crate::schema::models::Action;
use super::{
builders::golang_bin::{GolangBinBuild, GolangBinBuildOpts},
Builder, DynRunnableBin,
};
pub struct BuilderCapabilities;
impl BuilderCapabilities {
pub fn new() -> Self {
Self {}
}
}
#[async_trait]
impl Builder for BuilderCapabilities {
async fn build(&self, action_path: PathBuf, action: Action) -> eyre::Result<DynRunnableBin> {
match action {
Action::Go { entry } => {
let bin = GolangBinBuild::new()
.build(GolangBinBuildOpts {
entry,
src_path: action_path,
})
.await?;
Ok(Arc::new(bin))
}
}
}
}

View File

@@ -0,0 +1,55 @@
use std::path::PathBuf;
use async_trait::async_trait;
use crate::{
builder::RunnableBin,
shell::{execute_shell, print_res},
};
pub struct GolangBinBuildOpts {
pub entry: String,
pub src_path: PathBuf,
}
pub struct GolangBinBuild;
impl GolangBinBuild {
pub fn new() -> Self {
Self {}
}
pub async fn build(&self, opts: GolangBinBuildOpts) -> eyre::Result<GolangBin> {
tracing::trace!(
src = opts.src_path.to_string_lossy().to_string(),
entry = opts.entry,
"build golang_bin"
);
let res = execute_shell(
format!("go build {}", opts.entry),
Some(opts.src_path.clone()),
)
.await?;
print_res("golang_bin".into(), res);
Ok(GolangBin::new(opts.src_path))
}
}
pub struct GolangBin {
path: PathBuf,
}
impl GolangBin {
fn new(path: PathBuf) -> Self {
Self { path }
}
}
#[async_trait]
impl RunnableBin for GolangBin {
async fn run(&self) -> eyre::Result<()> {
todo!("not implemented")
}
}

View File

@@ -0,0 +1 @@
pub mod golang_bin;

View File

@@ -0,0 +1,22 @@
pub mod builder_capabilities;
mod builders;
use std::{path::PathBuf, sync::Arc};
use async_trait::async_trait;
use crate::schema::models::Action;
#[async_trait]
pub trait RunnableBin {
async fn run(&self) -> eyre::Result<()>;
}
pub type DynRunnableBin = Arc<dyn RunnableBin + Send + Sync>;
#[async_trait]
pub trait Builder {
async fn build(&self, action_path: PathBuf, action: Action) -> eyre::Result<DynRunnableBin>;
}
pub type DynBuilder = Arc<dyn Builder + Send + Sync>;

View File

@@ -1,16 +1,43 @@
use std::path::PathBuf;
use async_trait::async_trait;
use crate::schema::models::Action;
use crate::{builder::DynBuilder, schema::models::Action};
use super::executor::Executor;
use super::{
executor::Executor,
executors::golang::{GolangExecutor, GolangExecutorOpts},
};
pub struct DefaultExecutor;
pub struct DefaultExecutor {
builder: DynBuilder,
}
impl DefaultExecutor {
pub fn new(builder: DynBuilder) -> Self {
Self { builder }
}
}
#[async_trait]
impl Executor for DefaultExecutor {
async fn execute(&self, action: Action) -> eyre::Result<()> {
async fn execute(
&self,
victim_path: PathBuf,
action_path: PathBuf,
action: Action,
) -> eyre::Result<()> {
let bin = self.builder.build(action_path, action.clone()).await?;
match action {
Action::Go { entry } => todo!(),
Action::Go { entry } => {
GolangExecutor::new()
.execute(GolangExecutorOpts {
bin,
entry,
src_path: victim_path,
})
.await?
}
}
Ok(())

View File

@@ -1,4 +1,4 @@
use std::sync::Arc;
use std::{path::PathBuf, sync::Arc};
use async_trait::async_trait;
@@ -6,7 +6,12 @@ use crate::schema::models::Action;
#[async_trait]
pub trait Executor {
async fn execute(&self, action: Action) -> eyre::Result<()>;
async fn execute(
&self,
victim_path: PathBuf,
action_path: PathBuf,
action: Action,
) -> eyre::Result<()>;
}
pub type DynExecutor = Arc<dyn Executor + Send + Sync>;

View File

@@ -0,0 +1,21 @@
use std::path::PathBuf;
use crate::builder::DynRunnableBin;
pub struct GolangExecutorOpts {
pub bin: DynRunnableBin,
pub entry: String,
pub src_path: PathBuf,
}
pub struct GolangExecutor;
impl GolangExecutor {
pub fn new() -> Self {
Self {}
}
pub async fn execute(&self, opts: GolangExecutorOpts) -> eyre::Result<()> {
Ok(())
}
}

View File

@@ -1,4 +1,6 @@
pub mod git;
pub mod storage;
pub mod schema;
pub mod builder;
pub mod executor;
pub mod git;
pub mod schema;
mod shell;
pub mod storage;

View File

@@ -0,0 +1,57 @@
use std::{path::PathBuf, process::Stdio};
use eyre::Context;
use tokio::io::{AsyncBufReadExt, BufReader};
pub async fn execute_shell(cmd: String, path: Option<PathBuf>) -> eyre::Result<Vec<String>> {
let mut command = tokio::process::Command::new("sh");
let command = command.arg("-c");
let command = if let Some(path) = path {
command.current_dir(path)
} else {
command
};
let command = command.arg(format!("{}", cmd));
let command = command.stdout(Stdio::piped());
let mut child = command.spawn()?;
let stdout = child
.stdout
.take()
.ok_or(eyre::anyhow!("could not take stdout of command"))?;
let mut reader = BufReader::new(stdout).lines();
tokio::spawn(async move {
let status = child
.wait()
.await
.context(eyre::anyhow!("child process encountered an error"))
.unwrap();
if !status.success() {
tracing::error!(
cmd,
status = status.to_string(),
"child program encountered an error"
);
}
});
let mut lines: Vec<String> = Vec::new();
while let Some(line) = reader.next_line().await? {
lines.push(line)
}
Ok(lines)
}
pub fn print_res(scope: String, res: Vec<String>) {
for r in res {
tracing::debug!("{}: {}", scope, r);
}
}