244 lines
6.2 KiB
PHP
244 lines
6.2 KiB
PHP
|
<?php
|
||
|
|
||
|
declare(strict_types=1);
|
||
|
|
||
|
namespace Doctrine\RST;
|
||
|
|
||
|
use Doctrine\RST\Builder\Copier;
|
||
|
use Doctrine\RST\Builder\Documents;
|
||
|
use Doctrine\RST\Builder\ParseQueue;
|
||
|
use Doctrine\RST\Builder\ParseQueueProcessor;
|
||
|
use Doctrine\RST\Builder\Scanner;
|
||
|
use Doctrine\RST\Event\PostBuildRenderEvent;
|
||
|
use Doctrine\RST\Event\PreBuildParseEvent;
|
||
|
use Doctrine\RST\Event\PreBuildRenderEvent;
|
||
|
use Doctrine\RST\Event\PreBuildScanEvent;
|
||
|
use Doctrine\RST\Meta\CachedMetasLoader;
|
||
|
use Doctrine\RST\Meta\Metas;
|
||
|
use InvalidArgumentException;
|
||
|
use Symfony\Component\Filesystem\Filesystem;
|
||
|
use Symfony\Component\Finder\Finder;
|
||
|
|
||
|
use function file_exists;
|
||
|
use function is_dir;
|
||
|
use function sprintf;
|
||
|
|
||
|
final class Builder
|
||
|
{
|
||
|
/** @var Kernel */
|
||
|
private $kernel;
|
||
|
|
||
|
/** @var Configuration */
|
||
|
private $configuration;
|
||
|
|
||
|
/** @var ErrorManager */
|
||
|
private $errorManager;
|
||
|
|
||
|
/** @var Filesystem */
|
||
|
private $filesystem;
|
||
|
|
||
|
/** @var Metas */
|
||
|
private $metas;
|
||
|
|
||
|
/** @var CachedMetasLoader */
|
||
|
private $cachedMetasLoader;
|
||
|
|
||
|
/** @var Documents */
|
||
|
private $documents;
|
||
|
|
||
|
/** @var Copier */
|
||
|
private $copier;
|
||
|
|
||
|
/** @var Finder|null */
|
||
|
private $scannerFinder;
|
||
|
|
||
|
/** @var string */
|
||
|
private $indexName = 'index';
|
||
|
|
||
|
public function __construct(?Kernel $kernel = null)
|
||
|
{
|
||
|
$this->kernel = $kernel ?? new Kernel();
|
||
|
|
||
|
$this->configuration = $this->kernel->getConfiguration();
|
||
|
|
||
|
$this->errorManager = new ErrorManager($this->configuration);
|
||
|
|
||
|
$this->filesystem = new Filesystem();
|
||
|
|
||
|
$this->metas = new Metas();
|
||
|
|
||
|
$this->cachedMetasLoader = new CachedMetasLoader();
|
||
|
|
||
|
$this->documents = new Builder\Documents(
|
||
|
$this->filesystem,
|
||
|
$this->metas
|
||
|
);
|
||
|
|
||
|
$this->copier = new Builder\Copier($this->filesystem);
|
||
|
|
||
|
$this->kernel->initBuilder($this);
|
||
|
}
|
||
|
|
||
|
public function recreate(): Builder
|
||
|
{
|
||
|
return new Builder($this->kernel);
|
||
|
}
|
||
|
|
||
|
public function getKernel(): Kernel
|
||
|
{
|
||
|
return $this->kernel;
|
||
|
}
|
||
|
|
||
|
public function getConfiguration(): Configuration
|
||
|
{
|
||
|
return $this->configuration;
|
||
|
}
|
||
|
|
||
|
public function getDocuments(): Documents
|
||
|
{
|
||
|
return $this->documents;
|
||
|
}
|
||
|
|
||
|
public function getErrorManager(): ErrorManager
|
||
|
{
|
||
|
return $this->errorManager;
|
||
|
}
|
||
|
|
||
|
public function setIndexName(string $name): self
|
||
|
{
|
||
|
$this->indexName = $name;
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the "master document" name (e.g. index).
|
||
|
*
|
||
|
* This is the first document whose toctree should be read
|
||
|
* when building the table of contents. It is usually "index",
|
||
|
* which means index.rst is read first.
|
||
|
*/
|
||
|
public function getIndexName(): string
|
||
|
{
|
||
|
return $this->indexName;
|
||
|
}
|
||
|
|
||
|
public function getMetas(): Metas
|
||
|
{
|
||
|
return $this->metas;
|
||
|
}
|
||
|
|
||
|
public function build(
|
||
|
string $directory,
|
||
|
string $targetDirectory = 'output'
|
||
|
): void {
|
||
|
// Creating output directory if doesn't exists
|
||
|
if (! is_dir($targetDirectory)) {
|
||
|
$this->filesystem->mkdir($targetDirectory, 0755);
|
||
|
}
|
||
|
|
||
|
$indexFilename = sprintf('%s.%s', $this->indexName, $this->configuration->getSourceFileExtension());
|
||
|
if (! file_exists($directory . '/' . $indexFilename)) {
|
||
|
throw new InvalidArgumentException(sprintf('Could not find index file "%s" in "%s"', $indexFilename, $directory));
|
||
|
}
|
||
|
|
||
|
if ($this->configuration->getUseCachedMetas()) {
|
||
|
$this->cachedMetasLoader->loadCachedMetaEntries($targetDirectory, $this->metas);
|
||
|
}
|
||
|
|
||
|
$parseQueue = $this->scan($directory, $targetDirectory);
|
||
|
|
||
|
$this->parse($directory, $targetDirectory, $parseQueue);
|
||
|
|
||
|
$this->render($directory, $targetDirectory);
|
||
|
|
||
|
$this->cachedMetasLoader->cacheMetaEntries($targetDirectory, $this->metas);
|
||
|
}
|
||
|
|
||
|
public function copy(string $source, ?string $destination = null): self
|
||
|
{
|
||
|
$this->copier->copy($source, $destination);
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
public function mkdir(string $directory): self
|
||
|
{
|
||
|
$this->copier->mkdir($directory);
|
||
|
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set the Finder that will be used for scanning files.
|
||
|
*/
|
||
|
public function setScannerFinder(Finder $finder): void
|
||
|
{
|
||
|
$this->scannerFinder = $finder;
|
||
|
}
|
||
|
|
||
|
private function scan(string $directory, string $targetDirectory): ParseQueue
|
||
|
{
|
||
|
$this->configuration->dispatchEvent(
|
||
|
PreBuildScanEvent::PRE_BUILD_SCAN,
|
||
|
new PreBuildScanEvent($this, $directory, $targetDirectory)
|
||
|
);
|
||
|
|
||
|
$scanner = new Scanner(
|
||
|
$this->configuration->getSourceFileExtension(),
|
||
|
$directory,
|
||
|
$this->metas,
|
||
|
$this->getScannerFinder()
|
||
|
);
|
||
|
|
||
|
return $scanner->scan();
|
||
|
}
|
||
|
|
||
|
private function parse(string $directory, string $targetDirectory, ParseQueue $parseQueue): void
|
||
|
{
|
||
|
$this->configuration->dispatchEvent(
|
||
|
PreBuildParseEvent::PRE_BUILD_PARSE,
|
||
|
new PreBuildParseEvent($this, $directory, $targetDirectory, $parseQueue)
|
||
|
);
|
||
|
|
||
|
$parseQueueProcessor = new ParseQueueProcessor(
|
||
|
$this->kernel,
|
||
|
$this->errorManager,
|
||
|
$this->metas,
|
||
|
$this->documents,
|
||
|
$directory,
|
||
|
$targetDirectory,
|
||
|
$this->configuration->getFileExtension()
|
||
|
);
|
||
|
|
||
|
$parseQueueProcessor->process($parseQueue);
|
||
|
}
|
||
|
|
||
|
private function render(string $directory, string $targetDirectory): void
|
||
|
{
|
||
|
$this->configuration->dispatchEvent(
|
||
|
PreBuildRenderEvent::PRE_BUILD_RENDER,
|
||
|
new PreBuildRenderEvent($this, $directory, $targetDirectory)
|
||
|
);
|
||
|
|
||
|
$this->documents->render($targetDirectory);
|
||
|
|
||
|
$this->copier->doMkdir($targetDirectory);
|
||
|
$this->copier->doCopy($directory, $targetDirectory);
|
||
|
|
||
|
$this->configuration->dispatchEvent(
|
||
|
PostBuildRenderEvent::POST_BUILD_RENDER,
|
||
|
new PostBuildRenderEvent($this, $directory, $targetDirectory)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
private function getScannerFinder(): Finder
|
||
|
{
|
||
|
if ($this->scannerFinder === null) {
|
||
|
$this->scannerFinder = new Finder();
|
||
|
}
|
||
|
|
||
|
return $this->scannerFinder;
|
||
|
}
|
||
|
}
|