diff --git a/src/cargo/sources/path.rs b/src/cargo/sources/path.rs index db8e7d99876..0c4b1faa595 100644 --- a/src/cargo/sources/path.rs +++ b/src/cargo/sources/path.rs @@ -147,6 +147,8 @@ impl<'cfg> PathSource<'cfg> { if let Some(result) = self.discover_git_and_list_files(pkg, root, &mut filter) { return result; } + // no include option and not git repo discovered (see rust-lang/cargo#7183). + return self.list_files_walk_except_dot_files_and_dirs(pkg, &mut filter); } self.list_files_walk(pkg, &mut filter) } @@ -329,6 +331,28 @@ impl<'cfg> PathSource<'cfg> { } } + fn list_files_walk_except_dot_files_and_dirs( + &self, + pkg: &Package, + filter: &mut dyn FnMut(&Path) -> CargoResult, + ) -> CargoResult> { + let root = pkg.root(); + let mut exclude_dot_files_dir_builder = GitignoreBuilder::new(root); + exclude_dot_files_dir_builder.add_line(None, ".*")?; + let ignore_dot_files_and_dirs = exclude_dot_files_dir_builder.build()?; + + let mut filter_ignore_dot_files_and_dirs = |path: &Path| -> CargoResult { + let relative_path = path.strip_prefix(root)?; + match ignore_dot_files_and_dirs + .matched_path_or_any_parents(relative_path, /* is_dir */ false) + { + Match::Ignore(_) => Ok(false), + _ => filter(path), + } + }; + self.list_files_walk(pkg, &mut filter_ignore_dot_files_and_dirs) + } + fn list_files_walk( &self, pkg: &Package, @@ -368,10 +392,6 @@ impl<'cfg> PathSource<'cfg> { entries.sort_unstable_by(|a, b| a.as_os_str().cmp(b.as_os_str())); for path in entries { let name = path.file_name().and_then(|s| s.to_str()); - // Skip dotfile directories. - if name.map(|s| s.starts_with('.')) == Some(true) { - continue; - } if is_root && name == Some("target") { // Skip Cargo artifacts. continue; diff --git a/tests/testsuite/package.rs b/tests/testsuite/package.rs index 811642afa39..8b924eed791 100644 --- a/tests/testsuite/package.rs +++ b/tests/testsuite/package.rs @@ -425,11 +425,12 @@ fn include() { version = "0.0.1" authors = [] exclude = ["*.txt"] - include = ["foo.txt", "**/*.rs", "Cargo.toml"] + include = ["foo.txt", "**/*.rs", "Cargo.toml", ".dotfile"] "#, ) .file("foo.txt", "") .file("src/main.rs", r#"fn main() { println!("hello"); }"#) + .file(".dotfile", "") // Should be ignored when packaging. .file("src/bar.txt", "") .build(); @@ -442,6 +443,7 @@ fn include() { See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info. [WARNING] both package.include and package.exclude are specified; the exclude list will be ignored [PACKAGING] foo v0.0.1 ([..]) +[ARCHIVING] .dotfile [ARCHIVING] Cargo.toml [ARCHIVING] foo.txt [ARCHIVING] src/main.rs @@ -1420,3 +1422,26 @@ fn gitignore_negate() { ", ); } + +#[cargo_test] +fn exclude_dot_files_and_directories_by_default() { + include_exclude_test( + "[]", + "[]", + &["src/lib.rs", ".dotfile", ".dotdir/file"], + "Cargo.toml\n\ + src/lib.rs\n\ + ", + ); + + include_exclude_test( + r#"["Cargo.toml", "src/lib.rs", ".dotfile", ".dotdir/file"]"#, + "[]", + &["src/lib.rs", ".dotfile", ".dotdir/file"], + ".dotdir/file\n\ + .dotfile\n\ + Cargo.toml\n\ + src/lib.rs\n\ + ", + ); +}