aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-08-16 16:26:08 +0900
committernsfisis <nsfisis@gmail.com>2026-08-16 17:34:46 +0900
commita9b45cc01afa726bf9acd7f30ad3235593a258e2 (patch)
tree027b392d52d6e00a874853b5091be1cfa47563d4 /crates/shirabe
parent659e8a4ee130d968ef6bfb22159fb547e366f969 (diff)
downloadphp-shirabe-a9b45cc01afa726bf9acd7f30ad3235593a258e2.tar.gz
php-shirabe-a9b45cc01afa726bf9acd7f30ad3235593a258e2.tar.zst
php-shirabe-a9b45cc01afa726bf9acd7f30ad3235593a258e2.zip
fix(autoload): expand the dirsep placeholder in target-dir patterns
AutoloadGenerator.php builds the target-dir pattern by quoting the path with a <dirsep> marker in place of the separators, then replacing the quoted marker with [\\/]. The port kept that shape, but preg_quote() here deliberately leaves < and > alone so the regex crate does not read \< as a word boundary, so the replacement never matched and the pattern came out as the literal {^Main<dirsep>Foo<dirsep>}. A root package's target-dir was therefore never stripped from files, classmap or exclude-from-classmap, and dumping one failed outright. Split on the separators and quote each segment instead, so the marker never passes through preg_quote() at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe')
-rw-r--r--crates/shirabe/src/autoload/autoload_generator.rs35
-rw-r--r--crates/shirabe/tests/autoload/autoload_generator_test.rs1
2 files changed, 15 insertions, 21 deletions
diff --git a/crates/shirabe/src/autoload/autoload_generator.rs b/crates/shirabe/src/autoload/autoload_generator.rs
index 0f7fe22a..91df1749 100644
--- a/crates/shirabe/src/autoload/autoload_generator.rs
+++ b/crates/shirabe/src/autoload/autoload_generator.rs
@@ -1896,17 +1896,21 @@ class ComposerStaticInit{}
{
// remove target-dir from file paths of the root package
if is_root {
- let target_dir = str_replace(
- "\\<dirsep\\>",
- "[\\\\/]",
- &preg_quote(
- &str_replace_multi(
- &package.get_target_dir().unwrap_or_default(),
- &[("/", "<dirsep>"), ("\\", "<dirsep>")],
- ),
- None,
- ),
- );
+ // Regex pattern compatibility:
+ // PHP swaps every path separator for a `<dirsep>` marker, runs
+ // `preg_quote` over the whole target dir and rewrites the quoted
+ // `\<dirsep\>` into `[\\/]`. `preg_quote` emits `<` and `>`
+ // unescaped here, because the `regex` crate reads `\<`/`\>` as word
+ // boundaries, so the marker is not recoverable from the quoted
+ // string. Quote each separator-delimited segment on its own and join
+ // the segments with the same character class.
+ let target_dir = package
+ .get_target_dir()
+ .unwrap_or_default()
+ .split(['/', '\\'])
+ .map(|segment| preg_quote(segment, None))
+ .collect::<Vec<String>>()
+ .join("[\\\\/]");
path_str = ltrim(
&Preg::replace(
format!("{{^{}}}", target_dir),
@@ -2522,12 +2526,3 @@ fn find_top_level_arrow(entry: &str) -> Option<usize> {
}
None
}
-
-// Helper used by parse_autoloads_type for chained string substitutions.
-fn str_replace_multi(input: &str, pairs: &[(&str, &str)]) -> String {
- let mut s = input.to_string();
- for (from, to) in pairs {
- s = str_replace(from, to, &s);
- }
- s
-}
diff --git a/crates/shirabe/tests/autoload/autoload_generator_test.rs b/crates/shirabe/tests/autoload/autoload_generator_test.rs
index 3f2c142c..4efcc7e0 100644
--- a/crates/shirabe/tests/autoload/autoload_generator_test.rs
+++ b/crates/shirabe/tests/autoload/autoload_generator_test.rs
@@ -589,7 +589,6 @@ fn test_root_package_autoloading_alternative_vendor_dir() {
#[test]
#[serial]
-#[ignore = "autoload_real.php/autoload_static.php fixtures track a newer Composer template (single blank lines + $filesToLoad/$requireFile block) than the current AutoloadGenerator port emits; needs production template alignment"]
fn test_root_package_autoloading_with_target_dir() {
let mut s = set_up();
let package = new_root_pkg("root/a");