Try reading directly is it's not a directory

This commit is contained in:
konstin 2025-06-24 22:49:12 +02:00
parent 4e108feea9
commit 18ad3ab3bb
3 changed files with 24 additions and 70 deletions

View file

@ -9,7 +9,6 @@ pub use settings::{BuildBackendSettings, WheelDataIncludes};
pub use source_dist::{build_source_dist, list_source_dist};
pub use wheel::{build_editable, build_wheel, list_wheel, metadata};
use std::fs::FileType;
use std::io;
use std::path::{Path, PathBuf};
use std::str::FromStr;
@ -55,8 +54,6 @@ pub enum Error {
#[source]
err: walkdir::Error,
},
#[error("Unsupported file type {:?}: `{}`", _1, _0.user_display())]
UnsupportedFileType(PathBuf, FileType),
#[error("Failed to write wheel zip archive")]
Zip(#[from] zip::result::ZipError),
#[error("Failed to write RECORD file")]
@ -87,6 +84,16 @@ trait DirectoryWriter {
/// Files added through the method are considered generated when listing included files.
fn write_bytes(&mut self, path: &str, bytes: &[u8]) -> Result<(), Error>;
/// Add the file or directory to the path.
fn write_dir_entry(&mut self, entry: &DirEntry, target_path: &str) -> Result<(), Error> {
if entry.file_type().is_dir() {
self.write_directory(target_path)?;
} else {
self.write_file(target_path, entry.path())?;
}
Ok(())
}
/// Add a local file.
fn write_file(&mut self, path: &str, file: &Path) -> Result<(), Error>;
@ -314,19 +321,6 @@ fn module_path_from_module_name(src_root: &Path, module_name: &str) -> Result<Pa
Ok(module_relative)
}
/// Whether a [`DirEntry`] is a file or a symlink to a file.
///
/// Since we don't copy the file, but read it, a symlink to a file works like a regular file.
fn is_fileish_dir_entry(entry: &DirEntry) -> io::Result<bool> {
if entry.file_type().is_file() {
return Ok(true);
}
if entry.path_is_symlink() {
return Ok(fs_err::metadata(entry.path())?.file_type().is_file());
}
Ok(false)
}
#[cfg(test)]
mod tests {
use super::*;

View file

@ -2,7 +2,6 @@ use crate::metadata::DEFAULT_EXCLUDES;
use crate::wheel::build_exclude_matcher;
use crate::{
BuildBackendSettings, DirectoryWriter, Error, FileList, ListWriter, PyProjectToml, find_roots,
is_fileish_dir_entry,
};
use flate2::Compression;
use flate2::write::GzEncoder;
@ -251,32 +250,16 @@ fn write_source_dist(
.expect("walkdir starts with root");
if !include_matcher.match_path(relative) || exclude_matcher.is_match(relative) {
trace!("Excluding: `{}`", relative.user_display());
trace!("Excluding from sdist: `{}`", relative.user_display());
continue;
}
debug!("Including {}", relative.user_display());
if entry.file_type().is_dir() {
writer.write_directory(
&Path::new(&top_level)
.join(relative)
.portable_display()
.to_string(),
)?;
} else if is_fileish_dir_entry(&entry)? {
writer.write_file(
&Path::new(&top_level)
.join(relative)
.portable_display()
.to_string(),
entry.path(),
)?;
} else {
return Err(Error::UnsupportedFileType(
relative.to_path_buf(),
entry.file_type(),
));
}
let entry_path = Path::new(&top_level)
.join(relative)
.portable_display()
.to_string();
debug!("Adding to sdist: {}", relative.user_display());
writer.write_dir_entry(&entry, &entry_path)?;
}
debug!("Visited {files_visited} files for source dist build");

View file

@ -18,7 +18,6 @@ use uv_warnings::warn_user_once;
use crate::metadata::DEFAULT_EXCLUDES;
use crate::{
BuildBackendSettings, DirectoryWriter, Error, FileList, ListWriter, PyProjectToml, find_roots,
is_fileish_dir_entry,
};
/// Build a wheel from the source tree and place it in the output directory.
@ -165,7 +164,7 @@ fn write_wheel(
.path()
.strip_prefix(source_tree)
.expect("walkdir starts with root");
let wheel_path = entry
let entry_path = entry
.path()
.strip_prefix(&src_root)
.expect("walkdir starts with root");
@ -173,21 +172,10 @@ fn write_wheel(
trace!("Excluding from module: `{}`", match_path.user_display());
continue;
}
let wheel_path = wheel_path.portable_display().to_string();
debug!("Adding to wheel: `{wheel_path}`");
if entry.file_type().is_dir() {
wheel_writer.write_directory(&wheel_path)?;
} else if is_fileish_dir_entry(&entry)? {
wheel_writer.write_file(&wheel_path, entry.path())?;
} else {
// TODO(konsti): We may want to support symlinks, there is support for installing them.
return Err(Error::UnsupportedFileType(
entry.path().to_path_buf(),
entry.file_type(),
));
}
let entry_path = entry_path.portable_display().to_string();
debug!("Adding to wheel: {entry_path}");
wheel_writer.write_dir_entry(&entry, &entry_path)?;
}
debug!("Visited {files_visited} files for wheel build");
@ -520,23 +508,12 @@ fn wheel_subdir_from_globs(
continue;
}
let relative_licenses = Path::new(target)
let license_path = Path::new(target)
.join(relative)
.portable_display()
.to_string();
if entry.file_type().is_dir() {
wheel_writer.write_directory(&relative_licenses)?;
} else if is_fileish_dir_entry(&entry)? {
debug!("Adding {} file: `{}`", globs_field, relative.user_display());
wheel_writer.write_file(&relative_licenses, entry.path())?;
} else {
// TODO(konsti): We may want to support symlinks, there is support for installing them.
return Err(Error::UnsupportedFileType(
entry.path().to_path_buf(),
entry.file_type(),
));
}
debug!("Adding for {}: `{}`", globs_field, relative.user_display());
wheel_writer.write_dir_entry(&entry, &license_path)?;
}
Ok(())
}