|
11 | 11 |
|
12 | 12 | use std::path::PathBuf; |
13 | 13 |
|
14 | | -use cargo_test_support::prelude::*; |
15 | 14 | use cargo_test_support::{paths, project, str}; |
| 15 | +use cargo_test_support::{prelude::*, Project}; |
16 | 16 | use std::env::consts::{DLL_PREFIX, DLL_SUFFIX, EXE_SUFFIX}; |
17 | 17 |
|
18 | 18 | #[cargo_test] |
@@ -609,6 +609,85 @@ fn template_workspace_manfiest_path_hash() { |
609 | 609 | assert_exists(&p.root().join(&format!("target-dir/debug/foo{EXE_SUFFIX}"))); |
610 | 610 | } |
611 | 611 |
|
| 612 | +/// Verify that the {workspace-manifest-path-hash} does not changes if cargo is run from inside of |
| 613 | +/// a symlinked directory. |
| 614 | +/// The test approach is to build a project twice from the non-symlinked directory and a symlinked |
| 615 | +/// directory and then compare the build-dir paths. |
| 616 | +#[cargo_test] |
| 617 | +fn template_workspace_manfiest_path_hash_should_handle_symlink() { |
| 618 | + #[cfg(unix)] |
| 619 | + use std::os::unix::fs::symlink; |
| 620 | + #[cfg(windows)] |
| 621 | + use std::os::windows::fs::symlink_dir as symlink; |
| 622 | + |
| 623 | + let p = project() |
| 624 | + .file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#) |
| 625 | + .file( |
| 626 | + "Cargo.toml", |
| 627 | + r#" |
| 628 | + [package] |
| 629 | + name = "foo" |
| 630 | + version = "1.0.0" |
| 631 | + authors = [] |
| 632 | + edition = "2015" |
| 633 | + "#, |
| 634 | + ) |
| 635 | + .file( |
| 636 | + ".cargo/config.toml", |
| 637 | + r#" |
| 638 | + [build] |
| 639 | + build-dir = "foo/{workspace-path-hash}/build-dir" |
| 640 | + "#, |
| 641 | + ) |
| 642 | + .build(); |
| 643 | + |
| 644 | + // Build from the non-symlinked directory |
| 645 | + p.cargo("build -Z build-dir") |
| 646 | + .masquerade_as_nightly_cargo(&["build-dir"]) |
| 647 | + .enable_mac_dsym() |
| 648 | + .stream() |
| 649 | + .run(); |
| 650 | + |
| 651 | + // Parse and verify the hash dir created from the non-symlinked dir |
| 652 | + let foo_dir = p.root().join("foo"); |
| 653 | + assert_exists(&foo_dir); |
| 654 | + let original_hash_dir = parse_workspace_manifest_path_hash(&foo_dir); |
| 655 | + verify_layouts(&p, &original_hash_dir); |
| 656 | + |
| 657 | + // Create a symlink of the project root. |
| 658 | + let mut symlinked_dir = p.root().clone(); |
| 659 | + symlinked_dir.pop(); |
| 660 | + symlinked_dir = symlinked_dir.join("bar"); |
| 661 | + symlink(p.root(), &symlinked_dir).unwrap(); |
| 662 | + |
| 663 | + // Remove the foo dir (which contains the build-dir) before we rebuild from a symlinked dir. |
| 664 | + foo_dir.rm_rf(); |
| 665 | + |
| 666 | + // Run cargo from the symlinked dir |
| 667 | + p.cargo_with_working_dir("build -Z build-dir", &symlinked_dir) |
| 668 | + .masquerade_as_nightly_cargo(&["build-dir"]) |
| 669 | + .enable_mac_dsym() |
| 670 | + .stream() |
| 671 | + .run(); |
| 672 | + |
| 673 | + // Parse and verify the hash created from the symlinked dir |
| 674 | + assert_exists(&foo_dir); |
| 675 | + let symlink_hash_dir = parse_workspace_manifest_path_hash(&foo_dir); |
| 676 | + verify_layouts(&p, &symlink_hash_dir); |
| 677 | + |
| 678 | + // Verify the hash dir created from the symlinked and non-symlinked dirs are the same. |
| 679 | + assert_eq!(original_hash_dir, symlink_hash_dir); |
| 680 | + //panic!("PASSED"); |
| 681 | + |
| 682 | + fn verify_layouts(p: &Project, build_dir_parent: &PathBuf) { |
| 683 | + let build_dir = build_dir_parent.as_path().join("build-dir"); |
| 684 | + assert_build_dir_layout(build_dir, "debug"); |
| 685 | + assert_artifact_dir_layout(p.root().join("target"), "debug"); |
| 686 | + // Verify the binary was uplifted to the target-dir |
| 687 | + assert_exists(&p.root().join(&format!("target/debug/foo{EXE_SUFFIX}"))); |
| 688 | + } |
| 689 | +} |
| 690 | + |
612 | 691 | fn parse_workspace_manifest_path_hash(hash_dir: &PathBuf) -> PathBuf { |
613 | 692 | // Since the hash will change between test runs simply find the first directories and assume |
614 | 693 | // that is the hash dir. The format is a 2 char directory followed by the remaining hash in the |
|
0 commit comments