Repository navigation
feature: Prune stale files on upgrade via manifest.json (#443) - #448
Merged
Merged
Conversation
Add a root manifest.json (tombstones/expected/whitelist) and a syslog_prune_files() housecleaning pass that plugin_syslog_upgrade() runs on a version change. It deletes files and directories that older layouts shipped but have since moved or been removed (for example the old top-level database.php and functions.php that now live under includes/), so a stale module can no longer redeclare a function and fatal the plugin on load after an upgrade. User-data paths (config.php, config_local.php) and VCS metadata are never touched, the dev-only tests/ tree and phpunit.xml are removed, and any tombstone that resolves outside the plugin directory (a tampered manifest.json) is refused and logged. A CI check, tests/bin/validate-manifest.php, keeps the manifest expected-file list from drifting from the real top-level tree. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Upgrade paths can record the new version without pruning stale modules, while tombstone deletion can remove protected configuration through symlinked directories and destroy nested repository metadata.
3 open issues
What changed in this PR
Adds manifest-driven upgrade cleanup to remove obsolete Syslog plugin files that can cause duplicate-function failures, addressing #443.
Changes:
- Defines obsolete, expected, and protected paths in a root manifest.
- Adds upgrade-time pruning, path-safety checks, and logging.
- Adds focused tests and CI validation to detect manifest drift.
| File | Description |
|---|---|
tests/Unit/SetupModuleBoundaryTest.php |
Allows the two new cleanup helpers in the setup facade. |
tests/Unit/PruneFilesTest.php |
Tests pruning, protected paths, invalid manifests, and failure logging. |
tests/bin/validate-manifest.php |
Checks expected manifest entries against the top-level plugin tree. |
setup.php |
Adds the upgrade cleanup call and manifest-driven deletion helpers. |
manifest.json |
Lists obsolete files, expected entries, and protected configuration files. |
CHANGELOG.md |
Documents the cleanup feature and manifest validation. |
.github/workflows/plugin-ci-workflow.yml |
Runs manifest validation in CI. |
Review effort: Balanced
#443) Respond to the three review findings on the upgrade housecleaning: - Run pruning from the shared, version-aware syslog_check_upgrade() path instead of only plugin_syslog_upgrade(), so the re-enable path and cli/syslog_schema.php clean up too. It is gated on a genuinely older installed version so a fresh install or same-version repair never removes the dev-only tests/ tree, and it runs before the stored version is bumped. - Reject any tombstone reached through a symlinked parent directory, so a tombstone such as 'alias/config.php' (alias -> plugin root) can no longer alias and delete a protected, whitelisted file. A tombstone that is itself a symlink is still unlinked without following it. - Preserve .git*/.md* descendants nested inside a tombstoned directory during recursive deletion, retaining their containing directories without reporting the intentional retention as a failure. Adds regression tests for the shared-path gating, the symlinked-parent alias attack and nested .git preservation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
Author
|
Thanks for the review — all three findings are addressed in cb09b97, and the threads are resolved:
Added regression tests for all three (shared-path gating, symlinked-parent alias attack, nested Local validation
|
…rune # Conflicts: # CHANGELOG.md
|
xmacan
approved these changes
Nov 13, 2026
xmacan
approved these changes
Nov 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.





Description
Adds upgrade-time "housecleaning" to the Syslog plugin so stale files from older
layouts are removed automatically. A new root
manifest.jsondescribes theplugin tree in three lists —
tombstones(paths older versions shipped that havesince moved or been deleted),
expected(the files/directories that ship today),and
whitelist(user-data paths that must never be touched) — and a newsyslog_prune_files()runs duringplugin_syslog_upgrade()on a version change.On upgrade it:
tests/tree andphpunit.xml.config.php,config_local.php) or VCSmetadata (
.git*) and dotfiles (.md*).manifest.json), including through..segments or a symlinked directory, andlogs the refusal.
and logs anything it cannot delete (e.g. read-only).
The initial tombstone list captures the top-level files/directories removed across
the plugin's history that are gone from the current tree, notably the old
top-level
database.phpandfunctions.phpthat now live underincludes/— theexact files that redeclare functions and fatal the plugin on load after a
4.2 → 4.11 upgrade.
A CI step and
tests/bin/validate-manifest.phpkeep the manifest'sexpectedlist from silently drifting from the real top-level tree.
This mirrors the approach already used by FlowView (
flowview_prune_files()) andWeathermap.
Related Issue
Closes #443
Motivation and Context
Upgrading Syslog from 4.2 to 4.11 left behind stale top-level files that declared
functions now defined in the reorganized
includes/modules. The duplicatefunction declarations made Syslog unload until the offending file was removed by
hand. This change cleans those files up automatically on upgrade and gives the
plugin a maintainable, CI-guarded manifest to track future moves/removals.
How Has This Been Tested?
php tests/bin/validate-manifest.php→manifest.json 'expected' matches the plugin tree.(exit 0)php -lonsetup.php,tests/bin/validate-manifest.phpandtests/Unit/PruneFilesTest.php→ no syntax errors.tests/Unit/PruneFilesTest.php(6 cases) covering tombstone/tests/removal, whitelist/
.git/dotfile protection, missing/malformed manifestno-ops, traversal refusal, symlink-escape refusal, and unremovable-path
logging — all pass.
SetupModuleBoundaryTestupdated for the two new facade functions — passes.(
include/vendor/bin/pest --configuration=plugins/syslog/phpunit.xml):650 passed (2705 assertions), 1 pre-existing unrelated warning
(
ProcessHelperCompatTest/procread).Types of changes
Checklist: