Skip to content

[Blueprints] Unify website/CLI version-override merging#3705

Open
fellyph wants to merge 6 commits into
trunkfrom
investigating-version-rounting
Open

[Blueprints] Unify website/CLI version-override merging#3705
fellyph wants to merge 6 commits into
trunkfrom
investigating-version-rounting

Conversation

@fellyph
Copy link
Copy Markdown
Collaborator

@fellyph fellyph commented May 29, 2026

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 in blueprints-v1-handler.ts that 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 in packages/playground/blueprints/src/lib/merge-blueprint-versions.ts. Returns a new blueprint declaration without mutating the input. Short-circuits when preferredVersions.wp === false so the PHP-only opt-out is honored.
  • d4ca4142f [Blueprints] Export mergeBlueprintVersions from package entry — re-exports the helper and the BlueprintVersionOverrides type 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 (wp only / php only), empty-string overrides falling through, undefined overrides falling through, wp === false short-circuit, input immutability, and preservation of unrelated blueprint fields.
  • 8d4a0643d [CLI] Use shared mergeBlueprintVersions in getEffectiveBlueprint — replaces the local merge in packages/playground/cli/src/blueprints-v1/blueprints-v1-handler.ts. See Breaking changes below.
  • b006e67fc [Website] Use shared mergeBlueprintVersions in applyQueryOverrides — replaces the local merge in packages/playground/website/src/lib/state/url/resolve-blueprint-from-url.ts. The 6.3 WP_DEVELOPMENT_MODE workaround still runs at the call site, after the merge. Drops the now-unused RecommendedPHPVersion import.

Breaking changes (CLI only)

Three user-visible behavior changes for the CLI; the website is unchanged. Per AGENTS.md, surfacing here:

  1. --wp and --php now actually win over the blueprint. The previous CLI code spread resolvedBlueprint?.preferredVersions at 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.
  2. Empty-string flags no longer set the version to ''. 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).
  3. preferredVersions.wp === false is now honored by the CLI. A blueprint declaring wp: false (PHP-only opt-out) used to be ignored by the CLI, so --wp=6.8 would inject wp: '6.8' and risk tripping the compile-time guard that rejects WP-only fields when wp === 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-website
  • npx nx run-many --target=lint --projects=playground-blueprints,playground-cli,playground-website
  • CLI smoke: npx nx dev playground-cli server --wp=6.8 --php=8.4 --blueprint=<a blueprint with conflicting preferredVersions> and confirm flags win
  • CLI smoke: blueprint with preferredVersions: { wp: false, php: '8.3' } plus --wp=6.8 and confirm wp is not injected
  • Website smoke: load ?wp=6.8&php=8.4 against a blueprint with different preferredVersions and confirm the URL wins
  • Website smoke: confirm ?wp=6.3 still applies the WP_DEVELOPMENT_MODE workaround

Out of scope

The earlier investigation surfaced three further consolidation opportunities that are not in this PR and could be done as follow-ups:

  • Validate ?php=next on the website the same way the CLI's yargs choices does.
  • Unify WordPress version resolution (CLI dynamically queries wordpress.org; website uses a hardcoded switch in a generated file).
  • Document supported aliases (beta, trunk, nightly, custom URLs, version-prefix matching) consistently on both sides.

fellyph added 5 commits May 28, 2026 22:51
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.
Copy link
Copy Markdown
Collaborator

@mho22 mho22 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTAI. It also suggested to create a test that pins down the new "flag wins over blueprint" precedence.

It looks also good to me too of course.

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants