context: copy symlinks as symlinks and improve error messages

This commit is contained in:
2026-07-17 10:12:46 +02:00
parent 2b27b7b06e
commit c4b59a4376
11 changed files with 383 additions and 55 deletions
+24 -4
View File
@@ -1,5 +1,6 @@
use std::cmp::min;
use std::error::Error;
use std::os::unix::fs::symlink;
use std::path::Path;
use std::path::PathBuf;
@@ -101,7 +102,13 @@ fn copy_dir_all(src: &Path, dst: &Path) -> Result<(), Box<dyn Error>> {
let src_path = entry.path();
let dst_path = dst.join(entry.file_name());
if src_path.is_dir() {
// Reproduce symlinks as symlinks rather than following them, so that
// dangling/absolute symlinks do not abort the copy.
if std::fs::symlink_metadata(&src_path)?.file_type().is_symlink() {
let target = std::fs::read_link(&src_path)?;
let _ = std::fs::remove_file(&dst_path);
symlink(&target, &dst_path)?;
} else if src_path.is_dir() {
copy_dir_all(&src_path, &dst_path)?;
} else {
std::fs::copy(&src_path, &dst_path)?;
@@ -183,12 +190,25 @@ fn checkout_pristine_tar(package_dir: &Path, filename: &str) -> Result<(), Box<d
.current_dir(package_dir)
.args(["checkout", format!("../{filename}").as_str()])
.output()
.expect("pristine-tar checkout failed");
.map_err(|e| {
format!(
"Failed to run 'pristine-tar' to check out '{filename}': {}. \
Is 'pristine-tar' installed? It is required to reconstruct \
the upstream orig tarball from a git repository.",
e
)
})?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
return Err(format!(
"pristine-tar checkout failed with status: {}",
output.status
"pristine-tar checkout of '{filename}' failed with status: {}.{}",
output.status,
if stderr.trim().is_empty() {
String::new()
} else {
format!("\npristine-tar output:\n{}", stderr.trim())
}
)
.into());
}