diff --git a/src/build_context.rs b/src/build_context.rs index 91d27b4e4..e2f5d917e 100644 --- a/src/build_context.rs +++ b/src/build_context.rs @@ -486,30 +486,33 @@ impl BuildContext { Ok(()) } - fn excludes(&self, format: Format) -> Result> { + fn excludes(&self, format: Format) -> Result { + let project_dir = match self.pyproject_toml_path.normalize() { + Ok(pyproject_toml_path) => pyproject_toml_path.into_path_buf(), + Err(_) => self.manifest_path.normalize()?.into_path_buf(), + }; + let mut excludes = OverrideBuilder::new(project_dir.parent().unwrap()); if let Some(pyproject) = self.pyproject_toml.as_ref() { - let pyproject_dir = self - .pyproject_toml_path - .normalize() - .with_context(|| { - format!( - "failed to normalize path `{}`", - self.pyproject_toml_path.display() - ) - })? - .into_path_buf(); if let Some(glob_patterns) = &pyproject.exclude() { - let mut excludes = OverrideBuilder::new(pyproject_dir.parent().unwrap()); for glob in glob_patterns .iter() .filter_map(|glob_pattern| glob_pattern.targets(format)) { excludes.add(glob)?; } - return Ok(Some(excludes.build()?)); } } - Ok(None) + // Ignore sdist output files so that we don't include them in the sdist + if matches!(format, Format::Sdist) { + let glob_pattern = format!( + "{}{}{}-*.tar.gz", + self.out.display(), + std::path::MAIN_SEPARATOR, + &self.metadata21.get_distribution_escaped(), + ); + excludes.add(&glob_pattern)?; + } + Ok(excludes.build()?) } /// Returns the platform part of the tag for the wheel name diff --git a/src/module_writer.rs b/src/module_writer.rs index 9319def8c..a3e439afc 100644 --- a/src/module_writer.rs +++ b/src/module_writer.rs @@ -210,7 +210,7 @@ pub struct WheelWriter { record: Vec<(String, String, usize)>, record_file: PathBuf, wheel_path: PathBuf, - excludes: Option, + excludes: Override, } impl ModuleWriter for WheelWriter { @@ -266,7 +266,7 @@ impl WheelWriter { wheel_dir: &Path, metadata21: &Metadata21, tags: &[String], - excludes: Option, + excludes: Override, ) -> Result { let wheel_path = wheel_dir.join(format!( "{}-{}-{}.whl", @@ -321,11 +321,7 @@ impl WheelWriter { /// Returns `true` if the given path should be excluded fn exclude(&self, path: impl AsRef) -> bool { - if let Some(excludes) = &self.excludes { - excludes.matched(path.as_ref(), false).is_whitelist() - } else { - false - } + self.excludes.matched(path.as_ref(), false).is_whitelist() } /// Returns a DateTime representing the value SOURCE_DATE_EPOCH environment variable @@ -375,10 +371,10 @@ impl WheelWriter { /// Creates a .tar.gz archive containing the source distribution pub struct SDistWriter { - tar: tar::Builder>, + tar: tar::Builder>>, path: PathBuf, files: HashSet, - excludes: Option, + excludes: Override, } impl ModuleWriter for SDistWriter { @@ -423,13 +419,6 @@ impl ModuleWriter for SDistWriter { return Ok(()); } let target = target.as_ref(); - if source == self.path { - eprintln!( - "⚠️ Warning: Attempting to include the sdist output tarball {} into itself! Check 'cargo package --list' output.", - source.display() - ); - return Ok(()); - } if self.files.contains(target) { // Ignore duplicate files return Ok(()); @@ -453,16 +442,19 @@ impl SDistWriter { pub fn new( wheel_dir: impl AsRef, metadata21: &Metadata21, - excludes: Option, + excludes: Override, ) -> Result { - let path = wheel_dir.as_ref().join(format!( - "{}-{}.tar.gz", - &metadata21.get_distribution_escaped(), - &metadata21.get_version_escaped() - )); - - let tar_gz = File::create(&path)?; - let enc = GzEncoder::new(tar_gz, Compression::default()); + let path = wheel_dir + .as_ref() + .normalize()? + .join(format!( + "{}-{}.tar.gz", + &metadata21.get_distribution_escaped(), + &metadata21.get_version_escaped() + )) + .into_path_buf(); + + let enc = GzEncoder::new(Vec::new(), Compression::default()); let tar = tar::Builder::new(enc); Ok(Self { @@ -475,16 +467,13 @@ impl SDistWriter { /// Returns `true` if the given path should be excluded fn exclude(&self, path: impl AsRef) -> bool { - if let Some(excludes) = &self.excludes { - excludes.matched(path.as_ref(), false).is_whitelist() - } else { - false - } + self.excludes.matched(path.as_ref(), false).is_whitelist() } /// Finished the .tar.gz archive - pub fn finish(mut self) -> Result { - self.tar.finish()?; + pub fn finish(self) -> Result { + let archive = self.tar.into_inner()?; + fs::write(&self.path, archive.finish()?)?; Ok(self.path) } } @@ -1299,7 +1288,7 @@ mod tests { // No excludes let tmp_dir = TempDir::new()?; - let mut writer = SDistWriter::new(&tmp_dir, &metadata, None)?; + let mut writer = SDistWriter::new(&tmp_dir, &metadata, Override::empty())?; assert!(writer.files.is_empty()); writer.add_bytes_with_permissions("test", &[], perm)?; assert_eq!(writer.files.len(), 1); @@ -1311,7 +1300,7 @@ mod tests { let mut excludes = OverrideBuilder::new(&tmp_dir); excludes.add("test*")?; excludes.add("!test2")?; - let mut writer = SDistWriter::new(&tmp_dir, &metadata, Some(excludes.build()?))?; + let mut writer = SDistWriter::new(&tmp_dir, &metadata, excludes.build()?)?; writer.add_bytes_with_permissions("test1", &[], perm)?; writer.add_bytes_with_permissions("test3", &[], perm)?; assert!(writer.files.is_empty()); diff --git a/src/source_distribution.rs b/src/source_distribution.rs index 864968712..45b13ffdb 100644 --- a/src/source_distribution.rs +++ b/src/source_distribution.rs @@ -546,7 +546,7 @@ fn add_cargo_package_files_to_sdist( pub fn source_distribution( build_context: &BuildContext, pyproject: &PyProjectToml, - excludes: Option, + excludes: Override, ) -> Result { let pyproject_toml_path = build_context .pyproject_toml_path