113 lines
3.3 KiB
PHP
113 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace Toolbox;
|
|
|
|
/**
|
|
* `.duckbrain/lock.json`: estado resuelto (core + componentes con hashes).
|
|
*/
|
|
final class Lock
|
|
{
|
|
private const DIR = '.duckbrain';
|
|
private const FILE = 'lock.json';
|
|
|
|
/**
|
|
* @param array{version?:string, commit?:string, files?:array<string,string>}|null $core
|
|
* @param array<string, array{package:string, version:string, toolbox_commit:?string, mode:string, files:array<string,string>}> $components
|
|
*/
|
|
private function __construct(
|
|
private ?array $core,
|
|
private array $components,
|
|
) {
|
|
}
|
|
|
|
public static function path(string $root): string
|
|
{
|
|
return rtrim($root, '/') . '/' . self::DIR . '/' . self::FILE;
|
|
}
|
|
|
|
public static function empty(): self
|
|
{
|
|
return new self(null, []);
|
|
}
|
|
|
|
public static function load(string $root): self
|
|
{
|
|
$path = self::path($root);
|
|
if (!is_file($path)) {
|
|
return self::empty();
|
|
}
|
|
|
|
$data = json_decode((string) file_get_contents($path), true);
|
|
if (!is_array($data)) {
|
|
throw new ToolboxException("Lock inválido: {$path}");
|
|
}
|
|
|
|
$components = [];
|
|
foreach (($data['components'] ?? []) as $id => $entry) {
|
|
$components[$id] = [
|
|
'package' => (string) ($entry['package'] ?? ''),
|
|
'version' => (string) ($entry['version'] ?? ''),
|
|
'toolbox_commit' => $entry['toolbox_commit'] ?? null,
|
|
'mode' => (string) ($entry['mode'] ?? 'copy'),
|
|
'origin' => (string) ($entry['origin'] ?? 'toolbox'),
|
|
'files' => is_array($entry['files'] ?? null) ? $entry['files'] : [],
|
|
];
|
|
}
|
|
|
|
return new self($data['core'] ?? null, $components);
|
|
}
|
|
|
|
/** @return array{version?:string, commit?:string, files?:array<string,string>}|null */
|
|
public function core(): ?array
|
|
{
|
|
return $this->core;
|
|
}
|
|
|
|
/** @return array<string, array{package:string, version:string, toolbox_commit:?string, mode:string, files:array<string,string>}> */
|
|
public function components(): array
|
|
{
|
|
return $this->components;
|
|
}
|
|
|
|
public function has(string $id): bool
|
|
{
|
|
return isset($this->components[$id]);
|
|
}
|
|
|
|
public function component(string $id): ?array
|
|
{
|
|
return $this->components[$id] ?? null;
|
|
}
|
|
|
|
/** @param array{version?:string, commit?:string, files?:array<string,string>} $core */
|
|
public function setCore(array $core): void
|
|
{
|
|
$this->core = $core;
|
|
}
|
|
|
|
/** @param array{package:string, version:string, toolbox_commit:?string, mode:string, files:array<string,string>} $entry */
|
|
public function setComponent(string $id, array $entry): void
|
|
{
|
|
$this->components[$id] = $entry;
|
|
}
|
|
|
|
public function removeComponent(string $id): void
|
|
{
|
|
unset($this->components[$id]);
|
|
}
|
|
|
|
public function save(string $root): void
|
|
{
|
|
$dir = rtrim($root, '/') . '/' . self::DIR;
|
|
if (!is_dir($dir)) {
|
|
mkdir($dir, 0777, true);
|
|
}
|
|
|
|
$data = ['core' => $this->core, 'components' => $this->components];
|
|
file_put_contents(
|
|
self::path($root),
|
|
json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n"
|
|
);
|
|
}
|
|
}
|