use crate::ast::{
FileTrigger, FileTriggerKind, Interpreter, Scriptlet, ScriptletKind, Trigger, TriggerKind,
};
use super::deps::print_dep_expr;
use super::text::print_text;
use super::util::print_subpkg;
use super::{Printer, TokenKind};
pub(crate) fn print_scriptlet<T>(p: &mut Printer<'_>, s: &Scriptlet<T>) {
p.write_indent();
p.emit(TokenKind::SectionKeyword, scriptlet_keyword(s.kind));
print_subpkg(p, s.subpkg.as_ref());
print_interp(p, s.interp.as_ref());
if s.expand_macros {
p.raw(" -e");
}
if s.quiet {
p.raw(" -q");
}
if let Some(file) = &s.from_file {
p.raw(" -f ");
print_text(p, file);
}
p.newline();
print_shell_body(p, &s.body);
}
pub(crate) fn print_trigger<T>(p: &mut Printer<'_>, t: &Trigger<T>) {
p.write_indent();
p.emit(TokenKind::SectionKeyword, trigger_keyword(t.kind));
print_subpkg(p, t.subpkg.as_ref());
print_interp(p, t.interp.as_ref());
if !t.conditions.is_empty() {
p.raw(" --");
for (i, c) in t.conditions.iter().enumerate() {
if i == 0 {
p.raw_char(' ');
} else {
p.raw(", ");
}
print_dep_expr(p, c);
}
}
p.newline();
print_shell_body(p, &t.body);
}
pub(crate) fn print_file_trigger<T>(p: &mut Printer<'_>, ft: &FileTrigger<T>) {
p.write_indent();
p.emit(TokenKind::SectionKeyword, file_trigger_keyword(ft.kind));
print_subpkg(p, ft.subpkg.as_ref());
print_interp(p, ft.interp.as_ref());
if let Some(prio) = ft.priority {
p.raw(" -P ");
p.raw(&prio.to_string());
}
if !ft.prefixes.is_empty() {
p.raw(" --");
for (i, prefix) in ft.prefixes.iter().enumerate() {
if i == 0 {
p.raw_char(' ');
} else {
p.raw(", ");
}
print_text(p, prefix);
}
}
p.newline();
print_shell_body(p, &ft.body);
}
fn print_interp(p: &mut Printer<'_>, interp: Option<&Interpreter>) {
match interp {
Some(Interpreter::Lua) => p.raw(" -p <lua>"),
Some(Interpreter::Path(path)) => {
p.raw(" -p ");
print_text(p, path);
}
None => {}
}
}
fn print_shell_body(p: &mut Printer<'_>, body: &crate::ast::ShellBody) {
for line in &body.lines {
p.write_indent();
print_text(p, line);
p.newline();
}
}
fn scriptlet_keyword(k: ScriptletKind) -> &'static str {
match k {
ScriptletKind::Pre => "%pre",
ScriptletKind::Post => "%post",
ScriptletKind::Preun => "%preun",
ScriptletKind::Postun => "%postun",
ScriptletKind::Pretrans => "%pretrans",
ScriptletKind::Posttrans => "%posttrans",
ScriptletKind::Preuntrans => "%preuntrans",
ScriptletKind::Postuntrans => "%postuntrans",
}
}
fn trigger_keyword(k: TriggerKind) -> &'static str {
match k {
TriggerKind::Prein => "%triggerprein",
TriggerKind::In => "%triggerin",
TriggerKind::Un => "%triggerun",
TriggerKind::Postun => "%triggerpostun",
}
}
fn file_trigger_keyword(k: FileTriggerKind) -> &'static str {
match k {
FileTriggerKind::In => "%filetriggerin",
FileTriggerKind::Un => "%filetriggerun",
FileTriggerKind::Postun => "%filetriggerpostun",
FileTriggerKind::TransIn => "%transfiletriggerin",
FileTriggerKind::TransUn => "%transfiletriggerun",
FileTriggerKind::TransPostun => "%transfiletriggerpostun",
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ast::{DepAtom, DepExpr, ShellBody, SubpkgRef, Text};
use crate::printer::PrinterConfig;
fn render(s: &Scriptlet<()>) -> String {
let cfg = PrinterConfig::default();
let mut buf = String::new();
let mut p = Printer::new(&mut buf, &cfg);
print_scriptlet(&mut p, s);
buf
}
fn render_trigger(t: &Trigger<()>) -> String {
let cfg = PrinterConfig::default();
let mut buf = String::new();
let mut p = Printer::new(&mut buf, &cfg);
print_trigger(&mut p, t);
buf
}
fn render_ft(ft: &FileTrigger<()>) -> String {
let cfg = PrinterConfig::default();
let mut buf = String::new();
let mut p = Printer::new(&mut buf, &cfg);
print_file_trigger(&mut p, ft);
buf
}
#[test]
fn post_bare() {
let s = Scriptlet {
kind: ScriptletKind::Post,
subpkg: None,
interp: None,
expand_macros: false,
quiet: false,
from_file: None,
body: ShellBody {
lines: vec![Text::from("echo hi")],
},
data: (),
};
assert_eq!(render(&s), "%post\necho hi\n");
}
#[test]
fn post_with_path_interp() {
let s = Scriptlet {
kind: ScriptletKind::Post,
subpkg: None,
interp: Some(Interpreter::Path(Text::from("/sbin/ldconfig"))),
expand_macros: false,
quiet: false,
from_file: None,
body: ShellBody { lines: Vec::new() },
data: (),
};
assert_eq!(render(&s), "%post -p /sbin/ldconfig\n");
}
#[test]
fn post_with_lua() {
let s = Scriptlet {
kind: ScriptletKind::Post,
subpkg: None,
interp: Some(Interpreter::Lua),
expand_macros: false,
quiet: false,
from_file: None,
body: ShellBody {
lines: vec![Text::from("print('hi')")],
},
data: (),
};
assert_eq!(render(&s), "%post -p <lua>\nprint('hi')\n");
}
#[test]
fn post_bare_subpkg() {
let s = Scriptlet {
kind: ScriptletKind::Post,
subpkg: Some(SubpkgRef::Relative(Text::from("libfoo"))),
interp: None,
expand_macros: false,
quiet: false,
from_file: None,
body: ShellBody {
lines: vec![Text::from("echo")],
},
data: (),
};
assert_eq!(render(&s), "%post libfoo\necho\n");
}
#[test]
fn post_absolute_subpkg() {
let s = Scriptlet {
kind: ScriptletKind::Post,
subpkg: Some(SubpkgRef::Absolute(Text::from("libfoo"))),
interp: None,
expand_macros: false,
quiet: false,
from_file: None,
body: ShellBody { lines: Vec::new() },
data: (),
};
assert_eq!(render(&s), "%post -n libfoo\n");
}
#[test]
fn trigger_in_with_conditions() {
let t = Trigger {
kind: TriggerKind::In,
subpkg: None,
interp: None,
conditions: vec![
DepExpr::Atom(DepAtom {
name: Text::from("foo"),
arch: None,
constraint: None,
}),
DepExpr::Atom(DepAtom {
name: Text::from("bar"),
arch: None,
constraint: None,
}),
],
body: ShellBody {
lines: vec![Text::from("do-it")],
},
data: (),
};
assert_eq!(render_trigger(&t), "%triggerin -- foo, bar\ndo-it\n");
}
#[test]
fn file_trigger_with_priority() {
let ft = FileTrigger {
kind: FileTriggerKind::In,
subpkg: None,
interp: None,
priority: Some(200),
prefixes: vec![Text::from("/usr/lib")],
body: ShellBody {
lines: vec![Text::from("act")],
},
data: (),
};
assert_eq!(render_ft(&ft), "%filetriggerin -P 200 -- /usr/lib\nact\n");
}
}