summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2020-12-07 18:28:06 +0100
committerMatthias Beyer <mail@beyermatthias.de>2020-12-07 18:51:31 +0100
commitdd763e4635f74c52592ff27571e25a4c36d5210e (patch)
treed899c3503036a9be0293b11421f17b65ceded249
parentdcc9d0713b08090bc386e4124144b6c94829b618 (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.toml17
-rw-r--r--src/package/script.rs73
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(())
+ })
+ }
+}
+