<?php namespace Gitonomy\Git; use Gitonomy\Git\Exception\InvalidArgumentException; use Gitonomy\Git\Exception\UnexpectedValueException; class Tree { protected $repository; protected $hash; protected $isInitialized = false; protected $entries; protected $entriesByType; public function __construct(Repository $repository, $hash) { $this->repository = $repository; $this->hash = $hash; } public function getHash() { return $this->hash; } protected function initialize() { if (true === $this->isInitialized) { return; } $output = $this->repository->run('cat-file', ['-p', $this->hash]); $parser = new Parser\TreeParser(); $parser->parse($output); $this->entries = []; $this->entriesByType = [ 'blob' => [], 'tree' => [], 'commit' => [], ]; foreach ($parser->entries as $entry) { list($mode, $type, $hash, $name) = $entry; if ($type == 'blob') { $treeEntry = [$mode, $this->repository->getBlob($hash)]; } elseif ($type == 'tree') { $treeEntry = [$mode, $this->repository->getTree($hash)]; } else { $treeEntry = [$mode, new CommitReference($hash)]; } $this->entries[$name] = $treeEntry; $this->entriesByType[$type][$name] = $treeEntry; } $this->isInitialized = true; } public function getEntries(): array { $this->initialize(); return $this->entries; } public function getCommitReferenceEntries(): array { $this->initialize(); return $this->entriesByType['commit']; } public function getTreeEntries(): array { $this->initialize(); return $this->entriesByType['tree']; } public function getBlobEntries(): array { $this->initialize(); return $this->entriesByType['blob']; } public function getEntry($name) { $this->initialize(); if (!isset($this->entries[$name])) { throw new InvalidArgumentException('No entry '.$name); } return $this->entries[$name][1]; } public function resolvePath($path) { if ($path == '') { return $this; } $path = preg_replace('#^/#', '', $path); $segments = explode('/', $path); $element = $this; foreach ($segments as $segment) { if ($element instanceof self) { $element = $element->getEntry($segment); } elseif ($element instanceof Blob) { throw new InvalidArgumentException('Unresolvable path'); } else { throw new UnexpectedValueException('Unknow type of element'); } } return $element; } }