Skip to content

Make Intersphinx inventories configurable #494

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,15 @@ you can do so by creating a ``settings.php`` file in the input directory
of the manual you are building (that is the directory you would specify
as a first argument to the CLI).

That file needs to return a ``ProjectSettings``, and typically looks as
That file needs to return an `array`, and typically looks as
follows:

.. code-block:: php
.. code-block:: php

<?php
<?php

use phpDocumentor\Guides\Settings\ProjectSettings;

return new ProjectSettings(
title: 'My Documentation',
version:'42.12.7'
);
return [
'title' => 'My Project',
'version' => '3.1.4',
'inventories' => ['t3coreapi' => 'https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/'],
];
13 changes: 9 additions & 4 deletions packages/guides-cli/src/Command/Run.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use phpDocumentor\Guides\Handlers\CompileDocumentsCommand;
use phpDocumentor\Guides\Handlers\ParseDirectoryCommand;
use phpDocumentor\Guides\Handlers\RenderCommand;
use phpDocumentor\Guides\Intersphinx\InventoryRepository;
use phpDocumentor\Guides\Nodes\ProjectNode;
use phpDocumentor\Guides\Settings\ProjectSettings;
use phpDocumentor\Guides\Settings\SettingsManager;
Expand All @@ -33,6 +34,7 @@
use function count;
use function getcwd;
use function implode;
use function is_array;
use function is_countable;
use function is_dir;
use function is_file;
Expand All @@ -47,6 +49,7 @@ public function __construct(
private readonly Logger $logger,
private readonly ThemeManager $themeManager,
private readonly SettingsManager $settingsManager,
private readonly InventoryRepository $inventoryRepository,
) {
parent::__construct('run');

Expand Down Expand Up @@ -117,18 +120,20 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}

if (is_file($inputDir . '/settings.php')) {
$settings = require $inputDir . '/settings.php';
if (!$settings instanceof ProjectSettings) {
throw new RuntimeException('settings.php must return an instance of ' . ProjectSettings::class);
$settingsArray = require $inputDir . '/settings.php';
if (!is_array($settingsArray)) {
throw new RuntimeException('settings.php must return an array!');
}

$settings = new ProjectSettings($settingsArray);
$this->settingsManager->setProjectSettings($settings);
$projectNode = new ProjectNode(
$settings->getTitle(),
$settings->getVersion(),
);
$this->inventoryRepository->initialize($settings->getInventories());
} else {
$this->settingsManager->setProjectSettings(new ProjectSettings());
$this->settingsManager->setProjectSettings(new ProjectSettings([]));
$projectNode = new ProjectNode();
}

Expand Down
18 changes: 18 additions & 0 deletions packages/guides/resources/config/guides.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
use phpDocumentor\Guides\Compiler\NodeTransformer;
use phpDocumentor\Guides\Compiler\NodeTransformers\CustomNodeTransformerFactory;
use phpDocumentor\Guides\Compiler\NodeTransformers\NodeTransformerFactory;
use phpDocumentor\Guides\Intersphinx\InventoryLoader;
use phpDocumentor\Guides\Intersphinx\InventoryRepository;
use phpDocumentor\Guides\Intersphinx\JsonLoader;
use phpDocumentor\Guides\NodeRenderers\DefaultNodeRenderer;
use phpDocumentor\Guides\NodeRenderers\DelegatingNodeRenderer;
use phpDocumentor\Guides\NodeRenderers\Html\DocumentNodeRenderer;
Expand All @@ -24,6 +27,7 @@
use phpDocumentor\Guides\ReferenceResolvers\DocReferenceResolver;
use phpDocumentor\Guides\ReferenceResolvers\ExternalReferenceResolver;
use phpDocumentor\Guides\ReferenceResolvers\InternalReferenceResolver;
use phpDocumentor\Guides\ReferenceResolvers\IntersphinxReferenceResolver;
use phpDocumentor\Guides\ReferenceResolvers\ReferenceResolver;
use phpDocumentor\Guides\ReferenceResolvers\ReferenceResolverPreRender;
use phpDocumentor\Guides\ReferenceResolvers\RefReferenceResolver;
Expand All @@ -42,6 +46,8 @@
use phpDocumentor\Guides\UrlGeneratorInterface;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Twig\Loader\FilesystemLoader;

use function Symfony\Component\DependencyInjection\Loader\Configurator\param;
Expand Down Expand Up @@ -99,6 +105,16 @@

->set(DocumentNodeTraverser::class)

->set(InventoryRepository::class)

->set(InventoryLoader::class)

->set(JsonLoader::class)


->set(HttpClientInterface::class)
->factory([HttpClient::class, 'create'])

->set(UrlGenerator::class)

->set(ExternalReferenceResolver::class)
Expand All @@ -109,6 +125,8 @@

->set(RefReferenceResolver::class)

->set(IntersphinxReferenceResolver::class)

->set(DelegatingReferenceResolver::class)
->arg('$resolvers', tagged_iterator('phpdoc.guides.reference_resolver', defaultPriorityMethod: 'getPriority'))

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{%- if node.internalTarget -%}
<sup>[<a href="{{- renderInternalTarget(node.internalTarget) -}}">{{- node.value -}}</a>]</sup>
<sup>[<a href="{{- renderTarget(node.internalTarget) -}}">{{- node.value -}}</a>]</sup>
{%- else -%}
<sup>[{{- node.value -}}]</sup>
{%- endif -%}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{%- if node.internalTarget -%}
<sup>[<a href="{{- renderInternalTarget(node.internalTarget) -}}">{{- node.value -}}</a>]</sup>
<sup>[<a href="{{- renderTarget(node.internalTarget) -}}">{{- node.value -}}</a>]</sup>
{%- else -%}
<sup>[{{- node.value -}}]</sup>
{%- endif -%}
14 changes: 14 additions & 0 deletions packages/guides/src/Intersphinx/Inventory.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ final class Inventory
/** @var InventoryGroup[] */
private array $groups = [];

private bool $isLoaded = false;

public function __construct(private readonly string $baseUrl)
{
}
Expand Down Expand Up @@ -59,4 +61,16 @@ public function hasInventoryGroup(string $key): bool

return array_key_exists($lowerCaseKey, $this->groups);
}

public function isLoaded(): bool
{
return $this->isLoaded;
}

public function setIsLoaded(bool $isLoaded): Inventory
{
$this->isLoaded = $isLoaded;

return $this;
}
}
23 changes: 10 additions & 13 deletions packages/guides/src/Intersphinx/InventoryLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,14 @@
final class InventoryLoader
{
public function __construct(
private readonly InventoryRepository $inventoryRepository,
private readonly JsonLoader $jsonLoader,
private readonly string $pathToJson = 'objects.inv.json',
) {
}

public function getInventoryRepository(): InventoryRepository
{
return $this->inventoryRepository;
}

/** @param array<String, mixed> $json */
public function loadInventoryFromJson(string $key, string $baseUrl, array $json): void
public function loadInventoryFromJson(Inventory $inventory, array $json): void
{
$newInventory = new Inventory($baseUrl);
foreach ($json as $groupKey => $groupArray) {
$group = new InventoryGroup();
if (is_array($groupArray)) {
Expand All @@ -37,16 +30,20 @@ public function loadInventoryFromJson(string $key, string $baseUrl, array $json)
}
}

$newInventory->addGroup($groupKey, $group);
$inventory->addGroup($groupKey, $group);
}

$this->inventoryRepository->addInventory($key, $newInventory);
$inventory->setIsLoaded(true);
}

public function loadInventoryFromUrl(string $key, string $url): void
public function loadInventory(Inventory $inventory): void
{
$json = $this->jsonLoader->loadJsonFromUrl($url . $this->pathToJson);
if ($inventory->isLoaded()) {
return;
}

$json = $this->jsonLoader->loadJsonFromUrl($inventory->getBaseUrl() . $this->pathToJson);

$this->loadInventoryFromJson($key, $url, $json);
$this->loadInventoryFromJson($inventory, $json);
}
}
17 changes: 15 additions & 2 deletions packages/guides/src/Intersphinx/InventoryRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,20 @@

class InventoryRepository
{
/** @param array<String, Inventory> $inventories */
public function __construct(private array $inventories)
/** @var array<string, Inventory> */
private array $inventories = [];

public function __construct(private readonly InventoryLoader $inventoryLoader)
{
}

/** @param array<string, string> $inventoryConfigs */
public function initialize(array $inventoryConfigs): void
{
$this->inventories = [];
foreach ($inventoryConfigs as $key => $url) {
$this->inventories[$key] = new Inventory($url);
}
}

public function hasInventory(string $key): bool
Expand All @@ -30,6 +41,8 @@ public function getInventory(string $key): Inventory
throw new RuntimeException('Inventory with key ' . $lowerCaseKey . ' not found. ', 1_671_398_986);
}

$this->inventoryLoader->loadInventory($this->inventories[$lowerCaseKey]);

return $this->inventories[$lowerCaseKey];
}

Expand Down
4 changes: 1 addition & 3 deletions packages/guides/src/Intersphinx/JsonLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use RuntimeException;
use Symfony\Contracts\HttpClient\HttpClientInterface;

use function implode;
use function is_array;
use function json_decode;

Expand All @@ -27,9 +26,8 @@ public function loadJsonFromUrl(string $url): array
'GET',
$url,
);
$jsonString = implode("\n", $response->toArray());

return $this->loadJsonFromString($jsonString, $url);
return $response->toArray();
}

/** @return array<mixed> */
Expand Down
33 changes: 33 additions & 0 deletions packages/guides/src/Meta/ExternalTarget.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?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\Guides\Meta;

class ExternalTarget implements Target
{
public function __construct(
private readonly string $url,
private readonly string|null $title = null,
) {
}

public function getUrl(): string
{
return $this->url;
}

public function getTitle(): string|null
{
return $this->title;
}
}
16 changes: 15 additions & 1 deletion packages/guides/src/Meta/InternalTarget.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@

namespace phpDocumentor\Guides\Meta;

class InternalTarget
class InternalTarget implements Target
{
private string $url;

public function __construct(
private readonly string $documentPath,
protected string $anchorName,
Expand All @@ -41,4 +43,16 @@ public function getTitle(): string|null
{
return $this->title;
}

public function getUrl(): string
{
return $this->url;
}

public function setUrl(string $url): InternalTarget
{
$this->url = $url;

return $this;
}
}
12 changes: 12 additions & 0 deletions packages/guides/src/Meta/Target.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace phpDocumentor\Guides\Meta;

interface Target
{
public function getUrl(): string;

public function getTitle(): string|null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function resolve(LinkInlineNode $node, RenderContext $renderContext): boo
$node->setValue($link->getTitle());
}

return false;
return true;
}

public static function getPriority(): int
Expand Down
28 changes: 22 additions & 6 deletions packages/guides/src/Settings/ProjectSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,37 @@

namespace phpDocumentor\Guides\Settings;

use function is_array;
use function is_string;

class ProjectSettings
{
public function __construct(
private string|null $title = null,
private string|null $version = null,
) {
/** @var array<string, string> */
private array $inventories = [];
private string $title = '';
private string $version = '';

/** @param array<string, string|array<string, string>> $settingsArray */
public function __construct(array $settingsArray)
{
$this->title = isset($settingsArray['title']) && is_string($settingsArray['title']) ? $settingsArray['title'] : '';
$this->version = isset($settingsArray['version']) && is_string($settingsArray['version']) ? $settingsArray['version'] : '';
$this->inventories = isset($settingsArray['inventories']) && is_array($settingsArray['inventories']) ? $settingsArray['inventories'] : [];
}

public function getTitle(): string|null
public function getTitle(): string
{
return $this->title;
}

public function getVersion(): string|null
public function getVersion(): string
{
return $this->version;
}

/** @return array<string, string> */
public function getInventories(): array
{
return $this->inventories;
}
}
Loading