Skip to content

Commit

Permalink
fix(package): Normalize paths in published Cargo.toml
Browse files Browse the repository at this point in the history
For now, this is more for visual consistency.
However, this blocks rust-lang#13713 as we need to be able to make these paths
comparable to what is included in the package.
  • Loading branch information
epage committed Apr 9, 2024
1 parent dd71cf4 commit acd2717
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 16 deletions.
69 changes: 61 additions & 8 deletions src/cargo/util/toml/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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()
Expand All @@ -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(
Expand All @@ -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(
Expand All @@ -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,
Expand Down Expand Up @@ -2555,3 +2591,20 @@ fn prepare_toml_for_publish(
.map(manifest::InheritableDependency::Value)
}
}

fn prepare_targets_for_publish(
targets: Option<&Vec<manifest::TomlTarget>>,
) -> Option<Vec<manifest::TomlTarget>> {
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)
}
16 changes: 8 additions & 8 deletions tests/testsuite/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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'
"#,
)],
);
Expand Down

0 comments on commit acd2717

Please sign in to comment.