Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check for [workspace] when finding workspace root #30

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
23 changes: 14 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -644,17 +644,22 @@ 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)
.ancestors()
.filter(|it| it.join("Cargo.toml").exists())
.last()
.unwrap()
.to_path_buf();

Ok(workspace_root)
let workspace_root = Path::new(&manifest_dir).ancestors().find(|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
}
});

// 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
36 changes: 36 additions & 0 deletions tests/nested-workspaces.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Because this test modifies CARGO_MANIFEST_DIR, it has to be run as
// an integration test. This way we can isolate the modification to
// just one process.

use std::env;
use std::fs;
use std::path::Path;

use expect_test::ExpectFile;

#[test]
fn test_nested_workspaces() -> Result<(), std::io::Error> {
let tmpdir = tempfile::tempdir()?;
let outer_toml = tmpdir.path().join("Cargo.toml");
let nested = tmpdir.path().join("nested");
let nested_src = nested.join("src");
let inner_toml = nested.join("Cargo.toml");

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

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

// Fabricate a ExpectFile as if had been created with expect_file!
// inside the nested project.
env::set_var("CARGO_MANIFEST_DIR", nested.as_os_str());
let expect_file = ExpectFile { path: Path::new("bar.txt").to_owned(), position: "src/lib.rs" };
// Populate nested/src/bar.txt.
env::set_var("UPDATE_EXPECT", "1");
expect_file.assert_eq("Expected content");

assert_eq!(fs::read_to_string(nested_src.join("bar.txt"))?, "Expected content");

Ok(())
}