From d49882fa1ad7f46bab6859548778b20a80d68be4 Mon Sep 17 00:00:00 2001 From: CCherry07 <2405693142@qq.com> Date: Sun, 31 Mar 2024 16:53:41 +0800 Subject: [PATCH 1/9] feat: add_extension --- .../toolkit/src/pluginutils/add_extension.rs | 28 +++++++++++++++++++ .../toolkit/src/pluginutils/normalize_path.rs | 24 ++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 crates/toolkit/src/pluginutils/add_extension.rs create mode 100644 crates/toolkit/src/pluginutils/normalize_path.rs diff --git a/crates/toolkit/src/pluginutils/add_extension.rs b/crates/toolkit/src/pluginutils/add_extension.rs new file mode 100644 index 000000000..72392a66a --- /dev/null +++ b/crates/toolkit/src/pluginutils/add_extension.rs @@ -0,0 +1,28 @@ +use std::path::Path; + +pub fn add_extension(filename: &str, ext: Option<&str>) -> String { + let path = Path::new(filename); + if path.extension().is_none() { + format!("{}{}", filename, ext.unwrap_or(".js")) + } else { + filename.to_string() + } +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn add_extension_when_none_exists() { + let filename = "index"; + let filename_with_extension = add_extension(filename, None); + assert_eq!(filename_with_extension, "index.js"); + } + + #[test] + fn does_not_alter_filenames_with_existing_extension() { + let filename = "index.js"; + let filename_with_extension = add_extension(filename, Some(".ts")); + assert_eq!(filename_with_extension, "index.js"); + } +} diff --git a/crates/toolkit/src/pluginutils/normalize_path.rs b/crates/toolkit/src/pluginutils/normalize_path.rs new file mode 100644 index 000000000..f6b0176c5 --- /dev/null +++ b/crates/toolkit/src/pluginutils/normalize_path.rs @@ -0,0 +1,24 @@ +pub fn normalize_path(path: &str) -> String { + let windows_separator = "\\"; + path + .split(windows_separator) + .collect::>() + .join("/") +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_normalize_path() { + assert_eq!(normalize_path("folder\\file.txt"), "folder/file.txt"); + assert_eq!(normalize_path("folder\\\\file.txt"), "folder//file.txt"); + assert_eq!(normalize_path("C:\\folder\\file.txt"), "C:/folder/file.txt"); + assert_eq!(normalize_path("C:/folder/file.txt"), "C:/folder/file.txt"); + assert_eq!( + normalize_path("/folder\\subfolder\\file.txt"), + "/folder/subfolder/file.txt" + ); + } +} From c9076d7a6c768089be0308413205db9c2121f351 Mon Sep 17 00:00:00 2001 From: CCherry07 <2405693142@qq.com> Date: Sun, 31 Mar 2024 17:01:26 +0800 Subject: [PATCH 2/9] feat: add plugin utils --- crates/toolkit/src/lib.rs | 3 +++ crates/toolkit/src/pluginutils/mod.rs | 2 ++ 2 files changed, 5 insertions(+) create mode 100644 crates/toolkit/src/pluginutils/mod.rs diff --git a/crates/toolkit/src/lib.rs b/crates/toolkit/src/lib.rs index b50f8dada..5e0c720d9 100644 --- a/crates/toolkit/src/lib.rs +++ b/crates/toolkit/src/lib.rs @@ -40,3 +40,6 @@ pub use sourcemap; pub mod get_dynamic_resources_map; pub mod minify; + +// pluginutils +pub mod pluginutils; diff --git a/crates/toolkit/src/pluginutils/mod.rs b/crates/toolkit/src/pluginutils/mod.rs new file mode 100644 index 000000000..babb4b730 --- /dev/null +++ b/crates/toolkit/src/pluginutils/mod.rs @@ -0,0 +1,2 @@ +pub mod add_extension; +pub mod normalize_path; From 2fed5ad8f3fcd0f1129b739f5a22f4471b75870b Mon Sep 17 00:00:00 2001 From: CCherry07 <2405693142@qq.com> Date: Sun, 31 Mar 2024 17:11:10 +0800 Subject: [PATCH 3/9] feat: add create_filter --- Cargo.lock | 35 +++++-- crates/toolkit/Cargo.toml | 1 + crates/toolkit/src/resolve/create_filter.rs | 102 ++++++++++++++++++++ 3 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 crates/toolkit/src/resolve/create_filter.rs diff --git a/Cargo.lock b/Cargo.lock index a102ee1fd..8e2ffa0cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,9 +80,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -385,6 +385,16 @@ dependencies = [ "thiserror", ] +[[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.12.1" @@ -1612,6 +1622,7 @@ dependencies = [ "farmfe_testing_helpers", "farmfe_toolkit_plugin_types", "farmfe_utils 0.1.4", + "globset", "lazy_static", "preset_env_base", "sourcemap", @@ -1942,6 +1953,19 @@ dependencies = [ "xml-rs", ] +[[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.12.1" @@ -2575,12 +2599,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "lru" diff --git a/crates/toolkit/Cargo.toml b/crates/toolkit/Cargo.toml index 3f166d698..f66624db7 100644 --- a/crates/toolkit/Cargo.toml +++ b/crates/toolkit/Cargo.toml @@ -51,3 +51,4 @@ swc_ecma_utils = "0.126.0" lazy_static = "1.4.0" sourcemap = "6.2.3" anyhow = { version = "1.0.40", features = ["backtrace"] } +globset = "0.4.7" diff --git a/crates/toolkit/src/resolve/create_filter.rs b/crates/toolkit/src/resolve/create_filter.rs new file mode 100644 index 000000000..99d44b340 --- /dev/null +++ b/crates/toolkit/src/resolve/create_filter.rs @@ -0,0 +1,102 @@ +use globset::{GlobBuilder, GlobSetBuilder}; +use std::error::Error; + +pub fn create_filter<'a>( + include_patterns: Option<&'a [&str]>, + exclude_patterns: Option<&'a [&str]>, +) -> Result bool + 'a, Box> { + let mut include_builder = GlobSetBuilder::new(); + if let Some(patterns) = include_patterns { + for pattern in patterns { + include_builder.add(GlobBuilder::new(pattern.as_ref()).build()?); + } + } + let include_set = include_builder.build()?; + + let mut exclude_builder = GlobSetBuilder::new(); + if let Some(patterns) = exclude_patterns { + for pattern in patterns { + exclude_builder.add(GlobBuilder::new(pattern.as_ref()).build()?); + } + } + let exclude_set = exclude_builder.build()?; + + Ok(move |path: &str| { + let match_include = match include_patterns { + Some(patterns) => patterns.is_empty() || include_set.is_match(path), + None => true, + }; + let match_exclude = match exclude_patterns { + Some(patterns) => !patterns.is_empty() && exclude_set.is_match(path), + None => false, + }; + match_include && !match_exclude + }) +} +#[cfg(test)] +mod tests { + use crate::pluginutils::normalize_path::normalize_path; + + use super::*; + #[test] + fn includes_by_default() -> Result<(), Box> { + let filter = create_filter(None, None)?; + assert!(filter("index.html")); + Ok(()) + } + + #[test] + fn excludes_items_not_included_if_include_patterns_provided() -> Result<(), Box> { + let filter = create_filter(Some(&["*.y"]), None)?; + assert!(!filter("x")); + assert!(filter("a.y")); + Ok(()) + } + + #[test] + fn patterns_with_wildcards() -> Result<(), Box> { + let filter = create_filter(Some(&["*.y", "a.?"]), None)?; + assert!(filter("c.y")); + assert!(!filter("c.z")); + assert!(filter("a.x")); + assert!(!filter("b.x")); + Ok(()) + } + + #[test] + fn excludes_items_when_exclude_pattern_provided() -> Result<(), Box> { + let filter = create_filter(None, Some(&["*.tmp"]))?; + assert!(filter("a.out")); + assert!(!filter("b.tmp")); + Ok(()) + } + + #[test] + fn properly_handles_inclusion_and_exclusion_patterns() -> Result<(), Box> { + let filter = create_filter(Some(&["*.js"]), Some(&["*.min.js"]))?; + assert!(filter("app.js")); + assert!(!filter("app.min.js")); + assert!(!filter("app.ts")); + Ok(()) + } + + #[test] + fn handles_relative_paths_correctly() -> Result<(), Box> { + let filter = create_filter(Some(&["src/*.js"]), Some(&["src/*.test.js"]))?; + assert!(filter(&PathBuf::from("src/main.js").to_string_lossy())); + assert!(!filter( + &PathBuf::from("src/main.test.js").to_string_lossy() + )); + assert!(!filter(&PathBuf::from("lib/main.js").to_string_lossy())); + Ok(()) + } + + #[test] + fn handles_relative_paths() -> Result<(), Box> { + let filter = create_filter(Some(&["./index.js"]), Some(&["'./foo/../a.js'"]))?; + assert!(!filter(&normalize_path("index.js"))); + assert!(!filter(&normalize_path("a.js"))); + assert!(!filter(&normalize_path("foo/a.js"))); + Ok(()) + } +} From 7c24c10821aa1df8fadb95ab23bceb05d8596a2e Mon Sep 17 00:00:00 2001 From: CCherry07 <2405693142@qq.com> Date: Sun, 31 Mar 2024 17:12:48 +0800 Subject: [PATCH 4/9] feat: add create_filter --- crates/toolkit/src/{resolve => pluginutils}/create_filter.rs | 0 crates/toolkit/src/pluginutils/mod.rs | 1 + 2 files changed, 1 insertion(+) rename crates/toolkit/src/{resolve => pluginutils}/create_filter.rs (100%) diff --git a/crates/toolkit/src/resolve/create_filter.rs b/crates/toolkit/src/pluginutils/create_filter.rs similarity index 100% rename from crates/toolkit/src/resolve/create_filter.rs rename to crates/toolkit/src/pluginutils/create_filter.rs diff --git a/crates/toolkit/src/pluginutils/mod.rs b/crates/toolkit/src/pluginutils/mod.rs index babb4b730..bf0e82848 100644 --- a/crates/toolkit/src/pluginutils/mod.rs +++ b/crates/toolkit/src/pluginutils/mod.rs @@ -1,2 +1,3 @@ pub mod add_extension; +pub mod create_filter; pub mod normalize_path; From e0f9bc35d6a0dd6945eda0a51f59bca6db39d30f Mon Sep 17 00:00:00 2001 From: CCherry07 <2405693142@qq.com> Date: Sun, 31 Mar 2024 17:13:58 +0800 Subject: [PATCH 5/9] fix: PathBuf err --- crates/toolkit/src/pluginutils/create_filter.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/toolkit/src/pluginutils/create_filter.rs b/crates/toolkit/src/pluginutils/create_filter.rs index 99d44b340..cbd4e2bcd 100644 --- a/crates/toolkit/src/pluginutils/create_filter.rs +++ b/crates/toolkit/src/pluginutils/create_filter.rs @@ -35,9 +35,10 @@ pub fn create_filter<'a>( } #[cfg(test)] mod tests { + use super::*; + use std::path::PathBuf; use crate::pluginutils::normalize_path::normalize_path; - use super::*; #[test] fn includes_by_default() -> Result<(), Box> { let filter = create_filter(None, None)?; From c94c32f1c7e7bd74825f30f51ae60636494d170b Mon Sep 17 00:00:00 2001 From: CCherry07 <2405693142@qq.com> Date: Mon, 1 Apr 2024 12:37:49 +0800 Subject: [PATCH 6/9] feat: patterns_builder --- .../toolkit/src/pluginutils/create_filter.rs | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/crates/toolkit/src/pluginutils/create_filter.rs b/crates/toolkit/src/pluginutils/create_filter.rs index cbd4e2bcd..7b7eef9bc 100644 --- a/crates/toolkit/src/pluginutils/create_filter.rs +++ b/crates/toolkit/src/pluginutils/create_filter.rs @@ -1,25 +1,12 @@ -use globset::{GlobBuilder, GlobSetBuilder}; +use globset::{GlobBuilder, GlobSet, GlobSetBuilder}; use std::error::Error; pub fn create_filter<'a>( include_patterns: Option<&'a [&str]>, exclude_patterns: Option<&'a [&str]>, ) -> Result bool + 'a, Box> { - let mut include_builder = GlobSetBuilder::new(); - if let Some(patterns) = include_patterns { - for pattern in patterns { - include_builder.add(GlobBuilder::new(pattern.as_ref()).build()?); - } - } - let include_set = include_builder.build()?; - - let mut exclude_builder = GlobSetBuilder::new(); - if let Some(patterns) = exclude_patterns { - for pattern in patterns { - exclude_builder.add(GlobBuilder::new(pattern.as_ref()).build()?); - } - } - let exclude_set = exclude_builder.build()?; + let include_set = patterns_builder(include_patterns)?; + let exclude_set = patterns_builder(exclude_patterns)?; Ok(move |path: &str| { let match_include = match include_patterns { @@ -33,11 +20,22 @@ pub fn create_filter<'a>( match_include && !match_exclude }) } + +fn patterns_builder<'a>(patterns: Option<&'a [&str]>) -> Result> { + let mut builder = GlobSetBuilder::new(); + if let Some(patterns) = patterns { + for pattern in patterns { + builder.add(GlobBuilder::new(pattern.as_ref()).build()?); + } + } + Ok(builder.build()?) +} + #[cfg(test)] mod tests { use super::*; - use std::path::PathBuf; use crate::pluginutils::normalize_path::normalize_path; + use std::path::PathBuf; #[test] fn includes_by_default() -> Result<(), Box> { From b27e7a909cfd70684eed03af834ae4dfac68ee52 Mon Sep 17 00:00:00 2001 From: CCherry07 <2405693142@qq.com> Date: Tue, 2 Apr 2024 02:15:32 +0800 Subject: [PATCH 7/9] feat: update patterns type --- .../toolkit/src/pluginutils/create_filter.rs | 50 ++++++++----------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/crates/toolkit/src/pluginutils/create_filter.rs b/crates/toolkit/src/pluginutils/create_filter.rs index 7b7eef9bc..19795e4e1 100644 --- a/crates/toolkit/src/pluginutils/create_filter.rs +++ b/crates/toolkit/src/pluginutils/create_filter.rs @@ -2,35 +2,29 @@ use globset::{GlobBuilder, GlobSet, GlobSetBuilder}; use std::error::Error; pub fn create_filter<'a>( - include_patterns: Option<&'a [&str]>, - exclude_patterns: Option<&'a [&str]>, + include_patterns: Option>, + exclude_patterns: Option>, ) -> Result bool + 'a, Box> { - let include_set = patterns_builder(include_patterns)?; - let exclude_set = patterns_builder(exclude_patterns)?; + let include_set = patterns_builder(include_patterns.as_deref())?; + let exclude_set = patterns_builder(exclude_patterns.as_deref())?; - Ok(move |path: &str| { - let match_include = match include_patterns { - Some(patterns) => patterns.is_empty() || include_set.is_match(path), - None => true, - }; - let match_exclude = match exclude_patterns { - Some(patterns) => !patterns.is_empty() && exclude_set.is_match(path), - None => false, - }; - match_include && !match_exclude + Ok(move |path: &str| { + let match_include = include_set.is_match(path) || include_set.is_empty(); + let match_exclude = exclude_set.is_match(path) && !exclude_set.is_empty(); + + match_include && !match_exclude }) } -fn patterns_builder<'a>(patterns: Option<&'a [&str]>) -> Result> { - let mut builder = GlobSetBuilder::new(); - if let Some(patterns) = patterns { - for pattern in patterns { - builder.add(GlobBuilder::new(pattern.as_ref()).build()?); +fn patterns_builder(patterns: Option<&[&str]>) -> Result> { + let mut builder = GlobSetBuilder::new(); + if let Some(patterns) = patterns { + for &pattern in patterns { + builder.add(GlobBuilder::new(pattern).build()?); + } } - } - Ok(builder.build()?) + builder.build().map_err(Into::into) } - #[cfg(test)] mod tests { use super::*; @@ -46,7 +40,7 @@ mod tests { #[test] fn excludes_items_not_included_if_include_patterns_provided() -> Result<(), Box> { - let filter = create_filter(Some(&["*.y"]), None)?; + let filter = create_filter(Some(vec!["*.y"]), None)?; assert!(!filter("x")); assert!(filter("a.y")); Ok(()) @@ -54,7 +48,7 @@ mod tests { #[test] fn patterns_with_wildcards() -> Result<(), Box> { - let filter = create_filter(Some(&["*.y", "a.?"]), None)?; + let filter = create_filter(Some(vec!["*.y", "a.?"]), None)?; assert!(filter("c.y")); assert!(!filter("c.z")); assert!(filter("a.x")); @@ -64,7 +58,7 @@ mod tests { #[test] fn excludes_items_when_exclude_pattern_provided() -> Result<(), Box> { - let filter = create_filter(None, Some(&["*.tmp"]))?; + let filter = create_filter(None, Some(vec!["*.tmp"]))?; assert!(filter("a.out")); assert!(!filter("b.tmp")); Ok(()) @@ -72,7 +66,7 @@ mod tests { #[test] fn properly_handles_inclusion_and_exclusion_patterns() -> Result<(), Box> { - let filter = create_filter(Some(&["*.js"]), Some(&["*.min.js"]))?; + let filter = create_filter(Some(vec!["*.js"]), Some(vec!["*.min.js"]))?; assert!(filter("app.js")); assert!(!filter("app.min.js")); assert!(!filter("app.ts")); @@ -81,7 +75,7 @@ mod tests { #[test] fn handles_relative_paths_correctly() -> Result<(), Box> { - let filter = create_filter(Some(&["src/*.js"]), Some(&["src/*.test.js"]))?; + let filter = create_filter(Some(vec!["src/*.js"]), Some(vec!["src/*.test.js"]))?; assert!(filter(&PathBuf::from("src/main.js").to_string_lossy())); assert!(!filter( &PathBuf::from("src/main.test.js").to_string_lossy() @@ -92,7 +86,7 @@ mod tests { #[test] fn handles_relative_paths() -> Result<(), Box> { - let filter = create_filter(Some(&["./index.js"]), Some(&["'./foo/../a.js'"]))?; + let filter = create_filter(Some(vec!["./index.js"]), Some(vec!["'./foo/../a.js'"]))?; assert!(!filter(&normalize_path("index.js"))); assert!(!filter(&normalize_path("a.js"))); assert!(!filter(&normalize_path("foo/a.js"))); From 384c204277fb107f4daf4752abb3f939ece42593 Mon Sep 17 00:00:00 2001 From: CCherry07 <2405693142@qq.com> Date: Tue, 2 Apr 2024 10:36:58 +0800 Subject: [PATCH 8/9] chore: update globset version --- crates/toolkit/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/toolkit/Cargo.toml b/crates/toolkit/Cargo.toml index 82af769cf..d6d9db341 100644 --- a/crates/toolkit/Cargo.toml +++ b/crates/toolkit/Cargo.toml @@ -51,4 +51,4 @@ swc_ecma_utils = "=0.126.0" lazy_static = "1.4.0" sourcemap = "6.2.3" anyhow = { version = "1.0.40", features = ["backtrace"] } -globset = "0.4.7" +globset = "0.4.14" From 1bfffd0f05ae429cd12a0ac5287cbe8150f28d18 Mon Sep 17 00:00:00 2001 From: CCherry07 <2405693142@qq.com> Date: Tue, 2 Apr 2024 14:18:49 +0800 Subject: [PATCH 9/9] feat: add words --- cspell.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cspell.json b/cspell.json index 634ddc698..e1abb68d9 100644 --- a/cspell.json +++ b/cspell.json @@ -158,7 +158,8 @@ "concurrentify", "pageerror", "deepmerge", - "Mergeable" + "Mergeable", + "globset" ], "ignorePaths": [ "pnpm-lock.yaml",