summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock51
-rw-r--r--cli/Cargo.toml1
-rw-r--r--cli/tools/registry/tar.rs56
-rw-r--r--tests/integration/publish_tests.rs67
4 files changed, 156 insertions, 19 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 1cb8c9d48..5e6d1ee4e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -500,6 +500,16 @@ dependencies = [
]
[[package]]
+name = "bstr"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c"
+dependencies = [
+ "memchr",
+ "serde",
+]
+
+[[package]]
name = "bumpalo"
version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1060,6 +1070,7 @@ dependencies = [
"glibc_version",
"glob",
"hex",
+ "ignore",
"import_map",
"indexmap",
"jsonc-parser",
@@ -2848,6 +2859,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
+name = "globset"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1"
+dependencies = [
+ "aho-corasick",
+ "bstr",
+ "log",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
name = "glow"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3315,6 +3339,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed"
[[package]]
+name = "ignore"
+version = "0.4.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492"
+dependencies = [
+ "globset",
+ "lazy_static",
+ "log",
+ "memchr",
+ "regex",
+ "same-file",
+ "thread_local",
+ "walkdir",
+ "winapi-util",
+]
+
+[[package]]
name = "image"
version = "0.24.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6483,6 +6524,16 @@ dependencies = [
]
[[package]]
+name = "thread_local"
+version = "1.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+]
+
+[[package]]
name = "time"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/cli/Cargo.toml b/cli/Cargo.toml
index ae42d3c30..b376f924e 100644
--- a/cli/Cargo.toml
+++ b/cli/Cargo.toml
@@ -106,6 +106,7 @@ flate2.workspace = true
fs3.workspace = true
glob = "0.3.1"
hex.workspace = true
+ignore = "0.4"
import_map = { version = "=0.18.3", features = ["ext"] }
indexmap.workspace = true
jsonc-parser = { version = "=0.23.0", features = ["serde"] }
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
diff --git a/tests/integration/publish_tests.rs b/tests/integration/publish_tests.rs
index 61cb40fba..71bc838a8 100644
--- a/tests/integration/publish_tests.rs
+++ b/tests/integration/publish_tests.rs
@@ -216,6 +216,43 @@ itest!(config_flag {
});
#[test]
+fn ignores_gitignore() {
+ let context = publish_context_builder().build();
+ let temp_dir = context.temp_dir().path();
+ temp_dir.join("deno.json").write_json(&json!({
+ "name": "@foo/bar",
+ "version": "1.0.0",
+ "exports": "./main.ts"
+ }));
+
+ temp_dir.join("main.ts").write("import './sub_dir/b.ts';");
+
+ let gitignore = temp_dir.join(".gitignore");
+ gitignore.write("ignored.ts\nsub_dir/ignored.wasm");
+
+ let sub_dir = temp_dir.join("sub_dir");
+ sub_dir.create_dir_all();
+ sub_dir.join("ignored.wasm").write("");
+ sub_dir.join("b.ts").write("export default {}");
+
+ temp_dir.join("ignored.ts").write("");
+
+ let output = context
+ .new_command()
+ .arg("publish")
+ .arg("--dry-run")
+ .arg("--token")
+ .arg("sadfasdf")
+ .run();
+ output.assert_exit_code(0);
+ let output = output.combined_output();
+ assert_contains!(output, "b.ts");
+ assert_contains!(output, "main.ts");
+ assert_not_contains!(output, "ignored.ts");
+ assert_not_contains!(output, "ignored.wasm");
+}
+
+#[test]
fn ignores_directories() {
let context = publish_context_builder().build();
let temp_dir = context.temp_dir().path();
@@ -261,6 +298,35 @@ fn ignores_directories() {
}
#[test]
+fn includes_directories_with_gitignore() {
+ let context = publish_context_builder().build();
+ let temp_dir = context.temp_dir().path();
+ temp_dir.join("deno.json").write_json(&json!({
+ "name": "@foo/bar",
+ "version": "1.0.0",
+ "exports": "./main.ts",
+ "publish": {
+ "include": [ "deno.json", "main.ts" ]
+ }
+ }));
+
+ temp_dir.join(".gitignore").write("main.ts");
+ temp_dir.join("main.ts").write("");
+ temp_dir.join("ignored.ts").write("");
+
+ let output = context
+ .new_command()
+ .arg("publish")
+ .arg("--token")
+ .arg("sadfasdf")
+ .run();
+ output.assert_exit_code(0);
+ let output = output.combined_output();
+ assert_contains!(output, "main.ts");
+ assert_not_contains!(output, "ignored.ts");
+}
+
+#[test]
fn includes_directories() {
let context = publish_context_builder().build();
let temp_dir = context.temp_dir().path();
@@ -279,7 +345,6 @@ fn includes_directories() {
let output = context
.new_command()
.arg("publish")
- .arg("--log-level=debug")
.arg("--token")
.arg("sadfasdf")
.run();