From e5ff81b0e7c0bc5cad9358adcacf83ed39b98d5b Mon Sep 17 00:00:00 2001 From: Seb E Date: Tue, 11 Jan 2022 09:55:12 +0100 Subject: [PATCH] Fix use of .. in dep-info-basedir config --- src/cargo/core/compiler/output_depinfo.rs | 26 +++++---- tests/testsuite/build_script.rs | 65 ++++++++++++++++++++++- 2 files changed, 80 insertions(+), 11 deletions(-) diff --git a/src/cargo/core/compiler/output_depinfo.rs b/src/cargo/core/compiler/output_depinfo.rs index 66596bb1880..7a0d6277bbe 100644 --- a/src/cargo/core/compiler/output_depinfo.rs +++ b/src/cargo/core/compiler/output_depinfo.rs @@ -22,6 +22,7 @@ //! dependencies are not included under the assumption that changes to them can //! be detected via changes to `Cargo.lock`. +use cargo_util::paths::normalize_path; use std::collections::{BTreeSet, HashSet}; use std::io::{BufWriter, Write}; use std::path::{Path, PathBuf}; @@ -33,16 +34,21 @@ use log::debug; fn render_filename>(path: P, basedir: Option<&str>) -> CargoResult { let path = path.as_ref(); - let relpath = match basedir { - None => path, - Some(base) => match path.strip_prefix(base) { - Ok(relpath) => relpath, - _ => path, - }, - }; - relpath - .to_str() - .ok_or_else(|| internal(format!("path `{:?}` not utf-8", relpath))) + if let Some(basedir) = basedir { + let norm_path = normalize_path(path); + let norm_basedir = normalize_path(basedir.as_ref()); + match norm_path.strip_prefix(norm_basedir) { + Ok(relpath) => wrap_path(relpath), + _ => wrap_path(path), + } + } else { + wrap_path(path) + } +} + +fn wrap_path(path: &Path) -> CargoResult { + path.to_str() + .ok_or_else(|| internal(format!("path `{:?}` not utf-8", path))) .map(|f| f.replace(" ", "\\ ")) } diff --git a/tests/testsuite/build_script.rs b/tests/testsuite/build_script.rs index 40d8067d548..f5dffa1e515 100644 --- a/tests/testsuite/build_script.rs +++ b/tests/testsuite/build_script.rs @@ -4,7 +4,7 @@ use cargo_test_support::compare::assert_match_exact; use cargo_test_support::paths::CargoPathExt; use cargo_test_support::registry::Package; use cargo_test_support::tools; -use cargo_test_support::{basic_manifest, cross_compile, is_coarse_mtime, project}; +use cargo_test_support::{basic_manifest, cross_compile, is_coarse_mtime, project, project_in}; use cargo_test_support::{rustc_host, sleep_ms, slow_cpu_multiplier, symlink_supported}; use cargo_util::paths::remove_dir_all; use std::env; @@ -3248,6 +3248,69 @@ fn generate_good_d_files() { .any(|v| v == "barkbarkbark" || v == "build.rs")); } +#[cargo_test] +fn generate_good_d_files_for_external_tools() { + // This tests having a relative paths going out of the + // project root in config's dep-info-basedir + let p = project_in("rust_things") + .file( + "awoo/Cargo.toml", + r#" + [project] + name = "awoo" + version = "0.5.0" + build = "build.rs" + "#, + ) + .file("awoo/src/lib.rs", "") + .file( + "awoo/build.rs", + r#" + fn main() { + println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rerun-if-changed=barkbarkbark"); + } + "#, + ) + .file( + "Cargo.toml", + r#" + [project] + name = "meow" + version = "0.5.0" + [dependencies] + awoo = { path = "awoo" } + "#, + ) + .file("src/main.rs", "fn main() {}") + .file( + ".cargo/config.toml", + r#" + [build] + dep-info-basedir="../.." + "#, + ) + .build(); + + p.cargo("build -v").run(); + + let dot_d_path = p.bin("meow").with_extension("d"); + let dot_d = fs::read_to_string(&dot_d_path).unwrap(); + + println!("*.d file content with dep-info-basedir*: {}", &dot_d); + + assert_match_exact( + concat!( + "rust_things/foo/target/debug/meow[EXE]:", + " rust_things/foo/awoo/barkbarkbark", + " rust_things/foo/awoo/build.rs", + " rust_things/foo/awoo/src/lib.rs", + " rust_things/foo/src/main.rs", + ), + &dot_d, + ); +} + #[cargo_test] fn rebuild_only_on_explicit_paths() { let p = project()