first commit.
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
<?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"
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user