summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/util/fs.rs25
-rw-r--r--cli/util/gitignore.rs20
-rw-r--r--tests/integration/publish_tests.rs31
3 files changed, 69 insertions, 7 deletions
diff --git a/cli/util/fs.rs b/cli/util/fs.rs
index f6354097a..352e09999 100644
--- a/cli/util/fs.rs
+++ b/cli/util/fs.rs
@@ -326,7 +326,30 @@ impl<TFilter: Fn(WalkEntry) -> bool> FileCollector<TFilter> {
}
let mut maybe_git_ignores = if self.use_gitignore {
- Some(GitIgnoreTree::new(Arc::new(deno_runtime::deno_fs::RealFs)))
+ // Override explicitly specified include paths in the
+ // .gitignore file. This does not apply to globs because
+ // that is way too complicated to reason about.
+ let include_paths = file_patterns
+ .include
+ .as_ref()
+ .map(|include| {
+ include
+ .inner()
+ .iter()
+ .filter_map(|path_or_pattern| {
+ if let PathOrPattern::Path(p) = path_or_pattern {
+ Some(p.clone())
+ } else {
+ None
+ }
+ })
+ .collect::<Vec<_>>()
+ })
+ .unwrap_or_default();
+ Some(GitIgnoreTree::new(
+ Arc::new(deno_runtime::deno_fs::RealFs),
+ include_paths,
+ ))
} else {
None
};
diff --git a/cli/util/gitignore.rs b/cli/util/gitignore.rs
index da9065494..f4185aa0d 100644
--- a/cli/util/gitignore.rs
+++ b/cli/util/gitignore.rs
@@ -38,13 +38,19 @@ impl DirGitIgnores {
pub struct GitIgnoreTree {
fs: Arc<dyn deno_runtime::deno_fs::FileSystem>,
ignores: HashMap<PathBuf, Option<Rc<DirGitIgnores>>>,
+ include_paths: Vec<PathBuf>,
}
impl GitIgnoreTree {
- pub fn new(fs: Arc<dyn deno_runtime::deno_fs::FileSystem>) -> Self {
+ pub fn new(
+ fs: Arc<dyn deno_runtime::deno_fs::FileSystem>,
+ // paths that should override what's in the gitignore
+ include_paths: Vec<PathBuf>,
+ ) -> Self {
Self {
fs,
ignores: Default::default(),
+ include_paths,
}
}
@@ -94,6 +100,16 @@ impl GitIgnoreTree {
for line in text.lines() {
builder.add_line(None, line).ok()?;
}
+ // override the gitignore contents to include these paths
+ for path in &self.include_paths {
+ if let Ok(suffix) = path.strip_prefix(dir_path) {
+ let suffix = suffix.to_string_lossy().replace('\\', "/");
+ let _ignore = builder.add_line(None, &format!("!/{}", suffix));
+ if !suffix.ends_with('/') {
+ let _ignore = builder.add_line(None, &format!("!/{}/", suffix));
+ }
+ }
+ }
let gitignore = builder.build().ok()?;
Some(Rc::new(gitignore))
});
@@ -122,7 +138,7 @@ mod test {
"!file.txt\nignore.txt".into(),
),
]);
- let mut ignore_tree = GitIgnoreTree::new(Arc::new(fs));
+ let mut ignore_tree = GitIgnoreTree::new(Arc::new(fs), Vec::new());
let mut run_test = |path: &str, expected: bool| {
let path = PathBuf::from(path);
let gitignore = ignore_tree
diff --git a/tests/integration/publish_tests.rs b/tests/integration/publish_tests.rs
index 53bb6a376..28046d047 100644
--- a/tests/integration/publish_tests.rs
+++ b/tests/integration/publish_tests.rs
@@ -409,7 +409,7 @@ fn ignores_directories() {
}
#[test]
-fn not_include_gitignored_file_even_if_matched_in_include() {
+fn not_include_gitignored_file_unless_exact_match_in_include() {
let context = publish_context_builder().build();
let temp_dir = context.temp_dir().path();
temp_dir.join("deno.json").write_json(&json!({
@@ -417,22 +417,45 @@ fn not_include_gitignored_file_even_if_matched_in_include() {
"version": "1.0.0",
"exports": "./main.ts",
"publish": {
- // won't match ignored because it needs to be
+ // won't match ignored.ts because it needs to be
// unexcluded via a negated glob in exclude
- "include": [ "deno.json", "*.ts" ]
+ "include": [
+ "deno.json",
+ "*.ts",
+ "exact_include.ts",
+ "sub"
+ ]
}
}));
- temp_dir.join(".gitignore").write("ignored.ts");
+ temp_dir
+ .join(".gitignore")
+ .write("ignored.ts\nexact_include.ts\nsub/\nsub/ignored\n/sub_ignored\n");
temp_dir.join("main.ts").write("");
temp_dir.join("ignored.ts").write("");
+ temp_dir.join("exact_include.ts").write("");
+ let sub_dir = temp_dir.join("sub");
+ sub_dir.create_dir_all();
+ sub_dir.join("sub_included.ts").write("");
+ sub_dir.join("ignored.ts").write(""); // this one is gitignored
+ sub_dir.join("ignored").create_dir_all();
+ sub_dir.join("ignored").join("ignored_also.ts").write("");
+ let sub_ignored_dir = temp_dir.join("sub_ignored");
+ sub_ignored_dir.create_dir_all();
+ sub_ignored_dir.join("sub_ignored.ts").write("");
let output = context.new_command().arg("publish").arg("--dry-run").run();
output.assert_exit_code(0);
let output = output.combined_output();
assert_contains!(output, "main.ts");
+ // will match this exact match
+ assert_contains!(output, "exact_include.ts");
+ // will include this because the sub directory is included
+ assert_contains!(output, "sub_included.ts");
// it's gitignored
assert_not_contains!(output, "ignored.ts");
+ assert_not_contains!(output, "ignored_also.ts");
+ assert_not_contains!(output, "sub_ignored.ts");
}
#[test]