Some checks failed
Deploy Application / deploy (push) Has been cancelled
142 lines
3.7 KiB
PHP
142 lines
3.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\Composer\ValueObjects;
|
|
|
|
use App\Framework\Composer\Exception\ComposerLockException;
|
|
|
|
/**
|
|
* Immutable Value Object representing composer.lock data
|
|
*/
|
|
final readonly class ComposerLock
|
|
{
|
|
/**
|
|
* @param array<array<string, mixed>> $packages
|
|
* @param array<array<string, mixed>> $packagesDev
|
|
* @param array<string, mixed> $platform
|
|
* @param array<string, mixed> $platformDev
|
|
*/
|
|
public function __construct(
|
|
public array $packages = [],
|
|
public array $packagesDev = [],
|
|
public array $platform = [],
|
|
public array $platformDev = [],
|
|
public ?string $contentHash = null
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* Create ComposerLock from file path
|
|
*/
|
|
public static function fromFile(string $path): self
|
|
{
|
|
if (! file_exists($path)) {
|
|
throw ComposerLockException::fileNotFound($path);
|
|
}
|
|
|
|
$content = @file_get_contents($path);
|
|
if ($content === false) {
|
|
throw ComposerLockException::couldNotRead($path, new \RuntimeException('file_get_contents failed'));
|
|
}
|
|
|
|
$data = json_decode($content, true);
|
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
|
throw ComposerLockException::invalidJson($path, new \JsonException(json_last_error_msg()));
|
|
}
|
|
|
|
return self::fromArray($data);
|
|
}
|
|
|
|
/**
|
|
* Create ComposerLock from array data
|
|
*
|
|
* @param array<string, mixed> $data
|
|
*/
|
|
public static function fromArray(array $data): self
|
|
{
|
|
return new self(
|
|
packages: $data['packages'] ?? [],
|
|
packagesDev: $data['packages-dev'] ?? [],
|
|
platform: $data['platform'] ?? [],
|
|
platformDev: $data['platform-dev'] ?? [],
|
|
contentHash: $data['content-hash'] ?? null
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get all packages (production + dev) as flat array
|
|
*
|
|
* @return array<array<string, mixed>>
|
|
*/
|
|
public function getAllPackages(): array
|
|
{
|
|
return array_merge($this->packages, $this->packagesDev);
|
|
}
|
|
|
|
/**
|
|
* Get package by name
|
|
*
|
|
* @return array<string, mixed>|null
|
|
*/
|
|
public function getPackage(string $name): ?array
|
|
{
|
|
// Check production packages first
|
|
foreach ($this->packages as $package) {
|
|
if (isset($package['name']) && $package['name'] === $name) {
|
|
return $package;
|
|
}
|
|
}
|
|
|
|
// Check dev packages
|
|
foreach ($this->packagesDev as $package) {
|
|
if (isset($package['name']) && $package['name'] === $name) {
|
|
return $package;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Check if package exists
|
|
*/
|
|
public function hasPackage(string $name): bool
|
|
{
|
|
return $this->getPackage($name) !== null;
|
|
}
|
|
|
|
/**
|
|
* Get packages with their type (production or dev)
|
|
*
|
|
* @return array<array{name: string, version: string, type: 'production'|'dev'}>
|
|
*/
|
|
public function getPackagesWithType(): array
|
|
{
|
|
$result = [];
|
|
|
|
foreach ($this->packages as $package) {
|
|
if (isset($package['name']) && isset($package['version'])) {
|
|
$result[] = [
|
|
'name' => $package['name'],
|
|
'version' => $package['version'],
|
|
'type' => 'production',
|
|
];
|
|
}
|
|
}
|
|
|
|
foreach ($this->packagesDev as $package) {
|
|
if (isset($package['name']) && isset($package['version'])) {
|
|
$result[] = [
|
|
'name' => $package['name'],
|
|
'version' => $package['version'],
|
|
'type' => 'dev',
|
|
];
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
}
|
|
|