You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
3.5 KiB
110 lines
3.5 KiB
<?php |
|
|
|
namespace Spip\Autodoc; |
|
|
|
use Psr\Log\LoggerInterface; |
|
use Psr\Log\NullLogger; |
|
use Spip\Autodoc\Exception\AutodocException; |
|
use Symfony\Component\Filesystem\Filesystem; |
|
|
|
class AutodocFile { |
|
|
|
private array $items = []; |
|
private string $file; |
|
private string $old_file; |
|
|
|
public function __construct( |
|
private string $source, |
|
private string $cache_directory, |
|
private ?LoggerInterface $logger = null, |
|
private ?string $only_one_prefix = null, |
|
) { |
|
if ($logger === null) { |
|
$this->logger = new NullLogger(); |
|
} |
|
$this->file = $cache_directory . '/autodoc.txt'; |
|
$this->old_file = $cache_directory . '/autodoc.old.txt'; |
|
$this->analyse(); |
|
} |
|
|
|
/** @return array<string, Git> */ |
|
public function getItems(): array { |
|
if ($this->only_one_prefix) { |
|
return array_intersect_key($this->items, [$this->only_one_prefix => true]); |
|
} |
|
return $this->items; |
|
} |
|
|
|
private function analyse() { |
|
$this->rotate(); |
|
$this->items = $this->parse($this->file); |
|
} |
|
|
|
private function rotate() { |
|
if (!$this->source) { |
|
throw new AutodocException('No source for autodoc file'); |
|
} |
|
$content = file_get_contents($this->source); |
|
if (!$content) { |
|
throw new AutodocException('Can’t fetch autodoc file, or file is empty'); |
|
} |
|
$fs = new Filesystem(); |
|
if (!$fs->exists($this->cache_directory)) { |
|
$fs->mkdir($this->cache_directory); |
|
} |
|
$fs->remove($this->old_file); |
|
if ($fs->exists($this->file)) { |
|
$fs->copy($this->file, $this->old_file); |
|
} |
|
file_put_contents($this->file, $content); |
|
} |
|
|
|
private function parse(string $file, bool $write_errors = true): array |
|
{ |
|
if (!$lines = file($file)) { |
|
throw new AutodocException("Can’t read autodoc file"); |
|
} |
|
|
|
$list = []; |
|
foreach ($lines as $lineno => $line) { |
|
if (!$line) { |
|
continue; |
|
} |
|
$line = trim($line); |
|
if (!$line or $line[0] === '#') { |
|
continue; |
|
} |
|
$couples = explode(';', $line); |
|
$lineno++; |
|
if (count($couples) !== 2) { |
|
if (count($couples) === 1) { |
|
$this->logger->error(sprintf('Line %s ignored. No prefix on content "%s"', $lineno, $line)); |
|
} else { |
|
$this->logger->error(sprintf('Line %s ignored. Too much parts on content "%s"', $lineno, $line)); |
|
} |
|
continue; |
|
} |
|
|
|
list($url, $prefix) = $couples; |
|
if (!$url) { |
|
$this->logger->error(sprintf('Line %s ignored. URL unknown on content "%s"', $lineno, $line)); |
|
continue; |
|
} |
|
if (!$prefix) { |
|
$this->logger->error(sprintf('Line %s ignored. No prefix on content "%s"', $lineno, $line)); |
|
continue; |
|
} |
|
if (isset($list[$prefix])) { |
|
$this->logger->error(sprintf('Line %s ignored. Prefix "%s" already present on content "%s"', $lineno, $prefix, $line)); |
|
continue; |
|
} |
|
list($url, $branch) = array_pad(explode('@', $url), 2, null); |
|
$branch = $branch ?: 'master'; |
|
|
|
// pas d'erreur ! |
|
$list[$prefix] = (new Git($url))->setBranch($branch); |
|
} |
|
return $list; |
|
} |
|
|
|
} |