summaryrefslogtreecommitdiff
path: root/cli/tools/registry/tar.rs
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2024-02-23 07:56:34 +0530
committerGitHub <noreply@github.com>2024-02-23 07:56:34 +0530
commitf49abcc1ac3de72bf894ccfc0102d83ec19f1d46 (patch)
tree8a50b03bb1e1d2e9e8831620529ef328a5582041 /cli/tools/registry/tar.rs
parentae703041b1921affb7fa8a0aa865c6f302c72d6e (diff)
feat(publish): respect .gitignore during `deno publish` (#22514)
Files from `.gitignore`, global git config, `.git/info/exclude` and `deno.json`'s `exclude` are ignored.
Diffstat (limited to 'cli/tools/registry/tar.rs')
-rw-r--r--cli/tools/registry/tar.rs56
1 files changed, 38 insertions, 18 deletions
diff --git a/cli/tools/registry/tar.rs b/cli/tools/registry/tar.rs
index 3dc2616fa..66d15b5a6 100644
--- a/cli/tools/registry/tar.rs
+++ b/cli/tools/registry/tar.rs
@@ -3,12 +3,14 @@
use bytes::Bytes;
use deno_ast::MediaType;
use deno_config::glob::FilePatterns;
+use deno_config::glob::PathOrPattern;
use deno_core::anyhow::Context;
use deno_core::error::AnyError;
use deno_core::url::Url;
+use ignore::overrides::OverrideBuilder;
+use ignore::WalkBuilder;
use sha2::Digest;
use std::collections::HashSet;
-use std::ffi::OsStr;
use std::fmt::Write as FmtWrite;
use std::io::Write;
use std::path::Path;
@@ -46,27 +48,45 @@ pub fn create_gzipped_tarball(
let mut paths = HashSet::new();
- let mut iterator = walkdir::WalkDir::new(dir).follow_links(false).into_iter();
- while let Some(entry) = iterator.next() {
+ let mut ob = OverrideBuilder::new(dir);
+ ob.add("!.git")?.add("!node_modules")?.add("!.DS_Store")?;
+
+ for pattern in file_patterns.as_ref().iter().flat_map(|p| p.include.iter()) {
+ for path_or_pat in pattern.inner() {
+ match path_or_pat {
+ PathOrPattern::Path(p) => ob.add(p.to_str().unwrap())?,
+ PathOrPattern::Pattern(p) => ob.add(p.as_str())?,
+ PathOrPattern::RemoteUrl(_) => continue,
+ };
+ }
+ }
+
+ let overrides = ob.build()?;
+
+ let iterator = WalkBuilder::new(dir)
+ .follow_links(false)
+ .require_git(false)
+ .git_ignore(true)
+ .git_global(true)
+ .git_exclude(true)
+ .overrides(overrides)
+ .filter_entry(move |entry| {
+ let matches_pattern = file_patterns
+ .as_ref()
+ .map(|p| p.matches_path(entry.path()))
+ .unwrap_or(true);
+ matches_pattern
+ })
+ .build();
+
+ for entry in iterator {
let entry = entry?;
let path = entry.path();
- let file_type = entry.file_type();
-
- let matches_pattern = file_patterns
- .as_ref()
- .map(|p| p.matches_path(path))
- .unwrap_or(true);
- if !matches_pattern
- || path.file_name() == Some(OsStr::new(".git"))
- || path.file_name() == Some(OsStr::new("node_modules"))
- || path.file_name() == Some(OsStr::new(".DS_Store"))
- {
- if file_type.is_dir() {
- iterator.skip_current_dir();
- }
+ let Some(file_type) = entry.file_type() else {
+ // entry doesn’t have a file type if it corresponds to stdin.
continue;
- }
+ };
let Ok(specifier) = Url::from_file_path(path) else {
diagnostics_collector