From 2a4e8ae108bc44a0b9b7a4f5b624ec54976c02eb Mon Sep 17 00:00:00 2001 From: Einenlum Date: Thu, 4 Sep 2025 11:36:11 +0200 Subject: [PATCH 01/13] add node config dto --- lib/Detector.php | 1 + lib/FullConfiguration.php | 1 + lib/NodeConfiguration.php | 14 ++++++++++++++ 3 files changed, 16 insertions(+) create mode 100644 lib/NodeConfiguration.php diff --git a/lib/Detector.php b/lib/Detector.php index c794f04..32ad4b3 100644 --- a/lib/Detector.php +++ b/lib/Detector.php @@ -22,6 +22,7 @@ public function getFullConfiguration(string $baseUri, ?string $subFolder = null) return new FullConfiguration( $phpConfiguration, + null, $stack, ); } diff --git a/lib/FullConfiguration.php b/lib/FullConfiguration.php index 575e3e2..366975a 100644 --- a/lib/FullConfiguration.php +++ b/lib/FullConfiguration.php @@ -8,6 +8,7 @@ { public function __construct( public PhpConfiguration $phpConfiguration, + public ?NodeConfiguration $nodeConfiguration, public ?Stack $stack, ) { } diff --git a/lib/NodeConfiguration.php b/lib/NodeConfiguration.php new file mode 100644 index 0000000..53b256a --- /dev/null +++ b/lib/NodeConfiguration.php @@ -0,0 +1,14 @@ + Date: Thu, 4 Sep 2025 12:46:32 +0200 Subject: [PATCH 02/13] add node version parsing from .nvmrc and .node-version --- lib/Detector.php | 9 +- lib/Factory/FilesystemDetectorFactory.php | 8 +- lib/Factory/GithubDetectorFactory.php | 8 +- lib/NodeConfigurationDetector.php | 88 +++++++++++++++++++ tests/Unit/DetectorTest.php | 75 ++++++++++++++++ .../node-configuration/no-version/.gitkeep | 0 .../node-version-commented/.node-version | 1 + .../node-version/.node-version | 1 + .../node-configuration/nvmrc-commented/.nvmrc | 1 + .../fixtures/node-configuration/nvmrc/.nvmrc | 1 + 10 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 lib/NodeConfigurationDetector.php create mode 100644 tests/fixtures/node-configuration/no-version/.gitkeep create mode 100644 tests/fixtures/node-configuration/node-version-commented/.node-version create mode 100644 tests/fixtures/node-configuration/node-version/.node-version create mode 100644 tests/fixtures/node-configuration/nvmrc-commented/.nvmrc create mode 100644 tests/fixtures/node-configuration/nvmrc/.nvmrc diff --git a/lib/Detector.php b/lib/Detector.php index 32ad4b3..6290955 100644 --- a/lib/Detector.php +++ b/lib/Detector.php @@ -9,6 +9,7 @@ /** @param StackDetectorInterface[] $stackDetectors */ public function __construct( private PhpConfigurationDetector $phpConfigurationDetector, + private NodeConfigurationDetector $nodeConfigurationDetector, private array $stackDetectors, ) { } @@ -18,11 +19,12 @@ public function getFullConfiguration(string $baseUri, ?string $subFolder = null) $subFolder = $this->cleanSubFolder($subFolder); $phpConfiguration = $this->getPhpConfiguration($baseUri, $subFolder); + $nodeConfiguration = $this->getNodeConfiguration($baseUri, $subFolder); $stack = $this->getStack($baseUri, $subFolder); return new FullConfiguration( $phpConfiguration, - null, + $nodeConfiguration, $stack, ); } @@ -32,6 +34,11 @@ private function getPhpConfiguration(string $baseUri, ?string $subFolder = null) return $this->phpConfigurationDetector->getPhpConfiguration($baseUri, $subFolder); } + private function getNodeConfiguration(string $baseUri, ?string $subFolder = null): NodeConfiguration + { + return $this->nodeConfigurationDetector->getNodeConfiguration($baseUri, $subFolder); + } + /** * @param string $baseUri The base URI of the project, e.g. * /some/path/to/local/project diff --git a/lib/Factory/FilesystemDetectorFactory.php b/lib/Factory/FilesystemDetectorFactory.php index 18d92ce..32e52e5 100644 --- a/lib/Factory/FilesystemDetectorFactory.php +++ b/lib/Factory/FilesystemDetectorFactory.php @@ -7,6 +7,7 @@ use Einenlum\PhpStackDetector\Composer\ComposerConfigProvider; use Einenlum\PhpStackDetector\Detector; use Einenlum\PhpStackDetector\DirectoryCrawler\FilesystemAdapter; +use Einenlum\PhpStackDetector\NodeConfigurationDetector; use Einenlum\PhpStackDetector\PhpConfigurationDetector; class FilesystemDetectorFactory @@ -19,8 +20,13 @@ public function create(): Detector $composerConfigProvider = new ComposerConfigProvider($adapter); $phpConfigurationDetector = new PhpConfigurationDetector($composerConfigProvider); + $nodeConfigurationDetector = new NodeConfigurationDetector($adapter); $stackDetectors = $this->getStackDetectors($composerConfigProvider, $adapter); - return new Detector($phpConfigurationDetector, $stackDetectors); + return new Detector( + $phpConfigurationDetector, + $nodeConfigurationDetector, + $stackDetectors + ); } } diff --git a/lib/Factory/GithubDetectorFactory.php b/lib/Factory/GithubDetectorFactory.php index ba4e8b4..eca7473 100644 --- a/lib/Factory/GithubDetectorFactory.php +++ b/lib/Factory/GithubDetectorFactory.php @@ -7,6 +7,7 @@ use Einenlum\PhpStackDetector\Composer\ComposerConfigProvider; use Einenlum\PhpStackDetector\Detector; use Einenlum\PhpStackDetector\DirectoryCrawler\GithubAdapter; +use Einenlum\PhpStackDetector\NodeConfigurationDetector; use Einenlum\PhpStackDetector\PhpConfigurationDetector; use Github\Client; @@ -20,9 +21,14 @@ public function create(?Client $client = null): Detector $adapter = new GithubAdapter($client); $composerConfigProvider = new ComposerConfigProvider($adapter); $phpConfigurationDetector = new PhpConfigurationDetector($composerConfigProvider); + $nodeConfigurationDetector = new NodeConfigurationDetector($adapter); $stackDetectors = $this->getStackDetectors($composerConfigProvider, $adapter); - return new Detector($phpConfigurationDetector, $stackDetectors); + return new Detector( + $phpConfigurationDetector, + $nodeConfigurationDetector, + $stackDetectors + ); } } diff --git a/lib/NodeConfigurationDetector.php b/lib/NodeConfigurationDetector.php new file mode 100644 index 0000000..819312a --- /dev/null +++ b/lib/NodeConfigurationDetector.php @@ -0,0 +1,88 @@ +getNodeVersion($baseUri, $subFolder), + null, + ); + } + + private function getNodeVersion(string $baseUri, ?string $subFolder = null): ?string + { + if (!$this->adapter->directoryExists($baseUri, $subFolder)) { + return null; + } + + $nvmrcContent = $this->getFileContent( + $baseUri, + $subFolder, + '.nvmrc' + ); + $nodeVersion = $this->extractNodeVersion($nvmrcContent); + + if (null !== $nodeVersion) { + return $nodeVersion; + } + + $nodeVersionContent = $this->getFileContent( + $baseUri, + $subFolder, + '.node-version' + ); + $nodeVersion = $this->extractNodeVersion($nodeVersionContent); + + return $nodeVersion; + } + + private function extractNodeVersion(?string $content): ?string + { + if (null === $content) { + return null; + } + + $lines = explode("\n", trim($content)); + $lines = array_filter( + $lines, + fn ($line) => '' !== $line && false === str_starts_with($line, '#') + ); + + $firstLine = $lines[0] ?? null; + + if (null === $firstLine) { + return null; + } + + $version = ltrim($firstLine, 'v'); + + return $version ?: null; + } + + private function getFileContent(string $baseUri, ?string $subFolder, string $filename): ?string + { + try { + return $this->adapter->getFileContent( + $baseUri, + $subFolder, + $filename + ); + } catch (ResourceNotFoundException) { + return null; + } + } +} diff --git a/tests/Unit/DetectorTest.php b/tests/Unit/DetectorTest.php index c8a1654..d88f075 100644 --- a/tests/Unit/DetectorTest.php +++ b/tests/Unit/DetectorTest.php @@ -19,6 +19,81 @@ public function setUp(): void $this->sut = $factory->create(); } + /** + * @test + */ + public function it_detects_no_node_version(): void + { + $fullConfig = $this->sut->getFullConfiguration( + sprintf('%s/../fixtures/%s', __DIR__, 'node-configuration/no-version') + ); + + $this->assertNotNull($fullConfig); + + $this->assertNotNull($fullConfig->nodeConfiguration); + $this->assertNull($fullConfig->nodeConfiguration->version); + } + + /** + * @test + */ + public function it_detects_node_version_from_nvmrc(): void + { + $fullConfig = $this->sut->getFullConfiguration( + sprintf('%s/../fixtures/%s', __DIR__, 'node-configuration/nvmrc') + ); + + $this->assertNotNull($fullConfig); + + $this->assertNotNull($fullConfig->nodeConfiguration); + $this->assertSame('13.0.1', $fullConfig->nodeConfiguration->version); + } + + /** + * @test + */ + public function it_detects_node_version_from_commented_nvmrc(): void + { + $fullConfig = $this->sut->getFullConfiguration( + sprintf('%s/../fixtures/%s', __DIR__, 'node-configuration/nvmrc-commented') + ); + + $this->assertNotNull($fullConfig); + + $this->assertNotNull($fullConfig->nodeConfiguration); + $this->assertSame(null, $fullConfig->nodeConfiguration->version); + } + + /** + * @test + */ + public function it_detects_node_version_from_node_version_file(): void + { + $fullConfig = $this->sut->getFullConfiguration( + sprintf('%s/../fixtures/%s', __DIR__, 'node-configuration/node-version') + ); + + $this->assertNotNull($fullConfig); + + $this->assertNotNull($fullConfig->nodeConfiguration); + $this->assertSame('13.0.1', $fullConfig->nodeConfiguration->version); + } + + /** + * @test + */ + public function it_detects_no_node_version_from_commented_node_version_file(): void + { + $fullConfig = $this->sut->getFullConfiguration( + sprintf('%s/../fixtures/%s', __DIR__, 'node-configuration/node-version-commented') + ); + + $this->assertNotNull($fullConfig); + + $this->assertNotNull($fullConfig->nodeConfiguration); + $this->assertSame(null, $fullConfig->nodeConfiguration->version); + } + /** * @test * diff --git a/tests/fixtures/node-configuration/no-version/.gitkeep b/tests/fixtures/node-configuration/no-version/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/fixtures/node-configuration/node-version-commented/.node-version b/tests/fixtures/node-configuration/node-version-commented/.node-version new file mode 100644 index 0000000..59b8172 --- /dev/null +++ b/tests/fixtures/node-configuration/node-version-commented/.node-version @@ -0,0 +1 @@ +# 13.0.1 diff --git a/tests/fixtures/node-configuration/node-version/.node-version b/tests/fixtures/node-configuration/node-version/.node-version new file mode 100644 index 0000000..5cb7d85 --- /dev/null +++ b/tests/fixtures/node-configuration/node-version/.node-version @@ -0,0 +1 @@ +13.0.1 diff --git a/tests/fixtures/node-configuration/nvmrc-commented/.nvmrc b/tests/fixtures/node-configuration/nvmrc-commented/.nvmrc new file mode 100644 index 0000000..23a5055 --- /dev/null +++ b/tests/fixtures/node-configuration/nvmrc-commented/.nvmrc @@ -0,0 +1 @@ +#v13.0.1 diff --git a/tests/fixtures/node-configuration/nvmrc/.nvmrc b/tests/fixtures/node-configuration/nvmrc/.nvmrc new file mode 100644 index 0000000..c67637c --- /dev/null +++ b/tests/fixtures/node-configuration/nvmrc/.nvmrc @@ -0,0 +1 @@ +v13.0.1 From d420b701338a69cb7f6718cf4c0141f8b39e9c50 Mon Sep 17 00:00:00 2001 From: Einenlum Date: Thu, 4 Sep 2025 12:50:32 +0200 Subject: [PATCH 03/13] detect node requirements if they exist --- lib/NodeConfiguration.php | 1 + lib/NodeConfigurationDetector.php | 18 ++++++++++++++++++ tests/Unit/DetectorTest.php | 15 +++++++++++++++ .../package-json-requirements/package.json | 5 +++++ 4 files changed, 39 insertions(+) create mode 100644 tests/fixtures/node-configuration/package-json-requirements/package.json diff --git a/lib/NodeConfiguration.php b/lib/NodeConfiguration.php index 53b256a..1466cbb 100644 --- a/lib/NodeConfiguration.php +++ b/lib/NodeConfiguration.php @@ -8,6 +8,7 @@ class NodeConfiguration { public function __construct( public readonly ?string $version, + public readonly ?string $requirements, public readonly ?string $packageManager, ) { } diff --git a/lib/NodeConfigurationDetector.php b/lib/NodeConfigurationDetector.php index 819312a..03af199 100644 --- a/lib/NodeConfigurationDetector.php +++ b/lib/NodeConfigurationDetector.php @@ -19,6 +19,7 @@ public function getNodeConfiguration( ): ?NodeConfiguration { return new NodeConfiguration( $this->getNodeVersion($baseUri, $subFolder), + $this->getVersionRequirements($baseUri, $subFolder), null, ); } @@ -50,6 +51,23 @@ private function getNodeVersion(string $baseUri, ?string $subFolder = null): ?st return $nodeVersion; } + private function getVersionRequirements(string $baseUri, ?string $subFolder = null): ?string + { + $packageJsonContent = $this->getFileContent( + $baseUri, + $subFolder, + 'package.json' + ); + + if (null === $packageJsonContent) { + return null; + } + + $packageData = json_decode($packageJsonContent, true, 512, \JSON_THROW_ON_ERROR); + + return $packageData['engines']['node'] ?? null; + } + private function extractNodeVersion(?string $content): ?string { if (null === $content) { diff --git a/tests/Unit/DetectorTest.php b/tests/Unit/DetectorTest.php index d88f075..33ae8d1 100644 --- a/tests/Unit/DetectorTest.php +++ b/tests/Unit/DetectorTest.php @@ -94,6 +94,21 @@ public function it_detects_no_node_version_from_commented_node_version_file(): v $this->assertSame(null, $fullConfig->nodeConfiguration->version); } + /** + * @test + */ + public function it_detects_requirements_from_package_json(): void + { + $fullConfig = $this->sut->getFullConfiguration( + sprintf('%s/../fixtures/%s', __DIR__, 'node-configuration/package-json-requirements') + ); + + $this->assertNotNull($fullConfig); + + $this->assertNotNull($fullConfig->nodeConfiguration); + $this->assertSame('>=18 <20', $fullConfig->nodeConfiguration->requirements); + } + /** * @test * diff --git a/tests/fixtures/node-configuration/package-json-requirements/package.json b/tests/fixtures/node-configuration/package-json-requirements/package.json new file mode 100644 index 0000000..cdc79c3 --- /dev/null +++ b/tests/fixtures/node-configuration/package-json-requirements/package.json @@ -0,0 +1,5 @@ +{ + "engines": { + "node": ">=18 <20" + } +} From 3a3207f302bdec40471fa2410ca317ca216cd3de Mon Sep 17 00:00:00 2001 From: Einenlum Date: Thu, 4 Sep 2025 16:39:52 +0200 Subject: [PATCH 04/13] detect node package managers --- lib/Detector.php | 2 +- lib/DirectoryCrawler/AdapterInterface.php | 2 + lib/DirectoryCrawler/FilesystemAdapter.php | 7 ++ lib/DirectoryCrawler/GithubAdapter.php | 18 ++++ lib/NodeConfiguration.php | 8 +- lib/NodeConfigurationDetector.php | 75 ++++++++++++- lib/NodePackageManagerType.php | 14 +++ tests/Unit/DetectorTest.php | 100 ++++++++++++++++++ .../node-configuration/bun-lock/bun.lock | 3 + .../node-configuration/bun-lock/package.json | 3 + .../{no-version => empty}/.gitkeep | 0 .../no-version/package.json | 3 + .../node-version-commented/package.json | 3 + .../node-version/package.json | 3 + .../npm-lock/package-lock.json | 3 + .../node-configuration/npm-lock/package.json | 3 + .../nvmrc-commented/package.json | 3 + .../node-configuration/nvmrc/package.json | 3 + .../node-configuration/pnpm-lock/package.json | 3 + .../pnpm-lock/pnpm-lock.yaml | 2 + .../node-configuration/yarn-berry/.yarnrc.yml | 2 + .../yarn-berry/package.json | 3 + .../node-configuration/yarn-berry/yarn.lock | 3 + .../node-configuration/yarn/package.json | 3 + .../node-configuration/yarn/yarn.lock | 3 + 25 files changed, 266 insertions(+), 6 deletions(-) create mode 100644 lib/NodePackageManagerType.php create mode 100644 tests/fixtures/node-configuration/bun-lock/bun.lock create mode 100644 tests/fixtures/node-configuration/bun-lock/package.json rename tests/fixtures/node-configuration/{no-version => empty}/.gitkeep (100%) create mode 100644 tests/fixtures/node-configuration/no-version/package.json create mode 100644 tests/fixtures/node-configuration/node-version-commented/package.json create mode 100644 tests/fixtures/node-configuration/node-version/package.json create mode 100644 tests/fixtures/node-configuration/npm-lock/package-lock.json create mode 100644 tests/fixtures/node-configuration/npm-lock/package.json create mode 100644 tests/fixtures/node-configuration/nvmrc-commented/package.json create mode 100644 tests/fixtures/node-configuration/nvmrc/package.json create mode 100644 tests/fixtures/node-configuration/pnpm-lock/package.json create mode 100644 tests/fixtures/node-configuration/pnpm-lock/pnpm-lock.yaml create mode 100644 tests/fixtures/node-configuration/yarn-berry/.yarnrc.yml create mode 100644 tests/fixtures/node-configuration/yarn-berry/package.json create mode 100644 tests/fixtures/node-configuration/yarn-berry/yarn.lock create mode 100644 tests/fixtures/node-configuration/yarn/package.json create mode 100644 tests/fixtures/node-configuration/yarn/yarn.lock diff --git a/lib/Detector.php b/lib/Detector.php index 6290955..757f13b 100644 --- a/lib/Detector.php +++ b/lib/Detector.php @@ -34,7 +34,7 @@ private function getPhpConfiguration(string $baseUri, ?string $subFolder = null) return $this->phpConfigurationDetector->getPhpConfiguration($baseUri, $subFolder); } - private function getNodeConfiguration(string $baseUri, ?string $subFolder = null): NodeConfiguration + private function getNodeConfiguration(string $baseUri, ?string $subFolder = null): ?NodeConfiguration { return $this->nodeConfigurationDetector->getNodeConfiguration($baseUri, $subFolder); } diff --git a/lib/DirectoryCrawler/AdapterInterface.php b/lib/DirectoryCrawler/AdapterInterface.php index 421aec3..4b67bc1 100644 --- a/lib/DirectoryCrawler/AdapterInterface.php +++ b/lib/DirectoryCrawler/AdapterInterface.php @@ -11,6 +11,8 @@ interface AdapterInterface /** @throws ResourceNotFoundException */ public function getFileContent(string $baseUri, ?string ...$pathTree): string; + public function fileExists(string $baseUri, ?string ...$pathTree): bool; + public function directoryExists(string $baseUri, ?string ...$pathTree): bool; /** @return array */ diff --git a/lib/DirectoryCrawler/FilesystemAdapter.php b/lib/DirectoryCrawler/FilesystemAdapter.php index 97972fb..41fe967 100644 --- a/lib/DirectoryCrawler/FilesystemAdapter.php +++ b/lib/DirectoryCrawler/FilesystemAdapter.php @@ -23,6 +23,13 @@ public function getFileContent(string $baseUri, ?string ...$pathTree): string return $content; } + public function fileExists(string $baseUri, ?string ...$pathTree): bool + { + $fullUri = $this->getFullUri($baseUri, $pathTree); + + return is_file($fullUri); + } + public function directoryExists(string $baseUri, ?string ...$pathTree): bool { $fullUri = $this->getFullUri($baseUri, $pathTree); diff --git a/lib/DirectoryCrawler/GithubAdapter.php b/lib/DirectoryCrawler/GithubAdapter.php index e953c36..a099a1b 100644 --- a/lib/DirectoryCrawler/GithubAdapter.php +++ b/lib/DirectoryCrawler/GithubAdapter.php @@ -37,6 +37,24 @@ public function getFileContent(string $baseUri, ?string ...$pathTree): string return base64_decode($content['content']); } + public function fileExists(string $baseUri, ?string ...$pathTree): bool + { + $config = $this->splitBaseUri($baseUri); + + try { + $this->client->repo()->contents()->show( + $config['organization'], + $config['repository'], + $this->getPathTreeAsString($pathTree), + $config['reference'] + ); + + return true; + } catch (RuntimeException $e) { + return false; + } + } + public function directoryExists(string $baseUri, ?string ...$pathTree): bool { $config = $this->splitBaseUri($baseUri); diff --git a/lib/NodeConfiguration.php b/lib/NodeConfiguration.php index 1466cbb..ec8a521 100644 --- a/lib/NodeConfiguration.php +++ b/lib/NodeConfiguration.php @@ -4,12 +4,12 @@ namespace Einenlum\PhpStackDetector; -class NodeConfiguration +readonly class NodeConfiguration { public function __construct( - public readonly ?string $version, - public readonly ?string $requirements, - public readonly ?string $packageManager, + public ?string $version, + public ?string $requirements, + public ?NodePackageManagerType $packageManager, ) { } } diff --git a/lib/NodeConfigurationDetector.php b/lib/NodeConfigurationDetector.php index 03af199..25bc84b 100644 --- a/lib/NodeConfigurationDetector.php +++ b/lib/NodeConfigurationDetector.php @@ -17,10 +17,20 @@ public function getNodeConfiguration( string $baseUri, ?string $subFolder = null, ): ?NodeConfiguration { + $packageJsonExists = $this->adapter->fileExists( + $baseUri, + $subFolder, + 'package.json' + ); + + if (!$packageJsonExists) { + return null; + } + return new NodeConfiguration( $this->getNodeVersion($baseUri, $subFolder), $this->getVersionRequirements($baseUri, $subFolder), - null, + $this->getPackageManagerType($baseUri, $subFolder), ); } @@ -91,6 +101,69 @@ private function extractNodeVersion(?string $content): ?string return $version ?: null; } + private function getPackageManagerType( + string $baseUri, + ?string $subFolder = null, + ): ?NodePackageManagerType { + $lockFiles = [ + 'package-lock.json' => NodePackageManagerType::NPM, + 'pnpm-lock.yaml' => NodePackageManagerType::PNPM, + 'bun.lock' => NodePackageManagerType::BUN, + ]; + + foreach ($lockFiles as $filename => $type) { + if ($this->adapter->fileExists($baseUri, $subFolder, $filename)) { + return $type; + } + } + + $yarnType = $this->detectYarn($baseUri, $subFolder); + if (null !== $yarnType) { + return $yarnType; + } + + /** @var string $packageJsonContent */ + $packageJsonContent = $this->getFileContent( + $baseUri, + $subFolder, + 'package.json' + ); + + $packageData = json_decode( + $packageJsonContent, + true, + 512, + \JSON_THROW_ON_ERROR + ); + + $packageManager = $packageData['packageManager'] ?? null; + if (null !== $packageManager) { + $packageManagerParts = explode('@', $packageManager); + $managerName = $packageManagerParts[0]; + + $managerType = NodePackageManagerType::tryFrom($managerName); + + if (null !== $managerType) { + return $managerType; + } + } + + return NodePackageManagerType::NPM; // Default to NPM if no lock file or packageManager field is found + } + + private function detectYarn(string $baseUri, ?string $subFolder = null): ?NodePackageManagerType + { + if (!$this->adapter->fileExists($baseUri, $subFolder, 'yarn.lock')) { + return null; + } + + if ($this->adapter->fileExists($baseUri, $subFolder, '.yarnrc.yml')) { + return NodePackageManagerType::YARN_BERRY; + } + + return NodePackageManagerType::YARN; + } + private function getFileContent(string $baseUri, ?string $subFolder, string $filename): ?string { try { diff --git a/lib/NodePackageManagerType.php b/lib/NodePackageManagerType.php new file mode 100644 index 0000000..4b118dc --- /dev/null +++ b/lib/NodePackageManagerType.php @@ -0,0 +1,14 @@ +assertSame('>=18 <20', $fullConfig->nodeConfiguration->requirements); } + /** + * @test + */ + public function it_detects_no_node_configuration(): void + { + $fullConfig = $this->sut->getFullConfiguration( + sprintf('%s/../fixtures/%s', __DIR__, 'node-configuration/empty') + ); + + $this->assertNotNull($fullConfig); + + $this->assertNull($fullConfig->nodeConfiguration); + } + + /** + * @test + */ + public function it_detects_npm(): void + { + $fullConfig = $this->sut->getFullConfiguration( + sprintf('%s/../fixtures/%s', __DIR__, 'node-configuration/npm-lock') + ); + $this->assertNotNull($fullConfig); + + $this->assertNotNull($fullConfig->nodeConfiguration); + $this->assertSame( + NodePackageManagerType::NPM, + $fullConfig->nodeConfiguration->packageManager + ); + } + + /** + * @test + */ + public function it_detects_pnpm(): void + { + $fullConfig = $this->sut->getFullConfiguration( + sprintf('%s/../fixtures/%s', __DIR__, 'node-configuration/pnpm-lock') + ); + $this->assertNotNull($fullConfig); + + $this->assertNotNull($fullConfig->nodeConfiguration); + $this->assertSame( + NodePackageManagerType::PNPM, + $fullConfig->nodeConfiguration->packageManager + ); + } + + /** + * @test + */ + public function it_detects_bun(): void + { + $fullConfig = $this->sut->getFullConfiguration( + sprintf('%s/../fixtures/%s', __DIR__, 'node-configuration/bun-lock') + ); + $this->assertNotNull($fullConfig); + + $this->assertNotNull($fullConfig->nodeConfiguration); + $this->assertSame( + NodePackageManagerType::BUN, + $fullConfig->nodeConfiguration->packageManager + ); + } + + /** + * @test + */ + public function it_detects_yarn(): void + { + $fullConfig = $this->sut->getFullConfiguration( + sprintf('%s/../fixtures/%s', __DIR__, 'node-configuration/yarn') + ); + $this->assertNotNull($fullConfig); + + $this->assertNotNull($fullConfig->nodeConfiguration); + $this->assertSame( + NodePackageManagerType::YARN, + $fullConfig->nodeConfiguration->packageManager + ); + } + + /** + * @test + */ + public function it_detects_yarn_berry(): void + { + $fullConfig = $this->sut->getFullConfiguration( + sprintf('%s/../fixtures/%s', __DIR__, 'node-configuration/yarn-berry') + ); + $this->assertNotNull($fullConfig); + + $this->assertNotNull($fullConfig->nodeConfiguration); + $this->assertSame( + NodePackageManagerType::YARN_BERRY, + $fullConfig->nodeConfiguration->packageManager + ); + } + /** * @test * diff --git a/tests/fixtures/node-configuration/bun-lock/bun.lock b/tests/fixtures/node-configuration/bun-lock/bun.lock new file mode 100644 index 0000000..cc41dd1 --- /dev/null +++ b/tests/fixtures/node-configuration/bun-lock/bun.lock @@ -0,0 +1,3 @@ +{ + "name": "bun-lock" +} diff --git a/tests/fixtures/node-configuration/bun-lock/package.json b/tests/fixtures/node-configuration/bun-lock/package.json new file mode 100644 index 0000000..93a68a5 --- /dev/null +++ b/tests/fixtures/node-configuration/bun-lock/package.json @@ -0,0 +1,3 @@ +{ + "name": "test-package" +} diff --git a/tests/fixtures/node-configuration/no-version/.gitkeep b/tests/fixtures/node-configuration/empty/.gitkeep similarity index 100% rename from tests/fixtures/node-configuration/no-version/.gitkeep rename to tests/fixtures/node-configuration/empty/.gitkeep diff --git a/tests/fixtures/node-configuration/no-version/package.json b/tests/fixtures/node-configuration/no-version/package.json new file mode 100644 index 0000000..0aafd5a --- /dev/null +++ b/tests/fixtures/node-configuration/no-version/package.json @@ -0,0 +1,3 @@ +{ + "name": "no-version-package" +} diff --git a/tests/fixtures/node-configuration/node-version-commented/package.json b/tests/fixtures/node-configuration/node-version-commented/package.json new file mode 100644 index 0000000..93a68a5 --- /dev/null +++ b/tests/fixtures/node-configuration/node-version-commented/package.json @@ -0,0 +1,3 @@ +{ + "name": "test-package" +} diff --git a/tests/fixtures/node-configuration/node-version/package.json b/tests/fixtures/node-configuration/node-version/package.json new file mode 100644 index 0000000..93a68a5 --- /dev/null +++ b/tests/fixtures/node-configuration/node-version/package.json @@ -0,0 +1,3 @@ +{ + "name": "test-package" +} diff --git a/tests/fixtures/node-configuration/npm-lock/package-lock.json b/tests/fixtures/node-configuration/npm-lock/package-lock.json new file mode 100644 index 0000000..93a68a5 --- /dev/null +++ b/tests/fixtures/node-configuration/npm-lock/package-lock.json @@ -0,0 +1,3 @@ +{ + "name": "test-package" +} diff --git a/tests/fixtures/node-configuration/npm-lock/package.json b/tests/fixtures/node-configuration/npm-lock/package.json new file mode 100644 index 0000000..93a68a5 --- /dev/null +++ b/tests/fixtures/node-configuration/npm-lock/package.json @@ -0,0 +1,3 @@ +{ + "name": "test-package" +} diff --git a/tests/fixtures/node-configuration/nvmrc-commented/package.json b/tests/fixtures/node-configuration/nvmrc-commented/package.json new file mode 100644 index 0000000..93a68a5 --- /dev/null +++ b/tests/fixtures/node-configuration/nvmrc-commented/package.json @@ -0,0 +1,3 @@ +{ + "name": "test-package" +} diff --git a/tests/fixtures/node-configuration/nvmrc/package.json b/tests/fixtures/node-configuration/nvmrc/package.json new file mode 100644 index 0000000..93a68a5 --- /dev/null +++ b/tests/fixtures/node-configuration/nvmrc/package.json @@ -0,0 +1,3 @@ +{ + "name": "test-package" +} diff --git a/tests/fixtures/node-configuration/pnpm-lock/package.json b/tests/fixtures/node-configuration/pnpm-lock/package.json new file mode 100644 index 0000000..93a68a5 --- /dev/null +++ b/tests/fixtures/node-configuration/pnpm-lock/package.json @@ -0,0 +1,3 @@ +{ + "name": "test-package" +} diff --git a/tests/fixtures/node-configuration/pnpm-lock/pnpm-lock.yaml b/tests/fixtures/node-configuration/pnpm-lock/pnpm-lock.yaml new file mode 100644 index 0000000..4eddb87 --- /dev/null +++ b/tests/fixtures/node-configuration/pnpm-lock/pnpm-lock.yaml @@ -0,0 +1,2 @@ +foo: + bar diff --git a/tests/fixtures/node-configuration/yarn-berry/.yarnrc.yml b/tests/fixtures/node-configuration/yarn-berry/.yarnrc.yml new file mode 100644 index 0000000..4eddb87 --- /dev/null +++ b/tests/fixtures/node-configuration/yarn-berry/.yarnrc.yml @@ -0,0 +1,2 @@ +foo: + bar diff --git a/tests/fixtures/node-configuration/yarn-berry/package.json b/tests/fixtures/node-configuration/yarn-berry/package.json new file mode 100644 index 0000000..93a68a5 --- /dev/null +++ b/tests/fixtures/node-configuration/yarn-berry/package.json @@ -0,0 +1,3 @@ +{ + "name": "test-package" +} diff --git a/tests/fixtures/node-configuration/yarn-berry/yarn.lock b/tests/fixtures/node-configuration/yarn-berry/yarn.lock new file mode 100644 index 0000000..93a68a5 --- /dev/null +++ b/tests/fixtures/node-configuration/yarn-berry/yarn.lock @@ -0,0 +1,3 @@ +{ + "name": "test-package" +} diff --git a/tests/fixtures/node-configuration/yarn/package.json b/tests/fixtures/node-configuration/yarn/package.json new file mode 100644 index 0000000..93a68a5 --- /dev/null +++ b/tests/fixtures/node-configuration/yarn/package.json @@ -0,0 +1,3 @@ +{ + "name": "test-package" +} diff --git a/tests/fixtures/node-configuration/yarn/yarn.lock b/tests/fixtures/node-configuration/yarn/yarn.lock new file mode 100644 index 0000000..93a68a5 --- /dev/null +++ b/tests/fixtures/node-configuration/yarn/yarn.lock @@ -0,0 +1,3 @@ +{ + "name": "test-package" +} From 87d0f03b696cd48fb8da8cdb80b5ce1dba2641a2 Mon Sep 17 00:00:00 2001 From: Einenlum Date: Thu, 4 Sep 2025 16:50:21 +0200 Subject: [PATCH 05/13] refactor test fixtures to be cleaner --- lib/NodeConfiguration.php | 2 +- lib/NodeConfigurationDetector.php | 2 +- tests/Unit/DetectorTest.php | 76 ++--- .../{ => php-stack}/bolt_cms/5/composer.json | 0 .../{ => php-stack}/cakephp/5/composer.json | 0 .../codeigniter/4/composer.json | 0 .../{ => php-stack}/craft_cms/3/composer.json | 0 .../{ => php-stack}/craft_cms/4/composer.json | 0 .../craft_cms/unknown/composer.json | 0 .../{ => php-stack}/drupal/11/composer.json | 0 .../{ => php-stack}/grav_cms/2/composer.json | 0 .../{ => php-stack}/laravel/10/composer.json | 0 .../{ => php-stack}/laravel/5/composer.json | 0 .../{ => php-stack}/laravel/6/composer.json | 0 .../{ => php-stack}/laravel/7/composer.json | 0 .../{ => php-stack}/laravel/8/composer.json | 0 .../{ => php-stack}/laravel/9/composer.json | 0 .../laravel/star/composer.json | 0 .../laravel/unknown/composer.json | 0 .../{ => php-stack}/leaf/3/composer.json | 0 .../{ => php-stack}/lunar/1/composer.json | 0 .../october_cms/4/composer.json | 0 .../{ => php-stack}/shopware/6/composer.json | 0 .../{ => php-stack}/statamic/4/composer.json | 0 .../statamic/unknown/composer.json | 0 .../symfony-in-composer-lock/composer.json | 66 ++++ .../symfony-in-composer-lock/composer.lock | 316 ++++++++++++++++++ .../{ => php-stack}/symfony/2/composer.json | 0 .../{ => php-stack}/symfony/3/composer.json | 0 .../{ => php-stack}/symfony/4/composer.json | 0 .../{ => php-stack}/symfony/5/composer.json | 0 .../{ => php-stack}/symfony/6/composer.json | 0 .../symfony/unknown/composer.json | 0 .../{ => php-stack}/tempest/1/composer.json | 0 .../{ => php-stack}/twill/3/composer.json | 0 .../typo3_cms/13/composer.json | 0 .../winter_cms/1/composer.json | 0 .../wordpress/1/wp-includes/vars.php | 0 .../wordpress/2/wp-includes/version.php | 0 .../wordpress/3/wp-includes/version.php | 0 .../wordpress/4/wp-includes/version.php | 0 .../wordpress/5/wp-includes/version.php | 0 .../wordpress/6/wp-includes/version.php | 0 43 files changed, 422 insertions(+), 40 deletions(-) rename tests/fixtures/{ => php-stack}/bolt_cms/5/composer.json (100%) rename tests/fixtures/{ => php-stack}/cakephp/5/composer.json (100%) rename tests/fixtures/{ => php-stack}/codeigniter/4/composer.json (100%) rename tests/fixtures/{ => php-stack}/craft_cms/3/composer.json (100%) rename tests/fixtures/{ => php-stack}/craft_cms/4/composer.json (100%) rename tests/fixtures/{ => php-stack}/craft_cms/unknown/composer.json (100%) rename tests/fixtures/{ => php-stack}/drupal/11/composer.json (100%) rename tests/fixtures/{ => php-stack}/grav_cms/2/composer.json (100%) rename tests/fixtures/{ => php-stack}/laravel/10/composer.json (100%) rename tests/fixtures/{ => php-stack}/laravel/5/composer.json (100%) rename tests/fixtures/{ => php-stack}/laravel/6/composer.json (100%) rename tests/fixtures/{ => php-stack}/laravel/7/composer.json (100%) rename tests/fixtures/{ => php-stack}/laravel/8/composer.json (100%) rename tests/fixtures/{ => php-stack}/laravel/9/composer.json (100%) rename tests/fixtures/{ => php-stack}/laravel/star/composer.json (100%) rename tests/fixtures/{ => php-stack}/laravel/unknown/composer.json (100%) rename tests/fixtures/{ => php-stack}/leaf/3/composer.json (100%) rename tests/fixtures/{ => php-stack}/lunar/1/composer.json (100%) rename tests/fixtures/{ => php-stack}/october_cms/4/composer.json (100%) rename tests/fixtures/{ => php-stack}/shopware/6/composer.json (100%) rename tests/fixtures/{ => php-stack}/statamic/4/composer.json (100%) rename tests/fixtures/{ => php-stack}/statamic/unknown/composer.json (100%) create mode 100644 tests/fixtures/php-stack/symfony-in-composer-lock/composer.json create mode 100644 tests/fixtures/php-stack/symfony-in-composer-lock/composer.lock rename tests/fixtures/{ => php-stack}/symfony/2/composer.json (100%) rename tests/fixtures/{ => php-stack}/symfony/3/composer.json (100%) rename tests/fixtures/{ => php-stack}/symfony/4/composer.json (100%) rename tests/fixtures/{ => php-stack}/symfony/5/composer.json (100%) rename tests/fixtures/{ => php-stack}/symfony/6/composer.json (100%) rename tests/fixtures/{ => php-stack}/symfony/unknown/composer.json (100%) rename tests/fixtures/{ => php-stack}/tempest/1/composer.json (100%) rename tests/fixtures/{ => php-stack}/twill/3/composer.json (100%) rename tests/fixtures/{ => php-stack}/typo3_cms/13/composer.json (100%) rename tests/fixtures/{ => php-stack}/winter_cms/1/composer.json (100%) rename tests/fixtures/{ => php-stack}/wordpress/1/wp-includes/vars.php (100%) rename tests/fixtures/{ => php-stack}/wordpress/2/wp-includes/version.php (100%) rename tests/fixtures/{ => php-stack}/wordpress/3/wp-includes/version.php (100%) rename tests/fixtures/{ => php-stack}/wordpress/4/wp-includes/version.php (100%) rename tests/fixtures/{ => php-stack}/wordpress/5/wp-includes/version.php (100%) rename tests/fixtures/{ => php-stack}/wordpress/6/wp-includes/version.php (100%) diff --git a/lib/NodeConfiguration.php b/lib/NodeConfiguration.php index ec8a521..4e05080 100644 --- a/lib/NodeConfiguration.php +++ b/lib/NodeConfiguration.php @@ -9,7 +9,7 @@ public function __construct( public ?string $version, public ?string $requirements, - public ?NodePackageManagerType $packageManager, + public NodePackageManagerType $packageManager, ) { } } diff --git a/lib/NodeConfigurationDetector.php b/lib/NodeConfigurationDetector.php index 25bc84b..2f6eeac 100644 --- a/lib/NodeConfigurationDetector.php +++ b/lib/NodeConfigurationDetector.php @@ -104,7 +104,7 @@ private function extractNodeVersion(?string $content): ?string private function getPackageManagerType( string $baseUri, ?string $subFolder = null, - ): ?NodePackageManagerType { + ): NodePackageManagerType { $lockFiles = [ 'package-lock.json' => NodePackageManagerType::NPM, 'pnpm-lock.yaml' => NodePackageManagerType::PNPM, diff --git a/tests/Unit/DetectorTest.php b/tests/Unit/DetectorTest.php index b1d745f..cc8ac40 100644 --- a/tests/Unit/DetectorTest.php +++ b/tests/Unit/DetectorTest.php @@ -337,61 +337,61 @@ public function it_detects_no_extension_if_not_in_require() public static function packagesDataProvider(): array { return [ - 'Symfony 2' => ['symfony/2', '2.3', StackType::SYMFONY], - 'Symfony 3' => ['symfony/3', '3.4', StackType::SYMFONY], - 'Symfony 4' => ['symfony/4', '4', StackType::SYMFONY], - 'Symfony 5' => ['symfony/5', '5.0', StackType::SYMFONY], - 'Symfony 6' => ['symfony/6', '6.3', StackType::SYMFONY], - 'Symfony unknown version' => ['symfony/unknown', null, StackType::SYMFONY], + 'Symfony 2' => ['php-stack/symfony/2', '2.3', StackType::SYMFONY], + 'Symfony 3' => ['php-stack/symfony/3', '3.4', StackType::SYMFONY], + 'Symfony 4' => ['php-stack/symfony/4', '4', StackType::SYMFONY], + 'Symfony 5' => ['php-stack/symfony/5', '5.0', StackType::SYMFONY], + 'Symfony 6' => ['php-stack/symfony/6', '6.3', StackType::SYMFONY], + 'Symfony unknown version' => ['php-stack/symfony/unknown', null, StackType::SYMFONY], - 'Laravel *' => ['laravel/star', null, StackType::LARAVEL], - 'Laravel 5' => ['laravel/5', '5.2', StackType::LARAVEL], - 'Laravel 6' => ['laravel/6', '6', StackType::LARAVEL], - 'Laravel 7' => ['laravel/7', '7', StackType::LARAVEL], - 'Laravel 8' => ['laravel/8', '8', StackType::LARAVEL], - 'Laravel 9' => ['laravel/9', '9.8.3', StackType::LARAVEL], - 'Laravel 10' => ['laravel/10', '10', StackType::LARAVEL], - 'Laravel unknown version' => ['laravel/unknown', null, StackType::LARAVEL], + 'Laravel *' => ['php-stack/laravel/star', null, StackType::LARAVEL], + 'Laravel 5' => ['php-stack/laravel/5', '5.2', StackType::LARAVEL], + 'Laravel 6' => ['php-stack/laravel/6', '6', StackType::LARAVEL], + 'Laravel 7' => ['php-stack/laravel/7', '7', StackType::LARAVEL], + 'Laravel 8' => ['php-stack/laravel/8', '8', StackType::LARAVEL], + 'Laravel 9' => ['php-stack/laravel/9', '9.8.3', StackType::LARAVEL], + 'Laravel 10' => ['php-stack/laravel/10', '10', StackType::LARAVEL], + 'Laravel unknown version' => ['php-stack/laravel/unknown', null, StackType::LARAVEL], - 'Bolt CMS 5' => ['bolt_cms/5', '5', StackType::BOLT_CMS], + 'Bolt CMS 5' => ['php-stack/bolt_cms/5', '5', StackType::BOLT_CMS], - 'Cake PHP 5' => ['cakephp/5', '5.1', StackType::CAKE_PHP], + 'Cake PHP 5' => ['php-stack/cakephp/5', '5.1', StackType::CAKE_PHP], - 'Codeigniter 4' => ['codeigniter/4', '4', StackType::CODEIGNITER], + 'Codeigniter 4' => ['php-stack/codeigniter/4', '4', StackType::CODEIGNITER], - 'Drupal 11' => ['drupal/11', '11', StackType::DRUPAL], + 'Drupal 11' => ['php-stack/drupal/11', '11', StackType::DRUPAL], - 'Grav CMS 2' => ['grav_cms/2', '2', StackType::GRAV_CMS], + 'Grav CMS 2' => ['php-stack/grav_cms/2', '2', StackType::GRAV_CMS], - 'Leaf 3' => ['leaf/3', '3', StackType::LEAF_PHP], + 'Leaf 3' => ['php-stack/leaf/3', '3', StackType::LEAF_PHP], - 'Lunar 1' => ['lunar/1', '1', StackType::LUNAR], + 'Lunar 1' => ['php-stack/lunar/1', '1', StackType::LUNAR], - 'October CMS 4' => ['october_cms/4', '4', StackType::OCTOBER_CMS], + 'October CMS 4' => ['php-stack/october_cms/4', '4', StackType::OCTOBER_CMS], - 'Shopware 6' => ['shopware/6', '6.7.0', StackType::SHOPWARE], + 'Shopware 6' => ['php-stack/shopware/6', '6.7.0', StackType::SHOPWARE], - 'Twill 3' => ['twill/3', '3', StackType::TWILL], + 'Twill 3' => ['php-stack/twill/3', '3', StackType::TWILL], - 'Typo 3 13' => ['typo3_cms/13', '13', StackType::TYPO3_CMS], + 'Typo 3 13' => ['php-stack/typo3_cms/13', '13', StackType::TYPO3_CMS], - 'Winter CMS 1' => ['winter_cms/1', '1.2', StackType::WINTER_CMS], + 'Winter CMS 1' => ['php-stack/winter_cms/1', '1.2', StackType::WINTER_CMS], - 'Wordpress 1' => ['wordpress/1', '1.0.2', StackType::WORDPRESS], - 'Wordpress 2' => ['wordpress/2', '2.0.11', StackType::WORDPRESS], - 'Wordpress 3' => ['wordpress/3', '3.0.6', StackType::WORDPRESS], - 'Wordpress 4' => ['wordpress/4', '4.0.38', StackType::WORDPRESS], - 'Wordpress 5' => ['wordpress/5', '5.0.20', StackType::WORDPRESS], - 'Wordpress 6' => ['wordpress/6', '6.3.2', StackType::WORDPRESS], + 'Wordpress 1' => ['php-stack/wordpress/1', '1.0.2', StackType::WORDPRESS], + 'Wordpress 2' => ['php-stack/wordpress/2', '2.0.11', StackType::WORDPRESS], + 'Wordpress 3' => ['php-stack/wordpress/3', '3.0.6', StackType::WORDPRESS], + 'Wordpress 4' => ['php-stack/wordpress/4', '4.0.38', StackType::WORDPRESS], + 'Wordpress 5' => ['php-stack/wordpress/5', '5.0.20', StackType::WORDPRESS], + 'Wordpress 6' => ['php-stack/wordpress/6', '6.3.2', StackType::WORDPRESS], - 'Craft CMS 3' => ['craft_cms/3', '3.6', StackType::CRAFT_CMS], - 'Craft CMS 4' => ['craft_cms/4', '4.4', StackType::CRAFT_CMS], - 'Craft CMS unknown version' => ['craft_cms/unknown', null, StackType::CRAFT_CMS], + 'Craft CMS 3' => ['php-stack/craft_cms/3', '3.6', StackType::CRAFT_CMS], + 'Craft CMS 4' => ['php-stack/craft_cms/4', '4.4', StackType::CRAFT_CMS], + 'Craft CMS unknown version' => ['php-stack/craft_cms/unknown', null, StackType::CRAFT_CMS], - 'Statamic 4' => ['statamic/4', '4', StackType::STATAMIC], - 'Statamic unknown version' => ['statamic/unknown', null, StackType::STATAMIC], + 'Statamic 4' => ['php-stack/statamic/4', '4', StackType::STATAMIC], + 'Statamic unknown version' => ['php-stack/statamic/unknown', null, StackType::STATAMIC], - 'Composer lock test' => ['composer-lock', '6.3.5', StackType::SYMFONY], + 'Composer lock test' => ['php-stack/symfony-in-composer-lock', '6.3.5', StackType::SYMFONY], ]; } } diff --git a/tests/fixtures/bolt_cms/5/composer.json b/tests/fixtures/php-stack/bolt_cms/5/composer.json similarity index 100% rename from tests/fixtures/bolt_cms/5/composer.json rename to tests/fixtures/php-stack/bolt_cms/5/composer.json diff --git a/tests/fixtures/cakephp/5/composer.json b/tests/fixtures/php-stack/cakephp/5/composer.json similarity index 100% rename from tests/fixtures/cakephp/5/composer.json rename to tests/fixtures/php-stack/cakephp/5/composer.json diff --git a/tests/fixtures/codeigniter/4/composer.json b/tests/fixtures/php-stack/codeigniter/4/composer.json similarity index 100% rename from tests/fixtures/codeigniter/4/composer.json rename to tests/fixtures/php-stack/codeigniter/4/composer.json diff --git a/tests/fixtures/craft_cms/3/composer.json b/tests/fixtures/php-stack/craft_cms/3/composer.json similarity index 100% rename from tests/fixtures/craft_cms/3/composer.json rename to tests/fixtures/php-stack/craft_cms/3/composer.json diff --git a/tests/fixtures/craft_cms/4/composer.json b/tests/fixtures/php-stack/craft_cms/4/composer.json similarity index 100% rename from tests/fixtures/craft_cms/4/composer.json rename to tests/fixtures/php-stack/craft_cms/4/composer.json diff --git a/tests/fixtures/craft_cms/unknown/composer.json b/tests/fixtures/php-stack/craft_cms/unknown/composer.json similarity index 100% rename from tests/fixtures/craft_cms/unknown/composer.json rename to tests/fixtures/php-stack/craft_cms/unknown/composer.json diff --git a/tests/fixtures/drupal/11/composer.json b/tests/fixtures/php-stack/drupal/11/composer.json similarity index 100% rename from tests/fixtures/drupal/11/composer.json rename to tests/fixtures/php-stack/drupal/11/composer.json diff --git a/tests/fixtures/grav_cms/2/composer.json b/tests/fixtures/php-stack/grav_cms/2/composer.json similarity index 100% rename from tests/fixtures/grav_cms/2/composer.json rename to tests/fixtures/php-stack/grav_cms/2/composer.json diff --git a/tests/fixtures/laravel/10/composer.json b/tests/fixtures/php-stack/laravel/10/composer.json similarity index 100% rename from tests/fixtures/laravel/10/composer.json rename to tests/fixtures/php-stack/laravel/10/composer.json diff --git a/tests/fixtures/laravel/5/composer.json b/tests/fixtures/php-stack/laravel/5/composer.json similarity index 100% rename from tests/fixtures/laravel/5/composer.json rename to tests/fixtures/php-stack/laravel/5/composer.json diff --git a/tests/fixtures/laravel/6/composer.json b/tests/fixtures/php-stack/laravel/6/composer.json similarity index 100% rename from tests/fixtures/laravel/6/composer.json rename to tests/fixtures/php-stack/laravel/6/composer.json diff --git a/tests/fixtures/laravel/7/composer.json b/tests/fixtures/php-stack/laravel/7/composer.json similarity index 100% rename from tests/fixtures/laravel/7/composer.json rename to tests/fixtures/php-stack/laravel/7/composer.json diff --git a/tests/fixtures/laravel/8/composer.json b/tests/fixtures/php-stack/laravel/8/composer.json similarity index 100% rename from tests/fixtures/laravel/8/composer.json rename to tests/fixtures/php-stack/laravel/8/composer.json diff --git a/tests/fixtures/laravel/9/composer.json b/tests/fixtures/php-stack/laravel/9/composer.json similarity index 100% rename from tests/fixtures/laravel/9/composer.json rename to tests/fixtures/php-stack/laravel/9/composer.json diff --git a/tests/fixtures/laravel/star/composer.json b/tests/fixtures/php-stack/laravel/star/composer.json similarity index 100% rename from tests/fixtures/laravel/star/composer.json rename to tests/fixtures/php-stack/laravel/star/composer.json diff --git a/tests/fixtures/laravel/unknown/composer.json b/tests/fixtures/php-stack/laravel/unknown/composer.json similarity index 100% rename from tests/fixtures/laravel/unknown/composer.json rename to tests/fixtures/php-stack/laravel/unknown/composer.json diff --git a/tests/fixtures/leaf/3/composer.json b/tests/fixtures/php-stack/leaf/3/composer.json similarity index 100% rename from tests/fixtures/leaf/3/composer.json rename to tests/fixtures/php-stack/leaf/3/composer.json diff --git a/tests/fixtures/lunar/1/composer.json b/tests/fixtures/php-stack/lunar/1/composer.json similarity index 100% rename from tests/fixtures/lunar/1/composer.json rename to tests/fixtures/php-stack/lunar/1/composer.json diff --git a/tests/fixtures/october_cms/4/composer.json b/tests/fixtures/php-stack/october_cms/4/composer.json similarity index 100% rename from tests/fixtures/october_cms/4/composer.json rename to tests/fixtures/php-stack/october_cms/4/composer.json diff --git a/tests/fixtures/shopware/6/composer.json b/tests/fixtures/php-stack/shopware/6/composer.json similarity index 100% rename from tests/fixtures/shopware/6/composer.json rename to tests/fixtures/php-stack/shopware/6/composer.json diff --git a/tests/fixtures/statamic/4/composer.json b/tests/fixtures/php-stack/statamic/4/composer.json similarity index 100% rename from tests/fixtures/statamic/4/composer.json rename to tests/fixtures/php-stack/statamic/4/composer.json diff --git a/tests/fixtures/statamic/unknown/composer.json b/tests/fixtures/php-stack/statamic/unknown/composer.json similarity index 100% rename from tests/fixtures/statamic/unknown/composer.json rename to tests/fixtures/php-stack/statamic/unknown/composer.json diff --git a/tests/fixtures/php-stack/symfony-in-composer-lock/composer.json b/tests/fixtures/php-stack/symfony-in-composer-lock/composer.json new file mode 100644 index 0000000..0ac81ac --- /dev/null +++ b/tests/fixtures/php-stack/symfony-in-composer-lock/composer.json @@ -0,0 +1,66 @@ +{ + "type": "project", + "license": "proprietary", + "minimum-stability": "stable", + "prefer-stable": true, + "require": { + "symfony/framework-bundle": "6.3.*", + "symfony/runtime": "6.3.*", + "symfony/yaml": "6.3.*", + "lorem/ipsum": "2.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5", + "symfony/browser-kit": "6.3.*", + "symfony/css-selector": "6.3.*", + "symfony/phpunit-bridge": "^6.3" + }, + "config": { + "allow-plugins": { + "php-http/discovery": true, + "symfony/flex": true, + "symfony/runtime": true + }, + "sort-packages": true + }, + "autoload": { + "psr-4": { + "App\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "App\\Tests\\": "tests/" + } + }, + "replace": { + "symfony/polyfill-ctype": "*", + "symfony/polyfill-iconv": "*", + "symfony/polyfill-php72": "*", + "symfony/polyfill-php73": "*", + "symfony/polyfill-php74": "*", + "symfony/polyfill-php80": "*", + "symfony/polyfill-php81": "*" + }, + "scripts": { + "auto-scripts": { + "cache:clear": "symfony-cmd", + "assets:install %PUBLIC_DIR%": "symfony-cmd" + }, + "post-install-cmd": [ + "@auto-scripts" + ], + "post-update-cmd": [ + "@auto-scripts" + ] + }, + "conflict": { + "symfony/symfony": "*" + }, + "extra": { + "symfony": { + "allow-contrib": false, + "require": "6.3.*" + } + } +} diff --git a/tests/fixtures/php-stack/symfony-in-composer-lock/composer.lock b/tests/fixtures/php-stack/symfony-in-composer-lock/composer.lock new file mode 100644 index 0000000..4b3dcbf --- /dev/null +++ b/tests/fixtures/php-stack/symfony-in-composer-lock/composer.lock @@ -0,0 +1,316 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "0ff5bf63dfe00c079888b47286b794c9", + "packages": [ + { + "name": "someframework/foo", + "version": "v2.4.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "b47ca238b03e7b0d7880ffd1cf06e8d637ca1467" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/b47ca238b03e7b0d7880ffd1cf06e8d637ca1467", + "reference": "b47ca238b03e7b0d7880ffd1cf06e8d637ca1467", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/filesystem": "^5.4|^6.0", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/finder": "<5.4", + "symfony/service-contracts": "<2.5" + }, + "require-dev": { + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/messenger": "^5.4|^6.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v6.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-07-19T20:22:16+00:00" + }, + { + "name": "symfony/config", + "version": "v6.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "b47ca238b03e7b0d7880ffd1cf06e8d637ca1467" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/b47ca238b03e7b0d7880ffd1cf06e8d637ca1467", + "reference": "b47ca238b03e7b0d7880ffd1cf06e8d637ca1467", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/filesystem": "^5.4|^6.0", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/finder": "<5.4", + "symfony/service-contracts": "<2.5" + }, + "require-dev": { + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/messenger": "^5.4|^6.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v6.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-07-19T20:22:16+00:00" + }, + { + "name": "symfony/framework-bundle", + "version": "v6.3.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/framework-bundle.git", + "reference": "567cafcfc08e3076b47290a7558b0ca17a98b0ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/567cafcfc08e3076b47290a7558b0ca17a98b0ce", + "reference": "567cafcfc08e3076b47290a7558b0ca17a98b0ce", + "shasum": "" + }, + "require": { + "composer-runtime-api": ">=2.1", + "ext-xml": "*", + "php": ">=8.1", + "symfony/cache": "^5.4|^6.0", + "symfony/config": "^6.1", + "symfony/dependency-injection": "^6.3.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.1", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/filesystem": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/http-foundation": "^6.3", + "symfony/http-kernel": "^6.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/routing": "^5.4|^6.0" + }, + "conflict": { + "doctrine/annotations": "<1.13.1", + "doctrine/persistence": "<1.3", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/asset": "<5.4", + "symfony/clock": "<6.3", + "symfony/console": "<5.4", + "symfony/dom-crawler": "<6.3", + "symfony/dotenv": "<5.4", + "symfony/form": "<5.4", + "symfony/http-client": "<6.3", + "symfony/lock": "<5.4", + "symfony/mailer": "<5.4", + "symfony/messenger": "<6.3", + "symfony/mime": "<6.2", + "symfony/property-access": "<5.4", + "symfony/property-info": "<5.4", + "symfony/security-core": "<5.4", + "symfony/security-csrf": "<5.4", + "symfony/serializer": "<6.3", + "symfony/stopwatch": "<5.4", + "symfony/translation": "<6.2.8", + "symfony/twig-bridge": "<5.4", + "symfony/twig-bundle": "<5.4", + "symfony/validator": "<6.3", + "symfony/web-profiler-bundle": "<5.4", + "symfony/workflow": "<5.4" + }, + "require-dev": { + "doctrine/annotations": "^1.13.1|^2", + "doctrine/persistence": "^1.3|^2|^3", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/asset": "^5.4|^6.0", + "symfony/asset-mapper": "^6.3", + "symfony/browser-kit": "^5.4|^6.0", + "symfony/clock": "^6.2", + "symfony/console": "^5.4.9|^6.0.9", + "symfony/css-selector": "^5.4|^6.0", + "symfony/dom-crawler": "^6.3", + "symfony/dotenv": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/form": "^5.4|^6.0", + "symfony/html-sanitizer": "^6.1", + "symfony/http-client": "^6.3", + "symfony/lock": "^5.4|^6.0", + "symfony/mailer": "^5.4|^6.0", + "symfony/messenger": "^6.3", + "symfony/mime": "^6.2", + "symfony/notifier": "^5.4|^6.0", + "symfony/polyfill-intl-icu": "~1.0", + "symfony/process": "^5.4|^6.0", + "symfony/property-info": "^5.4|^6.0", + "symfony/rate-limiter": "^5.4|^6.0", + "symfony/scheduler": "^6.3", + "symfony/security-bundle": "^5.4|^6.0", + "symfony/semaphore": "^5.4|^6.0", + "symfony/serializer": "^6.3", + "symfony/stopwatch": "^5.4|^6.0", + "symfony/string": "^5.4|^6.0", + "symfony/translation": "^6.2.8", + "symfony/twig-bundle": "^5.4|^6.0", + "symfony/uid": "^5.4|^6.0", + "symfony/validator": "^6.3", + "symfony/web-link": "^5.4|^6.0", + "symfony/workflow": "^5.4|^6.0", + "symfony/yaml": "^5.4|^6.0", + "twig/twig": "^2.10|^3.0" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Symfony\\Bundle\\FrameworkBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/framework-bundle/tree/v6.3.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-09-29T10:45:15+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": ">=8.1", + "ext-ctype": "*", + "ext-iconv": "*" + }, + "platform-dev": [], + "plugin-api-version": "2.3.0" +} diff --git a/tests/fixtures/symfony/2/composer.json b/tests/fixtures/php-stack/symfony/2/composer.json similarity index 100% rename from tests/fixtures/symfony/2/composer.json rename to tests/fixtures/php-stack/symfony/2/composer.json diff --git a/tests/fixtures/symfony/3/composer.json b/tests/fixtures/php-stack/symfony/3/composer.json similarity index 100% rename from tests/fixtures/symfony/3/composer.json rename to tests/fixtures/php-stack/symfony/3/composer.json diff --git a/tests/fixtures/symfony/4/composer.json b/tests/fixtures/php-stack/symfony/4/composer.json similarity index 100% rename from tests/fixtures/symfony/4/composer.json rename to tests/fixtures/php-stack/symfony/4/composer.json diff --git a/tests/fixtures/symfony/5/composer.json b/tests/fixtures/php-stack/symfony/5/composer.json similarity index 100% rename from tests/fixtures/symfony/5/composer.json rename to tests/fixtures/php-stack/symfony/5/composer.json diff --git a/tests/fixtures/symfony/6/composer.json b/tests/fixtures/php-stack/symfony/6/composer.json similarity index 100% rename from tests/fixtures/symfony/6/composer.json rename to tests/fixtures/php-stack/symfony/6/composer.json diff --git a/tests/fixtures/symfony/unknown/composer.json b/tests/fixtures/php-stack/symfony/unknown/composer.json similarity index 100% rename from tests/fixtures/symfony/unknown/composer.json rename to tests/fixtures/php-stack/symfony/unknown/composer.json diff --git a/tests/fixtures/tempest/1/composer.json b/tests/fixtures/php-stack/tempest/1/composer.json similarity index 100% rename from tests/fixtures/tempest/1/composer.json rename to tests/fixtures/php-stack/tempest/1/composer.json diff --git a/tests/fixtures/twill/3/composer.json b/tests/fixtures/php-stack/twill/3/composer.json similarity index 100% rename from tests/fixtures/twill/3/composer.json rename to tests/fixtures/php-stack/twill/3/composer.json diff --git a/tests/fixtures/typo3_cms/13/composer.json b/tests/fixtures/php-stack/typo3_cms/13/composer.json similarity index 100% rename from tests/fixtures/typo3_cms/13/composer.json rename to tests/fixtures/php-stack/typo3_cms/13/composer.json diff --git a/tests/fixtures/winter_cms/1/composer.json b/tests/fixtures/php-stack/winter_cms/1/composer.json similarity index 100% rename from tests/fixtures/winter_cms/1/composer.json rename to tests/fixtures/php-stack/winter_cms/1/composer.json diff --git a/tests/fixtures/wordpress/1/wp-includes/vars.php b/tests/fixtures/php-stack/wordpress/1/wp-includes/vars.php similarity index 100% rename from tests/fixtures/wordpress/1/wp-includes/vars.php rename to tests/fixtures/php-stack/wordpress/1/wp-includes/vars.php diff --git a/tests/fixtures/wordpress/2/wp-includes/version.php b/tests/fixtures/php-stack/wordpress/2/wp-includes/version.php similarity index 100% rename from tests/fixtures/wordpress/2/wp-includes/version.php rename to tests/fixtures/php-stack/wordpress/2/wp-includes/version.php diff --git a/tests/fixtures/wordpress/3/wp-includes/version.php b/tests/fixtures/php-stack/wordpress/3/wp-includes/version.php similarity index 100% rename from tests/fixtures/wordpress/3/wp-includes/version.php rename to tests/fixtures/php-stack/wordpress/3/wp-includes/version.php diff --git a/tests/fixtures/wordpress/4/wp-includes/version.php b/tests/fixtures/php-stack/wordpress/4/wp-includes/version.php similarity index 100% rename from tests/fixtures/wordpress/4/wp-includes/version.php rename to tests/fixtures/php-stack/wordpress/4/wp-includes/version.php diff --git a/tests/fixtures/wordpress/5/wp-includes/version.php b/tests/fixtures/php-stack/wordpress/5/wp-includes/version.php similarity index 100% rename from tests/fixtures/wordpress/5/wp-includes/version.php rename to tests/fixtures/php-stack/wordpress/5/wp-includes/version.php diff --git a/tests/fixtures/wordpress/6/wp-includes/version.php b/tests/fixtures/php-stack/wordpress/6/wp-includes/version.php similarity index 100% rename from tests/fixtures/wordpress/6/wp-includes/version.php rename to tests/fixtures/php-stack/wordpress/6/wp-includes/version.php From 08bed3d42e82beda16fbb5e6f77e8a938e2a711b Mon Sep 17 00:00:00 2001 From: Einenlum Date: Thu, 4 Sep 2025 16:52:34 +0200 Subject: [PATCH 06/13] refactor detector test with php-stack prefix --- tests/Unit/DetectorTest.php | 78 ++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/tests/Unit/DetectorTest.php b/tests/Unit/DetectorTest.php index cc8ac40..543acc8 100644 --- a/tests/Unit/DetectorTest.php +++ b/tests/Unit/DetectorTest.php @@ -217,7 +217,7 @@ public function it_detects_yarn_berry(): void public function it_detects_stack(string $fixtureFolder, ?string $expectedVersion, StackType $expectedType): void { $fullConfig = $this->sut->getFullConfiguration( - sprintf('%s/../fixtures/%s', __DIR__, $fixtureFolder) + sprintf('%s/../fixtures/php-stack/%s', __DIR__, $fixtureFolder) ); $this->assertNotNull($fullConfig); @@ -337,61 +337,61 @@ public function it_detects_no_extension_if_not_in_require() public static function packagesDataProvider(): array { return [ - 'Symfony 2' => ['php-stack/symfony/2', '2.3', StackType::SYMFONY], - 'Symfony 3' => ['php-stack/symfony/3', '3.4', StackType::SYMFONY], - 'Symfony 4' => ['php-stack/symfony/4', '4', StackType::SYMFONY], - 'Symfony 5' => ['php-stack/symfony/5', '5.0', StackType::SYMFONY], - 'Symfony 6' => ['php-stack/symfony/6', '6.3', StackType::SYMFONY], - 'Symfony unknown version' => ['php-stack/symfony/unknown', null, StackType::SYMFONY], + 'Symfony 2' => ['symfony/2', '2.3', StackType::SYMFONY], + 'Symfony 3' => ['symfony/3', '3.4', StackType::SYMFONY], + 'Symfony 4' => ['symfony/4', '4', StackType::SYMFONY], + 'Symfony 5' => ['symfony/5', '5.0', StackType::SYMFONY], + 'Symfony 6' => ['symfony/6', '6.3', StackType::SYMFONY], + 'Symfony unknown version' => ['symfony/unknown', null, StackType::SYMFONY], - 'Laravel *' => ['php-stack/laravel/star', null, StackType::LARAVEL], - 'Laravel 5' => ['php-stack/laravel/5', '5.2', StackType::LARAVEL], - 'Laravel 6' => ['php-stack/laravel/6', '6', StackType::LARAVEL], - 'Laravel 7' => ['php-stack/laravel/7', '7', StackType::LARAVEL], - 'Laravel 8' => ['php-stack/laravel/8', '8', StackType::LARAVEL], - 'Laravel 9' => ['php-stack/laravel/9', '9.8.3', StackType::LARAVEL], - 'Laravel 10' => ['php-stack/laravel/10', '10', StackType::LARAVEL], - 'Laravel unknown version' => ['php-stack/laravel/unknown', null, StackType::LARAVEL], + 'Laravel *' => ['laravel/star', null, StackType::LARAVEL], + 'Laravel 5' => ['laravel/5', '5.2', StackType::LARAVEL], + 'Laravel 6' => ['laravel/6', '6', StackType::LARAVEL], + 'Laravel 7' => ['laravel/7', '7', StackType::LARAVEL], + 'Laravel 8' => ['laravel/8', '8', StackType::LARAVEL], + 'Laravel 9' => ['laravel/9', '9.8.3', StackType::LARAVEL], + 'Laravel 10' => ['laravel/10', '10', StackType::LARAVEL], + 'Laravel unknown version' => ['laravel/unknown', null, StackType::LARAVEL], - 'Bolt CMS 5' => ['php-stack/bolt_cms/5', '5', StackType::BOLT_CMS], + 'Bolt CMS 5' => ['bolt_cms/5', '5', StackType::BOLT_CMS], - 'Cake PHP 5' => ['php-stack/cakephp/5', '5.1', StackType::CAKE_PHP], + 'Cake PHP 5' => ['cakephp/5', '5.1', StackType::CAKE_PHP], - 'Codeigniter 4' => ['php-stack/codeigniter/4', '4', StackType::CODEIGNITER], + 'Codeigniter 4' => ['codeigniter/4', '4', StackType::CODEIGNITER], - 'Drupal 11' => ['php-stack/drupal/11', '11', StackType::DRUPAL], + 'Drupal 11' => ['drupal/11', '11', StackType::DRUPAL], - 'Grav CMS 2' => ['php-stack/grav_cms/2', '2', StackType::GRAV_CMS], + 'Grav CMS 2' => ['grav_cms/2', '2', StackType::GRAV_CMS], - 'Leaf 3' => ['php-stack/leaf/3', '3', StackType::LEAF_PHP], + 'Leaf 3' => ['leaf/3', '3', StackType::LEAF_PHP], - 'Lunar 1' => ['php-stack/lunar/1', '1', StackType::LUNAR], + 'Lunar 1' => ['lunar/1', '1', StackType::LUNAR], - 'October CMS 4' => ['php-stack/october_cms/4', '4', StackType::OCTOBER_CMS], + 'October CMS 4' => ['october_cms/4', '4', StackType::OCTOBER_CMS], - 'Shopware 6' => ['php-stack/shopware/6', '6.7.0', StackType::SHOPWARE], + 'Shopware 6' => ['shopware/6', '6.7.0', StackType::SHOPWARE], - 'Twill 3' => ['php-stack/twill/3', '3', StackType::TWILL], + 'Twill 3' => ['twill/3', '3', StackType::TWILL], - 'Typo 3 13' => ['php-stack/typo3_cms/13', '13', StackType::TYPO3_CMS], + 'Typo 3 13' => ['typo3_cms/13', '13', StackType::TYPO3_CMS], - 'Winter CMS 1' => ['php-stack/winter_cms/1', '1.2', StackType::WINTER_CMS], + 'Winter CMS 1' => ['winter_cms/1', '1.2', StackType::WINTER_CMS], - 'Wordpress 1' => ['php-stack/wordpress/1', '1.0.2', StackType::WORDPRESS], - 'Wordpress 2' => ['php-stack/wordpress/2', '2.0.11', StackType::WORDPRESS], - 'Wordpress 3' => ['php-stack/wordpress/3', '3.0.6', StackType::WORDPRESS], - 'Wordpress 4' => ['php-stack/wordpress/4', '4.0.38', StackType::WORDPRESS], - 'Wordpress 5' => ['php-stack/wordpress/5', '5.0.20', StackType::WORDPRESS], - 'Wordpress 6' => ['php-stack/wordpress/6', '6.3.2', StackType::WORDPRESS], + 'Wordpress 1' => ['wordpress/1', '1.0.2', StackType::WORDPRESS], + 'Wordpress 2' => ['wordpress/2', '2.0.11', StackType::WORDPRESS], + 'Wordpress 3' => ['wordpress/3', '3.0.6', StackType::WORDPRESS], + 'Wordpress 4' => ['wordpress/4', '4.0.38', StackType::WORDPRESS], + 'Wordpress 5' => ['wordpress/5', '5.0.20', StackType::WORDPRESS], + 'Wordpress 6' => ['wordpress/6', '6.3.2', StackType::WORDPRESS], - 'Craft CMS 3' => ['php-stack/craft_cms/3', '3.6', StackType::CRAFT_CMS], - 'Craft CMS 4' => ['php-stack/craft_cms/4', '4.4', StackType::CRAFT_CMS], - 'Craft CMS unknown version' => ['php-stack/craft_cms/unknown', null, StackType::CRAFT_CMS], + 'Craft CMS 3' => ['craft_cms/3', '3.6', StackType::CRAFT_CMS], + 'Craft CMS 4' => ['craft_cms/4', '4.4', StackType::CRAFT_CMS], + 'Craft CMS unknown version' => ['craft_cms/unknown', null, StackType::CRAFT_CMS], - 'Statamic 4' => ['php-stack/statamic/4', '4', StackType::STATAMIC], - 'Statamic unknown version' => ['php-stack/statamic/unknown', null, StackType::STATAMIC], + 'Statamic 4' => ['statamic/4', '4', StackType::STATAMIC], + 'Statamic unknown version' => ['statamic/unknown', null, StackType::STATAMIC], - 'Composer lock test' => ['php-stack/symfony-in-composer-lock', '6.3.5', StackType::SYMFONY], + 'Composer lock test' => ['symfony-in-composer-lock', '6.3.5', StackType::SYMFONY], ]; } } From 6b8eeaefc44efa82a743e2fe47195497493e1be9 Mon Sep 17 00:00:00 2001 From: Einenlum Date: Thu, 4 Sep 2025 17:01:48 +0200 Subject: [PATCH 07/13] move stack to dto --- lib/{ => DTO}/Stack.php | 4 +++- lib/Detector.php | 2 ++ lib/FullConfiguration.php | 2 ++ lib/StackDetector/BaseComposerTypeDetector.php | 2 +- lib/StackDetector/LaravelDetector.php | 2 +- lib/StackDetector/WordpressDetector.php | 2 +- lib/StackDetectorInterface.php | 2 ++ 7 files changed, 12 insertions(+), 4 deletions(-) rename lib/{ => DTO}/Stack.php (67%) diff --git a/lib/Stack.php b/lib/DTO/Stack.php similarity index 67% rename from lib/Stack.php rename to lib/DTO/Stack.php index 928d685..65fa639 100644 --- a/lib/Stack.php +++ b/lib/DTO/Stack.php @@ -2,7 +2,9 @@ declare(strict_types=1); -namespace Einenlum\PhpStackDetector; +namespace Einenlum\PhpStackDetector\DTO; + +use Einenlum\PhpStackDetector\StackType; readonly class Stack { diff --git a/lib/Detector.php b/lib/Detector.php index 757f13b..63dcc88 100644 --- a/lib/Detector.php +++ b/lib/Detector.php @@ -4,6 +4,8 @@ namespace Einenlum\PhpStackDetector; +use Einenlum\PhpStackDetector\DTO\Stack; + readonly class Detector { /** @param StackDetectorInterface[] $stackDetectors */ diff --git a/lib/FullConfiguration.php b/lib/FullConfiguration.php index 366975a..a21d353 100644 --- a/lib/FullConfiguration.php +++ b/lib/FullConfiguration.php @@ -4,6 +4,8 @@ namespace Einenlum\PhpStackDetector; +use Einenlum\PhpStackDetector\DTO\Stack; + readonly class FullConfiguration { public function __construct( diff --git a/lib/StackDetector/BaseComposerTypeDetector.php b/lib/StackDetector/BaseComposerTypeDetector.php index 8bb7ee6..a3ef3ab 100644 --- a/lib/StackDetector/BaseComposerTypeDetector.php +++ b/lib/StackDetector/BaseComposerTypeDetector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\Composer\PackageVersionProvider; -use Einenlum\PhpStackDetector\Stack; +use Einenlum\PhpStackDetector\DTO\Stack; use Einenlum\PhpStackDetector\StackType; abstract class BaseComposerTypeDetector diff --git a/lib/StackDetector/LaravelDetector.php b/lib/StackDetector/LaravelDetector.php index 4b17b8e..28c3e0a 100644 --- a/lib/StackDetector/LaravelDetector.php +++ b/lib/StackDetector/LaravelDetector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\DependencyTree; -use Einenlum\PhpStackDetector\Stack; +use Einenlum\PhpStackDetector\DTO\Stack; use Einenlum\PhpStackDetector\StackDetectorInterface; use Einenlum\PhpStackDetector\StackType; diff --git a/lib/StackDetector/WordpressDetector.php b/lib/StackDetector/WordpressDetector.php index 0a73d31..e570548 100644 --- a/lib/StackDetector/WordpressDetector.php +++ b/lib/StackDetector/WordpressDetector.php @@ -4,7 +4,7 @@ use Einenlum\PhpStackDetector\DirectoryCrawler\AdapterInterface; use Einenlum\PhpStackDetector\Exception\ResourceNotFoundException; -use Einenlum\PhpStackDetector\Stack; +use Einenlum\PhpStackDetector\DTO\Stack; use Einenlum\PhpStackDetector\StackDetectorInterface; use Einenlum\PhpStackDetector\StackType; diff --git a/lib/StackDetectorInterface.php b/lib/StackDetectorInterface.php index bfd7cd0..106c9b8 100644 --- a/lib/StackDetectorInterface.php +++ b/lib/StackDetectorInterface.php @@ -4,6 +4,8 @@ namespace Einenlum\PhpStackDetector; +use Einenlum\PhpStackDetector\DTO\Stack; + interface StackDetectorInterface { public function getStack(string $baseUri, ?string $subDirectory): ?Stack; From a725c390c306521b5d8d5121990a16b4714630a1 Mon Sep 17 00:00:00 2001 From: Einenlum Date: Thu, 4 Sep 2025 17:05:25 +0200 Subject: [PATCH 08/13] move things to DTO namespace --- lib/{ => DTO}/DependencyTree.php | 2 +- lib/{ => DTO}/FullConfiguration.php | 4 +--- lib/{ => DTO}/NodeConfiguration.php | 4 +++- lib/{ => DTO}/PhpConfiguration.php | 2 +- lib/{ => DTO}/PhpVersion.php | 2 +- lib/Detector.php | 3 +++ lib/NodeConfigurationDetector.php | 1 + lib/PhpConfigurationDetector.php | 2 ++ lib/StackDetector/LaravelDetector.php | 2 +- 9 files changed, 14 insertions(+), 8 deletions(-) rename lib/{ => DTO}/DependencyTree.php (95%) rename lib/{ => DTO}/FullConfiguration.php (76%) rename lib/{ => DTO}/NodeConfiguration.php (71%) rename lib/{ => DTO}/PhpConfiguration.php (86%) rename lib/{ => DTO}/PhpVersion.php (81%) diff --git a/lib/DependencyTree.php b/lib/DTO/DependencyTree.php similarity index 95% rename from lib/DependencyTree.php rename to lib/DTO/DependencyTree.php index aa5e5b6..ee716f3 100644 --- a/lib/DependencyTree.php +++ b/lib/DTO/DependencyTree.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Einenlum\PhpStackDetector; +namespace Einenlum\PhpStackDetector\DTO; use Einenlum\PhpStackDetector\StackDetector\LunarDetector; use Einenlum\PhpStackDetector\StackDetector\OctoberCMSDetector; diff --git a/lib/FullConfiguration.php b/lib/DTO/FullConfiguration.php similarity index 76% rename from lib/FullConfiguration.php rename to lib/DTO/FullConfiguration.php index a21d353..9a45c79 100644 --- a/lib/FullConfiguration.php +++ b/lib/DTO/FullConfiguration.php @@ -2,9 +2,7 @@ declare(strict_types=1); -namespace Einenlum\PhpStackDetector; - -use Einenlum\PhpStackDetector\DTO\Stack; +namespace Einenlum\PhpStackDetector\DTO; readonly class FullConfiguration { diff --git a/lib/NodeConfiguration.php b/lib/DTO/NodeConfiguration.php similarity index 71% rename from lib/NodeConfiguration.php rename to lib/DTO/NodeConfiguration.php index 4e05080..796fe0c 100644 --- a/lib/NodeConfiguration.php +++ b/lib/DTO/NodeConfiguration.php @@ -2,7 +2,9 @@ declare(strict_types=1); -namespace Einenlum\PhpStackDetector; +namespace Einenlum\PhpStackDetector\DTO; + +use Einenlum\PhpStackDetector\NodePackageManagerType; readonly class NodeConfiguration { diff --git a/lib/PhpConfiguration.php b/lib/DTO/PhpConfiguration.php similarity index 86% rename from lib/PhpConfiguration.php rename to lib/DTO/PhpConfiguration.php index aafea94..640971f 100644 --- a/lib/PhpConfiguration.php +++ b/lib/DTO/PhpConfiguration.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Einenlum\PhpStackDetector; +namespace Einenlum\PhpStackDetector\DTO; readonly class PhpConfiguration { diff --git a/lib/PhpVersion.php b/lib/DTO/PhpVersion.php similarity index 81% rename from lib/PhpVersion.php rename to lib/DTO/PhpVersion.php index a8e0ded..6a1f4f9 100644 --- a/lib/PhpVersion.php +++ b/lib/DTO/PhpVersion.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Einenlum\PhpStackDetector; +namespace Einenlum\PhpStackDetector\DTO; readonly class PhpVersion { diff --git a/lib/Detector.php b/lib/Detector.php index 63dcc88..7f13284 100644 --- a/lib/Detector.php +++ b/lib/Detector.php @@ -4,6 +4,9 @@ namespace Einenlum\PhpStackDetector; +use Einenlum\PhpStackDetector\DTO\FullConfiguration; +use Einenlum\PhpStackDetector\DTO\NodeConfiguration; +use Einenlum\PhpStackDetector\DTO\PhpConfiguration; use Einenlum\PhpStackDetector\DTO\Stack; readonly class Detector diff --git a/lib/NodeConfigurationDetector.php b/lib/NodeConfigurationDetector.php index 2f6eeac..a515909 100644 --- a/lib/NodeConfigurationDetector.php +++ b/lib/NodeConfigurationDetector.php @@ -4,6 +4,7 @@ namespace Einenlum\PhpStackDetector; +use Einenlum\PhpStackDetector\DTO\NodeConfiguration; use Einenlum\PhpStackDetector\DirectoryCrawler\AdapterInterface; use Einenlum\PhpStackDetector\Exception\ResourceNotFoundException; diff --git a/lib/PhpConfigurationDetector.php b/lib/PhpConfigurationDetector.php index e961cc0..507ee5c 100644 --- a/lib/PhpConfigurationDetector.php +++ b/lib/PhpConfigurationDetector.php @@ -7,6 +7,8 @@ use Einenlum\PhpStackDetector\Composer\ComposerConfig; use Einenlum\PhpStackDetector\Composer\ComposerConfigProvider; use Einenlum\PhpStackDetector\Composer\ComposerConfigType; +use Einenlum\PhpStackDetector\DTO\PhpConfiguration; +use Einenlum\PhpStackDetector\DTO\PhpVersion; class PhpConfigurationDetector { diff --git a/lib/StackDetector/LaravelDetector.php b/lib/StackDetector/LaravelDetector.php index 28c3e0a..d7a85be 100644 --- a/lib/StackDetector/LaravelDetector.php +++ b/lib/StackDetector/LaravelDetector.php @@ -4,7 +4,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; -use Einenlum\PhpStackDetector\DependencyTree; +use Einenlum\PhpStackDetector\DTO\DependencyTree; use Einenlum\PhpStackDetector\DTO\Stack; use Einenlum\PhpStackDetector\StackDetectorInterface; use Einenlum\PhpStackDetector\StackType; From f771348afb77e0658735521e75a120a2e3ebee00 Mon Sep 17 00:00:00 2001 From: Einenlum Date: Thu, 4 Sep 2025 17:07:10 +0200 Subject: [PATCH 09/13] move to Enum namespace --- README.md | 2 +- lib/DTO/NodeConfiguration.php | 2 +- lib/DTO/Stack.php | 2 +- lib/{ => Enum}/NodePackageManagerType.php | 2 +- lib/{ => Enum}/StackType.php | 2 +- lib/NodeConfigurationDetector.php | 1 + lib/StackDetector/BaseComposerTypeDetector.php | 2 +- lib/StackDetector/BoltCMSDetector.php | 2 +- lib/StackDetector/CakePhpDetector.php | 2 +- lib/StackDetector/CodeigniterDetector.php | 2 +- lib/StackDetector/CraftCMSDetector.php | 2 +- lib/StackDetector/DrupalDetector.php | 2 +- lib/StackDetector/GravCMSDetector.php | 2 +- lib/StackDetector/LaravelDetector.php | 2 +- lib/StackDetector/LeafDetector.php | 2 +- lib/StackDetector/LunarDetector.php | 2 +- lib/StackDetector/OctoberCMSDetector.php | 2 +- lib/StackDetector/ShopwareDetector.php | 2 +- lib/StackDetector/StatamicDetector.php | 2 +- lib/StackDetector/SymfonyDetector.php | 2 +- lib/StackDetector/TempestDetector.php | 2 +- lib/StackDetector/TwillDetector.php | 2 +- lib/StackDetector/Typo3Detector.php | 2 +- lib/StackDetector/WinterCMSDetector.php | 2 +- lib/StackDetector/WordpressDetector.php | 2 +- tests/Unit/DetectorTest.php | 4 ++-- 26 files changed, 27 insertions(+), 26 deletions(-) rename lib/{ => Enum}/NodePackageManagerType.php (82%) rename lib/{ => Enum}/StackType.php (93%) diff --git a/README.md b/README.md index dd0e2ed..6d33b33 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ require_once __DIR__ . '/vendor/autoload.php'; use Einenlum\PhpStackDetector\Detector; use Einenlum\PhpStackDetector\Factory\FilesystemDetectorFactory; use Einenlum\PhpStackDetector\Factory\GithubDetectorFactory; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; // Local usage diff --git a/lib/DTO/NodeConfiguration.php b/lib/DTO/NodeConfiguration.php index 796fe0c..321b38c 100644 --- a/lib/DTO/NodeConfiguration.php +++ b/lib/DTO/NodeConfiguration.php @@ -4,7 +4,7 @@ namespace Einenlum\PhpStackDetector\DTO; -use Einenlum\PhpStackDetector\NodePackageManagerType; +use Einenlum\PhpStackDetector\Enum\NodePackageManagerType; readonly class NodeConfiguration { diff --git a/lib/DTO/Stack.php b/lib/DTO/Stack.php index 65fa639..55109c4 100644 --- a/lib/DTO/Stack.php +++ b/lib/DTO/Stack.php @@ -4,7 +4,7 @@ namespace Einenlum\PhpStackDetector\DTO; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; readonly class Stack { diff --git a/lib/NodePackageManagerType.php b/lib/Enum/NodePackageManagerType.php similarity index 82% rename from lib/NodePackageManagerType.php rename to lib/Enum/NodePackageManagerType.php index 4b118dc..447b63a 100644 --- a/lib/NodePackageManagerType.php +++ b/lib/Enum/NodePackageManagerType.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Einenlum\PhpStackDetector; +namespace Einenlum\PhpStackDetector\Enum; enum NodePackageManagerType: string { diff --git a/lib/StackType.php b/lib/Enum/StackType.php similarity index 93% rename from lib/StackType.php rename to lib/Enum/StackType.php index a78a386..a5d8be0 100644 --- a/lib/StackType.php +++ b/lib/Enum/StackType.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Einenlum\PhpStackDetector; +namespace Einenlum\PhpStackDetector\Enum; enum StackType: string { diff --git a/lib/NodeConfigurationDetector.php b/lib/NodeConfigurationDetector.php index a515909..41db2dc 100644 --- a/lib/NodeConfigurationDetector.php +++ b/lib/NodeConfigurationDetector.php @@ -6,6 +6,7 @@ use Einenlum\PhpStackDetector\DTO\NodeConfiguration; use Einenlum\PhpStackDetector\DirectoryCrawler\AdapterInterface; +use Einenlum\PhpStackDetector\Enum\NodePackageManagerType; use Einenlum\PhpStackDetector\Exception\ResourceNotFoundException; class NodeConfigurationDetector diff --git a/lib/StackDetector/BaseComposerTypeDetector.php b/lib/StackDetector/BaseComposerTypeDetector.php index a3ef3ab..69457aa 100644 --- a/lib/StackDetector/BaseComposerTypeDetector.php +++ b/lib/StackDetector/BaseComposerTypeDetector.php @@ -6,7 +6,7 @@ use Einenlum\PhpStackDetector\Composer\PackageVersionProvider; use Einenlum\PhpStackDetector\DTO\Stack; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; abstract class BaseComposerTypeDetector { diff --git a/lib/StackDetector/BoltCMSDetector.php b/lib/StackDetector/BoltCMSDetector.php index f40488b..8806f4d 100644 --- a/lib/StackDetector/BoltCMSDetector.php +++ b/lib/StackDetector/BoltCMSDetector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class BoltCMSDetector extends BaseComposerTypeDetector implements StackDetectorInterface { diff --git a/lib/StackDetector/CakePhpDetector.php b/lib/StackDetector/CakePhpDetector.php index 32639eb..9a27406 100644 --- a/lib/StackDetector/CakePhpDetector.php +++ b/lib/StackDetector/CakePhpDetector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class CakePhpDetector extends BaseComposerTypeDetector implements StackDetectorInterface { diff --git a/lib/StackDetector/CodeigniterDetector.php b/lib/StackDetector/CodeigniterDetector.php index 439ab8a..5dab56e 100644 --- a/lib/StackDetector/CodeigniterDetector.php +++ b/lib/StackDetector/CodeigniterDetector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class CodeigniterDetector extends BaseComposerTypeDetector implements StackDetectorInterface { diff --git a/lib/StackDetector/CraftCMSDetector.php b/lib/StackDetector/CraftCMSDetector.php index f2e79c5..b6705d3 100644 --- a/lib/StackDetector/CraftCMSDetector.php +++ b/lib/StackDetector/CraftCMSDetector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class CraftCMSDetector extends BaseComposerTypeDetector implements StackDetectorInterface { diff --git a/lib/StackDetector/DrupalDetector.php b/lib/StackDetector/DrupalDetector.php index 8c0cfdc..813445d 100644 --- a/lib/StackDetector/DrupalDetector.php +++ b/lib/StackDetector/DrupalDetector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class DrupalDetector extends BaseComposerTypeDetector implements StackDetectorInterface { diff --git a/lib/StackDetector/GravCMSDetector.php b/lib/StackDetector/GravCMSDetector.php index 7afcde2..a7dc4ab 100644 --- a/lib/StackDetector/GravCMSDetector.php +++ b/lib/StackDetector/GravCMSDetector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class GravCMSDetector extends BaseComposerTypeDetector implements StackDetectorInterface { diff --git a/lib/StackDetector/LaravelDetector.php b/lib/StackDetector/LaravelDetector.php index d7a85be..a8b0501 100644 --- a/lib/StackDetector/LaravelDetector.php +++ b/lib/StackDetector/LaravelDetector.php @@ -7,7 +7,7 @@ use Einenlum\PhpStackDetector\DTO\DependencyTree; use Einenlum\PhpStackDetector\DTO\Stack; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class LaravelDetector extends BaseComposerTypeDetector implements StackDetectorInterface { diff --git a/lib/StackDetector/LeafDetector.php b/lib/StackDetector/LeafDetector.php index 04c5749..daee646 100644 --- a/lib/StackDetector/LeafDetector.php +++ b/lib/StackDetector/LeafDetector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class LeafDetector extends BaseComposerTypeDetector implements StackDetectorInterface { diff --git a/lib/StackDetector/LunarDetector.php b/lib/StackDetector/LunarDetector.php index 102fcc4..bbf42f6 100644 --- a/lib/StackDetector/LunarDetector.php +++ b/lib/StackDetector/LunarDetector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class LunarDetector extends BaseComposerTypeDetector implements StackDetectorInterface { diff --git a/lib/StackDetector/OctoberCMSDetector.php b/lib/StackDetector/OctoberCMSDetector.php index a4d34b2..92ee78b 100644 --- a/lib/StackDetector/OctoberCMSDetector.php +++ b/lib/StackDetector/OctoberCMSDetector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class OctoberCMSDetector extends BaseComposerTypeDetector implements StackDetectorInterface { diff --git a/lib/StackDetector/ShopwareDetector.php b/lib/StackDetector/ShopwareDetector.php index 1284bcd..e1fcef4 100644 --- a/lib/StackDetector/ShopwareDetector.php +++ b/lib/StackDetector/ShopwareDetector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class ShopwareDetector extends BaseComposerTypeDetector implements StackDetectorInterface { diff --git a/lib/StackDetector/StatamicDetector.php b/lib/StackDetector/StatamicDetector.php index 172ce42..fc055dd 100644 --- a/lib/StackDetector/StatamicDetector.php +++ b/lib/StackDetector/StatamicDetector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class StatamicDetector extends BaseComposerTypeDetector implements StackDetectorInterface { diff --git a/lib/StackDetector/SymfonyDetector.php b/lib/StackDetector/SymfonyDetector.php index 510b690..8c005bf 100644 --- a/lib/StackDetector/SymfonyDetector.php +++ b/lib/StackDetector/SymfonyDetector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class SymfonyDetector extends BaseComposerTypeDetector implements StackDetectorInterface { diff --git a/lib/StackDetector/TempestDetector.php b/lib/StackDetector/TempestDetector.php index 622caee..9cab639 100644 --- a/lib/StackDetector/TempestDetector.php +++ b/lib/StackDetector/TempestDetector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class TempestDetector extends BaseComposerTypeDetector implements StackDetectorInterface { diff --git a/lib/StackDetector/TwillDetector.php b/lib/StackDetector/TwillDetector.php index a6b1f8f..be53824 100644 --- a/lib/StackDetector/TwillDetector.php +++ b/lib/StackDetector/TwillDetector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class TwillDetector extends BaseComposerTypeDetector implements StackDetectorInterface { diff --git a/lib/StackDetector/Typo3Detector.php b/lib/StackDetector/Typo3Detector.php index 086e90f..da412e5 100644 --- a/lib/StackDetector/Typo3Detector.php +++ b/lib/StackDetector/Typo3Detector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class Typo3Detector extends BaseComposerTypeDetector implements StackDetectorInterface { diff --git a/lib/StackDetector/WinterCMSDetector.php b/lib/StackDetector/WinterCMSDetector.php index f297b09..209593f 100644 --- a/lib/StackDetector/WinterCMSDetector.php +++ b/lib/StackDetector/WinterCMSDetector.php @@ -5,7 +5,7 @@ namespace Einenlum\PhpStackDetector\StackDetector; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class WinterCMSDetector extends BaseComposerTypeDetector implements StackDetectorInterface { diff --git a/lib/StackDetector/WordpressDetector.php b/lib/StackDetector/WordpressDetector.php index e570548..fe207d8 100644 --- a/lib/StackDetector/WordpressDetector.php +++ b/lib/StackDetector/WordpressDetector.php @@ -6,7 +6,7 @@ use Einenlum\PhpStackDetector\Exception\ResourceNotFoundException; use Einenlum\PhpStackDetector\DTO\Stack; use Einenlum\PhpStackDetector\StackDetectorInterface; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\StackType; class WordpressDetector implements StackDetectorInterface { diff --git a/tests/Unit/DetectorTest.php b/tests/Unit/DetectorTest.php index 543acc8..ba3a5a0 100644 --- a/tests/Unit/DetectorTest.php +++ b/tests/Unit/DetectorTest.php @@ -6,8 +6,8 @@ use Einenlum\PhpStackDetector\Detector; use Einenlum\PhpStackDetector\Factory\FilesystemDetectorFactory; -use Einenlum\PhpStackDetector\NodePackageManagerType; -use Einenlum\PhpStackDetector\StackType; +use Einenlum\PhpStackDetector\Enum\NodePackageManagerType; +use Einenlum\PhpStackDetector\Enum\StackType; use PHPUnit\Framework\TestCase; class DetectorTest extends TestCase From 1102ff4104a76524671d8ecef25048660f63aa2e Mon Sep 17 00:00:00 2001 From: Einenlum Date: Thu, 4 Sep 2025 17:11:07 +0200 Subject: [PATCH 10/13] update readme and bin scripts to display node config --- README.md | 12 ++++++++++++ bin/detect-github.php | 7 +++++++ bin/detect-local.php | 7 +++++++ 3 files changed, 26 insertions(+) diff --git a/README.md b/README.md index 6d33b33..0a6b215 100644 --- a/README.md +++ b/README.md @@ -107,12 +107,20 @@ Required extensions: ctype, iconv, redis, sodium Detected stack: laravel Version: 10.19.0 +Detected Node.js version: 22.0 +Detected Node.js requirements: Unknown version +Package Manager: bun + php bin/detect-github.php 'symfony/demo' Detected PHP version: 8.4 Detected PHP requirements: ^8.3 Required extensions: ctype, iconv Detected stack: symfony Version: 6.3.0 + +Detected Node.js version: Unknown version +Detected Node.js requirements: Unknown version +Package Manager: npm ``` It is advised to use an access token for github parsing, to either access private repositories or avoid reaching Github API limit. @@ -121,6 +129,10 @@ It is advised to use an access token for github parsing, to either access privat GITHUB_ACCESS_TOKEN=my_token php bin/detect-github.php 'einenlum/private-repo' Detected stack: laravel Version: 10.19.0 + +Detected Node.js version: Unknown version +Detected Node.js requirements: Unknown version +Package Manager: npm ``` ### Usage with Symfony diff --git a/bin/detect-github.php b/bin/detect-github.php index 2eb25d4..12d4032 100644 --- a/bin/detect-github.php +++ b/bin/detect-github.php @@ -40,3 +40,10 @@ echo 'Detected stack: '.$stack->type->value."\n"; echo 'Version: '.($stack->version ?: 'Unknown version')."\n"; + +$nodeConfig = $config->nodeConfiguration; + +echo "\n"; +echo 'Detected Node.js version: '.($nodeConfig?->version ?: 'Unknown version')."\n"; +echo 'Detected Node.js requirements: '.($nodeConfig?->requirements ?: 'Unknown version')."\n"; +echo 'Package Manager: '.($nodeConfig?->packageManager?->value ?: 'Unknown')."\n"; diff --git a/bin/detect-local.php b/bin/detect-local.php index 26ac107..7d3f108 100644 --- a/bin/detect-local.php +++ b/bin/detect-local.php @@ -31,3 +31,10 @@ echo 'Detected stack: '.$stack->type->value."\n"; echo 'Version: '.($stack->version ?: 'Unknown version')."\n"; + +$nodeConfig = $config->nodeConfiguration; + +echo "\n"; +echo 'Detected Node.js version: '.($nodeConfig?->version ?: 'Unknown version')."\n"; +echo 'Detected Node.js requirements: '.($nodeConfig?->requirements ?: 'Unknown version')."\n"; +echo 'Package Manager: '.($nodeConfig?->packageManager?->value ?: 'Unknown')."\n"; From b1a0ed5146a605705e5ac19af68e600ffdc743a4 Mon Sep 17 00:00:00 2001 From: Einenlum Date: Thu, 4 Sep 2025 17:14:28 +0200 Subject: [PATCH 11/13] move composer files to DTO and Enum namespaces --- lib/Composer/ComposerConfigProvider.php | 2 ++ lib/Composer/PackageVersionProvider.php | 3 +++ lib/{ => DTO}/Composer/ComposerConfig.php | 4 +++- lib/{ => DTO}/Composer/PackageVersion.php | 2 +- lib/{Composer => DTO/Enum}/ComposerConfigType.php | 2 +- lib/PhpConfigurationDetector.php | 4 ++-- tests/Unit/Composer/ComposerConfigProviderFilesystemTest.php | 4 ++-- 7 files changed, 14 insertions(+), 7 deletions(-) rename lib/{ => DTO}/Composer/ComposerConfig.php (66%) rename lib/{ => DTO}/Composer/PackageVersion.php (93%) rename lib/{Composer => DTO/Enum}/ComposerConfigType.php (71%) diff --git a/lib/Composer/ComposerConfigProvider.php b/lib/Composer/ComposerConfigProvider.php index 1c4a22d..a083b0c 100644 --- a/lib/Composer/ComposerConfigProvider.php +++ b/lib/Composer/ComposerConfigProvider.php @@ -4,6 +4,8 @@ namespace Einenlum\PhpStackDetector\Composer; +use Einenlum\PhpStackDetector\DTO\Composer\ComposerConfig; +use Einenlum\PhpStackDetector\DTO\Enum\ComposerConfigType; use Einenlum\PhpStackDetector\DirectoryCrawler\AdapterInterface; use Einenlum\PhpStackDetector\Exception\CacheMissException; use Einenlum\PhpStackDetector\Exception\ResourceNotFoundException; diff --git a/lib/Composer/PackageVersionProvider.php b/lib/Composer/PackageVersionProvider.php index b886897..75335b8 100644 --- a/lib/Composer/PackageVersionProvider.php +++ b/lib/Composer/PackageVersionProvider.php @@ -4,6 +4,9 @@ namespace Einenlum\PhpStackDetector\Composer; +use Einenlum\PhpStackDetector\DTO\Composer\PackageVersion; +use Einenlum\PhpStackDetector\DTO\Enum\ComposerConfigType; + readonly class PackageVersionProvider { public function __construct(private ComposerConfigProvider $configProvider) diff --git a/lib/Composer/ComposerConfig.php b/lib/DTO/Composer/ComposerConfig.php similarity index 66% rename from lib/Composer/ComposerConfig.php rename to lib/DTO/Composer/ComposerConfig.php index 6988106..761a2cc 100644 --- a/lib/Composer/ComposerConfig.php +++ b/lib/DTO/Composer/ComposerConfig.php @@ -2,7 +2,9 @@ declare(strict_types=1); -namespace Einenlum\PhpStackDetector\Composer; +namespace Einenlum\PhpStackDetector\DTO\Composer; + +use Einenlum\PhpStackDetector\DTO\Enum\ComposerConfigType; readonly class ComposerConfig { diff --git a/lib/Composer/PackageVersion.php b/lib/DTO/Composer/PackageVersion.php similarity index 93% rename from lib/Composer/PackageVersion.php rename to lib/DTO/Composer/PackageVersion.php index 1b57792..d2c07bc 100644 --- a/lib/Composer/PackageVersion.php +++ b/lib/DTO/Composer/PackageVersion.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Einenlum\PhpStackDetector\Composer; +namespace Einenlum\PhpStackDetector\DTO\Composer; use Einenlum\ComposerVersionParser\Parser; diff --git a/lib/Composer/ComposerConfigType.php b/lib/DTO/Enum/ComposerConfigType.php similarity index 71% rename from lib/Composer/ComposerConfigType.php rename to lib/DTO/Enum/ComposerConfigType.php index 79d3b2a..1b48f0c 100644 --- a/lib/Composer/ComposerConfigType.php +++ b/lib/DTO/Enum/ComposerConfigType.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Einenlum\PhpStackDetector\Composer; +namespace Einenlum\PhpStackDetector\DTO\Enum; enum ComposerConfigType: string { diff --git a/lib/PhpConfigurationDetector.php b/lib/PhpConfigurationDetector.php index 507ee5c..7dceeaf 100644 --- a/lib/PhpConfigurationDetector.php +++ b/lib/PhpConfigurationDetector.php @@ -4,9 +4,9 @@ namespace Einenlum\PhpStackDetector; -use Einenlum\PhpStackDetector\Composer\ComposerConfig; +use Einenlum\PhpStackDetector\DTO\Composer\ComposerConfig; use Einenlum\PhpStackDetector\Composer\ComposerConfigProvider; -use Einenlum\PhpStackDetector\Composer\ComposerConfigType; +use Einenlum\PhpStackDetector\DTO\Enum\ComposerConfigType; use Einenlum\PhpStackDetector\DTO\PhpConfiguration; use Einenlum\PhpStackDetector\DTO\PhpVersion; diff --git a/tests/Unit/Composer/ComposerConfigProviderFilesystemTest.php b/tests/Unit/Composer/ComposerConfigProviderFilesystemTest.php index 38b16b7..432306f 100644 --- a/tests/Unit/Composer/ComposerConfigProviderFilesystemTest.php +++ b/tests/Unit/Composer/ComposerConfigProviderFilesystemTest.php @@ -4,9 +4,9 @@ namespace Einenlum\Tests\PhpStackDetector\Unit\Composer; -use Einenlum\PhpStackDetector\Composer\ComposerConfig; +use Einenlum\PhpStackDetector\DTO\Composer\ComposerConfig; use Einenlum\PhpStackDetector\Composer\ComposerConfigProvider; -use Einenlum\PhpStackDetector\Composer\ComposerConfigType; +use Einenlum\PhpStackDetector\DTO\Enum\ComposerConfigType; use Einenlum\PhpStackDetector\DirectoryCrawler\FilesystemAdapter; use PHPUnit\Framework\TestCase; From 16f0c146b826f87c42ec6d41f0f34b126867f203 Mon Sep 17 00:00:00 2001 From: Einenlum Date: Thu, 4 Sep 2025 17:28:22 +0200 Subject: [PATCH 12/13] add a PackageJsonProvider to avoid multiple requests --- lib/Composer/ComposerConfigProvider.php | 4 - lib/Factory/FilesystemDetectorFactory.php | 8 +- lib/Factory/GithubDetectorFactory.php | 8 +- lib/Node/PackageJsonProvider.php | 103 ++++++++++++++++++++++ lib/NodeConfigurationDetector.php | 26 +++--- 5 files changed, 130 insertions(+), 19 deletions(-) create mode 100644 lib/Node/PackageJsonProvider.php diff --git a/lib/Composer/ComposerConfigProvider.php b/lib/Composer/ComposerConfigProvider.php index a083b0c..2b0c453 100644 --- a/lib/Composer/ComposerConfigProvider.php +++ b/lib/Composer/ComposerConfigProvider.php @@ -24,10 +24,6 @@ public function __construct( ) { } - /** - * This returns the content of the composer lock file if it exists, - * otherwise the composer json file if it exists, otherwise null. - */ public function getComposerConfig( ComposerConfigType $type, string $baseUri, diff --git a/lib/Factory/FilesystemDetectorFactory.php b/lib/Factory/FilesystemDetectorFactory.php index 32e52e5..d2162b6 100644 --- a/lib/Factory/FilesystemDetectorFactory.php +++ b/lib/Factory/FilesystemDetectorFactory.php @@ -7,6 +7,7 @@ use Einenlum\PhpStackDetector\Composer\ComposerConfigProvider; use Einenlum\PhpStackDetector\Detector; use Einenlum\PhpStackDetector\DirectoryCrawler\FilesystemAdapter; +use Einenlum\PhpStackDetector\Node\PackageJsonProvider; use Einenlum\PhpStackDetector\NodeConfigurationDetector; use Einenlum\PhpStackDetector\PhpConfigurationDetector; @@ -20,7 +21,12 @@ public function create(): Detector $composerConfigProvider = new ComposerConfigProvider($adapter); $phpConfigurationDetector = new PhpConfigurationDetector($composerConfigProvider); - $nodeConfigurationDetector = new NodeConfigurationDetector($adapter); + + $packageJsonProvider = new PackageJsonProvider($adapter); + $nodeConfigurationDetector = new NodeConfigurationDetector( + $packageJsonProvider, + $adapter + ); $stackDetectors = $this->getStackDetectors($composerConfigProvider, $adapter); return new Detector( diff --git a/lib/Factory/GithubDetectorFactory.php b/lib/Factory/GithubDetectorFactory.php index eca7473..03671b3 100644 --- a/lib/Factory/GithubDetectorFactory.php +++ b/lib/Factory/GithubDetectorFactory.php @@ -7,6 +7,7 @@ use Einenlum\PhpStackDetector\Composer\ComposerConfigProvider; use Einenlum\PhpStackDetector\Detector; use Einenlum\PhpStackDetector\DirectoryCrawler\GithubAdapter; +use Einenlum\PhpStackDetector\Node\PackageJsonProvider; use Einenlum\PhpStackDetector\NodeConfigurationDetector; use Einenlum\PhpStackDetector\PhpConfigurationDetector; use Github\Client; @@ -21,7 +22,12 @@ public function create(?Client $client = null): Detector $adapter = new GithubAdapter($client); $composerConfigProvider = new ComposerConfigProvider($adapter); $phpConfigurationDetector = new PhpConfigurationDetector($composerConfigProvider); - $nodeConfigurationDetector = new NodeConfigurationDetector($adapter); + + $packageJsonProvider = new PackageJsonProvider($adapter); + $nodeConfigurationDetector = new NodeConfigurationDetector( + $packageJsonProvider, + $adapter + ); $stackDetectors = $this->getStackDetectors($composerConfigProvider, $adapter); diff --git a/lib/Node/PackageJsonProvider.php b/lib/Node/PackageJsonProvider.php new file mode 100644 index 0000000..cac7cdb --- /dev/null +++ b/lib/Node/PackageJsonProvider.php @@ -0,0 +1,103 @@ + */ + private array $cache = []; + + public function __construct( + private readonly AdapterInterface $adapter, + ) { + } + + /** @return array|null */ + public function getPackageJsonConfig( + string $baseUri, + ?string $subDirectory, + ): ?array { + try { + return $this->getFromCache($baseUri, $subDirectory); + } catch (CacheMissException) { + } + + $content = $this->getFileContent( + $baseUri, + $subDirectory, + ); + + $this->setToCache($baseUri, $subDirectory, $content); + + return $content; + } + + /** @return array|null */ + private function getFileContent( + string $baseUri, + ?string $subDirectory, + ): ?array { + if (!$this->adapter->directoryExists($baseUri, $subDirectory)) { + return null; + } + + try { + $fileContent = $this->adapter->getFileContent( + $baseUri, + $subDirectory, + 'package.json' + ); + } catch (ResourceNotFoundException $e) { + return null; + } + + $decoded = json_decode($fileContent, true); + if (null === $decoded) { + return null; + } + + return $decoded; + } + + /** @param array|null $config */ + private function setToCache( + string $baseUri, + ?string $subDirectory, + ?array $config, + ): void { + $cacheKey = $this->getCacheKey($baseUri, $subDirectory); + + $this->cache[$cacheKey] = $config; + } + + /** + * @return array|null + * + * @throws CacheMissException + */ + private function getFromCache( + string $baseUri, + ?string $subDirectory, + ): ?array { + $cacheKey = $this->getCacheKey($baseUri, $subDirectory); + + if (!array_key_exists($cacheKey, $this->cache)) { + throw new CacheMissException(); + } + + return $this->cache[$cacheKey]; + } + + private function getCacheKey( + string $baseUri, + ?string $subDirectory, + ): string { + return $baseUri.$subDirectory; + } +} diff --git a/lib/NodeConfigurationDetector.php b/lib/NodeConfigurationDetector.php index 41db2dc..7e7b358 100644 --- a/lib/NodeConfigurationDetector.php +++ b/lib/NodeConfigurationDetector.php @@ -8,24 +8,25 @@ use Einenlum\PhpStackDetector\DirectoryCrawler\AdapterInterface; use Einenlum\PhpStackDetector\Enum\NodePackageManagerType; use Einenlum\PhpStackDetector\Exception\ResourceNotFoundException; +use Einenlum\PhpStackDetector\Node\PackageJsonProvider; class NodeConfigurationDetector { - public function __construct(private AdapterInterface $adapter) - { + public function __construct( + private PackageJsonProvider $packageJsonProvider, + private AdapterInterface $adapter, + ) { } public function getNodeConfiguration( string $baseUri, ?string $subFolder = null, ): ?NodeConfiguration { - $packageJsonExists = $this->adapter->fileExists( + $packageJsonConfig = $this->packageJsonProvider->getPackageJsonConfig( $baseUri, $subFolder, - 'package.json' ); - - if (!$packageJsonExists) { + if (null === $packageJsonConfig) { return null; } @@ -65,19 +66,16 @@ private function getNodeVersion(string $baseUri, ?string $subFolder = null): ?st private function getVersionRequirements(string $baseUri, ?string $subFolder = null): ?string { - $packageJsonContent = $this->getFileContent( + $packageJsonContent = $this->packageJsonProvider->getPackageJsonConfig( $baseUri, $subFolder, - 'package.json' ); if (null === $packageJsonContent) { return null; } - $packageData = json_decode($packageJsonContent, true, 512, \JSON_THROW_ON_ERROR); - - return $packageData['engines']['node'] ?? null; + return $packageJsonContent['engines']['node'] ?? null; } private function extractNodeVersion(?string $content): ?string @@ -153,8 +151,10 @@ private function getPackageManagerType( return NodePackageManagerType::NPM; // Default to NPM if no lock file or packageManager field is found } - private function detectYarn(string $baseUri, ?string $subFolder = null): ?NodePackageManagerType - { + private function detectYarn( + string $baseUri, + ?string $subFolder = null, + ): ?NodePackageManagerType { if (!$this->adapter->fileExists($baseUri, $subFolder, 'yarn.lock')) { return null; } From d0c5989b22c2416024add535ab5894c88466be14 Mon Sep 17 00:00:00 2001 From: Einenlum Date: Thu, 4 Sep 2025 17:33:59 +0200 Subject: [PATCH 13/13] update readme --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 0a6b215..c88fb7a 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,16 @@ Supported Stacks for now: - Winter CMS - Wordpress +It also detects if the repository uses nodeJS. If so, it detects node version (through .nvmrc or .node-version), node version requirements, and package manager. + +Detected package managers: + +- npm +- pnpm +- bun +- yarn +- yarn berry + ## Install ```