From 6c610c72665731033e9faf37bebf73c436e0724b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucian=20V=C4=83c=C4=83roiu?= Date: Sun, 30 Nov 2025 13:07:25 +0200 Subject: [PATCH] Add Node package manager detection --- src/Enums/NodePackageManager.php | 16 +++++++++++ src/NewCommand.php | 2 +- tests/NodePackageManagerTest.php | 46 ++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 tests/NodePackageManagerTest.php diff --git a/src/Enums/NodePackageManager.php b/src/Enums/NodePackageManager.php index ba8fa7c8..e67c7297 100644 --- a/src/Enums/NodePackageManager.php +++ b/src/Enums/NodePackageManager.php @@ -58,4 +58,20 @@ public function lockFiles(): array self::BUN => ['bun.lock', 'bun.lockb'], }; } + + public function isAvailable(): bool + { + return (new \Symfony\Component\Process\ExecutableFinder())->find($this->value) !== null; + } + + public static function detect(): self + { + foreach ([self::BUN, self::PNPM, self::YARN, self::NPM] as $pm) { + if ($pm->isAvailable()) { + return $pm; + } + } + + return self::NPM; + } } diff --git a/src/NewCommand.php b/src/NewCommand.php index aa5ff393..1fef32b6 100644 --- a/src/NewCommand.php +++ b/src/NewCommand.php @@ -604,7 +604,7 @@ protected function determinePackageManager(string $directory, InputInterface $in } } - return [NodePackageManager::NPM, false]; + return [NodePackageManager::detect(), false]; } /** diff --git a/tests/NodePackageManagerTest.php b/tests/NodePackageManagerTest.php new file mode 100644 index 00000000..aebbbed1 --- /dev/null +++ b/tests/NodePackageManagerTest.php @@ -0,0 +1,46 @@ +assertIsBool($pm->isAvailable()); + } + } + + public function test_detect_returns_valid_package_manager() + { + $detected = NodePackageManager::detect(); + $this->assertContains($detected, NodePackageManager::cases()); + } + + public function test_detect_prefers_faster_package_managers() + { + $detected = NodePackageManager::detect(); + + if (NodePackageManager::BUN->isAvailable()) { + $this->assertSame(NodePackageManager::BUN, $detected); + } elseif (NodePackageManager::PNPM->isAvailable()) { + $this->assertSame(NodePackageManager::PNPM, $detected); + } elseif (NodePackageManager::YARN->isAvailable()) { + $this->assertSame(NodePackageManager::YARN, $detected); + } else { + $this->assertSame(NodePackageManager::NPM, $detected); + } + } + + public function test_npm_is_typically_available() + { + if (! NodePackageManager::NPM->isAvailable()) { + $this->markTestSkipped('npm is not installed.'); + } + + $this->assertTrue(NodePackageManager::NPM->isAvailable()); + } +}