[Blueprints] Unify website/CLI version-override merging#3705
Open
fellyph wants to merge 6 commits into
Open
Conversation
Shared pure function that merges a blueprint's preferredVersions with external overrides (CLI flags or URL query params). Applies the precedence override > blueprint > default and honors the preferredVersions.wp === false PHP-only opt-out so wp overrides are ignored in that case.
Re-exports the new helper and its BlueprintVersionOverrides type from @wp-playground/blueprints so the website and CLI can consume them.
Nine unit tests covering: default values when neither side specifies a version, blueprint-only values, overrides winning over blueprint values, partial overrides (wp only, php only), empty-string overrides falling through, undefined overrides falling through, the wp === false PHP-only opt-out short-circuit, input immutability, and preservation of unrelated blueprint fields.
Replaces the local merge implementation with the shared helper from @wp-playground/blueprints. Three behavior changes for CLI users: - Fixes a precedence bug where --wp / --php flags were silently overridden by the blueprint's preferredVersions because the original blueprint values were spread last in the result object. - Aligns empty-string handling with the website: --php= now falls through to the blueprint or default instead of setting PHP to ''. - Honors preferredVersions.wp === false (PHP-only opt-out): a blueprint declaring wp:false is now respected by the CLI and the --wp flag is ignored, matching the website's behavior and the compile-time guard.
Replaces the local version-merge block with the shared helper from @wp-playground/blueprints. Behavior is unchanged: ?wp / ?php query params still win over the blueprint, which still wins over defaults. The WP_DEVELOPMENT_MODE workaround for the 6.3 case still runs at the call site after the merge. Drops the now-unused RecommendedPHPVersion import.
mho22
approved these changes
May 29, 2026
Resolves a conflict in resolve-blueprint-from-url.ts introduced by trunk's #3704 ([Website] Infer PHP for older WordPress URLs), which swapped the static PHP default for a wp-version-aware getDefaultPhpVersionForWordPress() call. To keep mergeBlueprintVersions as the single source of precedence truth, extend it with an optional resolveDefaultPhp callback and pass the website's resolver from the call site. The CLI omits it and keeps the static RecommendedPHPVersion default, so CLI behavior is unchanged. Two new unit tests cover the resolveDefaultPhp path.
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
Extracts the duplicated "blueprint preferredVersions override" merge into a single shared helper,
mergeBlueprintVersions, in@wp-playground/blueprints, and has both the website and the CLI delegate to it. Removes the long-standing TODO inblueprints-v1-handler.tsthat flagged the duplication.Precedence is unchanged in principle — external override (URL query param or CLI flag) > blueprint's
preferredVersions> hardcoded default — but the CLI path had real bugs that the consolidation fixes.Changes by commit
6e397f15e[Blueprints] Add mergeBlueprintVersions helper — new pure function inpackages/playground/blueprints/src/lib/merge-blueprint-versions.ts. Returns a new blueprint declaration without mutating the input. Short-circuits whenpreferredVersions.wp === falseso the PHP-only opt-out is honored.d4ca4142f[Blueprints] Export mergeBlueprintVersions from package entry — re-exports the helper and theBlueprintVersionOverridestype so the website and CLI can consume them through the package's public surface.830e8e141[Blueprints] Add tests for mergeBlueprintVersions — 9 unit tests covering defaults, blueprint-only values, overrides winning over blueprint values, partial overrides (wponly /phponly), empty-string overrides falling through, undefined overrides falling through,wp === falseshort-circuit, input immutability, and preservation of unrelated blueprint fields.8d4a0643d[CLI] Use shared mergeBlueprintVersions in getEffectiveBlueprint — replaces the local merge inpackages/playground/cli/src/blueprints-v1/blueprints-v1-handler.ts. See Breaking changes below.b006e67fc[Website] Use shared mergeBlueprintVersions in applyQueryOverrides — replaces the local merge inpackages/playground/website/src/lib/state/url/resolve-blueprint-from-url.ts. The 6.3WP_DEVELOPMENT_MODEworkaround still runs at the call site, after the merge. Drops the now-unusedRecommendedPHPVersionimport.Breaking changes (CLI only)
Three user-visible behavior changes for the CLI; the website is unchanged. Per
AGENTS.md, surfacing here:--wpand--phpnow actually win over the blueprint. The previous CLI code spreadresolvedBlueprint?.preferredVersionsat the end of the preferredVersions object, which silently undid the flag override whenever the blueprint declared its own version. After this change, the documented precedence (flag > blueprint > default) is what runs.''. The previous CLI code used??, so--php=was treated as a real override of''. Now it falls through to the blueprint or default (the website's prior behavior).preferredVersions.wp === falseis now honored by the CLI. A blueprint declaringwp: false(PHP-only opt-out) used to be ignored by the CLI, so--wp=6.8would injectwp: '6.8'and risk tripping the compile-time guard that rejects WP-only fields whenwp === false. The CLI now short-circuits in this case, matching the website.Test plan
npx nx test playground-blueprints(188 tests, including the 9 new ones)npx nx run-many --target=typecheck --projects=playground-blueprints,playground-cli,playground-websitenpx nx run-many --target=lint --projects=playground-blueprints,playground-cli,playground-websitenpx nx dev playground-cli server --wp=6.8 --php=8.4 --blueprint=<a blueprint with conflicting preferredVersions>and confirm flags winpreferredVersions: { wp: false, php: '8.3' }plus--wp=6.8and confirmwpis not injected?wp=6.8&php=8.4against a blueprint with differentpreferredVersionsand confirm the URL wins?wp=6.3still applies theWP_DEVELOPMENT_MODEworkaroundOut of scope
The earlier investigation surfaced three further consolidation opportunities that are not in this PR and could be done as follow-ups:
?php=nexton the website the same way the CLI's yargschoicesdoes.beta,trunk,nightly, custom URLs, version-prefix matching) consistently on both sides.