Let extensions upgrade their own data via versioned @extensions#403
Open
gustavdelius wants to merge 1 commit into
Open
Let extensions upgrade their own data via versioned @extensions#403gustavdelius wants to merge 1 commit into
gustavdelius wants to merge 1 commit into
Conversation
mizer could upgrade core slots across mizer versions, but extensions had no hook to migrate their own data and no record of which extension version last conformed an object. This adds per-extension version tracking and an upgrade dispatch path so extensions can upgrade their objects independently of the mizer version. - The `@extensions` slot (now typed "ANY") may hold either the legacy named character vector of requirement strings or a named list of `c(requirement, version)` entries. `objectExtensions()` returns the requirement-only view, so all dispatch/suffix logic is unchanged. New helpers: `recordExtension()` (exported), `extensionRequirements()`, `extensionVersions()`, `extensionVersion()`, `makeExtensions()`. - `upgradeParams()`/`upgradeSim()` are now the `upgrade.MizerParams()` / `upgrade.MizerSim()` methods of `utils::upgrade()`; the old names remain as thin internal wrappers. - `validParams()` orchestrates upgrades: it runs the core upgrade when `@mizer_version` is stale, then `runExtensionUpgrades()` calls each out-of-date extension's `upgrade` method directly (no `NextMethod()`) and re-stamps it. `needs_upgrading()` now also fires on a missing or stale extension stamp. - `registerExtensions()` / `readParams()` / `requiredExtensionPackages()` accept the versioned list form via the requirement view. - Documented the pattern in the creating-extension-packages vignette and added tests in test-extension-versions.R. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Summary
mizer can upgrade its own (core) slots across mizer versions, but extension
packages had no way to migrate their data when their storage layout changes,
and an object carried no record of which extension version it conformed to.
This PR adds per-extension version tracking and an upgrade-dispatch path so an
extension can upgrade its objects independently of the mizer version.
The motivating case is mizerMR moving its
resource_paramsdata frame to a newlocation; with this PR a saved mizerMR model is migrated automatically the first
time it passes through
validParams()/readParams().What changed
@extensionsslot. Slot type widened to"ANY". It may holdthe legacy named character vector of requirement strings, or a named list of
c(requirement = ..., version = ...)entries, whereversionis the versionof the extension package the object conforms to.
objectExtensions()returnsthe requirement-only view, so all dispatch / suffix-chain logic is unchanged.
New helpers: exported
recordExtension()plus internalextensionRequirements(),extensionVersions(),extensionVersion(),makeExtensions().upgrade()methods.upgradeParams()/upgradeSim()are now theupgrade.MizerParams()/upgrade.MizerSim()methods of theutils::upgrade()generic; the old names remain as thin internal wrappers.Extensions register their own method with
@exportS3Method utils::upgrade.validParams(). It runs the core upgrade when@mizer_versionis stale, thenrunExtensionUpgrades()calls eachout-of-date extension's
upgrademethod directly (noNextMethod()) andre-stamps it afterwards. Extension methods are pure, idempotent migrations.
needs_upgrading()now also fires when an extension's recorded stamp ismissing or older than the installed package version. A missing stamp counts
as stale, so objects created before version tracking are migrated and stamped
on first use.
registerExtensions(),readParams()/readSim()andrequiredExtensionPackages()accept the versioned list form.Testing
tests/testthat/test-extension-versions.R.Note: the unrelated
getFluxGradient()doc cross-references thatdocument()would otherwise add were left out to keep this PR focused.
🤖 Generated with Claude Code