first commit.
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace Toolbox;
|
||||
|
||||
/**
|
||||
* Mapa de propiedad: cada ruta instalada pertenece al core o a un componente.
|
||||
*/
|
||||
final class Ownership
|
||||
{
|
||||
/** @var array<string, string> path => owner id ('core' o 'pkg:comp') */
|
||||
private array $owners = [];
|
||||
|
||||
/** @var array<string, list<string>> path => owners en conflicto */
|
||||
private array $collisions = [];
|
||||
|
||||
public static function fromLock(Lock $lock): self
|
||||
{
|
||||
$ownership = new self();
|
||||
|
||||
$core = $lock->core();
|
||||
foreach (($core['files'] ?? []) as $path => $hash) {
|
||||
$ownership->claim('core', $path);
|
||||
}
|
||||
|
||||
foreach ($lock->components() as $id => $entry) {
|
||||
foreach (($entry['files'] ?? []) as $path => $hash) {
|
||||
$ownership->claim($id, $path);
|
||||
}
|
||||
}
|
||||
|
||||
return $ownership;
|
||||
}
|
||||
|
||||
private function claim(string $owner, string $path): void
|
||||
{
|
||||
if (!isset($this->owners[$path])) {
|
||||
$this->owners[$path] = $owner;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->owners[$path] !== $owner) {
|
||||
$this->collisions[$path][] = $this->owners[$path];
|
||||
$this->collisions[$path][] = $owner;
|
||||
}
|
||||
}
|
||||
|
||||
public function ownerOf(string $path): ?string
|
||||
{
|
||||
return $this->owners[$path] ?? null;
|
||||
}
|
||||
|
||||
/** @return list<string> */
|
||||
public function pathsOf(string $owner): array
|
||||
{
|
||||
return array_keys(array_filter($this->owners, fn ($o) => $o === $owner));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, list<string>>
|
||||
*/
|
||||
public function collisions(): array
|
||||
{
|
||||
$result = [];
|
||||
foreach ($this->collisions as $path => $owners) {
|
||||
$result[$path] = array_values(array_unique($owners));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function assertNoCollisions(): void
|
||||
{
|
||||
$collisions = $this->collisions();
|
||||
if ($collisions === []) {
|
||||
return;
|
||||
}
|
||||
|
||||
$parts = [];
|
||||
foreach ($collisions as $path => $owners) {
|
||||
$parts[] = $path . ' (' . implode(', ', $owners) . ')';
|
||||
}
|
||||
|
||||
throw new ToolboxException('Colisión de propiedad: ' . implode('; ', $parts));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user