Skip to content

Commit

Permalink
Merge pull request #2 from loco-rs/plan-ctx
Browse files Browse the repository at this point in the history
add plan ctx
  • Loading branch information
kaplanelad authored Oct 20, 2024
2 parents 45f7db2 + c03996d commit c5bb0be
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 26 deletions.
16 changes: 7 additions & 9 deletions examples/run.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crazy_train::{
step::{Plan, StepTrait},
step::{Plan, PlanCtx, StepTrait},
Result, StringDef,
};
use serde::{Deserialize, Serialize};
Expand All @@ -10,15 +10,14 @@ struct StepOne {}
impl StepTrait for StepOne {
fn plan(&self, randomizer: &crazy_train::Randomizer) -> Result<crazy_train::step::Plan> {
let eco_string = randomizer.string(StringDef::default()).to_string();
Ok(Plan {
id: std::any::type_name::<Self>().to_string(),
command: format!("echo {eco_string}"),
})

Ok(Plan::new::<Self>(format!("echo {eco_string}")))
}

fn is_success(
&self,
execution_result: &crazy_train::executer::Output,
_plan_ctx: &PlanCtx,
) -> Result<bool, &'static str> {
if execution_result.status_code == Some(0) {
Ok(true)
Expand All @@ -38,15 +37,14 @@ struct StepTwo {}
impl StepTrait for StepTwo {
fn plan(&self, randomizer: &crazy_train::Randomizer) -> Result<crazy_train::step::Plan> {
let eco_string = randomizer.string(StringDef::default()).to_string();
Ok(Plan {
id: std::any::type_name::<Self>().to_string(),
command: format!("unknown-command {eco_string}"),
})

Ok(Plan::new::<Self>(format!("unknown-command {eco_string}")))
}

fn is_success(
&self,
execution_result: &crazy_train::executer::Output,
_plan_ctx: &PlanCtx,
) -> Result<bool, &'static str> {
if execution_result.status_code == Some(0) {
Err("expected failure command")
Expand Down
51 changes: 35 additions & 16 deletions src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,13 @@ impl Runner {
"{}",
format!("Execute plan finished in {:?}", start.elapsed()).yellow()
);
let is_success = step.is_success(&result).map_err(|err| Error::StepError {
kind: step::Kind::Plan,
description: err.to_string(),
command_output: result,
})?;
let is_success =
step.is_success(&result, &step_plan.ctx)
.map_err(|err| Error::StepError {
kind: step::Kind::Plan,
description: err.to_string(),
command_output: result,
})?;

if !is_success {
continue;
Expand Down Expand Up @@ -156,9 +158,10 @@ impl Runner {
#[cfg(test)]
mod tests {

use std::path::PathBuf;
use std::{collections::HashMap, path::PathBuf};

use serde::{Deserialize, Serialize};
use step::PlanCtx;

use super::*;
use crate::{executer::Output, generator::StringDef, step::Plan};
Expand All @@ -180,16 +183,28 @@ mod tests {

fn plan(&self, randomizer: &Randomizer) -> Result<Plan> {
let eco_string = randomizer.string(StringDef::default()).to_string();
Ok(Plan {
id: std::any::type_name::<Self>().to_string(),
command: format!(
Ok(Plan::with_vars::<Self>(
format!(
"echo {eco_string} >> {}",
self.location.join("test.txt").display()
),
})
HashMap::from([("foo".to_string(), "bar".to_string())]),
))
}

fn is_success(&self, execution_result: &Output) -> Result<bool, &'static str> {
fn is_success(
&self,
execution_result: &Output,
plan_ctx: &PlanCtx,
) -> Result<bool, &'static str> {
if let Some(foo_var) = plan_ctx.vars.get("foo") {
if foo_var != "bar" {
return Err("foo value should be equal to var");
}
} else {
return Err("foo plan ctx var not found");
};

if execution_result.status_code == Some(0) {
Ok(true)
} else {
Expand Down Expand Up @@ -223,16 +238,20 @@ mod tests {

fn plan(&self, randomizer: &Randomizer) -> Result<Plan> {
let eco_string = randomizer.string(StringDef::default()).to_string();
Ok(Plan {
id: std::any::type_name::<Self>().to_string(),
command: format!(
Ok(Plan::with_vars::<Self>(
format!(
"cat {eco_string} >> {}",
self.location.join("test.txt").display()
),
})
HashMap::from([("foo".to_string(), "bar".to_string())]),
))
}

fn is_success(&self, execution_result: &Output) -> Result<bool, &'static str> {
fn is_success(
&self,
execution_result: &Output,
_plan_ctx: &PlanCtx,
) -> Result<bool, &'static str> {
if execution_result.status_code == Some(1) {
Ok(true)
} else {
Expand Down
32 changes: 31 additions & 1 deletion src/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
//! which encapsulates a command to be executed as part of a step.
//!

use std::collections::HashMap;

use crate::{
errors,
executer::{self, Output},
Expand Down Expand Up @@ -42,7 +44,11 @@ pub trait StepTrait {
///
/// # Errors
/// When plan result parsing is not the expected behavior.
fn is_success(&self, execution_result: &Output) -> Result<bool, &'static str>;
fn is_success(
&self,
execution_result: &Output,
plan_ctx: &PlanCtx,
) -> Result<bool, &'static str>;

/// Optionally returns a command to run as a check after the execution of the plan.
fn run_check(&self) -> Option<String> {
Expand All @@ -63,6 +69,12 @@ pub trait StepTrait {
pub struct Plan {
pub id: String,
pub command: String,
pub ctx: PlanCtx,
}

#[derive(Default, Debug, Clone)]
pub struct PlanCtx {
pub vars: HashMap<String, String>,
}

impl Plan {
Expand All @@ -74,4 +86,22 @@ impl Plan {
pub fn execute(&self) -> errors::Result<executer::Output> {
executer::run_sh(&self.command)
}

#[must_use]
pub fn new<T>(command: impl Into<String>) -> Self {
Self {
id: std::any::type_name::<T>().to_string(),
command: command.into(),
ctx: PlanCtx::default(),
}
}

#[must_use]
pub fn with_vars<T>(command: impl Into<String>, vars: HashMap<String, String>) -> Self {
Self {
id: std::any::type_name::<T>().to_string(),
command: command.into(),
ctx: PlanCtx { vars },
}
}
}

0 comments on commit c5bb0be

Please sign in to comment.