new: flag rust-toolchain.toml pins in pkh new

This commit is contained in:
2026-09-16 23:59:16 +02:00
parent 84824f61c6
commit 8e06b2074d
4 changed files with 228 additions and 15 deletions
+52 -11
View File
@@ -160,6 +160,22 @@ async fn run_wizard(mut cli: NewCli) -> Result<NewOptions, Box<dyn Error>> {
}
let template = TemplateId::parse(cli.lang.as_deref().unwrap_or_default())?;
// The rust toolchain pin of the packaged project does not travel into
// the chroot build: surface it now so a too-old pin is not a surprise
// when `pkh deb` compiles with the distribution's rustc.
let toolchain_pin = if template == TemplateId::Rust {
probe.as_ref().and_then(|p| p.toolchain_pin.clone())
} else {
None
};
if let Some(pin) = &toolchain_pin {
log::info!(
"Project pins rust {pin} via rust-toolchain.toml; the chroot \
build uses the distribution's rustc and ignores the pin — \
adjust or remove it if the code needs newer compiler features"
);
}
// 3. Source location. Skipped (with the inline notice) when a confident
// detection already decided to package the current directory; a
// --source flag skips it too.
@@ -398,7 +414,7 @@ async fn run_wizard(mut cli: NewCli) -> Result<NewOptions, Box<dyn Error>> {
// Summary screen + final confirmation: Ctrl+C or 'n' abort with
// nothing written (generation is all-or-nothing later anyway).
println!("{}", summary_text(&opts));
println!("{}", summary_text(&opts, toolchain_pin.as_deref()));
if !prompt::confirm("Generate?", true)? {
return Err("Aborted: nothing was written to disk.".into());
}
@@ -714,12 +730,13 @@ pub fn watch_template(homepage: Option<&str>) -> Option<String> {
))
}
/// The summary screen shown before the final `Generate?` confirmation
/// (spec transcript): identity line, template/license/maintainer line, the
/// generated-file overview and — for a metapackage — the Depends payload,
/// for a skeleton — the upstream files that will be created, and for rust —
/// a warning when dependencies cannot be vendored on this host.
pub fn summary_text(opts: &NewOptions) -> String {
/// The pre-flight summary screen shown before the final `Generate?`
/// confirmation (spec transcript): identity line, template/license/maintainer
/// line, the generated-file overview and — for a metapackage — the Depends
/// payload, for a skeleton — the upstream files that will be created, and
/// for rust — the probed toolchain pin (when any; the chroot build ignores
/// it) plus a warning when dependencies cannot be vendored on this host.
pub fn summary_text(opts: &NewOptions, toolchain_pin: Option<&str>) -> String {
let template = templates::get(opts.template);
let mut lines = Vec::new();
@@ -756,6 +773,13 @@ pub fn summary_text(opts: &NewOptions) -> String {
" debian/rules cargo build --release --offline (vendored at generation)"
.to_string(),
);
// A pinned rust-toolchain.toml does not reach the chroot build:
// flagged here so a too-old pin is no surprise later.
if let Some(pin) = toolchain_pin {
lines.push(format!(
" rust-toolchain {pin} (ignored by the chroot build)"
));
}
} else {
lines.push(format!(" debian/rules {}", template.rules_dh_line()));
}
@@ -923,7 +947,7 @@ mod tests {
#[test]
fn summary_screen_skeleton() {
let text = summary_text(&opts(Tid::Makefile));
let text = summary_text(&opts(Tid::Makefile), None);
assert!(
text.contains("mytool 0.1.0-1 · builds for ubuntu/resolute"),
"{text}"
@@ -956,7 +980,7 @@ mod tests {
let mut o = opts(Tid::Empty);
o.depends = vec!["hello".to_string(), "hello-data (>= 1.0)".to_string()];
o.source_dir = options::SourceDir::Here;
let text = summary_text(&o);
let text = summary_text(&o, None);
assert!(text.contains("Architecture: all"), "{text}");
assert!(
text.contains("Depends hello, hello-data (>= 1.0)"),
@@ -973,7 +997,7 @@ mod tests {
o.release = true;
o.autopkgtest = true;
o.watch = Some("version=4\n".to_string());
let text = summary_text(&o);
let text = summary_text(&o, None);
assert!(text.contains("0.1.0-1 resolute, Initial release"), "{text}");
assert!(
text.contains("debian/tests autopkgtest smoke test"),
@@ -987,7 +1011,7 @@ mod tests {
/// yet (regression: it claimed "(vendored)" before generating).
#[test]
fn summary_screen_rust_does_not_presume_vendoring() {
let text = summary_text(&opts(Tid::Rust));
let text = summary_text(&opts(Tid::Rust), None);
assert!(
text.contains("cargo build --release --offline (vendored at generation)"),
"{text}"
@@ -995,6 +1019,23 @@ mod tests {
assert!(!text.contains("(vendored)"), "{text}");
}
/// A probed rust toolchain pin surfaces in the summary as its own row
/// (rust template only), flagged as ignored by the chroot build.
#[test]
fn summary_screen_shows_the_toolchain_pin() {
let text = summary_text(&opts(Tid::Rust), Some("1.98.0"));
assert!(
text.contains("rust-toolchain 1.98.0 (ignored by the chroot build)"),
"{text}"
);
// No pin, no row.
assert!(!summary_text(&opts(Tid::Rust), None).contains("rust-toolchain"));
// A pin under a template other than rust is not shown either (the
// pin only matters for a cargo build).
assert!(!summary_text(&opts(Tid::Go), Some("1.98.0")).contains("rust-toolchain"));
}
#[test]
fn answer_validators() {
assert!(validate_revision_answer("1").is_ok());