Skip to content

Commit

Permalink
fix(package): Normalize path separators
Browse files Browse the repository at this point in the history
A windows user could use `\` and no Linux or Mac user could use the
package.
This normalizes the separator to what works on all platforms.
  • Loading branch information
epage committed Apr 10, 2024
1 parent 74e7796 commit 44d9af4
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 30 deletions.
76 changes: 54 additions & 22 deletions src/cargo/util/toml/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2338,11 +2338,11 @@ fn prepare_toml_for_publish(
package.workspace = None;
if let Some(StringOrBool::String(path)) = &package.build {
let path = paths::normalize_path(Path::new(path));
package.build = Some(StringOrBool::String(
package.build = Some(StringOrBool::String(normalize_path_string_sep(
path.into_os_string()
.into_string()
.map_err(|_err| anyhow::format_err!("non-UTF8 `package.build`"))?,
));
)));
}
let current_resolver = package
.resolver
Expand Down Expand Up @@ -2372,10 +2372,12 @@ fn prepare_toml_for_publish(
let abs_license_path = paths::normalize_path(&package_root.join(license_path));
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(),
normalize_path_string_sep(
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`
Expand All @@ -2401,10 +2403,14 @@ fn prepare_toml_for_publish(
let abs_readme_path = paths::normalize_path(&package_root.join(readme_path));
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(),
normalize_path_string_sep(
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`
Expand All @@ -2426,14 +2432,14 @@ fn prepare_toml_for_publish(
}

let lib = if let Some(target) = &me.lib {
Some(prepare_target_for_publish(target))
Some(prepare_target_for_publish(target, "lib")?)
} 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 bin = prepare_targets_for_publish(me.bin.as_ref(), "bin")?;
let example = prepare_targets_for_publish(me.example.as_ref(), "example")?;
let test = prepare_targets_for_publish(me.test.as_ref(), "test")?;
let bench = prepare_targets_for_publish(me.bench.as_ref(), "bench")?;

let all = |_d: &manifest::TomlDependency| true;
let mut manifest = manifest::TomlManifest {
Expand Down Expand Up @@ -2591,22 +2597,48 @@ fn prepare_toml_for_publish(

fn prepare_targets_for_publish(
targets: Option<&Vec<manifest::TomlTarget>>,
) -> Option<Vec<manifest::TomlTarget>> {
let targets = targets?;
context: &str,
) -> CargoResult<Option<Vec<manifest::TomlTarget>>> {
let Some(targets) = targets else {
return Ok(None);
};

let mut prepared = Vec::with_capacity(targets.len());
for target in targets {
let target = prepare_target_for_publish(target);
let target = prepare_target_for_publish(target, context)?;
prepared.push(target);
}

Some(prepared)
Ok(Some(prepared))
}

fn prepare_target_for_publish(target: &manifest::TomlTarget) -> manifest::TomlTarget {
fn prepare_target_for_publish(
target: &manifest::TomlTarget,
context: &str,
) -> CargoResult<manifest::TomlTarget> {
let mut target = target.clone();
if let Some(path) = target.path {
target.path = Some(manifest::PathValue(normalize_path(&path.0)));
target.path = Some(manifest::PathValue(normalize_path_sep(
normalize_path(&path.0),
context,
)?));
}
Ok(target)
}

fn normalize_path_sep(path: PathBuf, context: &str) -> CargoResult<PathBuf> {
let path = path
.into_os_string()
.into_string()
.map_err(|_err| anyhow::format_err!("non-UTF8 path for {context}"))?;
let path = normalize_path_string_sep(path);
Ok(path.into())
}

fn normalize_path_string_sep(path: String) -> String {
if std::path::MAIN_SEPARATOR != '/' {
path.replace(std::path::MAIN_SEPARATOR, "/")
} else {
path
}
target
}
16 changes: 8 additions & 8 deletions tests/testsuite/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3638,30 +3638,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 44d9af4

Please sign in to comment.