From 9394ecf7f3a254384f0bc053fffa1144edb25576 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 9 Apr 2024 16:08:21 -0500 Subject: [PATCH] fix(package): Normalize paths in published `Cargo.toml` For now, this is more for visual consistency. However, this blocks #13713 as we need to be able to make these paths comparable to what is included in the package. --- src/cargo/util/toml/mod.rs | 69 +++++++++++++++++++++++++++++++++----- tests/testsuite/package.rs | 16 ++++----- 2 files changed, 69 insertions(+), 16 deletions(-) diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 73637038bcbc..0c0ec00deaed 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -8,7 +8,7 @@ use std::str::{self, FromStr}; use crate::AlreadyPrintedError; use anyhow::{anyhow, bail, Context as _}; use cargo_platform::Platform; -use cargo_util::paths; +use cargo_util::paths::{self, normalize_path}; use cargo_util_schemas::manifest::{self, TomlManifest}; use cargo_util_schemas::manifest::{RustVersion, StringOrBool}; use itertools::Itertools; @@ -2336,6 +2336,14 @@ fn prepare_toml_for_publish( let mut package = me.package().unwrap().clone(); package.workspace = None; + if let Some(StringOrBool::String(path)) = &package.build { + let path = paths::normalize_path(Path::new(path)); + package.build = Some(StringOrBool::String( + path.into_os_string() + .into_string() + .map_err(|_err| anyhow::format_err!("non-UTF8 `package.build`"))?, + )); + } let current_resolver = package .resolver .as_ref() @@ -2362,7 +2370,14 @@ fn prepare_toml_for_publish( .context("license file should have been resolved before `prepare_for_publish()`")?; let license_path = Path::new(&license_file); let abs_license_path = paths::normalize_path(&package_root.join(license_path)); - if abs_license_path.strip_prefix(package_root).is_err() { + if let Ok(license_file) = abs_license_path.strip_prefix(package_root) { + package.license_file = Some(manifest::InheritableField::Value( + license_file + .to_str() + .ok_or_else(|| anyhow::format_err!("non-UTF8 `package.license-file`"))? + .to_owned(), + )); + } else { // This path points outside of the package root. `cargo package` // will copy it into the root, so adjust the path to this location. package.license_file = Some(manifest::InheritableField::Value( @@ -2384,7 +2399,14 @@ fn prepare_toml_for_publish( manifest::StringOrBool::String(readme) => { let readme_path = Path::new(&readme); let abs_readme_path = paths::normalize_path(&package_root.join(readme_path)); - if abs_readme_path.strip_prefix(package_root).is_err() { + if let Ok(readme_path) = abs_readme_path.strip_prefix(package_root) { + package.readme = Some(manifest::InheritableField::Value(StringOrBool::String( + readme_path + .to_str() + .ok_or_else(|| anyhow::format_err!("non-UTF8 `package.license-file`"))? + .to_owned(), + ))); + } else { // This path points outside of the package root. `cargo package` // will copy it into the root, so adjust the path to this location. package.readme = Some(manifest::InheritableField::Value( @@ -2402,16 +2424,30 @@ fn prepare_toml_for_publish( manifest::StringOrBool::Bool(_) => {} } } + + let lib = if let Some(mut target) = me.lib.clone() { + if let Some(path) = target.path { + target.path = Some(manifest::PathValue(normalize_path(&path.0))); + } + Some(target) + } else { + None + }; + let bin = prepare_targets_for_publish(me.bin.as_ref()); + let example = prepare_targets_for_publish(me.example.as_ref()); + let test = prepare_targets_for_publish(me.test.as_ref()); + let bench = prepare_targets_for_publish(me.bench.as_ref()); + let all = |_d: &manifest::TomlDependency| true; let mut manifest = manifest::TomlManifest { package: Some(package), project: None, profile: me.profile.clone(), - lib: me.lib.clone(), - bin: me.bin.clone(), - example: me.example.clone(), - test: me.test.clone(), - bench: me.bench.clone(), + lib, + bin, + example, + test, + bench, dependencies: map_deps(gctx, me.dependencies.as_ref(), all)?, dev_dependencies: map_deps( gctx, @@ -2555,3 +2591,20 @@ fn prepare_toml_for_publish( .map(manifest::InheritableDependency::Value) } } + +fn prepare_targets_for_publish( + targets: Option<&Vec>, +) -> Option> { + let targets = targets?; + + let mut prepared = Vec::with_capacity(targets.len()); + for target in targets { + let mut target = target.clone(); + if let Some(path) = target.path { + target.path = Some(manifest::PathValue(normalize_path(&path.0))); + } + prepared.push(target); + } + + Some(prepared) +} diff --git a/tests/testsuite/package.rs b/tests/testsuite/package.rs index b7d4c0a62ce8..91c59ae92836 100644 --- a/tests/testsuite/package.rs +++ b/tests/testsuite/package.rs @@ -3637,30 +3637,30 @@ edition = "2015" name = "foo" version = "0.0.1" authors = [] -build = './src/build.rs' +build = 'src/build.rs' description = "foo" documentation = "docs.rs/foo" -readme = './docs/README.md' -license-file = './docs/LICENSE' +readme = 'docs/README.md' +license-file = 'docs/LICENSE' [lib] -path = './src/lib.rs' +path = 'src/lib.rs' [[bin]] name = "foo" -path = './src/bin/foo/main.rs' +path = 'src/bin/foo/main.rs' [[example]] name = "example_foo" -path = './examples/example_foo.rs' +path = 'examples/example_foo.rs' [[test]] name = "test_foo" -path = './tests/test_foo.rs' +path = 'tests/test_foo.rs' [[bench]] name = "bench_foo" -path = './benches/bench_foo.rs' +path = 'benches/bench_foo.rs' "#, )], );