Skip to content

Commit

Permalink
Merge pull request #3485 from phpDocumentor/extract-pipeline-for-docu…
Browse files Browse the repository at this point in the history
…mentation-set

Extract pipeline for documentation set
  • Loading branch information
jaapio committed Mar 22, 2023
2 parents 8f89881 + abbf0ce commit 2597b8a
Show file tree
Hide file tree
Showing 16 changed files with 150 additions and 125 deletions.
5 changes: 5 additions & 0 deletions config/pipelines.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ services:
tags:
- { name: 'phpdoc.pipeline.api_documentation.generate', priority: 8000 }

phpdoc.parse_api_documentation_set.pipeline:
class: 'League\Pipeline\Pipeline'
factory: ['phpDocumentor\Pipeline\PipelineFactory', 'create']
arguments: [!tagged phpdoc.pipeline.api_documentation.parse_api_documentation_set]

phpdoc.transform.pipeline:
class: 'League\Pipeline\Pipeline'
factory: ['phpDocumentor\Pipeline\PipelineFactory', 'create']
Expand Down
12 changes: 7 additions & 5 deletions config/stages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,23 @@ services:
## Autoloading definitions for parser stages #################################
###################################################################################

phpDocumentor\Pipeline\Stage\Parser\TransformToParserPayload:
phpDocumentor\Pipeline\Stage\ParseApiDocumentationSets:
arguments:
$parseApiDocumentationSetPipeline: '@phpdoc.parse_api_documentation_set.pipeline'
tags:
- { name: 'phpdoc.pipeline.api_documentation.parse', priority: 5000 }
- { name: 'phpdoc.pipeline.api_documentation.parse', priority: 3000 }

phpDocumentor\Pipeline\Stage\Parser\CollectFiles:
tags:
- { name: 'phpdoc.pipeline.api_documentation.parse', priority: 4000 }
- { name: 'phpdoc.pipeline.api_documentation.parse_api_documentation_set', priority: 4000 }

phpDocumentor\Pipeline\Stage\Cache\GarbageCollectCache:
tags:
- { name: 'phpdoc.pipeline.api_documentation.parse', priority: 3000 }
- { name: 'phpdoc.pipeline.api_documentation.parse_api_documentation_set', priority: 3000 }

phpDocumentor\Pipeline\Stage\Parser\ParseFiles:
tags:
- { name: 'phpdoc.pipeline.api_documentation.parse', priority: 0 }
- { name: 'phpdoc.pipeline.api_documentation.parse_api_documentation_set', priority: 0 }

###################################################################################
## Autoloading definitions for transform stages #################################
Expand Down
23 changes: 20 additions & 3 deletions docs/internals/pipeline.rst
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,29 @@ For performance, files can be cached and retrieved during the parsing phase.

As of writing, the main stages in this pipeline are:

#. :php:class:`Converting the payload into a parser-specific variant<phpDocumentor\Pipeline\Stage\Parser\TransformToParserPayload>`
#. :php:class:`Load previously parsed files from cache<phpDocumentor\Pipeline\Stage\Cache\LoadProjectDescriptorFromCache>`
#. :php:class:`Parse each API Documentation Set using the *PHP API Documentation Set Parser sub-pipeline*<phpDocumentor\Pipeline\Stage\ParseApiDocumentationSets>`
#. :php:class:`Update cache<phpDocumentor\Pipeline\Stage\Cache\StoreProjectDescriptorToCache>`

PHP API Documentation Set Parser sub-pipeline
---------------------------------------------

This sub-pipeline is responsible for parsing each API Documentation Set using the API Specification from the
configuration and adding it to the Project Descriptor.

**Input**
:php:class:`ApiSetPayload<phpDocumentor\Pipeline\Stage\Parser\ApiSetPayload>` with the loaded configuration, a
:php:class:`ProjectDescriptorBuilder<phpDocumentor\Descriptor\ProjectDescriptorBuilder>` and the
:php:class:`API Set's specification<phpDocumentor\Configuration\ApiSpecification>`.

**Output**
:php:class:`ApiSetPayload<phpDocumentor\Pipeline\Stage\Parser\ApiSetPayload>` with the loaded configuration, a
:php:class:`ProjectDescriptorBuilder<phpDocumentor\Descriptor\ProjectDescriptorBuilder>` and the
:php:class:`API Set's specification<phpDocumentor\Configuration\ApiSpecification>`.

#. :php:class:`Gathering which files to parse<phpDocumentor\Pipeline\Stage\Parser\CollectFiles>`
#. :php:class:`Remove all files from cache that are not in this list<phpDocumentor\Pipeline\Stage\Cache\GarbageCollectCache>`
#. :php:class:`Load unmodified parsed files from cache<phpDocumentor\Pipeline\Stage\Cache\LoadProjectDescriptorFromCache>`
#. :php:class:`Parse any modified files and create/update FileDescriptors<phpDocumentor\Pipeline\Stage\Parser\ParseFiles>`
#. :php:class:`Update cache<phpDocumentor\Pipeline\Stage\Cache\StoreProjectDescriptorToCache>`

Transformer pipeline
====================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,18 @@
namespace phpDocumentor\Pipeline\Stage\Cache;

use phpDocumentor\Descriptor\Cache\ProjectDescriptorMapper;
use phpDocumentor\Pipeline\Stage\Parser\Payload;
use phpDocumentor\Pipeline\Stage\Parser\ApiSetPayload;

final class GarbageCollectCache
{
/** @var ProjectDescriptorMapper */
private $descriptorMapper;
private ProjectDescriptorMapper $descriptorMapper;

public function __construct(ProjectDescriptorMapper $descriptorMapper)
{
$this->descriptorMapper = $descriptorMapper;
}

public function __invoke(Payload $payload): Payload
public function __invoke(ApiSetPayload $payload): ApiSetPayload
{
$this->descriptorMapper->garbageCollect($payload->getFiles());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use League\Tactician\CommandBus;
use phpDocumentor\Guides\Handlers\LoadCacheCommand;
use phpDocumentor\Pipeline\Stage\Parser\Payload;
use phpDocumentor\Pipeline\Stage\Payload;
use Psr\Log\LoggerInterface;

final class LoadGuidesFromCache
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace phpDocumentor\Pipeline\Stage\Cache;

use phpDocumentor\Descriptor\Cache\ProjectDescriptorMapper;
use phpDocumentor\Pipeline\Stage\Parser\Payload;
use phpDocumentor\Pipeline\Stage\Payload;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

use League\Tactician\CommandBus;
use phpDocumentor\Guides\Handlers\PersistCacheCommand;
use phpDocumentor\Pipeline\Stage\Parser\Payload;
use phpDocumentor\Pipeline\Stage\Payload;
use Psr\Log\LoggerInterface;

final class StoreGuidesToCache
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
namespace phpDocumentor\Pipeline\Stage\Cache;

use phpDocumentor\Descriptor\Cache\ProjectDescriptorMapper;
use phpDocumentor\Pipeline\Stage\Parser\Payload;
use phpDocumentor\Pipeline\Stage\Payload;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;

Expand Down
43 changes: 43 additions & 0 deletions src/phpDocumentor/Pipeline/Stage/ParseApiDocumentationSets.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

/**
* This file is part of phpDocumentor.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @link https://phpdoc.org
*/

namespace phpDocumentor\Pipeline\Stage;

use League\Pipeline\Pipeline;
use phpDocumentor\Configuration\VersionSpecification;

final class ParseApiDocumentationSets
{
private Pipeline $parseApiDocumentationSetPipeline;

public function __construct(Pipeline $parseApiDocumentationSetPipeline)
{
$this->parseApiDocumentationSetPipeline = $parseApiDocumentationSetPipeline;
}

public function __invoke(Payload $payload): Payload
{
/** @var VersionSpecification[] $versions */
$versions = $payload->getConfig()['phpdocumentor']['versions'];

foreach ($versions as $version) {
foreach ($version->getApi() as $apiSpecification) {
$this->parseApiDocumentationSetPipeline->process(
new Parser\ApiSetPayload($payload->getConfig(), $payload->getBuilder(), $apiSpecification)
);
}
}

return $payload;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,53 +15,68 @@

use phpDocumentor\Configuration\ApiSpecification;
use phpDocumentor\Configuration\Configuration;
use phpDocumentor\Configuration\VersionSpecification;
use phpDocumentor\Descriptor\ProjectDescriptorBuilder;
use phpDocumentor\Pipeline\Stage\Payload as ApplicationPayload;
use phpDocumentor\Reflection\File;
use Webmozart\Assert\Assert;

use function array_merge;
use function current;

/**
* @psalm-import-type ConfigurationMap from Configuration
*/
final class Payload extends ApplicationPayload
final class ApiSetPayload
{
/** @var ConfigurationMap */
private array $configuration;
private ProjectDescriptorBuilder $builder;
private ApiSpecification $specification;

/** @var File[] */
private array $files;

/**
* @param ConfigurationMap $config
* @param ConfigurationMap $configuration
* @param File[] $files
*/
public function __construct(array $config, ProjectDescriptorBuilder $builder, array $files = [])
{
parent::__construct($config, $builder);
public function __construct(
array $configuration,
ProjectDescriptorBuilder $builder,
ApiSpecification $specification,
array $files = []
) {
$this->configuration = $configuration;
$this->builder = $builder;
$this->specification = $specification;

$this->files = $files;
}

/**
* @return array<int, ApiSpecification>
* @return ConfigurationMap
*/
public function getApiConfigs(): array
public function getConfiguration(): array
{
return $this->configuration;
}

public function getBuilder(): ProjectDescriptorBuilder
{
// Grep only the first version for now. Multi version support will be added later
$version = current($this->getConfig()['phpdocumentor']['versions']);
Assert::isInstanceOf($version, VersionSpecification::class);
return $this->builder;
}

return $version->getApi();
public function getSpecification(): ApiSpecification
{
return $this->specification;
}

/**
* @param array<File> $files
*/
public function withFiles(array $files): Payload
public function withFiles(array $files): self
{
return new self(
$this->getConfig(),
return new static(
$this->getConfiguration(),
$this->getBuilder(),
$this->getSpecification(),
array_merge($this->getFiles(), $files)
);
}
Expand Down
45 changes: 14 additions & 31 deletions src/phpDocumentor/Pipeline/Stage/Parser/CollectFiles.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,57 +15,40 @@

use phpDocumentor\Parser\FileCollector;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;

use function count;

final class CollectFiles
{
/** @var FileCollector */
private $fileCollector;

/** @var LoggerInterface */
private $logger;
private FileCollector $fileCollector;
private LoggerInterface $logger;

public function __construct(FileCollector $fileCollector, LoggerInterface $logger)
{
$this->fileCollector = $fileCollector;
$this->logger = $logger;
}

public function __invoke(Payload $payload): Payload
public function __invoke(ApiSetPayload $payload): ApiSetPayload
{
foreach ($payload->getApiConfigs() as $apiConfig) {
$this->log('Collecting files from ' . $apiConfig->source()->dsn());
$apiConfig = $payload->getSpecification();
$this->logger->info('Collecting files from ' . $apiConfig->source()->dsn());

$files = $this->fileCollector->getFiles(
$apiConfig->source()->dsn(),
$apiConfig->source()->globPatterns(),
$apiConfig['ignore'],
$apiConfig['extensions']
);
$files = $this->fileCollector->getFiles(
$apiConfig->source()->dsn(),
$apiConfig->source()->globPatterns(),
$apiConfig['ignore'],
$apiConfig['extensions']
);

$payload = $payload->withFiles($files);
}
$payload = $payload->withFiles($files);

$this->log('OK');
$this->logger->info('OK');

if (count($payload->getFiles()) === 0) {
$this->log('Your project seems to be empty!', LogLevel::WARNING);
$this->log('Where are the files??!!!', LogLevel::DEBUG);
$this->logger->warning('Your documentationset seems to be empty!');
}

return $payload;
}

/**
* Dispatches a logging request.
*
* @param string $priority The logging priority as declared in the LogLevel PSR-3 class.
* @param string[] $parameters
*/
private function log(string $message, string $priority = LogLevel::INFO, array $parameters = []): void
{
$this->logger->log($priority, $message, $parameters);
}
}

0 comments on commit 2597b8a

Please sign in to comment.