From c79cfb609769b8f3fa46c4fe8ec7f1d9876eab88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20La=CC=88mmer?= Date: Fri, 26 Jun 2026 13:55:08 +0200 Subject: [PATCH] Detect Craft 6 (Laravel-based) as Craft, not Laravel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Craft 6 is a Laravel-based rewrite, so it requires both laravel/framework and craftcms/cms. LaravelDetector runs first and only defers to a more specific stack when the package is listed in DependencyTree::CHILDREN_STACKS['laravel/framework'] — craftcms/cms was missing, so Craft 6 resolved to Laravel before CraftCMSDetector ran. Mirror the Statamic pattern: expose CraftCMSDetector::PACKAGE_NAME and add it to the Laravel children so LaravelDetector defers and CraftCMSDetector wins. Craft 5 is unaffected (Yii-based, no laravel/framework). Adds a Craft 6 fixture + regression test. Co-Authored-By: Claude Opus 4.8 (1M context) --- lib/DTO/DependencyTree.php | 2 ++ lib/StackDetector/CraftCMSDetector.php | 4 ++- tests/Unit/DetectorTest.php | 1 + .../php-stack/craft_cms/6/composer.json | 27 +++++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/php-stack/craft_cms/6/composer.json diff --git a/lib/DTO/DependencyTree.php b/lib/DTO/DependencyTree.php index a517d0d..5170f25 100644 --- a/lib/DTO/DependencyTree.php +++ b/lib/DTO/DependencyTree.php @@ -4,6 +4,7 @@ namespace fortrabbit\StackDetector\DTO; +use fortrabbit\StackDetector\StackDetector\CraftCMSDetector; use fortrabbit\StackDetector\StackDetector\LunarDetector; use fortrabbit\StackDetector\StackDetector\OctoberCMSDetector; use fortrabbit\StackDetector\StackDetector\StatamicDetector; @@ -19,6 +20,7 @@ class DependencyTree LunarDetector::PACKAGE_NAME, TwillDetector::PACKAGE_NAME, WinterCMSDetector::PACKAGE_NAME, + CraftCMSDetector::PACKAGE_NAME, ], ]; diff --git a/lib/StackDetector/CraftCMSDetector.php b/lib/StackDetector/CraftCMSDetector.php index 43944ef..544d07d 100644 --- a/lib/StackDetector/CraftCMSDetector.php +++ b/lib/StackDetector/CraftCMSDetector.php @@ -9,9 +9,11 @@ class CraftCMSDetector extends BaseComposerTypeDetector implements StackDetectorInterface { + public const string PACKAGE_NAME = 'craftcms/cms'; + protected function packagesToSearch(): array { - return ['craftcms/cms']; + return [self::PACKAGE_NAME]; } protected function detectedStackType(): StackType diff --git a/tests/Unit/DetectorTest.php b/tests/Unit/DetectorTest.php index 21c512f..d3191dd 100644 --- a/tests/Unit/DetectorTest.php +++ b/tests/Unit/DetectorTest.php @@ -549,6 +549,7 @@ public static function packagesDataProvider(): array 'Craft CMS 3' => ['craft_cms/3', '3.6', StackType::CRAFT_CMS], 'Craft CMS 4' => ['craft_cms/4', '4.4', StackType::CRAFT_CMS], + 'Craft CMS 6 (Laravel based)' => ['craft_cms/6', '6.0', StackType::CRAFT_CMS], 'Craft CMS unknown version' => ['craft_cms/unknown', null, StackType::CRAFT_CMS], 'Statamic 4' => ['statamic/4', '4', StackType::STATAMIC], diff --git a/tests/fixtures/php-stack/craft_cms/6/composer.json b/tests/fixtures/php-stack/craft_cms/6/composer.json new file mode 100644 index 0000000..363cd7a --- /dev/null +++ b/tests/fixtures/php-stack/craft_cms/6/composer.json @@ -0,0 +1,27 @@ +{ + "name": "craftcms/craft", + "description": "Craft CMS", + "keywords": [ + "craft", + "cms", + "craftcms", + "laravel", + "project" + ], + "license": "0BSD", + "homepage": "https://craftcms.com/", + "type": "project", + "require": { + "php": "^8.5", + "craftcms/cms": "^6.0.0", + "laravel/framework": "^13.8", + "laravel/tinker": "^3.0" + }, + "config": { + "allow-plugins": { + "craftcms/plugin-installer": true + }, + "sort-packages": true, + "optimize-autoloader": true + } +}