From baab792c67e2cd1d0c3dc428b57503fc5fcdc7a2 Mon Sep 17 00:00:00 2001 From: Emma De Silva Date: Fri, 3 Jul 2026 21:59:51 +0200 Subject: [PATCH 1/3] Breaking: Remove the rebuild command --- HYDEPHP_V3_PLANNING.md | 4 + UPGRADE.md | 24 +++- docs/creating-content/compile-and-deploy.md | 7 -- docs/getting-started/console-commands.md | 19 --- .../Console/Commands/RebuildPageCommand.php | 119 ------------------ .../src/Console/ConsoleServiceProvider.php | 1 - .../Commands/RebuildPageCommandTest.php | 83 ------------ .../Feature/PostsAuthorIntegrationTest.php | 14 ++- .../tests/Feature/Views/MetadataViewTest.php | 4 +- .../Unit/MediaDirectoryCanBeChangedTest.php | 18 --- .../Unit/Views/NavigationMenuViewTest.php | 6 +- 11 files changed, 42 insertions(+), 257 deletions(-) delete mode 100644 packages/framework/src/Console/Commands/RebuildPageCommand.php delete mode 100644 packages/framework/tests/Feature/Commands/RebuildPageCommandTest.php diff --git a/HYDEPHP_V3_PLANNING.md b/HYDEPHP_V3_PLANNING.md index 2fb15a611c4..d49332cd29f 100644 --- a/HYDEPHP_V3_PLANNING.md +++ b/HYDEPHP_V3_PLANNING.md @@ -23,6 +23,10 @@ Having this document in code lets us know the devlopment state at any given poin ### Breaking Changes +- Removed the `rebuild` command (`RebuildPageCommand`). It was originally added to build a single file to disk before the realtime compiler existed, and later used internally by the RC to build-and-serve a path, but the RC now renders everything in-memory, leaving `rebuild` with no remaining consumer. It also had no safe user-facing use case: a single-page build only produces a correct `_site` when the page is self-contained, while a page change routinely invalidates aggregate outputs (sitemap, RSS, search index, post listings, navigation), so single-path building could silently leave a stale output directory that looked complete. The underlying single-page build capability remains available internally via the `StaticPageBuilder` action. ([#2490](https://github.com/hydephp/develop/pull/2490)) + ### Upgrade guide Please fill in UPGRADE.md as you make changes. + +- The `rebuild` command has been removed. If you need to build a single page programmatically, use `Hyde\Framework\Actions\StaticPageBuilder::handle()` instead. diff --git a/UPGRADE.md b/UPGRADE.md index da52a0505be..4a841e045c2 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -40,11 +40,33 @@ git commit -m "Pre-upgrade backup before HydePHP v3.0" // +## Step 2: Replace the Removed `rebuild` Command + +The `rebuild` command has been removed in v3.0. It had no remaining internal consumers now that the realtime compiler renders pages entirely in-memory, and building a single page could silently leave aggregate outputs (sitemap, RSS, search index, navigation) stale while looking like a complete build. + +**Before:** +```bash +php hyde rebuild _posts/hello-world.md +``` + +**After:** + +If you need to build a single page programmatically, use `StaticPageBuilder::handle()` directly: + +```php +use Hyde\Foundation\Facades\Pages; +use Hyde\Framework\Actions\StaticPageBuilder; + +StaticPageBuilder::handle(Pages::getPage('_posts/hello-world.md')); +``` + +Note that this only produces a correct `_site` when the page is self-contained. For anything that touches aggregate outputs, run `php hyde build` to rebuild the whole site instead. + ## Migration Checklist Use this checklist to track your upgrade progress: -- [ ] Example item +- [ ] Replaced any `php hyde rebuild ` usage with `StaticPageBuilder::handle()` or a full `php hyde build` ## Troubleshooting diff --git a/docs/creating-content/compile-and-deploy.md b/docs/creating-content/compile-and-deploy.md index 7025c3ba559..32df6ea18e7 100644 --- a/docs/creating-content/compile-and-deploy.md +++ b/docs/creating-content/compile-and-deploy.md @@ -16,12 +16,6 @@ Now that you have some amazing content, you'll want to compile your site into st php hyde build ``` -**You can also compile a single file, though this is deprecated and will be removed in v3.0 (use `Hyde\Framework\Actions\StaticPageBuilder::handle()` instead if you need this programmatically):** - -```bash -php hyde rebuild -``` - **And, you can even start a development server to compile your site on the fly:** ```bash @@ -35,7 +29,6 @@ php hyde serve #### Learn more about these commands in the [console commands](console-commands) documentation: - [Build command](console-commands#build-the-static-site) -- [Rebuild command (Deprecated)](console-commands#rebuild) - [Serve command](console-commands#start-the-realtime-compiler) --- diff --git a/docs/getting-started/console-commands.md b/docs/getting-started/console-commands.md index ac6bd345847..bcaf5ad599f 100644 --- a/docs/getting-started/console-commands.md +++ b/docs/getting-started/console-commands.md @@ -47,7 +47,6 @@ Here is a quick reference of all the available commands. You can also run `php h |-----------------------------------------|---------------------------------------------------------------------------------------------| | [`build`](#build) | Build the static site | | [`serve`](#serve) | Start the realtime compiler server | -| [`rebuild`](#rebuild) | Run the static site builder for a single file (Deprecated, will be removed in v3.0) | | [`build:rss`](#build-rss) | Generate the RSS feed | | [`build:search`](#build-search) | Generate the `docs/search.json` file | | [`build:sitemap`](#build-sitemap) | Generate the `sitemap.xml` file | @@ -79,24 +78,6 @@ Build the static site | `--pretty-urls` | Should links in output use pretty URLs? | | `--no-api` | Disable API calls, for example, Torchlight | -## Run the static site builder for a single file - - - ->warning **Deprecated:** The `rebuild` command is deprecated and will be removed in HydePHP v3.0. It has no remaining internal consumers now that the realtime compiler renders pages in-memory, and building a single page can silently leave aggregate outputs (sitemap, RSS, search index, navigation) stale. If you need to build a single page programmatically, use `Hyde\Framework\Actions\StaticPageBuilder::handle()` instead. - -```bash -php hyde rebuild -``` - -Run the static site builder for a single file - -#### Arguments - -| | | -|--------|--------------------------------------------------------------------------------| -| `path` | The relative file path (example: \_posts/hello-world.md) \n - Is required: yes | - ## Start the Realtime Compiler Server diff --git a/packages/framework/src/Console/Commands/RebuildPageCommand.php b/packages/framework/src/Console/Commands/RebuildPageCommand.php deleted file mode 100644 index f6cdb201858..00000000000 --- a/packages/framework/src/Console/Commands/RebuildPageCommand.php +++ /dev/null @@ -1,119 +0,0 @@ -printDeprecationWarning(); - - if ($this->argument('path') === Hyde::getMediaDirectory()) { - return (new TransferMediaAssets())->run($this->output); - - $this->info('All done!'); - - return Command::SUCCESS; - } - - return $this->makeBuildTask($this->output, $this->getNormalizedPathString())->run(); - } - - /** - * @deprecated The `rebuild` command is deprecated and will be removed in HydePHP v3.0. - */ - protected function printDeprecationWarning(): void - { - $this->warn('The `rebuild` command is deprecated and will be removed in HydePHP v3.0.'); - $this->line('If you need to build a single page programmatically, use Hyde\Framework\Actions\StaticPageBuilder::handle() instead.'); - $this->newLine(); - } - - protected function getNormalizedPathString(): string - { - return str_replace('\\', '/', unslash($this->argument('path'))); - } - - protected function makeBuildTask(OutputStyle $output, string $path): BuildTask - { - return new class($output, $path) extends BuildTask - { - public static string $message = 'Rebuilding page'; - - protected string $path; - - public function __construct(OutputStyle $output, string $path) - { - $this->output = $output; - $this->path = $path; - } - - public function handle(): void - { - $this->validate(); - - StaticPageBuilder::handle(Pages::getPage($this->path)); - } - - public function printFinishMessage(): void - { - $this->createdSiteFile(Command::fileLink( - Hyde::sitePath(Pages::getPage($this->path)->getOutputPath()) - ))->withExecutionTime(); - } - - protected function validate(): void - { - $directory = Hyde::pathToRelative(dirname($this->path)); - - $directories = [ - Hyde::pathToRelative(BladePage::path()), - Hyde::pathToRelative(BladePage::path()), - Hyde::pathToRelative(MarkdownPage::path()), - Hyde::pathToRelative(MarkdownPost::path()), - Hyde::pathToRelative(DocumentationPage::path()), - ]; - - if (! in_array($directory, $directories)) { - throw new Exception("Path [$this->path] is not in a valid source directory.", 400); - } - - if (! file_exists(Hyde::path($this->path))) { - throw new Exception("File [$this->path] not found.", 404); - } - } - }; - } -} diff --git a/packages/framework/src/Console/ConsoleServiceProvider.php b/packages/framework/src/Console/ConsoleServiceProvider.php index a62819aa05e..5d50838deb2 100644 --- a/packages/framework/src/Console/ConsoleServiceProvider.php +++ b/packages/framework/src/Console/ConsoleServiceProvider.php @@ -21,7 +21,6 @@ public function register(): void Commands\BuildSearchCommand::class, Commands\BuildSiteCommand::class, Commands\BuildSitemapCommand::class, - Commands\RebuildPageCommand::class, Commands\MakePageCommand::class, Commands\MakePostCommand::class, diff --git a/packages/framework/tests/Feature/Commands/RebuildPageCommandTest.php b/packages/framework/tests/Feature/Commands/RebuildPageCommandTest.php deleted file mode 100644 index df3e6acaa4c..00000000000 --- a/packages/framework/tests/Feature/Commands/RebuildPageCommandTest.php +++ /dev/null @@ -1,83 +0,0 @@ -file('_pages/test-page.md', 'foo'); - - $this->artisan('rebuild _pages/test-page.md') - ->expectsOutputToContain('_site/test-page.html') - ->assertExitCode(0); - - $this->assertFileExists(Hyde::path('_site/test-page.html')); - - $this->resetSite(); - } - - public function testCommandOutputsDeprecationWarning() - { - $this->file('_pages/test-page.md', 'foo'); - - $this->artisan('rebuild _pages/test-page.md') - ->expectsOutput('The `rebuild` command is deprecated and will be removed in HydePHP v3.0.') - ->expectsOutput('If you need to build a single page programmatically, use Hyde\Framework\Actions\StaticPageBuilder::handle() instead.') - ->assertExitCode(0); - - $this->resetSite(); - } - - public function testMediaFilesCanBeTransferred() - { - $this->directory(Hyde::path('_site/media')); - $this->file('_media/test.jpg'); - - $this->artisan('rebuild _media')->assertExitCode(0); - - $this->assertFileExists(Hyde::path('_site/media/test.jpg')); - } - - public function testValidateCatchesBadSourceDirectory() - { - $this->artisan('rebuild foo/bar') - ->expectsOutput('Path [foo/bar] is not in a valid source directory.') - ->assertExitCode(400); - } - - public function testValidateCatchesMissingFile() - { - $this->artisan('rebuild _pages/foo.md') - ->expectsOutput('File [_pages/foo.md] not found.') - ->assertExitCode(404); - } - - public function testRebuildDocumentationPage() - { - $this->file('_docs/foo.md'); - - $this->artisan('rebuild _docs/foo.md')->assertExitCode(0); - - $this->assertFileExists(Hyde::path('_site/docs/foo.html')); - - $this->resetSite(); - } - - public function testRebuildBlogPost() - { - $this->file('_posts/foo.md'); - - $this->artisan('rebuild _posts/foo.md')->assertExitCode(0); - - $this->assertFileExists(Hyde::path('_site/posts/foo.html')); - - $this->resetSite(); - } -} diff --git a/packages/framework/tests/Feature/PostsAuthorIntegrationTest.php b/packages/framework/tests/Feature/PostsAuthorIntegrationTest.php index 85c653095ec..be5d11955ef 100644 --- a/packages/framework/tests/Feature/PostsAuthorIntegrationTest.php +++ b/packages/framework/tests/Feature/PostsAuthorIntegrationTest.php @@ -6,7 +6,9 @@ use Hyde\Facades\Author; use Hyde\Pages\MarkdownPost; +use Hyde\Foundation\Facades\Pages; use Hyde\Framework\Actions\CreatesNewMarkdownPostFile; +use Hyde\Framework\Actions\StaticPageBuilder; use Hyde\Hyde; use Hyde\Testing\TestCase; use Illuminate\Support\Facades\Config; @@ -34,7 +36,7 @@ public function testCreatePostWithUndefinedAuthor() { $this->createPostFile('post-with-undefined-author', 'test_undefined_author'); - $this->artisan('rebuild _posts/post-with-undefined-author.md')->assertExitCode(0); + StaticPageBuilder::handle(Pages::getPage('_posts/post-with-undefined-author.md')); $this->assertFileExists(Hyde::path('_site/posts/post-with-undefined-author.html')); // Check that the author is rendered as is in the DOM @@ -55,7 +57,7 @@ public function testCreatePostWithDefinedAuthorWithName() 'named_author' => Author::create('Test Author', null), ]); - $this->artisan('rebuild _posts/post-with-defined-author-with-name.md')->assertExitCode(0); + StaticPageBuilder::handle(Pages::getPage('_posts/post-with-defined-author-with-name.md')); $this->assertFileExists(Hyde::path('_site/posts/post-with-defined-author-with-name.html')); // Check that the author is contains the set name in the DOM @@ -76,7 +78,7 @@ public function testCreatePostWithDefinedAuthorWithWebsite() 'test_author_with_website' => Author::create('Test Author', 'https://example.org'), ]); - $this->artisan('rebuild _posts/post-with-defined-author-with-name.md')->assertExitCode(0); + StaticPageBuilder::handle(Pages::getPage('_posts/post-with-defined-author-with-name.md')); $this->assertFileExists(Hyde::path('_site/posts/post-with-defined-author-with-name.html')); // Check that the author is contains the set name in the DOM @@ -111,7 +113,7 @@ public function testAllPostAuthorFieldsCanBeSetInFrontMatter() MD ); - $this->artisan('rebuild _posts/post-with-all-author-fields.md')->assertExitCode(0); + StaticPageBuilder::handle(Pages::getPage('_posts/post-with-all-author-fields.md')); $this->cleanUpWhenDone('_site/posts/post-with-all-author-fields.html'); $this->assertFileExists(Hyde::path('_site/posts/post-with-all-author-fields.html')); @@ -167,8 +169,8 @@ public function testConfiguredPostAuthorFieldsCanBeOverriddenInFrontMatter() MD ); - $this->artisan('rebuild _posts/literal.md')->assertExitCode(0); - $this->artisan('rebuild _posts/changed.md')->assertExitCode(0); + StaticPageBuilder::handle(Pages::getPage('_posts/literal.md')); + StaticPageBuilder::handle(Pages::getPage('_posts/changed.md')); $this->assertFileExists(Hyde::path('_site/posts/literal.html')); $this->assertFileExists(Hyde::path('_site/posts/changed.html')); $this->cleanUpWhenDone('_site/posts/literal.html'); diff --git a/packages/framework/tests/Feature/Views/MetadataViewTest.php b/packages/framework/tests/Feature/Views/MetadataViewTest.php index fb23472ea34..ad3bc28796a 100644 --- a/packages/framework/tests/Feature/Views/MetadataViewTest.php +++ b/packages/framework/tests/Feature/Views/MetadataViewTest.php @@ -7,6 +7,8 @@ use Hyde\Hyde; use Hyde\Testing\TestCase; use Hyde\Foundation\HydeKernel; +use Hyde\Foundation\Facades\Pages; +use Hyde\Framework\Actions\StaticPageBuilder; /** * This tests ensures all metadata is rendered correctly in the compiled pages. @@ -33,7 +35,7 @@ protected function setUp(): void protected function build(?string $page = null): void { if ($page) { - $this->artisan("rebuild $page"); + StaticPageBuilder::handle(Pages::getPage($page)); } else { $this->artisan('build'); } diff --git a/packages/framework/tests/Unit/MediaDirectoryCanBeChangedTest.php b/packages/framework/tests/Unit/MediaDirectoryCanBeChangedTest.php index 585ffebfb06..c1dc7be7599 100644 --- a/packages/framework/tests/Unit/MediaDirectoryCanBeChangedTest.php +++ b/packages/framework/tests/Unit/MediaDirectoryCanBeChangedTest.php @@ -37,24 +37,6 @@ public function testMediaOutputDirectoryCanBeChangedForSiteBuilds() $this->resetSite(); } - public function testMediaOutputDirectoryCanBeChangedForSiteRebuilds() - { - Filesystem::deleteDirectory('_site'); - - $this->directory('_assets'); - $this->file('_assets/app.css'); - - Hyde::setMediaDirectory('_assets'); - - $this->artisan('rebuild _assets'); - - $this->assertDirectoryDoesNotExist(Hyde::path('_site/media')); - $this->assertDirectoryExists(Hyde::path('_site/assets')); - $this->assertFileExists(Hyde::path('_site/assets/app.css')); - - $this->resetSite(); - } - public function testCompiledPagesHaveLinksToTheRightMediaFileLocation() { Filesystem::moveDirectory('_media', '_assets'); diff --git a/packages/framework/tests/Unit/Views/NavigationMenuViewTest.php b/packages/framework/tests/Unit/Views/NavigationMenuViewTest.php index e1aa632ac05..f8a5c578046 100644 --- a/packages/framework/tests/Unit/Views/NavigationMenuViewTest.php +++ b/packages/framework/tests/Unit/Views/NavigationMenuViewTest.php @@ -6,6 +6,8 @@ use Illuminate\Support\Str; use Hyde\Facades\Filesystem; +use Hyde\Foundation\Facades\Pages; +use Hyde\Framework\Actions\StaticPageBuilder; use Hyde\Hyde; use Hyde\Testing\TestCase; use Hyde\Pages\MarkdownPage; @@ -137,7 +139,7 @@ public function testNavigationMenuLabelCanBeChangedInFrontMatter() '); Hyde::boot(); - $this->artisan('rebuild _pages/foo.md'); + StaticPageBuilder::handle(Pages::getPage('_pages/foo.md')); $this->assertStringContainsString('My custom label', file_get_contents(Hyde::path('_site/foo.html'))); Filesystem::unlink('_site/foo.html'); } @@ -151,7 +153,7 @@ public function testNavigationMenuLabelCanBeChangedInBladeMatter() ); Hyde::boot(); - $this->artisan('rebuild _pages/foo.blade.php'); + StaticPageBuilder::handle(Pages::getPage('_pages/foo.blade.php')); $this->assertStringContainsString('My custom label', file_get_contents(Hyde::path('_site/foo.html'))); Filesystem::unlink('_site/foo.html'); } From f79ba1b678f96f9c9d3d85e3084a8817a14b96df Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Jul 2026 20:15:53 +0000 Subject: [PATCH 2/3] Fix broken anchor links in compile-and-deploy.md to use explicit anchors --- docs/creating-content/compile-and-deploy.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/creating-content/compile-and-deploy.md b/docs/creating-content/compile-and-deploy.md index 32df6ea18e7..d8c23b6cfd0 100644 --- a/docs/creating-content/compile-and-deploy.md +++ b/docs/creating-content/compile-and-deploy.md @@ -28,8 +28,8 @@ php hyde serve #### Learn more about these commands in the [console commands](console-commands) documentation: -- [Build command](console-commands#build-the-static-site) -- [Serve command](console-commands#start-the-realtime-compiler) +- [Build command](console-commands#build) +- [Serve command](console-commands#serve) --- From 36622d54bf0c9e727ac6bc9e3c568207b32bedee Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 3 Jul 2026 20:23:37 +0000 Subject: [PATCH 3/3] Move rebuild command from Deprecated to Removed in CHANGELOG --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0a1df9e67a..29d1e175337 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,10 +23,10 @@ This serves two purposes: - for changes in existing functionality. ### Deprecated -- Deprecated the `rebuild` command. It has no remaining internal consumers now that the realtime compiler renders pages in-memory, and single-page builds can silently leave aggregate outputs (sitemap, RSS, search index, navigation) stale. It will be removed in v3.0; use `Hyde\Framework\Actions\StaticPageBuilder::handle()` instead if you need to build a single page programmatically. +- for changes that will be removed in upcoming releases. ### Removed -- for now removed features. +- Removed the `rebuild` command. It had no remaining internal consumers now that the realtime compiler renders pages in-memory, and single-page builds can silently leave aggregate outputs (sitemap, RSS, search index, navigation) stale. Use `Hyde\Framework\Actions\StaticPageBuilder::handle()` instead if you need to build a single page programmatically. ### Fixed - Improved documentation page detection in MarkdownService so it works for child classes in https://github.com/hydephp/develop/pull/2332