Don't recurse out of CARGO_HOME when looking for workspace root
authorAnthony Ramine <n.oxyde@gmail.com>
Fri, 1 Dec 2017 01:32:15 +0000 (02:32 +0100)
committerAnthony Ramine <n.oxyde@gmail.com>
Fri, 1 Dec 2017 01:41:02 +0000 (02:41 +0100)
This fixes #4765.

src/cargo/core/workspace.rs
src/cargo/util/flock.rs
tests/workspaces.rs

index 3dc50a6f2b4b0f5eb407e7db3229e9903335636e..dee5b248d6a1ca47ec18b9ea979c0cc6f90fc3de 100644 (file)
@@ -333,6 +333,9 @@ impl<'cfg> Workspace<'cfg> {
         }
 
         for path in paths::ancestors(manifest_path).skip(2) {
+            if self.config.home() == path {
+                return Ok(None);
+            }
             let ances_manifest_path = path.join("Cargo.toml");
             debug!("find_root - trying {}", ances_manifest_path.display());
             if ances_manifest_path.exists() {
index 9f6ae48ea38528b5c2bfea37dcd243e539bce1e5..0a8887d8b03c434947a4cdbfbbc739ab8700b8b8 100644 (file)
@@ -233,6 +233,18 @@ impl Filesystem {
     }
 }
 
+impl PartialEq<Path> for Filesystem {
+    fn eq(&self, other: &Path) -> bool {
+        self.root == other
+    }
+}
+
+impl PartialEq<Filesystem> for Path {
+    fn eq(&self, other: &Filesystem) -> bool {
+        self == other.root
+    }
+}
+
 /// Acquires a lock on a file in a "nice" manner.
 ///
 /// Almost all long-running blocking actions in Cargo have a status message
index c90464318fa3b6644f388633776cf364d48df369..19214dbd0798a0124739a28ea7798c3d6993a716 100644 (file)
@@ -1700,6 +1700,54 @@ fn dep_used_with_separate_features() {
 "));
 }
 
+#[test]
+fn dont_recurse_out_of_cargo_home() {
+    let git_project = git::new("dep", |project| {
+        project
+            .file("Cargo.toml", r#"
+                [package]
+                name = "dep"
+                version = "0.1.0"
+            "#)
+            .file("src/lib.rs", "")
+            .file("build.rs", r#"
+                use std::env;
+                use std::path::Path;
+                use std::process::{self, Command};
+
+                fn main() {
+                    let cargo = env::var_os("CARGO").unwrap();
+                    let cargo_manifest_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap();
+                    let output = Command::new(cargo)
+                        .args(&["metadata", "--format-version", "1", "--manifest-path"])
+                        .arg(&Path::new(&cargo_manifest_dir).join("Cargo.toml"))
+                        .output()
+                        .unwrap();
+                    if !output.status.success() {
+                        eprintln!("{}", String::from_utf8(output.stderr).unwrap());
+                        process::exit(1);
+                    }
+                }
+            "#)
+    }).unwrap();
+    let p = project("lib")
+        .file("Cargo.toml", &format!(r#"
+            [package]
+            name = "lib"
+            version = "0.1.0"
+
+            [dependencies.dep]
+            git = "{}"
+
+            [workspace]
+        "#, git_project.url()))
+        .file("src/lib.rs", "");
+    let p = p.build();
+
+    assert_that(p.cargo("build").env("CARGO_HOME", p.root().join(".cargo")),
+                execs().with_status(0));
+}
+
 /*FIXME: This fails because of how workspace.exclude and workspace.members are working.
 #[test]
 fn include_and_exclude() {