new: template manifests and registry infrastructure
Split the Template trait into a data half and a logic half. Every
template is now declared by a manifest under data/templates/<id>/
(CLI id, wizard label, detection markers, Build-Depends, architecture,
rules dh line, rules-extra body, control source fields, gitignore
entries and static file bodies with {placeholder} substitution),
embedded through the TEMPLATE_SOURCES index and parsed once into the
registry; the order of the index is the wizard menu order and the
detection priority at once. The logic half is the slim TemplateHooks
trait (probe, post_write, file-body overrides merged over the manifest
bodies by path shadowing, Build-Depends/architecture amendments and
extra context values), registered per template as a HOOKS static: a
template without hooks needs zero Rust.
- TemplateId becomes a Copy wrapper of the stable CLI string; the
enum, its all/as_str/display_name/from_label matches and the old
statics array collapse into the registry accessors.
- rust's rules overrides move to data/templates/rust/rules.extra.tpl
with {locked}/{artifact} hook context; python's backend table,
meson/cmake's pkg-config opt-in, autotools' gettext and python's
C-extension hints become hook amendments over the manifest baseline.
- detect.rs drops its hardcoded marker cascade: the manifests'
detect.files drive detection in registry order, with the shell
single-script heuristic and the never-detected empty template kept
as the code special cases they are. License sniffing is untouched.
- The template tests port to manifest validation: registry coverage
and stable order, placeholder presence in the rendering context,
rules composition, the Build-Depends/architecture/dh-line table now
asserted against the manifest data, and the hook shadowing merge.
The static skeleton bodies of the shell/empty/makefile/go templates
stay in their Rust hooks for now; the next commit moves them into
their manifests.
This commit is contained in:
+11
-11
@@ -51,7 +51,7 @@ pub fn orig_tarball_path(
|
||||
}
|
||||
|
||||
/// Render every common `debian/` file of the package.
|
||||
pub fn files(opts: &NewOptions, template: &dyn Template) -> Vec<OutputFile> {
|
||||
pub fn files(opts: &NewOptions, template: &Template) -> Vec<OutputFile> {
|
||||
let mut files = vec![
|
||||
source_format(opts),
|
||||
changelog(opts),
|
||||
@@ -195,7 +195,7 @@ fn render_continuation_text(text: &str) -> String {
|
||||
/// comes from the template (`all` for shell/empty), and a non-empty
|
||||
/// `opts.depends` (the empty/metapackage flavor) lands in the binary
|
||||
/// stanza's `Depends` field.
|
||||
fn control(opts: &NewOptions, template: &dyn Template) -> OutputFile {
|
||||
fn control(opts: &NewOptions, template: &Template) -> OutputFile {
|
||||
let mut control = String::new();
|
||||
|
||||
// Source stanza.
|
||||
@@ -238,7 +238,7 @@ fn control(opts: &NewOptions, template: &dyn Template) -> OutputFile {
|
||||
/// `debian/rules`: the shebang and `%:` target whose recipe is the
|
||||
/// template's dh line (plus the template's extra overrides, when any),
|
||||
/// written with the executable bit.
|
||||
fn rules(opts: &NewOptions, template: &dyn Template) -> OutputFile {
|
||||
fn rules(opts: &NewOptions, template: &Template) -> OutputFile {
|
||||
let mut contents = format!("#!/usr/bin/make -f\n%:\n\t{}\n", template.rules_dh_line());
|
||||
let extra = template.rules_extra(opts);
|
||||
if !extra.is_empty() {
|
||||
@@ -533,7 +533,7 @@ mod tests {
|
||||
fn opts() -> NewOptions {
|
||||
NewOptions {
|
||||
name: "mytool".into(),
|
||||
template: TemplateId::Shell,
|
||||
template: TemplateId::SHELL,
|
||||
source_dir: SourceDir::Skeleton,
|
||||
upstream_version: "0.1.0".into(),
|
||||
revision: 1,
|
||||
@@ -559,7 +559,7 @@ mod tests {
|
||||
#[test]
|
||||
fn source_format_and_local_options() {
|
||||
let o = opts();
|
||||
let files = super::files(&o, crate::new::templates::get(TemplateId::Shell).unwrap());
|
||||
let files = super::files(&o, crate::new::templates::get(TemplateId::SHELL).unwrap());
|
||||
let find = |path: &str| {
|
||||
files
|
||||
.iter()
|
||||
@@ -582,7 +582,7 @@ mod tests {
|
||||
};
|
||||
let files = super::files(
|
||||
&native,
|
||||
crate::new::templates::get(TemplateId::Shell).unwrap(),
|
||||
crate::new::templates::get(TemplateId::SHELL).unwrap(),
|
||||
);
|
||||
assert!(
|
||||
files
|
||||
@@ -642,7 +642,7 @@ mod tests {
|
||||
#[test]
|
||||
fn control_rendering_and_parse() {
|
||||
let o = opts();
|
||||
let control = super::control(&o, crate::new::templates::get(TemplateId::Shell).unwrap());
|
||||
let control = super::control(&o, crate::new::templates::get(TemplateId::SHELL).unwrap());
|
||||
|
||||
// RFC822 continuation: first dep on the field line, the rest indented.
|
||||
assert!(
|
||||
@@ -679,7 +679,7 @@ mod tests {
|
||||
homepage: None,
|
||||
..opts()
|
||||
};
|
||||
let control = super::control(&o, crate::new::templates::get(TemplateId::Shell).unwrap());
|
||||
let control = super::control(&o, crate::new::templates::get(TemplateId::SHELL).unwrap());
|
||||
assert!(!control.contents.contains("Homepage:"));
|
||||
let parsed = crate::debian::ControlInfo::parse_content(&control.contents).unwrap();
|
||||
assert!(parsed.source.get("Homepage").is_none());
|
||||
@@ -688,7 +688,7 @@ mod tests {
|
||||
#[test]
|
||||
fn rules_is_executable_minimal_makefile() {
|
||||
let o = opts();
|
||||
let rules = super::rules(&o, crate::new::templates::get(TemplateId::Shell).unwrap());
|
||||
let rules = super::rules(&o, crate::new::templates::get(TemplateId::SHELL).unwrap());
|
||||
assert!(rules.executable);
|
||||
assert_eq!(rules.contents, "#!/usr/bin/make -f\n%:\n\tdh $@\n");
|
||||
}
|
||||
@@ -701,7 +701,7 @@ mod tests {
|
||||
"version=4\nhttps://github.com/example/mytool/releases .*/v?@ANY_VERSION@\\.tar\\.gz\n"
|
||||
.to_string(),
|
||||
);
|
||||
let files = super::files(&o, crate::new::templates::get(TemplateId::Shell).unwrap());
|
||||
let files = super::files(&o, crate::new::templates::get(TemplateId::SHELL).unwrap());
|
||||
let find = |path: &str| {
|
||||
files
|
||||
.iter()
|
||||
@@ -731,7 +731,7 @@ mod tests {
|
||||
// Without the extras none of the files are rendered.
|
||||
let plain = super::files(
|
||||
&opts(),
|
||||
crate::new::templates::get(TemplateId::Shell).unwrap(),
|
||||
crate::new::templates::get(TemplateId::SHELL).unwrap(),
|
||||
);
|
||||
assert!(!plain.iter().any(|f| f.path.starts_with("debian/tests")));
|
||||
assert!(!plain.iter().any(|f| f.path == "debian/watch"));
|
||||
|
||||
Reference in New Issue
Block a user