Skip to content

Commit

Permalink
Check for [workspace] when finding workspace root
Browse files Browse the repository at this point in the history
Before, the top-most `Cargo.toml` file was used. Now we use the
nearest `Cargo.toml` file which contain a line saying `[workspace]`.

This should avoid false positives when Cargo workspaces are nested
inside each other: in this case, the inner package will have an empty
`[workspace]` table.
  • Loading branch information
mgeisler committed Apr 6, 2022
1 parent ec83506 commit 9960b05
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 8 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ members = ["xtask"]
[dependencies]
once_cell = "1"
dissimilar = "1"

[dev-dependencies]
tempfile = "3"
45 changes: 37 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -644,17 +644,23 @@ fn to_abs_ws_path(path: &Path) -> PathBuf {
static WORKSPACE_ROOT: OnceCell<PathBuf> = OnceCell::new();
WORKSPACE_ROOT
.get_or_try_init(|| {
let my_manifest = env::var("CARGO_MANIFEST_DIR")?;
let manifest_dir = env::var("CARGO_MANIFEST_DIR")?;

// Heuristic, see https://github.com/rust-lang/cargo/issues/3946
let workspace_root = Path::new(&my_manifest)
let workspace_root = Path::new(&manifest_dir)
.ancestors()
.filter(|it| it.join("Cargo.toml").exists())
.last()
.unwrap()
.to_path_buf();

Ok(workspace_root)
.filter(|it| match fs::read_to_string(it.join("Cargo.toml")) {
Ok(cargo_toml) => cargo_toml.lines().any(|line| line.trim() == "[workspace]"),
Err(_) => false, // no Cargo.toml
})
.next();

// Check if we found a workspace or if we should use
// manifest_dir.
match workspace_root {
Some(workspace_root) => Ok(workspace_root.to_path_buf()),
None => Ok(PathBuf::from(manifest_dir)),
}
})
.unwrap_or_else(|_: env::VarError| {
panic!("No CARGO_MANIFEST_DIR env var and the path is relative: {}", path.display())
Expand Down Expand Up @@ -867,4 +873,27 @@ line1
"#\"#\"#",
];
}

#[test]
fn test_nested_workspaces1() -> Result<(), std::io::Error> {
let dir = tempfile::tempdir()?;

let outer = dir.path().join("Cargo.toml");
let nested = dir.path().join("nested");
let inner = nested.join("Cargo.toml");

std::fs::write(outer, r#"[package]\nname = "foo""#)?;

std::fs::create_dir(&nested)?;
std::fs::write(&inner, r#"[package]\nname = "bar"\n[workspace]\n"#)?;

let old_manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
env::set_var("CARGO_MANIFEST_DIR", nested.as_os_str());
let nested_bar = to_abs_ws_path(&Path::new("bar.txt"));
env::set_var("CARGO_MANIFEST_DIR", old_manifest_dir);

assert_eq!(nested_bar, nested.join("bar.txt"));

Ok(())
}
}

0 comments on commit 9960b05

Please sign in to comment.