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 clap::{Arg, ArgAction, ArgMatches, Command};
|
||||||
use octopush_core::schema::{self, models::Action};
|
use octopush_core::schema;
|
||||||
use octopush_infra::service_register::ServiceRegister;
|
use octopush_infra::service_register::ServiceRegister;
|
||||||
|
|
||||||
pub fn execute_cmd() -> Command {
|
pub fn execute_cmd() -> Command {
|
||||||
@ -53,7 +53,14 @@ pub async fn execute_subcommand(args: &ArgMatches) -> eyre::Result<()> {
|
|||||||
paths.push(path);
|
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 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]
|
#[async_trait]
|
||||||
impl Executor for DefaultExecutor {
|
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 {
|
match action {
|
||||||
Action::Go { entry } => todo!(),
|
Action::Go { entry } => {
|
||||||
|
GolangExecutor::new()
|
||||||
|
.execute(GolangExecutorOpts {
|
||||||
|
bin,
|
||||||
|
entry,
|
||||||
|
src_path: victim_path,
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::sync::Arc;
|
use std::{path::PathBuf, sync::Arc};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
@ -6,7 +6,12 @@ use crate::schema::models::Action;
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait Executor {
|
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>;
|
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 builder;
|
||||||
pub mod storage;
|
|
||||||
pub mod schema;
|
|
||||||
pub mod executor;
|
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 std::sync::Arc;
|
||||||
|
|
||||||
use octopush_core::{
|
use octopush_core::{
|
||||||
|
builder::{builder_capabilities::BuilderCapabilities, DynBuilder},
|
||||||
|
executor::{default_executor::DefaultExecutor, executor::DynExecutor},
|
||||||
git::{github::GitHubGitProvider, DynGitProvider},
|
git::{github::GitHubGitProvider, DynGitProvider},
|
||||||
schema::parser::{DefaultSchemaParser, DynSchemaParser},
|
schema::parser::{DefaultSchemaParser, DynSchemaParser},
|
||||||
storage::{local::LocalStorageEngine, DynStorageEngine},
|
storage::{local::LocalStorageEngine, DynStorageEngine},
|
||||||
@ -10,6 +12,8 @@ pub struct ServiceRegister {
|
|||||||
pub storage_engine: DynStorageEngine,
|
pub storage_engine: DynStorageEngine,
|
||||||
pub git_provider: DynGitProvider,
|
pub git_provider: DynGitProvider,
|
||||||
pub schema_parser: DynSchemaParser,
|
pub schema_parser: DynSchemaParser,
|
||||||
|
pub builder: DynBuilder,
|
||||||
|
pub executor: DynExecutor,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServiceRegister {
|
impl ServiceRegister {
|
||||||
@ -17,11 +21,15 @@ impl ServiceRegister {
|
|||||||
let storage_engine = Arc::new(LocalStorageEngine::new("/tmp/octopush".into()));
|
let storage_engine = Arc::new(LocalStorageEngine::new("/tmp/octopush".into()));
|
||||||
let git_provider = Arc::new(GitHubGitProvider::new(storage_engine.clone()));
|
let git_provider = Arc::new(GitHubGitProvider::new(storage_engine.clone()));
|
||||||
let schema_parser = Arc::new(DefaultSchemaParser::new());
|
let schema_parser = Arc::new(DefaultSchemaParser::new());
|
||||||
|
let builder = Arc::new(BuilderCapabilities::new());
|
||||||
|
let executor = Arc::new(DefaultExecutor::new(builder.clone()));
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
storage_engine,
|
storage_engine,
|
||||||
git_provider,
|
git_provider,
|
||||||
schema_parser,
|
schema_parser,
|
||||||
|
builder,
|
||||||
|
executor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user