first commit.

This commit is contained in:
kj
2026-10-05 15:08:39 -03:00
commit b7799f9fff
93 changed files with 8966 additions and 0 deletions
+112
View File
@@ -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"
);
}
}