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:
+19
-19
@@ -181,7 +181,7 @@ fn scaffold_steps(opts: &NewOptions, pb: &ProgressBar) -> Result<ScaffoldOutcome
|
||||
// mode, plus the template's own entries (rust: the vendored layout) in
|
||||
// every mode — missing ones appended, an existing file never
|
||||
// overwritten.
|
||||
let template_gitignore = template.gitignore_entries(opts);
|
||||
let template_gitignore = template.gitignore_entries();
|
||||
let mut entries: Vec<&str> = Vec::new();
|
||||
let mut header = None;
|
||||
if skeleton {
|
||||
@@ -216,7 +216,7 @@ fn scaffold_steps(opts: &NewOptions, pb: &ProgressBar) -> Result<ScaffoldOutcome
|
||||
if opts.source_format == SourceFormat::Quilt {
|
||||
pb.set_message("Creating orig tarball");
|
||||
let vendored_rust =
|
||||
template.id() == options::TemplateId::Rust && orig::has_vendored_dir(&target);
|
||||
template.id() == options::TemplateId::RUST && orig::has_vendored_dir(&target);
|
||||
let created = orig::create_orig(
|
||||
&target,
|
||||
&opts.name,
|
||||
@@ -349,7 +349,7 @@ mod tests {
|
||||
let dir = tempdir().unwrap();
|
||||
scaffold_in(
|
||||
dir.path(),
|
||||
opts(TemplateId::Shell, "mytool", SourceDir::Skeleton),
|
||||
opts(TemplateId::SHELL, "mytool", SourceDir::Skeleton),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -423,7 +423,7 @@ mod tests {
|
||||
#[serial]
|
||||
fn scaffold_skeleton_forced_quilt_snapshots_the_tree() {
|
||||
let dir = tempdir().unwrap();
|
||||
let mut o = opts(TemplateId::Shell, "mytool", SourceDir::Skeleton);
|
||||
let mut o = opts(TemplateId::SHELL, "mytool", SourceDir::Skeleton);
|
||||
o.source_format = SourceFormat::Quilt;
|
||||
o.orig = Some(OrigOrigin::Snapshot);
|
||||
scaffold_in(dir.path(), o).unwrap();
|
||||
@@ -471,7 +471,7 @@ mod tests {
|
||||
fn scaffold_empty_base_and_metapackage_flavors() {
|
||||
let dir = tempdir().unwrap();
|
||||
// Metapackage flavor: non-empty depends.
|
||||
let mut o = opts(TemplateId::Empty, "metapkg", SourceDir::Skeleton);
|
||||
let mut o = opts(TemplateId::EMPTY, "metapkg", SourceDir::Skeleton);
|
||||
o.depends = vec!["hello".into(), "hello-data (>= 1.0)".into()];
|
||||
scaffold_in(dir.path(), o).unwrap();
|
||||
|
||||
@@ -493,7 +493,7 @@ mod tests {
|
||||
let dir = tempdir().unwrap();
|
||||
scaffold_in(
|
||||
dir.path(),
|
||||
opts(TemplateId::Empty, "basepkg", SourceDir::Skeleton),
|
||||
opts(TemplateId::EMPTY, "basepkg", SourceDir::Skeleton),
|
||||
)
|
||||
.unwrap();
|
||||
let control =
|
||||
@@ -505,7 +505,7 @@ mod tests {
|
||||
#[serial]
|
||||
fn scaffold_release_targets_series() {
|
||||
let dir = tempdir().unwrap();
|
||||
let mut o = opts(TemplateId::Empty, "released", SourceDir::Skeleton);
|
||||
let mut o = opts(TemplateId::EMPTY, "released", SourceDir::Skeleton);
|
||||
o.release = true;
|
||||
scaffold_in(dir.path(), o).unwrap();
|
||||
|
||||
@@ -525,7 +525,7 @@ mod tests {
|
||||
let tree = dir.path().join("packdir");
|
||||
std::fs::create_dir_all(&tree).unwrap();
|
||||
std::fs::write(tree.join("run.sh"), "#!/bin/sh\necho hi\n").unwrap();
|
||||
scaffold_in(&tree, opts(TemplateId::Shell, "runtool", SourceDir::Here)).unwrap();
|
||||
scaffold_in(&tree, opts(TemplateId::SHELL, "runtool", SourceDir::Here)).unwrap();
|
||||
|
||||
// debian/ lands directly in the directory; no skeleton file, no
|
||||
// root .gitignore (the shell template contributes none and the
|
||||
@@ -574,7 +574,7 @@ mod tests {
|
||||
std::fs::write(tree.join("debian/control"), "Source: mytool\n").unwrap();
|
||||
let err = scaffold_in(
|
||||
dir.path(),
|
||||
opts(TemplateId::Shell, "mytool", SourceDir::Skeleton),
|
||||
opts(TemplateId::SHELL, "mytool", SourceDir::Skeleton),
|
||||
)
|
||||
.unwrap_err();
|
||||
assert!(err.to_string().contains("debian/control"), "{err}");
|
||||
@@ -585,7 +585,7 @@ mod tests {
|
||||
std::fs::write(dir.path().join("mytool/junk"), "x").unwrap();
|
||||
let err = scaffold_in(
|
||||
dir.path(),
|
||||
opts(TemplateId::Shell, "mytool", SourceDir::Skeleton),
|
||||
opts(TemplateId::SHELL, "mytool", SourceDir::Skeleton),
|
||||
)
|
||||
.unwrap_err();
|
||||
assert!(err.to_string().contains("not empty"), "{err}");
|
||||
@@ -593,7 +593,7 @@ mod tests {
|
||||
// Existing orig tarball (quilt only): nothing gets written.
|
||||
let dir = tempdir().unwrap();
|
||||
std::fs::write(dir.path().join("mytool_0.1.0.orig.tar.xz"), b"old").unwrap();
|
||||
let mut o = opts(TemplateId::Shell, "mytool", SourceDir::Skeleton);
|
||||
let mut o = opts(TemplateId::SHELL, "mytool", SourceDir::Skeleton);
|
||||
o.source_format = SourceFormat::Quilt;
|
||||
o.orig = Some(OrigOrigin::Snapshot);
|
||||
let err = scaffold_in(dir.path(), o).unwrap_err();
|
||||
@@ -605,7 +605,7 @@ mod tests {
|
||||
let err = scaffold_in(
|
||||
dir.path(),
|
||||
opts(
|
||||
TemplateId::Shell,
|
||||
TemplateId::SHELL,
|
||||
"mytool",
|
||||
SourceDir::Path(dir.path().join("missing")),
|
||||
),
|
||||
@@ -622,7 +622,7 @@ mod tests {
|
||||
let dir = tempdir().unwrap();
|
||||
scaffold_in(
|
||||
dir.path(),
|
||||
opts(TemplateId::Shell, "nativepkg", SourceDir::Skeleton),
|
||||
opts(TemplateId::SHELL, "nativepkg", SourceDir::Skeleton),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -649,7 +649,7 @@ mod tests {
|
||||
let dir = tempdir().unwrap();
|
||||
let outcome = scaffold_in(
|
||||
dir.path(),
|
||||
opts(TemplateId::Rust, "mytool", SourceDir::Skeleton),
|
||||
opts(TemplateId::RUST, "mytool", SourceDir::Skeleton),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -711,7 +711,7 @@ mod tests {
|
||||
let tree = dir.path().join("packdir");
|
||||
std::fs::create_dir_all(&tree).unwrap();
|
||||
std::fs::write(tree.join(".gitignore"), "# my project\n*.log\n").unwrap();
|
||||
scaffold_in(&tree, opts(TemplateId::Rust, "mytool", SourceDir::Here)).unwrap();
|
||||
scaffold_in(&tree, opts(TemplateId::RUST, "mytool", SourceDir::Here)).unwrap();
|
||||
|
||||
let gitignore = std::fs::read_to_string(tree.join(".gitignore")).unwrap();
|
||||
assert!(
|
||||
@@ -753,7 +753,7 @@ mod tests {
|
||||
.unwrap();
|
||||
std::fs::write(source.join("src/main.rs"), "fn main() {}\n").unwrap();
|
||||
|
||||
let mut o = opts(TemplateId::Rust, "mytool", SourceDir::Path(source.clone()));
|
||||
let mut o = opts(TemplateId::RUST, "mytool", SourceDir::Path(source.clone()));
|
||||
o.source_format = SourceFormat::Quilt;
|
||||
o.orig = Some(OrigOrigin::Snapshot);
|
||||
let outcome = scaffold_in(dir.path(), o).unwrap();
|
||||
@@ -848,7 +848,7 @@ mod tests {
|
||||
let dir = tempdir().unwrap();
|
||||
scaffold_in(
|
||||
dir.path(),
|
||||
opts(TemplateId::Python, "mytool", SourceDir::Skeleton),
|
||||
opts(TemplateId::PYTHON, "mytool", SourceDir::Skeleton),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -880,7 +880,7 @@ mod tests {
|
||||
let tree = dir.path().join("mytool");
|
||||
std::fs::create_dir_all(&tree).unwrap();
|
||||
std::fs::write(tree.join("run.sh"), "#!/bin/sh\necho hi\n").unwrap();
|
||||
scaffold_in(&tree, opts(TemplateId::Shell, "mytool", SourceDir::Here)).unwrap();
|
||||
scaffold_in(&tree, opts(TemplateId::SHELL, "mytool", SourceDir::Here)).unwrap();
|
||||
|
||||
let output = crate::build::run_source_build(
|
||||
&dir.path().join("mytool"),
|
||||
@@ -909,7 +909,7 @@ mod tests {
|
||||
let dir = tempdir().unwrap();
|
||||
scaffold_in(
|
||||
dir.path(),
|
||||
opts(TemplateId::Shell, "mytool", SourceDir::Skeleton),
|
||||
opts(TemplateId::SHELL, "mytool", SourceDir::Skeleton),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user