[BUGFIX] Exclude directories whose name contains a slash - #106
Conversation
The packaging filter interpolates every entry of the exclude configuration straight into a slash-delimited regular expression, so an entry naming a nested directory such as `Resources/Private/Build` ends up as `/^Resources/Private/Build/i`. PHP reads that as the pattern `^Resources` followed by the modifiers `Private...`, emits "Unknown modifier 'P'" once per inspected file and returns false - so the directory is packaged instead of skipped, and the published archive carries the very sources the configuration excludes. Quote the configured entries. They are documented as directory and file names and the shipped default configuration contains no regular expressions, so nothing that works today changes: the file rule still matches a suffix, the directory rule still matches a prefix. The regression test fails against the old filter with exactly the file that should have been excluded. Assisted-by: claude-code:claude-opus-5 Agent-Session: https://claude.ai/code/session_01JYQciiXoiApXBfcJrFMnA9 Agent-Host: 32116e Signed-off-by: Sebastian Mendel <github@sebastianmendel.de>
|
Hi @CybotTM @bmack, this is actually a breaking change. Some extensions out there already escape slashes in directory excludes to circumvent the described issue. However, with this change, the slash gets double-encoded and the exclude no longer works as expected. See https://github.com/search?q=path%3Apackaging_exclude.php+-is%3Afork+%22%5C%5C%2F%22&type=code&p=1 for affected extensions. We should either find a more stable solution (e.g. strip existing escapes off before doing |
|
There must be some breaking change before this one, because the powermail release 13.2.0 was published on Aug. 3rd and was uploaded to TER without any problems. Something some have changed inbetween, because I did not touch the code, causing the issue. |
The reason may be in the TER data, something in there made updating release info for your package stop working. Someone at TER needs to look into this. |
|
Hi @eliashaeussler,
Thanks for the heads up. We may unescape before escaping. We may switch to different delimiters. We may mark it as breaking change. |
Quoting the configured exclude entries (#106) broke the workaround extensions used for nested directories: an entry written as `Resources\/Private\/Build` was passed to preg_quote as is, so the backslash itself got escaped and the resulting pattern only matched a directory whose name literally contains a backslash. Those extensions silently packaged the directory they excluded before. Strip the escaped slashes before quoting, so both notations describe the same directory and no extension configuration needs a change.
VersionService::createZipArchiveFromPath()builds its exclude patterns by interpolating each configured entry into a slash-delimited regular expression —'/^' . $excludeDirectory . '/i'for directories,'/' . $excludeFile . '$/i'for files. An entry containing a slash therefore closes the pattern early:Resources/Private/Buildbecomes/^Resources/Private/Build/i, which PHP reads as the pattern^Resourcesfollowed by the modifiersPrivate…. It emitspreg_match(): Unknown modifier 'P'once per inspected file and returnsfalse, so the directory is packaged instead of skipped.Observed on a real release: the job linked in #105 prints that warning a few hundred times, and the archive published from it carries 36 files below
Resources/Private/Build/— the directory its configuration excludes.The fix quotes the configured entries. The README documents them as directory and file names, and
conf/ExcludeFromPackaging.phpcontains no regular expressions, so the shipped defaults behave exactly as before: the file rule still matches a suffix, the directory rule still matches a prefix.The added test packages a tree containing
Resources/Private/Build/gulpfile.jsand asserts the file is absent from the archive. Against the unpatched filter it fails withFailed asserting that an array does not contain 'Resources/Private/Build/gulpfile.js'; with the patch the full unit suite is green (153 tests) andcomposer csreports no findings.This is not the cause of #105. The
HTTP 500reported there comes from TER, not from tailor — the archive was accepted and the version record was written. This change only explains the warnings in the same log, so please do not close #105 with it.Assisted by claude-code:claude-opus-5 — Session