mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
feat(publish): respect .gitignore during deno publish
(#22514)
Files from `.gitignore`, global git config, `.git/info/exclude` and `deno.json`'s `exclude` are ignored.
This commit is contained in:
parent
ae703041b1
commit
f49abcc1ac
4 changed files with 156 additions and 19 deletions
51
Cargo.lock
generated
51
Cargo.lock
generated
|
@ -499,6 +499,16 @@ dependencies = [
|
|||
"alloc-stdlib",
|
||||
]
|
||||
|
||||
[[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"
|
||||
|
@ -1060,6 +1070,7 @@ dependencies = [
|
|||
"glibc_version",
|
||||
"glob",
|
||||
"hex",
|
||||
"ignore",
|
||||
"import_map",
|
||||
"indexmap",
|
||||
"jsonc-parser",
|
||||
|
@ -2847,6 +2858,19 @@ version = "0.3.1"
|
|||
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"
|
||||
|
@ -3314,6 +3338,23 @@ version = "1.0.2"
|
|||
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"
|
||||
|
@ -6482,6 +6523,16 @@ dependencies = [
|
|||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[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"
|
||||
|
|
|
@ -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"] }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -215,6 +215,43 @@ itest!(config_flag {
|
|||
http_server: true,
|
||||
});
|
||||
|
||||
#[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();
|
||||
|
@ -260,6 +297,35 @@ fn ignores_directories() {
|
|||
assert_not_contains!(output, "ignored.ts");
|
||||
}
|
||||
|
||||
#[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();
|
||||
|
@ -279,7 +345,6 @@ fn includes_directories() {
|
|||
let output = context
|
||||
.new_command()
|
||||
.arg("publish")
|
||||
.arg("--log-level=debug")
|
||||
.arg("--token")
|
||||
.arg("sadfasdf")
|
||||
.run();
|
||||
|
|
Loading…
Reference in a new issue