new: ignore vendored rust artifacts in the generated gitignore

This commit is contained in:
2026-09-17 10:37:58 +02:00
parent bac82f0afe
commit bc3d07abaa
4 changed files with 183 additions and 20 deletions
+59 -8
View File
@@ -3,7 +3,9 @@
//!
//! This module orchestrates a scaffold run: target directory checks, project
//! detection, in-memory rendering of every file (all-or-nothing write), the
//! template post-write hook (e.g. `cargo vendor`), orig tarball creation
//! root `.gitignore` merge (skeleton build artifacts plus the template's own
//! entries, e.g. the rust vendored layout), the template post-write hook
//! (e.g. `cargo vendor`), orig tarball creation
//! (from the origin the run decided on — see [`origin`] and [`orig`]), git
//! initialization, structural verification and the next-steps message.
//! The interactive wizard ([`questions`]) fills a [`options::NewCli`] from
@@ -35,8 +37,10 @@ use templates::{OutputFile, ScaffoldOutcome};
/// 1. resolve the template from the registry,
/// 2. check the target directory (refuse an existing `debian/control`),
/// 3. render every file in memory and check for collisions,
/// 4. write the files all-or-nothing (plus the root `.gitignore` in skeleton
/// mode, appending to an existing one),
/// 4. write the files all-or-nothing (plus the root `.gitignore` merge:
/// the skeleton build-artifact entries in skeleton mode and the
/// template's own entries — rust: the vendored layout — in every mode,
/// appending to an existing file),
/// 5. run the template post-write hook (e.g. `cargo vendor`, so the vendored
/// sources land inside the orig tarball created next),
/// 6. create the orig tarball (quilt only, refusing overwrites),
@@ -171,13 +175,25 @@ fn scaffold_steps(opts: &NewOptions, pb: &ProgressBar) -> Result<ScaffoldOutcome
pb.set_message("Writing files");
debian::write_files(&target, &files)?;
// Root .gitignore: skeleton mode only, never overwriting an existing
// file (append the missing entries instead).
if skeleton
&& let Some(contents) = debian::merge_root_gitignore(
// Root .gitignore: the skeleton build-artifact entries in skeleton
// 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 mut entries: Vec<&str> = Vec::new();
let mut header = None;
if skeleton {
entries.extend(debian::ROOT_GITIGNORE_ENTRIES);
header = Some(debian::ROOT_GITIGNORE_HEADER);
}
entries.extend(template_gitignore.iter().map(String::as_str));
if !entries.is_empty()
&& let Some(contents) = debian::merge_gitignore_entries(
std::fs::read_to_string(target.join(".gitignore"))
.ok()
.as_deref(),
&entries,
header,
)
{
std::fs::write(target.join(".gitignore"), contents)?;
@@ -502,7 +518,8 @@ mod tests {
scaffold_in(&tree, opts(TemplateId::Shell, "runtool", SourceDir::Here)).unwrap();
// debian/ lands directly in the directory; no skeleton file, no
// root .gitignore (skeleton mode only), no debian/install (the
// root .gitignore (the shell template contributes none and the
// artifact entries are skeleton-only), no debian/install (the
// generated one would reference the non-existent skeleton script),
// and the existing script is left alone.
assert!(tree.join("debian/control").exists());
@@ -662,6 +679,40 @@ mod tests {
assert!(config.contains("[source.crates-io]"), "{config}");
assert!(config.contains("[net]\noffline = true"), "{config}");
}
// Root .gitignore: the skeleton build-artifact entries plus the
// template's vendoring entries (contributed in every mode).
let gitignore = std::fs::read_to_string(tree.join(".gitignore")).unwrap();
assert!(gitignore.contains("# pkh build artifacts"), "{gitignore}");
assert!(gitignore.contains("*.deb"), "{gitignore}");
assert!(gitignore.contains("target/"), "{gitignore}");
assert!(gitignore.contains("vendor/\n"), "{gitignore}");
assert!(gitignore.contains(".cargo/config.toml\n"), "{gitignore}");
}
/// The rust template's vendoring entries land in the root `.gitignore`
/// in every mode: a Here-mode tree gets them appended to its existing
/// file (custom lines kept, no header comment), while the skeleton-only
/// build-artifact entries do not appear.
#[test]
#[serial]
fn scaffold_rust_here_merges_vendoring_gitignore_entries() {
let dir = tempdir().unwrap();
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();
let gitignore = std::fs::read_to_string(tree.join(".gitignore")).unwrap();
assert!(
gitignore.starts_with("# my project\n*.log\n"),
"{gitignore}"
);
assert!(gitignore.contains("vendor/\n"), "{gitignore}");
assert!(gitignore.contains(".cargo/config.toml\n"), "{gitignore}");
// The build-artifact entries stay skeleton-only.
assert!(!gitignore.contains("*.deb"), "{gitignore}");
assert!(!gitignore.contains("# pkh build artifacts"), "{gitignore}");
}
/// End-to-end vendored rust quilt package: the vendoring hook creates