diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-08-16 16:26:08 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-08-16 17:34:46 +0900 |
| commit | a9b45cc01afa726bf9acd7f30ad3235593a258e2 (patch) | |
| tree | 027b392d52d6e00a874853b5091be1cfa47563d4 /crates | |
| parent | 659e8a4ee130d968ef6bfb22159fb547e366f969 (diff) | |
| download | php-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')
| -rw-r--r-- | crates/shirabe/src/autoload/autoload_generator.rs | 35 | ||||
| -rw-r--r-- | crates/shirabe/tests/autoload/autoload_generator_test.rs | 1 |
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"); |
