Skip to content

Commit 1480a16

Browse files
committed
Introduce a DocBuilder and BuildResult
1 parent c7d27dc commit 1480a16

File tree

6 files changed

+166
-20
lines changed

6 files changed

+166
-20
lines changed

composer.lock

Lines changed: 10 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/BuildContext.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function __construct(
4141
$this->symfonyDocUrl = $symfonyDocUrl;
4242
}
4343

44-
public function initializeRuntimeConfig(string $sourceDir, string $outputDir, ?string $parseSubPath = null, bool $disableCache = false, string $theme = Configuration::THEME_DEFAULT)
44+
public function initializeRuntimeConfig(string $sourceDir, string $outputDir, string $publicImagesDir, string $publicImagesPrefix, ?string $parseSubPath = null, bool $disableCache = false, string $theme = Configuration::THEME_DEFAULT)
4545
{
4646
if (!file_exists($sourceDir)) {
4747
throw new \Exception(sprintf('Source directory "%s" does not exist', $sourceDir));
@@ -51,8 +51,14 @@ public function initializeRuntimeConfig(string $sourceDir, string $outputDir, ?s
5151
throw new \Exception(sprintf('Output directory "%s" does not exist', $outputDir));
5252
}
5353

54+
if (!file_exists($publicImagesDir)) {
55+
throw new \Exception(sprintf('Public images directory "%s" does not exist', $publicImagesDir));
56+
}
57+
5458
$this->sourceDir = realpath($sourceDir);
5559
$this->outputDir = realpath($outputDir);
60+
$this->publicImagesDir = realpath($publicImagesDir);
61+
$this->publicImagesPrefix = $publicImagesPrefix;
5662
$this->parseSubPath = $parseSubPath;
5763
$this->disableCache = $disableCache;
5864
$this->theme = $theme;
@@ -93,6 +99,20 @@ public function getOutputDir(): string
9399
return $this->outputDir;
94100
}
95101

102+
public function getPublicImagesDir(): string
103+
{
104+
$this->checkThatRuntimeConfigIsInitialized();
105+
106+
return $this->publicImagesDir;
107+
}
108+
109+
public function getPublicImagesPrefix(): string
110+
{
111+
$this->checkThatRuntimeConfigIsInitialized();
112+
113+
return $this->publicImagesPrefix;
114+
}
115+
96116
public function getParseSubPath(): ?string
97117
{
98118
$this->checkThatRuntimeConfigIsInitialized();

src/BuildResult.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace SymfonyDocsBuilder;
4+
5+
use Doctrine\RST\Builder;
6+
use Symfony\Component\Console\Output\NullOutput;
7+
use Symfony\Component\Filesystem\Filesystem;
8+
use SymfonyDocsBuilder\BuildContext;
9+
use SymfonyDocsBuilder\CI\MissingFilesChecker;
10+
use SymfonyDocsBuilder\ConfigFileParser;
11+
use SymfonyDocsBuilder\Generator\HtmlForPdfGenerator;
12+
use SymfonyDocsBuilder\Generator\JsonGenerator;
13+
use SymfonyDocsBuilder\KernelFactory;
14+
15+
class BuildResult
16+
{
17+
private $errors;
18+
19+
public function __construct(array $errors)
20+
{
21+
$this->errors = $errors;
22+
}
23+
24+
public function appendError(string $errorMessage): void
25+
{
26+
$this->errors[] = $errorMessage;
27+
}
28+
29+
public function prependError(string $errorMessage): void
30+
{
31+
$this->errors = array_merge([$errorMessage], $this->errors);
32+
}
33+
34+
public function isSuccessful(): bool
35+
{
36+
return null === $this->errors || 0 === \count($this->errors);
37+
}
38+
39+
public function getErrors(): array
40+
{
41+
return $this->errors;
42+
}
43+
}

src/DocBuilder.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
namespace SymfonyDocsBuilder;
4+
5+
use Doctrine\RST\Builder;
6+
use Doctrine\RST\Configuration;
7+
use Symfony\Component\Console\Output\NullOutput;
8+
use Symfony\Component\Filesystem\Filesystem;
9+
use SymfonyDocsBuilder\CI\MissingFilesChecker;
10+
use SymfonyDocsBuilder\Generator\HtmlForPdfGenerator;
11+
use SymfonyDocsBuilder\Generator\JsonGenerator;
12+
13+
final class DocBuilder
14+
{
15+
private $useBuildCache = true;
16+
private $symfonyVersion = '4.4';
17+
private $theme = Configuration::THEME_DEFAULT;// 'rtd'; // also: Configuration::THEME_DEFAULT
18+
private const PHP_DOC_URL = 'https://secure.php.net/manual/en';
19+
private const SYMFONY_API_URL = 'https://api.symfony.com/{symfonyVersion}';
20+
private const SYMFONY_DOC_URL = 'https://symfony.com/doc/{symfonyVersion}';
21+
22+
public function buildDir(string $rstContentsDir/*, BuildConfig $config*/, string $outputDir, string $publicImagesDir = null, string $publicImagesPrefix = null): BuildResult
23+
{
24+
return $this->doBuild($rstContentsDir, $outputDir, $publicImagesDir ?? $outputDir.'/_images', $publicImagesPrefix ?? $publicImagesPrefix.'/_images');
25+
}
26+
27+
public function buildDocument(string $rstContent, BuildConfig $config): BuildResult
28+
{
29+
// TODO
30+
}
31+
32+
private function doBuild(string $rstContentsDir, string $htmlOutputDir, string $publicImagesDir, string $publicImagesPrefix, ?string $rstBookSubDir = null): BuildResult
33+
{
34+
if (!file_exists($rstContentsDir)) {
35+
throw new \InvalidArgumentException(sprintf('RST contents directory "%s" does not exist', $rstContentsDir));
36+
}
37+
38+
$filesystem = new Filesystem();
39+
if (!$this->useBuildCache && $filesystem->exists($htmlOutputDir)) {
40+
$filesystem->remove($htmlOutputDir);
41+
}
42+
$filesystem->mkdir($htmlOutputDir);
43+
44+
if ($rstBookSubDir && !file_exists($rstContentsDir.'/'.$rstBookSubDir)) {
45+
throw new \InvalidArgumentException(sprintf('Given book directory "%s" is not a subdirectory of the RST contents dir "%s".', $rstBookSubDir, $rstContentsDir));
46+
}
47+
48+
$buildContext = new BuildContext(
49+
$this->symfonyVersion,
50+
str_replace('{symfonyVersion}', $this->symfonyVersion, self::SYMFONY_API_URL),
51+
self::PHP_DOC_URL,
52+
str_replace('{symfonyVersion}', $this->symfonyVersion, self::SYMFONY_DOC_URL)
53+
);
54+
$buildContext->initializeRuntimeConfig($rstContentsDir, $htmlOutputDir, $publicImagesDir, $publicImagesPrefix, $rstBookSubDir, !$this->useBuildCache, $this->theme);
55+
56+
$configFileParser = new ConfigFileParser($buildContext, new NullOutput());
57+
$configFileParser->processConfigFile($rstContentsDir);
58+
59+
$builder = new Builder(KernelFactory::createKernel($buildContext));
60+
$builder->build($buildContext->getSourceDir(), $buildContext->getOutputDir());
61+
62+
$buildResult = new BuildResult($builder->getErrorManager()->getErrors());
63+
64+
$missingFilesChecker = new MissingFilesChecker($buildContext);
65+
$missingFiles = $missingFilesChecker->getMissingFiles();
66+
foreach ($missingFiles as $missingFile) {
67+
$buildResult->appendError(sprintf('Missing file "%s"', $missingFile));
68+
}
69+
70+
if (!$buildResult->isSuccessful()) {
71+
$buildResult->prependError(sprintf('Build errors from "%s"', date('Y-m-d h:i:s')));
72+
$filesystem->dumpFile($htmlOutputDir.'/build_errors.txt', implode("\n", $buildResult->getErrors()));
73+
}
74+
75+
$metas = $builder->getMetas();
76+
if ($buildContext->getParseSubPath()) {
77+
$htmlForPdfGenerator = new HtmlForPdfGenerator($metas, $buildContext);
78+
$htmlForPdfGenerator->generateHtmlForPdf();
79+
} else {
80+
$jsonGenerator = new JsonGenerator($metas, $buildContext);
81+
$jsonGenerator->generateJson();
82+
}
83+
84+
return $buildResult;
85+
}
86+
}

src/DocsKernel.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public function initBuilder(Builder $builder): void
3737
$builder->getErrorManager()
3838
);
3939

40-
$builder->setScannerFinder($this->buildContext->createFileFinder());
40+
// $builder->setScannerFinder($this->buildContext->createFileFinder());
4141
}
4242

4343
private function initializeListeners(EventManager $eventManager, ErrorManager $errorManager)

src/Listener/CopyImagesListener.php

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,10 @@ public function preNodeRender(PreNodeRenderEvent $event)
5050
$fileInfo = new \SplFileInfo($sourceImage);
5151
$fs = new Filesystem();
5252

53-
// the /_images path is currently hardcoded here and respected
54-
// in the overridden image node template
55-
$newPath = '/_images/'.$fileInfo->getFilename();
56-
$fs->copy($sourceImage, $this->buildContext->getOutputDir().$newPath, true);
57-
58-
$node->setValue($node->getEnvironment()->relativeUrl(
59-
'/_images/'.$fileInfo->getFilename()
60-
));
53+
$newAbsoluteFilePath = $this->buildContext->getPublicImagesDir().'/'.$fileInfo->getFilename();
54+
$newUrlPath = $this->buildContext->getPublicImagesPrefix().'/'.$fileInfo->getFilename();
55+
56+
$fs->copy($sourceImage, $newAbsoluteFilePath, true);
57+
$node->setValue($newUrlPath);
6158
}
6259
}

0 commit comments

Comments
 (0)