|
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]
|
@@ -569,7 +569,7 @@ fn template_cargo_cache_home() {
|
569 | 569 | }
|
570 | 570 |
|
571 | 571 | #[cargo_test]
|
572 |
| -fn template_workspace_manfiest_path_hash() { |
| 572 | +fn template_workspace_path_hash() { |
573 | 573 | let p = project()
|
574 | 574 | .file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
|
575 | 575 | .file(
|
@@ -609,6 +609,81 @@ 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-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_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/lib.rs", "") |
| 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("check -Z build-dir") |
| 646 | + .masquerade_as_nightly_cargo(&["build-dir"]) |
| 647 | + .enable_mac_dsym() |
| 648 | + .run(); |
| 649 | + |
| 650 | + // Parse and verify the hash dir created from the non-symlinked dir |
| 651 | + let foo_dir = p.root().join("foo"); |
| 652 | + assert_exists(&foo_dir); |
| 653 | + let original_hash_dir = parse_workspace_manifest_path_hash(&foo_dir); |
| 654 | + verify_layouts(&p, &original_hash_dir); |
| 655 | + |
| 656 | + // Create a symlink of the project root. |
| 657 | + let mut symlinked_dir = p.root().clone(); |
| 658 | + symlinked_dir.pop(); |
| 659 | + symlinked_dir = symlinked_dir.join("symlink-dir"); |
| 660 | + symlink(p.root(), &symlinked_dir).unwrap(); |
| 661 | + |
| 662 | + // Remove the foo dir (which contains the build-dir) before we rebuild from a symlinked dir. |
| 663 | + foo_dir.rm_rf(); |
| 664 | + |
| 665 | + // Run cargo from the symlinked dir |
| 666 | + p.cargo("check -Z build-dir") |
| 667 | + .cwd(&symlinked_dir) |
| 668 | + .masquerade_as_nightly_cargo(&["build-dir"]) |
| 669 | + .enable_mac_dsym() |
| 670 | + .run(); |
| 671 | + |
| 672 | + // Parse and verify the hash created from the symlinked dir |
| 673 | + assert_exists(&foo_dir); |
| 674 | + let symlink_hash_dir = parse_workspace_manifest_path_hash(&foo_dir); |
| 675 | + verify_layouts(&p, &symlink_hash_dir); |
| 676 | + |
| 677 | + // Verify the hash dir created from the symlinked and non-symlinked dirs are the same. |
| 678 | + assert_eq!(original_hash_dir, symlink_hash_dir); |
| 679 | + |
| 680 | + fn verify_layouts(p: &Project, build_dir_parent: &PathBuf) { |
| 681 | + let build_dir = build_dir_parent.as_path().join("build-dir"); |
| 682 | + assert_build_dir_layout(build_dir, "debug"); |
| 683 | + assert_artifact_dir_layout(p.root().join("target"), "debug"); |
| 684 | + } |
| 685 | +} |
| 686 | + |
612 | 687 | fn parse_workspace_manifest_path_hash(hash_dir: &PathBuf) -> PathBuf {
|
613 | 688 | // Since the hash will change between test runs simply find the first directories and assume
|
614 | 689 | // that is the hash dir. The format is a 2 char directory followed by the remaining hash in the
|
|
0 commit comments