diff --git a/Cargo.lock b/Cargo.lock index 25e181acd..04b642ead 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -565,6 +565,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "ctor" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdffe87e1d521a10f9696f833fe502293ea446d7f256c06128293a4119bdf4cb" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "data-encoding" version = "2.3.2" @@ -591,6 +601,12 @@ dependencies = [ "console", ] +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + [[package]] name = "digest" version = "0.9.0" @@ -1262,6 +1278,7 @@ dependencies = [ "once_cell", "pep440", "platform-info", + "pretty_assertions", "pretty_env_logger", "pyproject-toml", "python-pkginfo", @@ -1590,6 +1607,15 @@ dependencies = [ "regex", ] +[[package]] +name = "output_vt100" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66" +dependencies = [ + "winapi", +] + [[package]] name = "parking" version = "2.0.0" @@ -1695,6 +1721,18 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +[[package]] +name = "pretty_assertions" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a25e9bcb20aa780fd0bb16b72403a9064d6b3f22f026946029acb941a50af755" +dependencies = [ + "ctor", + "diff", + "output_vt100", + "yansi", +] + [[package]] name = "pretty_env_logger" version = "0.4.0" @@ -2825,6 +2863,12 @@ dependencies = [ "zip", ] +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + [[package]] name = "zbus" version = "1.9.3" diff --git a/Cargo.toml b/Cargo.toml index b24b7c20f..66f26d3dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -77,6 +77,7 @@ native-tls-crate = { package = "native-tls", version = "0.2.8", optional = true [dev-dependencies] indoc = "1.0.3" +pretty_assertions = "1.3.0" [features] default = ["log", "upload", "rustls", "human-panic"] diff --git a/src/auditwheel/audit.rs b/src/auditwheel/audit.rs index bca9571c3..c56e985dc 100644 --- a/src/auditwheel/audit.rs +++ b/src/auditwheel/audit.rs @@ -467,6 +467,7 @@ pub fn relpath(to: &Path, from: &Path) -> PathBuf { #[cfg(test)] mod test { use crate::auditwheel::audit::relpath; + use pretty_assertions::assert_eq; use std::path::Path; #[test] diff --git a/src/auditwheel/policy.rs b/src/auditwheel/policy.rs index b9e84c502..dc52e25d9 100644 --- a/src/auditwheel/policy.rs +++ b/src/auditwheel/policy.rs @@ -116,6 +116,7 @@ impl Policy { #[cfg(test)] mod test { use super::{Arch, Policy, MANYLINUX_POLICIES, MUSLLINUX_POLICIES}; + use pretty_assertions::assert_eq; #[test] fn test_load_policy() { diff --git a/src/build_context.rs b/src/build_context.rs index b0b696cd0..cedfba1d8 100644 --- a/src/build_context.rs +++ b/src/build_context.rs @@ -83,6 +83,8 @@ pub struct BuildContext { pub bridge: BridgeModel, /// Whether this project is pure rust or rust mixed with python pub project_layout: ProjectLayout, + /// The path to pyproject.toml. Required for the source distribution + pub pyproject_toml_path: PathBuf, /// Parsed pyproject.toml if any pub pyproject_toml: Option, /// Python Package Metadata 2.1 diff --git a/src/build_options.rs b/src/build_options.rs index 10c9e1a86..249c26b4d 100644 --- a/src/build_options.rs +++ b/src/build_options.rs @@ -489,6 +489,7 @@ impl BuildOptions { project_layout, cargo_toml_path, cargo_toml, + pyproject_toml_path, pyproject_toml, module_name, metadata21, @@ -690,6 +691,7 @@ impl BuildOptions { target, bridge, project_layout, + pyproject_toml_path, pyproject_toml, metadata21, crate_name, @@ -1175,6 +1177,7 @@ impl CargoOptions { #[cfg(test)] mod test { use cargo_metadata::MetadataCommand; + use pretty_assertions::assert_eq; use std::path::Path; use super::*; diff --git a/src/cargo_toml.rs b/src/cargo_toml.rs index f06b607f8..523f60c7c 100644 --- a/src/cargo_toml.rs +++ b/src/cargo_toml.rs @@ -184,6 +184,7 @@ pub struct RemainingCoreMetadata { mod test { use super::*; use indoc::indoc; + use pretty_assertions::assert_eq; #[test] fn test_metadata_from_cargo_toml() { diff --git a/src/metadata.rs b/src/metadata.rs index 8557e0304..eff2d8ab0 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -555,6 +555,7 @@ fn fold_header(text: &str) -> String { mod test { use super::*; use indoc::indoc; + use pretty_assertions::assert_eq; use std::io::Write; fn assert_metadata_from_cargo_toml(readme: &str, cargo_toml: &str, expected: &str) { diff --git a/src/project_layout.rs b/src/project_layout.rs index d3677d938..295d9e181 100644 --- a/src/project_layout.rs +++ b/src/project_layout.rs @@ -32,6 +32,8 @@ pub struct ProjectResolver { pub cargo_toml_path: PathBuf, /// Parsed Cargo.toml pub cargo_toml: CargoToml, + /// pyproject.toml path + pub pyproject_toml_path: PathBuf, /// Parsed pyproject.toml pub pyproject_toml: Option, /// Rust module name @@ -143,6 +145,7 @@ impl ProjectResolver { project_layout, cargo_toml_path: manifest_file, cargo_toml, + pyproject_toml_path: pyproject_file, pyproject_toml, module_name, metadata21, diff --git a/src/pyproject_toml.rs b/src/pyproject_toml.rs index 524fa235b..9cd6d5473 100644 --- a/src/pyproject_toml.rs +++ b/src/pyproject_toml.rs @@ -193,6 +193,7 @@ impl PyProjectToml { mod tests { use crate::PyProjectToml; use fs_err as fs; + use pretty_assertions::assert_eq; use std::path::Path; use tempfile::TempDir; diff --git a/src/python_interpreter/config.rs b/src/python_interpreter/config.rs index c40f6b210..0d6771079 100644 --- a/src/python_interpreter/config.rs +++ b/src/python_interpreter/config.rs @@ -241,6 +241,7 @@ suppress_build_script_link_lines=false"#, #[cfg(test)] mod test { use super::*; + use pretty_assertions::assert_eq; #[test] fn test_load_sysconfig() { diff --git a/src/source_distribution.rs b/src/source_distribution.rs index 9098871a7..27a9a009e 100644 --- a/src/source_distribution.rs +++ b/src/source_distribution.rs @@ -121,12 +121,14 @@ fn rewrite_cargo_toml( /// Runs `cargo package --list --allow-dirty` to obtain a list of files to package. fn add_crate_to_source_distribution( writer: &mut SDistWriter, + pyproject_toml_path: impl AsRef, manifest_path: impl AsRef, prefix: impl AsRef, known_path_deps: &HashMap, root_crate: bool, ) -> Result<()> { let manifest_path = manifest_path.as_ref(); + let pyproject_toml_path = pyproject_toml_path.as_ref(); let output = Command::new("cargo") .args(&["package", "--list", "--allow-dirty", "--manifest-path"]) .arg(manifest_path) @@ -154,12 +156,21 @@ fn add_crate_to_source_distribution( .collect(); let manifest_dir = manifest_path.parent().unwrap(); + let abs_manifest_dir = manifest_dir.canonicalize()?; + let pyproject_dir = pyproject_toml_path.parent().unwrap().canonicalize()?; + let cargo_toml_in_subdir = root_crate + && abs_manifest_dir != pyproject_dir + && abs_manifest_dir.starts_with(pyproject_dir.canonicalize()?); - let target_source: Vec<(PathBuf, PathBuf)> = file_list + let mut target_source: Vec<(PathBuf, PathBuf)> = file_list .iter() .map(|relative_to_manifests| { let relative_to_cwd = manifest_dir.join(relative_to_manifests); - (relative_to_manifests.to_path_buf(), relative_to_cwd) + if root_crate && cargo_toml_in_subdir { + (relative_to_cwd.clone(), relative_to_cwd) + } else { + (relative_to_manifests.to_path_buf(), relative_to_cwd) + } }) // We rewrite Cargo.toml and add it separately .filter(|(target, source)| { @@ -178,10 +189,19 @@ fn add_crate_to_source_distribution( .iter() .any(|(target, _)| target == Path::new("pyproject.toml")) { - bail!( - "pyproject.toml was not included by `cargo package`. \ - Please make sure pyproject.toml is not excluded or build without `--sdist`" - ) + // Add pyproject.toml to the source distribution + // if Cargo.toml is in subdirectory of pyproject.toml directory + if cargo_toml_in_subdir { + target_source.push(( + PathBuf::from("pyproject.toml"), + pyproject_toml_path.to_path_buf(), + )); + } else { + bail!( + "pyproject.toml was not included by `cargo package`. \ + Please make sure pyproject.toml is not excluded or build without `--sdist`" + ) + } } let rewritten_cargo_toml = rewrite_cargo_toml(&manifest_path, known_path_deps, root_crate)?; @@ -257,6 +277,7 @@ pub fn source_distribution( for (name, path_dep) in known_path_deps.iter() { add_crate_to_source_distribution( &mut writer, + &build_context.pyproject_toml_path, &path_dep, &root_dir.join(LOCAL_DEPENDENCIES_FOLDER).join(name), &known_path_deps, @@ -272,6 +293,7 @@ pub fn source_distribution( // Add the main crate add_crate_to_source_distribution( &mut writer, + &build_context.pyproject_toml_path, &manifest_path, &root_dir, &known_path_deps, diff --git a/src/target.rs b/src/target.rs index ccd165c2b..2667e7e19 100644 --- a/src/target.rs +++ b/src/target.rs @@ -701,6 +701,7 @@ fn emcc_version() -> Result { #[cfg(test)] mod test { use super::macosx_deployment_target; + use pretty_assertions::assert_eq; #[test] fn test_macosx_deployment_target() { diff --git a/tests/common/errors.rs b/tests/common/errors.rs index 216db7705..0de3f202c 100644 --- a/tests/common/errors.rs +++ b/tests/common/errors.rs @@ -2,6 +2,7 @@ use anyhow::format_err; use anyhow::{bail, Result}; use clap::Parser; use maturin::BuildOptions; +use pretty_assertions::assert_eq; pub fn abi3_without_version() -> Result<()> { // The first argument is ignored by clap diff --git a/tests/common/other.rs b/tests/common/other.rs index 86b28679f..9bbec3560 100644 --- a/tests/common/other.rs +++ b/tests/common/other.rs @@ -2,7 +2,8 @@ use anyhow::{Context, Result}; use clap::Parser; use flate2::read::GzDecoder; use maturin::{BuildOptions, CargoOptions}; -use std::collections::HashSet; +use pretty_assertions::assert_eq; +use std::collections::BTreeSet; use std::iter::FromIterator; use std::path::{Path, PathBuf}; use tar::Archive; @@ -139,14 +140,14 @@ pub fn test_source_distribution( let tar_gz = fs_err::File::open(path)?; let tar = GzDecoder::new(tar_gz); let mut archive = Archive::new(tar); - let mut files = HashSet::new(); + let mut files = BTreeSet::new(); for entry in archive.entries()? { let entry = entry?; files.insert(format!("{}", entry.path()?.display())); } assert_eq!( files, - HashSet::from_iter(expected_files.into_iter().map(ToString::to_string)) + BTreeSet::from_iter(expected_files.into_iter().map(ToString::to_string)) ); Ok(()) }