Skip to content

Commit f4bc17c

Browse files
committed
removing command trait to simplify things
1 parent a8f7c7c commit f4bc17c

File tree

4 files changed

+134
-118
lines changed

4 files changed

+134
-118
lines changed

src/Command/BuildDocsCommand.php

Lines changed: 50 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,39 @@
22

33
namespace SymfonyDocsBuilder\Command;
44

5+
use Doctrine\Common\EventManager;
6+
use Doctrine\RST\Builder;
57
use Doctrine\RST\Event\PostBuildRenderEvent;
6-
use Doctrine\RST\Meta\CachedMetasLoader;
78
use Doctrine\RST\Meta\Metas;
89
use Symfony\Component\Console\Command\Command;
9-
use Symfony\Component\Console\Helper\ProgressBar;
1010
use Symfony\Component\Console\Input\InputArgument;
1111
use Symfony\Component\Console\Input\InputInterface;
1212
use Symfony\Component\Console\Input\InputOption;
1313
use Symfony\Component\Console\Output\OutputInterface;
14+
use Symfony\Component\Console\Style\SymfonyStyle;
1415
use Symfony\Component\Filesystem\Filesystem;
15-
use Symfony\Component\Finder\Finder;
1616
use SymfonyDocsBuilder\BuildContext;
1717
use SymfonyDocsBuilder\CI\MissingFilesChecker;
1818
use SymfonyDocsBuilder\Generator\HtmlForPdfGenerator;
1919
use SymfonyDocsBuilder\Generator\JsonGenerator;
20+
use SymfonyDocsBuilder\KernelFactory;
21+
use SymfonyDocsBuilder\Listener\BuildProgressListener;
2022
use SymfonyDocsBuilder\Listener\CopyImagesDirectoryListener;
2123

2224
class BuildDocsCommand extends Command
2325
{
24-
use CommandInitializerTrait;
25-
2626
protected static $defaultName = 'build:docs';
2727

28+
private $buildContext;
2829
private $missingFilesChecker;
30+
/** @var SymfonyStyle */
31+
private $io;
2932

3033
public function __construct(BuildContext $buildContext)
3134
{
3235
parent::__construct(self::$defaultName);
3336

34-
$this->filesystem = new Filesystem();
35-
$this->finder = new Finder();
3637
$this->buildContext = $buildContext;
37-
3838
$this->missingFilesChecker = new MissingFilesChecker($buildContext);
3939
}
4040

@@ -75,26 +75,50 @@ protected function configure()
7575

7676
protected function initialize(InputInterface $input, OutputInterface $output)
7777
{
78-
if ($input->getOption('parse-sub-path') && $input->getOption('output-json')) {
79-
throw new \InvalidArgumentException(sprintf('Cannot pass both --parse-sub-path and --output-json options.'));
78+
$this->io = new SymfonyStyle($input, $output);
79+
80+
$sourceDir = $input->getArgument('source-dir');
81+
if (!file_exists($sourceDir)) {
82+
throw new \InvalidArgumentException(sprintf('RST source directory "%s" does not exist', $sourceDir));
8083
}
8184

85+
$filesystem = new Filesystem();
86+
$htmlOutputDir = $input->getArgument('output-dir') ?? $sourceDir.'/html';
87+
if ($input->getOption('disable-cache') && $filesystem->exists($htmlOutputDir)) {
88+
$filesystem->remove($htmlOutputDir);
89+
}
8290

83-
$sourceDir = $this->initializeSourceDir($input, $this->filesystem);
84-
$outputDir = $input->getArgument('output-dir') ?? $sourceDir.'/html';
91+
$parseSubPath = $input->getOption('parse-sub-path');
92+
if ($parseSubPath && $input->getOption('output-json')) {
93+
throw new \InvalidArgumentException('Cannot pass both --parse-sub-path and --output-json options.');
94+
}
8595

86-
$this->doInitialize($input, $output, $sourceDir, $outputDir);
96+
if (!file_exists($sourceDir.'/'.$parseSubPath)) {
97+
throw new \InvalidArgumentException(sprintf('Given "parse-sub-path" directory "%s" does not exist', $parseSubPath));
98+
}
8799

88-
$this->builder->getConfiguration()->getEventManager()->addEventListener(
89-
PostBuildRenderEvent::POST_BUILD_RENDER,
90-
new CopyImagesDirectoryListener($this->buildContext)
100+
$this->buildContext->initializeRuntimeConfig(
101+
$sourceDir,
102+
$htmlOutputDir,
103+
$parseSubPath,
104+
$input->getOption('disable-cache')
91105
);
92106
}
93107

94108
protected function execute(InputInterface $input, OutputInterface $output)
95109
{
96-
$this->startBuild();
97-
$buildErrors = $this->builder->getErrorManager()->getErrors();
110+
$builder = new Builder(
111+
KernelFactory::createKernel($this->buildContext, $this->urlChecker ?? null)
112+
);
113+
114+
$this->initializeListeners($builder->getConfiguration()->getEventManager());
115+
116+
$builder->build(
117+
$this->buildContext->getSourceDir(),
118+
$this->buildContext->getOutputDir()
119+
);
120+
121+
$buildErrors = $builder->getErrorManager()->getErrors();
98122

99123
$this->io->success('HTML rendering complete!');
100124

@@ -113,7 +137,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
113137
file_put_contents($logPath, implode("\n", $buildErrors));
114138
}
115139

116-
$metas = $this->getMetas();
140+
$metas = $builder->getMetas();
117141
if ($this->buildContext->getParseSubPath()) {
118142
$this->renderDocForPDF($metas);
119143
} elseif ($input->getOption('output-json')) {
@@ -129,11 +153,9 @@ protected function execute(InputInterface $input, OutputInterface $output)
129153
private function generateJson(Metas $metas)
130154
{
131155
$this->io->note('Start exporting doc into json files');
132-
$this->progressBar = new ProgressBar($this->output, $this->finder->count());
133156

134157
$jsonGenerator = new JsonGenerator($metas, $this->buildContext);
135158
$jsonGenerator->setOutput($this->io);
136-
$jsonGenerator->generateJson($this->progressBar);
137159
}
138160

139161
private function renderDocForPDF(Metas $metas)
@@ -142,15 +164,14 @@ private function renderDocForPDF(Metas $metas)
142164
$htmlForPdfGenerator->generateHtmlForPdf();
143165
}
144166

145-
public function preBuildRender()
167+
private function initializeListeners(EventManager $eventManager)
146168
{
147-
$this->doPreBuildRender();
148-
149-
$this->io->note('Start rendering in HTML...');
150-
}
169+
$eventManager->addEventListener(
170+
PostBuildRenderEvent::POST_BUILD_RENDER,
171+
new CopyImagesDirectoryListener($this->buildContext)
172+
);
151173

152-
private function getMetas(): Metas
153-
{
154-
return $this->builder->getMetas();
174+
$progressListener = new BuildProgressListener($this->io);
175+
$progressListener->attachListeners($eventManager);
155176
}
156177
}

src/Command/CommandInitializerTrait.php

Lines changed: 0 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,6 @@ trait CommandInitializerTrait
2121
{
2222
/** @var BuildContext */
2323
private $buildContext;
24-
/** @var SymfonyStyle */
25-
private $io;
26-
/** @var OutputInterface */
27-
private $output;
28-
/** @var InputInterface */
29-
private $input;
3024
/** @var Builder */
3125
private $builder;
3226
/** @var Filesystem */
@@ -42,91 +36,14 @@ trait CommandInitializerTrait
4236

4337
private function doInitialize(InputInterface $input, OutputInterface $output, string $sourceDir, string $outputDir)
4438
{
45-
$this->io = new SymfonyStyle($input, $output);
46-
$this->input = $input;
47-
$this->output = $output;
48-
49-
$this->buildContext->initializeRuntimeConfig(
50-
$sourceDir,
51-
$this->initializeHtmlOutputDir($this->filesystem, $outputDir),
52-
$this->initializeParseSubPath($input, $sourceDir),
53-
$this->isCacheDisabled()
54-
);
55-
56-
$this->builder = new Builder(
57-
KernelFactory::createKernel($this->buildContext, $this->urlChecker ?? null)
58-
);
59-
6039
$this->eventManager = $this->builder->getConfiguration()->getEventManager();
6140

6241
$this->initializeProgressBarEventListeners();
6342
}
6443

65-
private function initializeSourceDir(InputInterface $input, Filesystem $filesystem): string
66-
{
67-
$sourceDir = rtrim($this->getRealAbsolutePath($input->getArgument('source-dir'), $filesystem), '/');
68-
if (!$filesystem->exists($sourceDir)) {
69-
throw new \InvalidArgumentException(sprintf('RST source directory "%s" does not exist', $sourceDir));
70-
}
71-
72-
return $sourceDir;
73-
}
74-
75-
private function initializeHtmlOutputDir(Filesystem $filesystem, string $path): string
76-
{
77-
$htmlOutputDir = rtrim($this->getRealAbsolutePath($path, $filesystem), '/');
78-
if ($this->isCacheDisabled() && $filesystem->exists($htmlOutputDir)) {
79-
$filesystem->remove($htmlOutputDir);
80-
}
81-
82-
return $htmlOutputDir;
83-
}
84-
85-
private function initializeParseSubPath(InputInterface $input, string $sourceDir): string
86-
{
87-
if (!$input->hasOption('parse-sub-path')) {
88-
return '';
89-
}
90-
91-
if ($parseSubPath = trim($input->getOption('parse-sub-path'), '/')) {
92-
$absoluteParseSubPath = sprintf(
93-
'%s/%s',
94-
$sourceDir,
95-
$parseSubPath
96-
);
97-
98-
if (!$this->filesystem->exists($absoluteParseSubPath) || !is_dir($absoluteParseSubPath)) {
99-
throw new \InvalidArgumentException(sprintf('Given "parse-sub-path" directory "%s" does not exist', $parseSubPath));
100-
}
101-
}
102-
103-
return $parseSubPath;
104-
}
105-
106-
private function getRealAbsolutePath(string $path, Filesystem $filesystem): string
107-
{
108-
return sprintf(
109-
'/%s',
110-
rtrim(
111-
$filesystem->makePathRelative($path, '/'),
112-
'/'
113-
)
114-
);
115-
}
116-
11744
private function initializeProgressBarEventListeners(): void
11845
{
119-
// sets up the "parsing" progress bar
120-
$this->eventManager->addEventListener(
121-
[PreBuildParseEvent::PRE_BUILD_PARSE],
122-
$this
123-
);
12446

125-
// advances "parsing" progress bar
126-
$this->eventManager->addEventListener(
127-
[PostParseDocumentEvent::POST_PARSE_DOCUMENT],
128-
$this
129-
);
13047

13148
// tries to handle progress bar for "rendering"
13249
$this->eventManager->addEventListener(
@@ -196,11 +113,6 @@ function ($file) use ($outputDir, $format) {
196113
}
197114
}
198115

199-
private function isCacheDisabled(): bool
200-
{
201-
return $this->input->hasOption('disable-cache') && (bool) $this->input->getOption('disable-cache');
202-
}
203-
204116
/**
205117
* Called very early: used to initialize the "parsing" progress bar.
206118
*

src/Generator/JsonGenerator.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Doctrine\RST\Meta\MetaEntry;
77
use Doctrine\RST\Meta\Metas;
88
use Symfony\Component\Console\Helper\ProgressBar;
9+
use Symfony\Component\Console\Output\NullOutput;
910
use Symfony\Component\Console\Style\SymfonyStyle;
1011
use Symfony\Component\DomCrawler\Crawler;
1112
use Symfony\Component\Filesystem\Filesystem;
@@ -27,10 +28,13 @@ public function __construct(Metas $metas, BuildContext $buildContext)
2728
$this->buildContext = $buildContext;
2829
}
2930

30-
public function generateJson(ProgressBar $progressBar)
31+
public function generateJson()
3132
{
3233
$fs = new Filesystem();
3334

35+
$progressBar = new ProgressBar($this->output ?: new NullOutput());
36+
$progressBar->setMaxSteps(count($this->metas->getAll()));
37+
3438
foreach ($this->metas->getAll() as $filename => $metaEntry) {
3539
$parserFilename = $filename;
3640
$jsonFilename = $this->buildContext->getOutputDir().'/'.$filename.'.fjson';
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace SymfonyDocsBuilder\Listener;
4+
5+
use Doctrine\Common\EventManager;
6+
use Doctrine\RST\Event\PostBuildRenderEvent;
7+
use Doctrine\RST\Event\PostParseDocumentEvent;
8+
use Doctrine\RST\Event\PreBuildParseEvent;
9+
use Doctrine\RST\Event\PreBuildRenderEvent;
10+
use Symfony\Component\Console\Helper\ProgressBar;
11+
use Symfony\Component\Console\Style\SymfonyStyle;
12+
use Symfony\Component\Filesystem\Filesystem;
13+
use SymfonyDocsBuilder\BuildContext;
14+
15+
class BuildProgressListener
16+
{
17+
private $io;
18+
private $progressBar;
19+
private $parsedFiles = [];
20+
21+
public function __construct(SymfonyStyle $io)
22+
{
23+
$this->io = $io;
24+
$this->progressBar = new ProgressBar($io);
25+
}
26+
27+
public function attachListeners(EventManager $eventManager)
28+
{
29+
// sets up the "parsing" progress bar
30+
$eventManager->addEventListener(
31+
[PreBuildParseEvent::PRE_BUILD_PARSE],
32+
$this
33+
);
34+
35+
// advances "parsing" progress bar
36+
$eventManager->addEventListener(
37+
[PostParseDocumentEvent::POST_PARSE_DOCUMENT],
38+
$this
39+
);
40+
41+
// tries to handle progress bar for "rendering"
42+
$eventManager->addEventListener(
43+
[PreBuildRenderEvent::PRE_BUILD_RENDER],
44+
$this
45+
);
46+
}
47+
48+
/**
49+
* Called very early: used to initialize the "parsing" progress bar.
50+
*
51+
* @param PreBuildParseEvent $event
52+
*/
53+
public function preBuildParse(PreBuildParseEvent $event)
54+
{
55+
$parseQueue = $event->getParseQueue();
56+
$parseCount = count($parseQueue->getAllFilesThatRequireParsing());
57+
$this->io->note(sprintf('Start parsing %d out-of-date rst files', $parseCount));
58+
$this->progressBar->setMaxSteps($parseCount);
59+
}
60+
61+
public function postParseDocument(PostParseDocumentEvent $postParseDocumentEvent): void
62+
{
63+
$file = $postParseDocumentEvent->getDocumentNode()->getEnvironment()->getCurrentFileName();
64+
if (!\in_array($file, $this->parsedFiles)) {
65+
$this->parsedFiles[] = $file;
66+
$this->progressBar->advance();
67+
}
68+
}
69+
70+
public function preBuildRender()
71+
{
72+
// finishes the "parse" progress bar
73+
$this->progressBar->finish();
74+
75+
$this->io->newLine(2);
76+
$this->io->note('Start rendering in HTML...');
77+
// TODO: create a proper progress bar for rendering
78+
}
79+
}

0 commit comments

Comments
 (0)