diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2024-02-23 07:56:34 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-23 07:56:34 +0530 |
commit | f49abcc1ac3de72bf894ccfc0102d83ec19f1d46 (patch) | |
tree | 8a50b03bb1e1d2e9e8831620529ef328a5582041 /cli/tools/registry/tar.rs | |
parent | ae703041b1921affb7fa8a0aa865c6f302c72d6e (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.rs | 56 |
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 |