pub mod deployer;
use steps::{Step, core::*, git::*, rollback::*};
use config::steps::{StepConfig, StepPosition::*};
use std::cell::RefCell;
pub struct Recipe {
pub name : String,
pub steps: Vec<Box<Step>>,
pub rollback_steps: Vec<Box<Step>>
}
impl Recipe {
pub fn build() -> RecipeBuilder {
RecipeBuilder {
recipe: Some(RefCell::new(Recipe::default()))
}
}
fn get_step_index(&self, step_name: &str) -> Option<usize> {
let mut node_index: Option<usize> = None;
let mut index: usize = 0;
for step in &self.steps {
if step.get_name() == step_name {
node_index = Some(index);
break;
}
index += 1;
}
node_index
}
}
impl Default for Recipe {
fn default() -> Recipe {
Recipe {
name: "Anonymous Recipe".into(),
steps: Vec::new(),
rollback_steps: Vec::new()
}
}
}
pub struct RecipeBuilder {
recipe: Option<RefCell<Recipe>>
}
impl RecipeBuilder {
pub fn name(&mut self, name: &str) -> &mut Self {
if let Some(ref mut recipe) = self.recipe {
recipe.borrow_mut().name = name.into()
}
self
}
pub fn with_core_steps(&mut self) -> &mut Self {
if let Some(ref mut recipe) = self.recipe {
let mut recipe_ref = recipe.borrow_mut();
recipe_ref.steps.push(Box::new(InitStep));
recipe_ref.steps.push(Box::new(GitClone));
recipe_ref.steps.push(Box::new(LinkFiles));
recipe_ref.steps.push(Box::new(LinkDirs));
recipe_ref.steps.push(Box::new(SymlinkCurrent));
recipe_ref.steps.push(Box::new(CleanUpReleases));
}
self
}
pub fn with_core_rollback_steps(&mut self) -> &mut Self {
if let Some(ref mut recipe) = self.recipe {
let mut recipe_ref = recipe.borrow_mut();
recipe_ref.rollback_steps.push(Box::new(CanRollBack));
recipe_ref.rollback_steps.push(Box::new(RemoveCurrentRelease));
recipe_ref.rollback_steps.push(Box::new(SymlinkPreviousRelease));
}
self
}
pub fn with_config_steps(&mut self, config_steps: Vec<StepConfig>) -> &mut Self {
if let Some(ref mut recipe) = self.recipe {
for step_config in config_steps.into_iter() {
let mut step_index = recipe.borrow().get_step_index(&step_config.ref_step)
.expect(&format!("Step '{}' doesn't exist in the recipe", &step_config.ref_step));
if let After = step_config.position { step_index += 1 };
recipe.borrow_mut().steps.insert(step_index, Box::new(RawCmdStep::from(step_config)));
};
}
self
}
pub fn with_step_after<T: 'static + Step>(&mut self, subject_name: &str, extra_step: T) -> &mut Self {
if let Some(ref mut recipe) = self.recipe {
let step_index = recipe.borrow().get_step_index(subject_name)
.expect(&format!("Step '{}' doesn't exist in the recipe", subject_name));
recipe.borrow_mut().steps.insert(step_index + 1, Box::new(extra_step));
}
self
}
pub fn with_step_before<T: 'static + Step>(&mut self, subject_name: &str, extra_step: T) -> &mut Self {
if let Some(ref mut recipe) = self.recipe {
let step_index = recipe.borrow().get_step_index(subject_name)
.expect(&format!("Step '{}' doesn't exist in the recipe", subject_name));
recipe.borrow_mut().steps.insert(step_index, Box::new(extra_step));
}
self
}
pub fn finish(&mut self) -> Recipe {
let recipe = self.recipe.take().expect("Cannot reuse recipe builder");
recipe.into_inner()
}
}