with builder
This commit is contained in:
parent
b7a0e0b96e
commit
367fa16fd7
BIN
_examples/actions/write_a_readme/main
Executable file
BIN
_examples/actions/write_a_readme/main
Executable file
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
use std::path::{self, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||
use octopush_core::schema::{self, models::Action};
|
||||
use octopush_core::schema;
|
||||
use octopush_infra::service_register::ServiceRegister;
|
||||
|
||||
pub fn execute_cmd() -> Command {
|
||||
@ -53,7 +53,14 @@ pub async fn execute_subcommand(args: &ArgMatches) -> eyre::Result<()> {
|
||||
paths.push(path);
|
||||
}
|
||||
|
||||
kk
|
||||
for path in paths {
|
||||
for action in actions.clone() {
|
||||
service_register
|
||||
.executor
|
||||
.execute(path.clone(), action_path.clone(), action)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
36
crates/octopush_core/src/builder/builder_capabilities.rs
Normal file
36
crates/octopush_core/src/builder/builder_capabilities.rs
Normal 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
55
crates/octopush_core/src/builder/builders/golang_bin.rs
Normal file
55
crates/octopush_core/src/builder/builders/golang_bin.rs
Normal 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")
|
||||
}
|
||||
}
|
1
crates/octopush_core/src/builder/builders/mod.rs
Normal file
1
crates/octopush_core/src/builder/builders/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod golang_bin;
|
22
crates/octopush_core/src/builder/mod.rs
Normal file
22
crates/octopush_core/src/builder/mod.rs
Normal 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>;
|
@ -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(())
|
||||
|
@ -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>;
|
||||
|
@ -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(())
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
57
crates/octopush_core/src/shell/mod.rs
Normal file
57
crates/octopush_core/src/shell/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use octopush_core::{
|
||||
builder::{builder_capabilities::BuilderCapabilities, DynBuilder},
|
||||
executor::{default_executor::DefaultExecutor, executor::DynExecutor},
|
||||
git::{github::GitHubGitProvider, DynGitProvider},
|
||||
schema::parser::{DefaultSchemaParser, DynSchemaParser},
|
||||
storage::{local::LocalStorageEngine, DynStorageEngine},
|
||||
@ -10,6 +12,8 @@ pub struct ServiceRegister {
|
||||
pub storage_engine: DynStorageEngine,
|
||||
pub git_provider: DynGitProvider,
|
||||
pub schema_parser: DynSchemaParser,
|
||||
pub builder: DynBuilder,
|
||||
pub executor: DynExecutor,
|
||||
}
|
||||
|
||||
impl ServiceRegister {
|
||||
@ -17,11 +21,15 @@ impl ServiceRegister {
|
||||
let storage_engine = Arc::new(LocalStorageEngine::new("/tmp/octopush".into()));
|
||||
let git_provider = Arc::new(GitHubGitProvider::new(storage_engine.clone()));
|
||||
let schema_parser = Arc::new(DefaultSchemaParser::new());
|
||||
let builder = Arc::new(BuilderCapabilities::new());
|
||||
let executor = Arc::new(DefaultExecutor::new(builder.clone()));
|
||||
|
||||
Self {
|
||||
storage_engine,
|
||||
git_provider,
|
||||
schema_parser,
|
||||
builder,
|
||||
executor,
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user