Be less strict about loading directory sources
authorAlex Crichton <alex@alexcrichton.com>
Wed, 24 Jan 2018 18:04:47 +0000 (10:04 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Wed, 24 Jan 2018 23:41:45 +0000 (15:41 -0800)
Historically Cargo has been pretty strict about loading directory sources by
ensuring that everything inside was a crate. This was intended to protect
against accidental misconfiguration by failing loudly rather than silently
returning fewer crates.

This has caused a number of issues, however:

* #4969
* #4811
* #3899

so it seems like this is too aspirational of Cargo

Closes #4811
Closes #4969

src/cargo/sources/directory.rs
tests/directory.rs

index 8416485b572fa5be75a29f2a610c87fe2826db54..04df0a5ba627e834b14982609d0c5538e11f1d98 100644 (file)
@@ -97,23 +97,16 @@ impl<'cfg> Source for DirectorySource<'cfg> {
             // when a dir is removed from a different checkout. Sometimes a
             // mostly-empty dir is left behind.
             //
-            // To help Cargo work by default in more cases we try to handle this
-            // case by default. If the directory looks like it only has dotfiles
-            // in it (or no files at all) then we skip it.
+            // Additionally vendor directories are sometimes accompanied with
+            // readme files and other auxiliary information not too interesting
+            // to Cargo.
             //
-            // In general we don't want to skip completely malformed directories
-            // to help with debugging, so we don't just ignore errors in
-            // `update` below.
-            let mut only_dotfile = true;
-            for entry in path.read_dir()?.filter_map(|e| e.ok()) {
-                if let Some(s) = entry.file_name().to_str() {
-                    if s.starts_with('.') {
-                        continue
-                    }
-                }
-                only_dotfile = false;
-            }
-            if only_dotfile {
+            // To help handle all this we only try processing folders with a
+            // `Cargo.toml` in them. This has the upside of being pretty
+            // flexible with the contents of vendor directories but has the
+            // downside of accidentally misconfigured vendor directories
+            // silently returning less crates.
+            if !path.join("Cargo.toml").exists() {
                 continue
             }
 
index 83e56106175b43c5833d7a2deb3e463787f57b77..6dde10e97e8ba0d0ada08d77aae6fb0031d6414a 100644 (file)
@@ -511,6 +511,40 @@ fn only_dot_files_ok() {
     assert_that(p.cargo("build"), execs().with_status(0));
 }
 
+#[test]
+fn random_files_ok() {
+    setup();
+
+    VendorPackage::new("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.1.0"
+            authors = []
+        "#)
+        .file("src/lib.rs", "")
+        .build();
+    VendorPackage::new("bar")
+        .file("foo", "")
+        .file("../test", "")
+        .build();
+
+    let p = project("bar")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "bar"
+            version = "0.1.0"
+            authors = []
+
+            [dependencies]
+            foo = "0.1.0"
+        "#)
+        .file("src/lib.rs", "")
+        .build();
+
+    assert_that(p.cargo("build"), execs().with_status(0));
+}
+
 #[test]
 fn git_lock_file_doesnt_change() {