deps: build against the crates packaged in Debian

The audit of the lock against Debian's archive (qa.debian.org
madison, sid/trixie/bookworm) showed 255 of 291 crates packaged, the
36 missing ones all Windows/wasm/apple/redox-only. Making the tree
build against the Debian-packaged crates — the difference between a
vendored source package and a thin debcargo one — needed:

- sha1/sha2/md-5 bumped to the digest 0.11 line (sid moved, 0.10 is
  trixie-only): finalize() now returns hybrid-array Output without
  LowerHex (hex::encode it) and no io::Write impl (sha256_file reads
  chunks into update()). The digest outputs are unchanged; the full
  suite including the checksums tests passes.
- crossterm 0.28 -> 0.29: Debian skipped 0.28 entirely.
- reqwest 0.12 -> 0.13: the blocking/json/stream usages carried over
  unchanged.
- suppaftp behind an opt-out 'ftp' feature: the one dependency absent
  from the archive, used only by the plain-FTP upload fallback of
  'pkh put' — the Debian build drops it and the SFTP failure path
  reports the transport as unavailable instead.
- every patch-level requirement pin relaxed to the minor level
  (4.5.51 -> 4.5, 1.0.228 -> 1.0, ...) — semver-compatible, and what
  lets trixie's slightly older crates satisfy the manifest.

Result: 30 of 32 direct dependencies resolve from sid as-is; the
remaining two are indicatif 0.18 (sitting in experimental, migrating)
and the feature-gated suppaftp. No vendoring on sid.
This commit is contained in:
2026-10-04 15:59:56 +02:00
parent 537bf52656
commit d0b5ce65a4
6 changed files with 493 additions and 211 deletions
+1 -1
View File
@@ -284,7 +284,7 @@ pub(crate) fn chroot_tarball_filename(
Some(m) => {
let mut hasher = Sha256::new();
hasher.update(m.as_bytes());
let hash = format!("{:x}", hasher.finalize());
let hash = hex::encode(hasher.finalize());
format!("{target}-{}-buildd.tar.xz", &hash[..12])
}
}
+10 -2
View File
@@ -44,7 +44,7 @@
use std::collections::BTreeMap;
use std::fs;
use std::io::{self, Seek, Write};
use std::io::{self, Read, Seek, Write};
use std::os::unix::fs::{FileTypeExt, MetadataExt};
use std::os::unix::io::AsRawFd;
use std::path::{Path, PathBuf};
@@ -806,7 +806,15 @@ fn hex(digest: &[u8]) -> String {
pub(crate) fn sha256_file(path: &Path) -> io::Result<String> {
let mut file = fs::File::open(path)?;
let mut hasher = Sha256::new();
io::copy(&mut file, &mut hasher)?;
// digest 0.11 no longer implements io::Write for hashers
let mut buf = [0u8; 64 * 1024];
loop {
let read = file.read(&mut buf)?;
if read == 0 {
break;
}
hasher.update(&buf[..read]);
}
Ok(hex(&hasher.finalize()))
}
+3
View File
@@ -43,8 +43,10 @@ struct LaunchpadData {
ssh_port: u16,
/// Host of the PPA upload queue over anonymous FTP (the transport
/// `pkh put` degrades to when the SSH connection never comes up)
#[cfg(feature = "ftp")]
ftp_host: String,
/// Port of the anonymous FTP upload queue
#[cfg(feature = "ftp")]
ftp_port: u16,
/// Upload queue incoming directory template (`{owner}`/`{ppa}`)
incoming_template: String,
@@ -61,6 +63,7 @@ embed_data! {
/// The PPA upload queue over anonymous FTP (host, port): the transport
/// dput-ng's plain `ppa:` profile pushes over, and the one `pkh put`
/// degrades to when the SSH connection itself never comes up.
#[cfg(feature = "ftp")]
pub(crate) fn ppa_ftp_queue() -> (String, u16) {
(LAUNCHPAD_DATA.ftp_host.clone(), LAUNCHPAD_DATA.ftp_port)
}
+33 -18
View File
@@ -6,6 +6,11 @@
//! transport dput's plain `ppa:` profiles use — through [`ftp`].
pub mod changes;
// The plain-FTP fallback transport: feature-gated (the `ftp` feature) so
// the Debian build can drop its one unpackaged dependency; with the
// feature off, the SFTP failure path reports the transport as
// unavailable instead of degrading to the anonymous FTP queue.
#[cfg(feature = "ftp")]
pub mod ftp;
pub mod ssh;
pub mod target;
@@ -164,24 +169,34 @@ async fn put_impl(opts: &PutOptions<'_>) -> Result<(), Box<dyn std::error::Error
Ok(session) => sftp_transfer(&session, &uploads, incoming, &host, opts.view),
Err(ssh::ConnectFailure::Transport(e)) => {
log::warn!("SSH transport to {host}:{port} failed: {e}");
let (ftp_host, ftp_port) = launchpad::ppa_ftp_queue();
opts.view.message(&format!(
"Falling back to the anonymous FTP queue on {ftp_host}:{ftp_port} \
(dput's upload method)..."
));
ftp::upload_queue(
&ftp_host,
ftp_port,
incoming,
&uploads,
&|name, uploaded, total| {
opts.view.progress(
&format!("Uploading {name}"),
uploaded as usize,
total as usize,
);
},
)
#[cfg(feature = "ftp")]
{
let (ftp_host, ftp_port) = launchpad::ppa_ftp_queue();
opts.view.message(&format!(
"Falling back to the anonymous FTP queue on \
{ftp_host}:{ftp_port} (dput's upload method)..."
));
ftp::upload_queue(
&ftp_host,
ftp_port,
incoming,
&uploads,
&|name, uploaded, total| {
opts.view.progress(
&format!("Uploading {name}"),
uploaded as usize,
total as usize,
);
},
)
}
#[cfg(not(feature = "ftp"))]
{
let _ = (&host, &port, incoming, &uploads);
Err("the SFTP transport failed, and this build has no FTP \
fallback (built without the 'ftp' feature)"
.into())
}
}
Err(ssh::ConnectFailure::Refused(e)) => return Err(e),
};