feat: keep config of addons missing from composer (dev-only addons)#6541
Merged
Conversation
Supports addons installed as composer require-dev (present only locally) that survive a `--no-dev` production deploy, where their code is intentionally absent but their entry remains in the committed addons.json. - getAddonOrder() filters out addons that are currently unavailable, so boot no longer crashes with "Required addon ... does not exist" when addons.json lists an addon whose code is missing. The stored order is left untouched. - saveConfig() preserves config entries of addons that are configured but not currently loaded, instead of rebuilding the config solely from loaded addons (which silently dropped a missing dev-only addon on every install/activate). - synchronizeWithFileSystem() only cleans up addons that vanished from composer when running a dev install (i.e. a real `composer remove`); under `--no-dev` the entry is kept untouched. When a still-installed addon is removed, its name-reachable leftovers (assets, cache, config) are cleaned up and a warning is logged, since its own uninstall hook can no longer run (its code is gone). - Dev mode is read from the install data set that actually contains redaxo/core, not InstalledVersions::getRootPackage(), which a dependency's scoped vendor (e.g. rector) can shadow. - The addons.json config is now always sorted (ksort centralised in saveAddonsData) so the committed file stays stable.
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.
Enables installing an addon as a composer require-dev dependency (so it only exists in local/dev installs) that cleanly survives a
--no-devproduction deploy: the addon's code is intentionally absent there, but its entry stays in the committedaddons.json.Today that scenario breaks: boot crashes on the missing addon, and even where it doesn't, the entry is silently dropped again on the next addon operation.
Changes
getAddonOrder()filters out addons that aren't currently available, so boot no longer throwsRequired addon "…" does not existwhenaddons.jsonlists an addon whose code is missing. The persisted order is left untouched, so it returns unchanged once the addon is available again.saveConfig()now preserves config entries of addons that are configured but not currently loaded, instead of rebuilding the config solely from the loaded addons (which silently dropped a missing dev-only addon on everyinstall/activate/…).synchronizeWithFileSystem()only removes an addon that vanished from composer when running a dev install (a realcomposer remove); under--no-devthe entry is kept untouched. When a still-installed addon is removed, its name-reachable leftovers (assets, cache, config) are cleaned up and a warning is logged — its own uninstall hook can no longer run because its code is gone, so e.g. database changes must be undone by uninstalling before removing it via composer.redaxo/core, notInstalledVersions::getRootPackage()— the latter can be shadowed by a dependency that ships a scoped vendor with its own autoloader (e.g. rector returnsrector/rector-src/dev=false).addons.jsonconfig is now always sorted (ksortcentralised insaveAddonsData()), so the committed file stays stable across writers.