use sigil_stitch::lang::bash::Bash;
use sigil_stitch::prelude::*;
fn main() {
println!("=== Builder API ===\n");
let builder_output = builder_approach();
println!("{builder_output}");
println!("=== sigil_quote! Macro ===\n");
let macro_output = macro_approach();
println!("{macro_output}");
}
fn builder_approach() -> String {
let utils = TypeName::importable("./utils.sh", "");
let mut log_body = CodeBlock::builder();
log_body.add("local level=$1", ());
log_body.add_line();
log_body.add("local message=$2", ());
log_body.add_line();
log_body.add("echo \"[$level] $(date): $message\"", ());
let log_fn = FunSpec::builder("log_message")
.body(log_body.build().unwrap())
.build()
.unwrap();
let mut deploy_body = CodeBlock::builder();
deploy_body.add("local env=$1", ());
deploy_body.add_line();
deploy_body.add_line();
deploy_body.add("%<", ());
deploy_body.add("if [ -z \"$env\" ]; then", ());
deploy_body.add_line();
deploy_body.add("%>", ());
deploy_body.add("log_message \"ERROR\" \"No environment specified\"", ());
deploy_body.add_line();
deploy_body.add("return 1", ());
deploy_body.add_line();
deploy_body.add("%<", ());
deploy_body.add("fi", ());
deploy_body.add_line();
deploy_body.add("%>", ());
deploy_body.add_line();
deploy_body.add("log_message \"INFO\" \"Deploying to $env\"", ());
deploy_body.add_line();
deploy_body.add_line();
deploy_body.add("%<", ());
deploy_body.add("for service in api worker scheduler; do", ());
deploy_body.add_line();
deploy_body.add("%>", ());
deploy_body.add("log_message \"INFO\" \"Starting $service\"", ());
deploy_body.add_line();
deploy_body.add("%<", ());
deploy_body.add("done", ());
deploy_body.add_line();
deploy_body.add("%>", ());
let deploy_fn = FunSpec::builder("deploy")
.doc("Deploy services to the given environment.")
.body(deploy_body.build().unwrap())
.build()
.unwrap();
let trigger = CodeBlock::of("# %T", (utils,)).unwrap();
FileSpec::builder_with("deploy.bash", Bash::new())
.header(CodeBlock::of("#!/usr/bin/env bash\nset -euo pipefail", ()).unwrap())
.add_code(trigger)
.add_function(log_fn)
.add_function(deploy_fn)
.build()
.unwrap()
.render(80)
.unwrap()
}
fn macro_approach() -> String {
let utils = TypeName::importable("./utils.sh", "");
let log_body = sigil_quote!(Bash {
local level=$$1
local message=$$2
echo $S("[$level] $(date): $message")
})
.unwrap();
let log_fn = FunSpec::builder("log_message")
.body(log_body)
.build()
.unwrap();
let mut deploy_body = CodeBlock::builder();
deploy_body.add("local env=$1", ());
deploy_body.add_line();
deploy_body.add_line();
deploy_body.begin_control_flow("if [ -z \"$env\" ];", ());
deploy_body.add("log_message \"ERROR\" \"No environment specified\"", ());
deploy_body.add_line();
deploy_body.add("return 1", ());
deploy_body.add_line();
deploy_body.end_control_flow();
deploy_body.add_line();
deploy_body.add("log_message \"INFO\" \"Deploying to $env\"", ());
deploy_body.add_line();
deploy_body.add_line();
deploy_body.begin_control_flow("for service in api worker scheduler;", ());
deploy_body.add("log_message \"INFO\" \"Starting $service\"", ());
deploy_body.add_line();
deploy_body.end_control_flow();
let deploy_fn = FunSpec::builder("deploy")
.doc("Deploy services to the given environment.")
.body(deploy_body.build().unwrap())
.build()
.unwrap();
let trigger = CodeBlock::of("# %T", (utils,)).unwrap();
FileSpec::builder_with("deploy.bash", Bash::new())
.header(CodeBlock::of("#!/usr/bin/env bash\nset -euo pipefail", ()).unwrap())
.add_code(trigger)
.add_function(log_fn)
.add_function(deploy_fn)
.build()
.unwrap()
.render(80)
.unwrap()
}