diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2020-12-07 18:28:06 +0100 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2020-12-07 18:51:31 +0100 |
commit | dd763e4635f74c52592ff27571e25a4c36d5210e (patch) | |
tree | d899c3503036a9be0293b11421f17b65ceded249 | |
parent | dcc9d0713b08090bc386e4124144b6c94829b618 (diff) |
Add script helpers
This patch adds script helpers, so that we do not have to write out
echo "#BUTIDO:STATE:OK:succeeded"
but can write
{{state "OK"}}
for example.
Three helpers were added, for progress, state and phase.
These can be only used in bash scripts for now.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r-- | examples/packages/example_3/pkg.toml | 17 | ||||
-rw-r--r-- | src/package/script.rs | 73 |
2 files changed, 81 insertions, 9 deletions
diff --git a/examples/packages/example_3/pkg.toml b/examples/packages/example_3/pkg.toml index c8cd1cf..f908065 100644 --- a/examples/packages/example_3/pkg.toml +++ b/examples/packages/example_3/pkg.toml @@ -32,33 +32,34 @@ unpack.script = ''' # repo where we prepare a build container. # This is, of course, not be the way it would be done in a real-world scenario! depinst.script = ''' - echo "#BUTIDO:PHASE:depinst" - echo "#BUTIDO:PROGRESS:0" + {{phase "depinst"}} + {{progress 0}} for n in {1..10}; do sleep 0.1; done - echo "#BUTIDO:PROGRESS:10" + {{progress 10}} ''' configure.script = ''' - echo "#BUTIDO:PHASE:configure-preparing" + {{phase "configure-preparing"}} for n in {1..10}; do sleep 0.1; done - echo "#BUTIDO:PROGRESS:20" + {{progress 20}} for n in {1..10}; do sleep 0.1; done ''' build.script = ''' - echo "#BUTIDO:PHASE:build" + {{phase "build"}} for n in {1..10}; do sleep 0.1; done echo "#BUTIDO:PROGRESS:60" + {{progress 60}} ''' install.script = ''' - echo "#BUTIDO:PHASE:install" + {{phase "install"}} for n in {1..10}; do sleep 0.1; done - echo "#BUTIDO:PROGRESS:80" + {{progress 80}} ''' diff --git a/src/package/script.rs b/src/package/script.rs index 968f364..06e1602 100644 --- a/src/package/script.rs +++ b/src/package/script.rs @@ -1,6 +1,6 @@ use anyhow::Error; use anyhow::Result; -use handlebars::Handlebars; +use handlebars::{Handlebars, HelperDef, RenderContext, Helper, Context, JsonRender, HelperResult, Output, RenderError}; use serde::Deserialize; use serde::Serialize; @@ -85,7 +85,78 @@ impl<'a> ScriptBuilder<'a> { fn interpolate_package(script: String, package: &Package, strict_mode: bool) -> Result<String> { let mut hb = Handlebars::new(); hb.register_template_string("script", script)?; + hb.register_helper("phase", Box::new(PhaseHelper)); + hb.register_helper("state", Box::new(StateHelper)); + hb.register_helper("progress", Box::new(ProgressHelper)); hb.set_strict_mode(strict_mode); hb.render("script", package).map_err(Error::from) } } + +#[derive(Clone, Copy)] +struct PhaseHelper; + +impl HelperDef for PhaseHelper { + fn call<'reg: 'rc, 'rc>(&self, h: &Helper, _: &Handlebars, _: &Context, _rc: &mut RenderContext, out: &mut dyn Output) -> HelperResult { + h.param(0) + .ok_or_else(|| RenderError::new("Required parameter missing: phase name"))? + .value() + .as_str() + .ok_or_else(|| RenderError::new("Required parameter must be a string: phase name")) + .and_then(|phase_name| { + out.write("echo '#BUTIDO:PHASE:")?; + out.write(phase_name)?; + out.write("'\n")?; + Ok(()) + }) + } +} + +#[derive(Clone, Copy)] +struct StateHelper; + +impl HelperDef for StateHelper { + fn call<'reg: 'rc, 'rc>(&self, h: &Helper, _: &Handlebars, _: &Context, _rc: &mut RenderContext, out: &mut dyn Output) -> HelperResult { + let state_msg = h.param(1).ok_or_else(|| RenderError::new("Required parameter missing: state message"))?; + h.param(0) + .ok_or_else(|| RenderError::new("Required parameter missing: state"))? + .value() + .as_str() + .ok_or_else(|| RenderError::new("Required parameter must be a string: state")) + .and_then(|state| match state { + "OK" => { + out.write("echo '#BUTIDO:STATE:OK:")?; + out.write(state_msg.value().render().as_ref())?; + out.write("'\n")?; + Ok(()) + }, + "ERR" => { + out.write("echo '#BUTIDO:STATE:ERR:")?; + out.write(state_msg.value().render().as_ref())?; + out.write("'\n")?; + Ok(()) + }, + other => Err(RenderError::new(format!("Parameter must bei either 'OK' or 'ERR', '{}' is invalid", other))), + }) + } +} + +#[derive(Clone, Copy)] +struct ProgressHelper; + +impl HelperDef for ProgressHelper { + fn call<'reg: 'rc, 'rc>(&self, h: &Helper, _: &Handlebars, _: &Context, _rc: &mut RenderContext, out: &mut dyn Output) -> HelperResult { + h.param(0) + .ok_or_else(|| RenderError::new("Required parameter missing: progress"))? + .value() + .as_i64() + .ok_or_else(|| RenderError::new("Required parameter must be a number: progress")) + .and_then(|progress| { + out.write("echo '#BUTIDO:PROGRESS:")?; + out.write(&progress.to_string())?; + out.write("'\n")?; + Ok(()) + }) + } +} + |