From 6c597cb112320fc9efc12bb7e79b213c9bd03a07 Mon Sep 17 00:00:00 2001 From: messense Date: Mon, 12 Sep 2022 11:33:10 +0800 Subject: [PATCH] Fix sdist when `pyproject.toml` isn't in the same dir of `Cargo.toml` And switch to use `pretty-assertions` --- Cargo.lock | 44 ++++++++++++++++++++++++++++ Cargo.toml | 1 + Changelog.md | 1 + src/auditwheel/audit.rs | 1 + src/auditwheel/policy.rs | 1 + src/build_context.rs | 2 ++ src/build_options.rs | 3 ++ src/cargo_toml.rs | 1 + src/metadata.rs | 1 + src/project_layout.rs | 3 ++ src/pyproject_toml.rs | 1 + src/python_interpreter/config.rs | 1 + src/source_distribution.rs | 49 +++++++++++++++++++++++++------- src/target.rs | 1 + tests/common/errors.rs | 1 + tests/common/other.rs | 7 +++-- 16 files changed, 104 insertions(+), 14 deletions(-) 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/Changelog.md b/Changelog.md index 78f167ed4..62a580640 100644 --- a/Changelog.md +++ b/Changelog.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * auditwheel: find dylibs in Cargo target directory in [#1092](https://github.com/PyO3/maturin/pull/1092) * Add library search paths in Cargo target directory to rpath in editable mode on Linux in [#1094](https://github.com/PyO3/maturin/pull/1094) * Remove default manifest path for `maturin sdist` command in [#1097](https://github.com/PyO3/maturin/pull/1097) +* Fix sdist when `pyproject.toml` isn't in the same dir of `Cargo.toml` in [#1099](https://github.com/PyO3/maturin/pull/1099) ## [0.13.2] - 2022-08-14 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..bec0a591c 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,18 +156,29 @@ 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)| { // Skip generated files. See https://github.com/rust-lang/cargo/issues/7938#issuecomment-593280660 // and https://github.com/PyO3/maturin/issues/449 - if target == Path::new("Cargo.toml.orig") || target == Path::new("Cargo.toml") { + if target == Path::new("Cargo.toml.orig") + || (root_crate && target.file_name() == Some("Cargo.toml".as_ref())) + { false } else { source.exists() @@ -178,20 +191,32 @@ 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)?; let prefix = prefix.as_ref(); writer.add_directory(prefix)?; - writer.add_bytes( - prefix.join(manifest_path.file_name().unwrap()), - rewritten_cargo_toml.as_bytes(), - )?; + + let cargo_toml = if cargo_toml_in_subdir { + prefix.join(manifest_path) + } else { + prefix.join(manifest_path.file_name().unwrap()) + }; + writer.add_bytes(cargo_toml, rewritten_cargo_toml.as_bytes())?; for (target, source) in target_source { writer.add_file(prefix.join(target), source)?; } @@ -257,6 +282,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 +298,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(()) }