[3.x] New publish command#2500
Draft
emmadesilva wants to merge 40 commits into
Draft
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## v3-dev #2500 +/- ##
=============================================
- Coverage 100.00% 99.97% -0.03%
- Complexity 1608 1757 +149
=============================================
Files 168 169 +1
Lines 4039 4337 +298
=============================================
+ Hits 4039 4336 +297
- Misses 0 1 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
1b5066d to
6f48418
Compare
Introduces the shared, pure decision primitive for the new publish command: given a source and destination path, it returns copy (missing), skip (unchanged), or blocked (user-modified). Comparison is EOL-agnostic via unixsum so line-ending-only differences (e.g. CRLF checkouts) count as unchanged rather than modified. No console/view/page knowledge; no checksum manifest. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Gemini <218195315+gemini-cli@users.noreply.github.com>
Introduces the data model for starter pages used by the new publish command: an immutable PublishablePage value object (key, label, description, source, defaultTarget, alternativeTargets, allowCustomTarget) and the PublishablePages registry (all/get/register) seeded with the default catalog — welcome, posts, blank, and 404. Pages get a value object + registry (unlike the fixed view file-maps) because a page can have multiple valid destinations, carries display metadata, and the registry is an extension point for Hyde Cloud and plugins. Source paths are stored framework-relative for resolution via Hyde::vendorPath() at publish time; destination resolution and publishing land in a later step. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Gemini <218195315+gemini-cli@users.noreply.github.com>
Per review decision: `blank` is a general-purpose empty starter you drop anywhere rather than a third homepage variant, so it declares no default target. Makes PublishablePage::$defaultTarget nullable and sets blank's to null; destination resolution (Step 5) will always prompt interactively and require --to non-interactively. This also removes the welcome/blank collision on _pages/index.blade.php that the default catalog would otherwise create. Updates spec 5.1/5.2/5.4 to match so the acceptance sweep stays consistent. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Gemini <218195315+gemini-cli@users.noreply.github.com>
Introduces the flag-driven publish command shell that routes to the views and pages flows (both stubbed here, filled in by Steps 4-5). It owns the full flag surface (--layouts --components --all --page[=NAME] --to=PATH --force) and all guardrails: - Raw tag/provider/config publishing is redirected to vendor:publish. These are deliberately not declared as options (which would advertise them in --help, the exact raw-publishing surface this command exists to hide); instead run() intercepts the raw input before Symfony's strict bind. Only those three tokens are short-circuited, so a genuine typo like --layout still hits Symfony's native "unknown option" error rather than being swallowed. - --layouts and --components are mutually exclusive. - --to is only valid alongside --page. - Non-interactive with no actionable flag fails with a usage hint before any prompt is attempted; the interactive wizard (Views / A starter page / Cancel) routes to the stub handlers, with Cancel exiting cleanly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Gemini <218195315+gemini-cli@users.noreply.github.com>
Replace the publishViews() stub with a real ViewsPublisher (§4, §7): - Reads the two declared groups (layouts, components) via ViewPublishGroup; --layouts/--components prefilter the offered set, --all skips the picker, and a non-interactive scoped run behaves exactly like adding --all. - Adds a minimal shared InteractiveMultiselect helper: a grouped multi-select with an "All views" sentinel (selecting it means everything regardless of other checkbox state) and group-prefixed labels (layouts/app.blade.php). - Decides every file's outcome first (OverwritePolicy: copy/skip/blocked), resolves modified-file conflicts second (interactive Skip/Overwrite/Cancel or --force; non-interactive without --force is a hard §7 error), and writes last, so Cancel never leaves a half-published tree. - Cardinality-aware output that reports the real breakdown: "Published all N" prints only when the entire offered set was genuinely copied; mixed runs report copied / already-current / left-modified (with a --force hint). Re-points the four Step 3 views-routing tests off the removed stub string to assert real views behavior, adds a dedicated views-flow test suite, and notes the mixed-run reporting rule in §4 of the spec. Additional commits: - Make the publish multiselect "All" sentinel row optional Add a nullable $allLabel to InteractiveMultiselect::select() so callers can omit the "select all" row entirely. The views picker keeps its "All views" affordance; the pages picker (Step 5) passes no label, since "publish all starter pages at once" is never a sensible selection and would only trip destination resolution and conflict detection. This is a backward-compatible parameter on the shared helper, not a fork — both callers depend on the same picker. - Simplify publish multiselect all sentinel Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Gemini <218195315+gemini-cli@users.noreply.github.com>
Replace the publishPage() stub with a real PagesPublisher backed by the PublishablePages registry (§5): - Selection: --page=NAME publishes one page directly; a bare --page or the wizard opens the interactive multi-select picker. - Destination resolution (§5.4): --to → non-interactive default → interactive prompt (default / alternative / custom path) → default. A page with no default (blank) fails helpfully non-interactively, pointing to --to. - --to validation: must resolve under _pages/ and end in .blade.php. - --to is only valid for a single named page; a bare --page (multi-select) with --to is rejected. Documented as a new line in spec §5.4. - Conflict detection (§5.6): two pages resolving to the same target fail before any write. - Interactive confirm (§5.5): select → resolve → "Ready to publish… Proceed?". - Overwrite policy (§7): reuses OverwritePolicy exactly as the views flow does (missing→copy, identical→skip, modified→confirm-or-force). - Optional rebuild (§5.7): offered interactively only, defaulting to NO. Implemented inline rather than via AsksToRebuildSite, which defaults to YES — a why-comment guards against a future consolidation reintroducing the yes-default. Registry lookups compare ->key (never array access) so the string '404' key survives PHP's numeric-key coercion. The Step 3 routing tests that asserted the old stub are updated to assert the real, non-destructive routing behavior. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Gemini <218195315+gemini-cli@users.noreply.github.com>
Destination resolution UX (§5.4): only prompt interactively when a page is genuinely ambiguous — it has alternative targets or no default. A page whose default is its one sensible destination (welcome, 404) publishes in a single frictionless step instead of asking "Where should this go?" for a near-certain answer. allowCustomTarget now governs only whether a "Custom path…" entry is offered and whether --to is accepted, not whether the prompt appears; custom placement of an otherwise-unambiguous page is reached via --to. Consequently --to is rejected for a page that disallows custom targets (404). Polish: - The overwrite-conflict "Cancel" choice now prints "Cancelled. No pages were published." instead of exiting silently, matching the views flow and the "Proceed? no" path. - The destination-conflict message uses "both target" for a pair and "all target" for three or more colliding pages. - Added tests: --to rejected for 404, the picker round-tripping the numeric '404' key (the coerced-int-key path the named lookup can't reach), and the pages picker omitting the "All" row that the views picker offers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Gemini <218195315+gemini-cli@users.noreply.github.com>
Add a test proving the two --to rejections cannot disagree. Bare --page + --to is caught by the top-level "one path can't serve several pages" guard (message A) before selectPages() runs, so the per-page allowCustomTarget rejection (message B) can never pre-empt it. The test runs interactively — it would hang on an unanswered picker prompt if the picker were reached — and asserts message A wins and message B is absent. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Gemini <218195315+gemini-cli@users.noreply.github.com>
Add a single `hyde-config` publish group on ConfigurationServiceProvider that publishes exactly the six Hyde-owned config files (hyde, docs, markdown, view, cache, commands) and not torchlight.php, per spec §6. The legacy `configs` / `hyde-configs` / `support-configs` tags are left in place; the deprecated publish:configs command still relies on them until Step 7. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Gemini <218195315+gemini-cli@users.noreply.github.com>
Per spec §8, publish:views, publish:configs, and publish:homepage become thin delegators that print a one-line deprecation notice and forward to the new surface: - publish:views [group] -> publish --layouts / --components (no group -> --all, keeping legacy non-interactive scripts non-interactive) - publish:configs -> vendor:publish --tag=hyde-config - publish:homepage [template] -> publish --page=[template], forwarding --force The old command classes stay registered and keep working through v3; target removal in v4. Their tests are rewritten to assert the notice and delegation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Gemini <218195315+gemini-cli@users.noreply.github.com>
Rewrite the publishing docs around php hyde publish (views + --page) and php hyde vendor:publish --tag=hyde-config for config. Fix the nonexistent publish:components reference in advanced-markdown.md, and update remaining publish:views/publish:configs/publish:homepage references throughout the primary docs. The deprecated aliases now appear only in a migration note in the console commands reference (historical release notes left as-is). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Gemini <218195315+gemini-cli@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Gemini <218195315+gemini-cli@users.noreply.github.com>
Co-Authored-By: Codex <codex@openai.com>
Fill the coverage gaps flagged on PagesPublisher and ViewsPublisher by
testing the feature paths they exercise, not lines for their own sake:
Pages (§5, §7):
- interactive overwrite-conflict prompt: overwrite / skip / cancel
(the §7 interactive flow was tested for views but not for pages)
- mixed run reporting published pages alongside already-current ones,
with pluralized cardinality
- three-or-more pages colliding on one target ("all target" wording)
- accepting the §5.7 rebuild offer actually runs the build
- --to path traversal (..) rejected
Views (§4):
- mixed run reporting copied views alongside already-current ones
The only lines left uncovered are unreachable defensive guards behind
`required` multi-selects (empty-selection is rejected by the prompt
before the guard) and joinLabels' <2 branch — not feature paths.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6f48418 to
c4c8a66
Compare
Delete publish:views, publish:configs, and publish:homepage entirely — classes, ConsoleServiceProvider registrations, and their test files. The behavior they covered lives in the new command's suites. Add one pin test asserting publish:views now raises the native CommandNotFoundException, proving the command is gone and no shim intercepts it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Verified each candidate repo-wide before deleting. Removed with zero remaining consumers: - InteractivePublishCommandHelper (+ its unit test) - ViewDiffService / checksumMatchesAny (+ its unit test); unixsum helpers stay (OverwritePolicy and GenerateBuildManifest still use unixsum_file) - AsksToRebuildSite trait (no use/method consumer; reworded the PagesPublisher comment that named it) - The hyde-welcome-page / hyde-posts-page / hyde-blank-page publish tags (the new PublishablePages resolves homepages by direct source path) Kept: hyde-page-404 (general 404 publish surface, not a homepage-command tag). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Remove the configs, hyde-configs, and support-configs tag registrations from ConfigurationServiceProvider. With the alias command gone they are dead public surface, and v3 is the moment to drop them rather than carry them another major cycle. Keep hyde-config (the exact six-file set, torchlight excluded) and its two tests unchanged. Add a test pinning that the removed tags publish nothing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add a "Removed Publishing Commands" section to the v3 upgrade guide (and UPGRADE.md) with the full replacement table, including the posts/blank --to mappings that don't map 1:1, the config-tag consolidation, and the never-overwrite-without-force behavioral note. - Fix the config-update instructions in updating-hyde.md and troubleshooting.md to use --force, noting existing files are skipped without it. - Replace the "Deprecated publishing commands" table in console-commands.md with a single line linking to the upgrade guide's removed-commands section. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Rewrite spec §8 from "Deprecated aliases (kept for v3)" to "Removed commands (v3)": removal, native command-not-found behavior, and pointer to the upgrade guide. Drop the notice-printing requirement. - Update §11 criterion 16 to the removal + native-error + documented-replacement wording (including the posts/blank --to mappings). - Update §6 to note the legacy config tags are removed, hyde-config is the only tag, and updating existing files requires --force. Fix the incidental stale alias references in §10 and §12. - Repair the StyleCI-mangled multi-line @return docblocks in ViewsPublisher and PagesPublisher by putting each description back on the tag line. No behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The final sweep of packages/ surfaced three shipped, user-facing references to the now-removed commands (criterion 1 requires only historical notes to remain): - The default welcome homepage told every new user to run `publish:homepage`; now points to `publish --page` (and the text-representation meta test's expected string tracks the blade file). - ValidationService's missing-404 and missing-index tips pointed to `publish:views` / `publish:homepage`; now `publish --page=404` / `publish --page`. packages/ is clean of live references (only CHANGELOG history and the pin test remain); `hyde list` shows only publish and vendor:publish; suite green (the sole failure is the pre-existing, unrelated FeaturedImageUnitTest PHP 8.5 issue). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Codex <codex@openai.com>
Co-Authored-By: Codex <codex@openai.com>
Co-Authored-By: Codex <codex@openai.com>
Co-Authored-By: Codex <codex@openai.com>
Co-Authored-By: Codex <codex@openai.com>
Co-Authored-By: Codex <codex@openai.com>
Co-Authored-By: Codex <codex@openai.com>
Co-Authored-By: Codex <codex@openai.com>
Co-Authored-By: Codex <codex@openai.com>
Co-Authored-By: Codex <codex@openai.com>
c287970 to
62d568b
Compare
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.
No description provided.