Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2c3b6f1
wip
jygaulier Jun 25, 2025
af41bc5
wip
jygaulier Jun 27, 2025
1bbba71
wip
jygaulier Jul 2, 2025
d195a25
wip
jygaulier Jul 2, 2025
cb1ce74
fix
jygaulier Jul 2, 2025
2c17f36
auto-find documentation generators ; output to stdout or file
jygaulier Jul 3, 2025
b353a8a
Merge branch 'master' into PS-906_initial-values-tests
jygaulier Jul 3, 2025
f7bb49b
Merge branch 'PS-906_initial-values-tests' of github.com:alchemy-fr/p…
jygaulier Jul 3, 2025
eb88c0f
cs
jygaulier Jul 3, 2025
f2cbf61
add multi-chapters (recursive), with numbered levels
jygaulier Jul 7, 2025
7b0b9a5
add tests and allow empty metadata in tests
jygaulier Jul 7, 2025
fbbc695
Merge branch 'master' into PS-906_initial-values-tests
jygaulier Jul 17, 2025
b0b6e4e
move test data provider to src (because used to generate doc) ; add f…
jygaulier Jul 17, 2025
c46925c
remove app:documentation:dump options
jygaulier Jul 17, 2025
baf4542
add generated doc to git
jygaulier Jul 17, 2025
377b7b9
apply review
jygaulier Jul 22, 2025
a3fd199
wip
jygaulier Jun 25, 2025
c28b48b
wip
jygaulier Jun 27, 2025
b3067d0
wip
jygaulier Jul 2, 2025
759807a
wip
jygaulier Jul 2, 2025
8b88685
fix
jygaulier Jul 2, 2025
1223044
auto-find documentation generators ; output to stdout or file
jygaulier Jul 3, 2025
bb40530
cs
jygaulier Jul 3, 2025
c933e4a
add multi-chapters (recursive), with numbered levels
jygaulier Jul 7, 2025
3dc8aae
add tests and allow empty metadata in tests
jygaulier Jul 7, 2025
bf785bc
move test data provider to src (because used to generate doc) ; add f…
jygaulier Jul 17, 2025
5869216
remove app:documentation:dump options
jygaulier Jul 17, 2025
68a4229
add generated doc to git
jygaulier Jul 17, 2025
7269658
apply review
jygaulier Jul 22, 2025
c87d32d
remove generated doc
jygaulier Jul 28, 2025
12bd7f4
generates databox-api schema (json)
jygaulier Jul 28, 2025
44147cb
Merge branch 'master' into PS-906_initial-values-tests
jygaulier Jul 28, 2025
39101c1
Merge branch 'PS-906_initial-values-tests' of github.com:alchemy-fr/p…
jygaulier Jul 28, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
use App\Entity\Core\AttributeDefinition;
use App\File\FileMetadataAccessorWrapper;
use App\Repository\Core\AttributeDefinitionRepository;
use Doctrine\ORM\EntityManagerInterface;
use Twig\Environment;
use Twig\Loader\ArrayLoader;

Expand All @@ -21,7 +20,7 @@ class InitialAttributeValuesResolver
private readonly Environment $twig;

public function __construct(
private readonly EntityManagerInterface $em,
private readonly AttributeDefinitionRepository $attributeDefinitionRepository,
private readonly AttributeAssigner $attributeAssigner,
) {
$this->twig = new Environment(new ArrayLoader(), [
Expand All @@ -36,10 +35,7 @@ public function resolveInitialAttributes(Asset $asset): array
{
$attributes = [];

/** @var AttributeDefinitionRepository $repo */
$repo = $this->em->getRepository(AttributeDefinition::class);

$definitions = $repo->getWorkspaceInitializeDefinitions($asset->getWorkspaceId());
$definitions = $this->attributeDefinitionRepository->getWorkspaceInitializeDefinitions($asset->getWorkspaceId());
$fileMetadataAccessorWrapper = new FileMetadataAccessorWrapper($asset->getSource());

foreach ($definitions as $definition) {
Expand Down
95 changes: 91 additions & 4 deletions databox/api/src/Command/DocumentationDumperCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,113 @@

namespace App\Command;

use Alchemy\RenditionFactory\RenditionBuilderConfigurationDocumentation;
use App\Documentation\DocumentationGeneratorInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\Attribute\AutowireIterator;

#[AsCommand('app:documentation:dump')]
class DocumentationDumperCommand extends Command
{
/** @var array<string, DocumentationGeneratorInterface> */
private array $chapters = [];

public function __construct(
private readonly RenditionBuilderConfigurationDocumentation $renditionBuilderConfigurationDocumentation,
#[AutowireIterator(DocumentationGeneratorInterface::TAG)] private readonly iterable $documentations,
) {
parent::__construct();
}

protected function configure(): void
{
parent::configure();

/** @var DocumentationGeneratorInterface $documentation */
foreach ($this->documentations as $documentation) {
$k = $documentation->getPath();
if (isset($this->chapters[$k])) {
throw new \LogicException(sprintf('Chapter "%s" is already registered.', $k));
}
$this->chapters[$k] = $documentation;
}

$this
->setDescription('Dump code-generated documentation(s)')
->setHelp(sprintf('chapters: <info>%s</info>', join('</info> ; <info>', array_keys($this->chapters))))
;
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln('# '.$this->renditionBuilderConfigurationDocumentation::getName());
$output->writeln($this->renditionBuilderConfigurationDocumentation->generate());
foreach ($this->chapters as $chapter) {
$title = $chapter->getTitle() ?? $chapter->getPath();
$pathParts = pathinfo($chapter->getPath());

$outputDir = '../../doc/'.$pathParts['dirname'];
$filename = $pathParts['filename'];
$extension = $pathParts['extension'] ?? 'md';
if (!in_array($extension, ['md', 'xml', 'json'], true)) {
$output->writeln(sprintf('<error>Chapter "%s" must have a [md | xml | json] extension, found "%s".</error>', $title, $extension));
continue;
}

@mkdir($outputDir, 0777, true);
$outputFile = $outputDir.'/'.$filename.'.'.$extension;

file_put_contents($outputFile, $this->getAsText($chapter, $extension));
$output->writeln(sprintf('<info>Documentation for chapter "%s" written to "%s".</info>', $title, $outputFile));
}

return Command::SUCCESS;
}

private function getAsText(DocumentationGeneratorInterface $chapter, string $extension, array $levels = []): string
{
$chapter->setLevels($levels);

$title = str_replace("'", "''", $chapter->getTitle() ?? $chapter->getPath()); // Escape single quotes for YAML frontmatter
if (!empty($levels)) {
$title = join('.', $levels).': '.$title;
}

$text = '';
switch ($extension) {
case 'md':
$text = "---\n"
."title: '".$title."'\n"
."comment: 'Generated by the DocumentationDumperCommand, do not modify'\n"
."---\n\n";
break;
case 'xml':
$text = "<!--\n"
."title: '".$title."'\n"
."comment: 'Generated by the DocumentationDumperCommand, do not modify'\n"
."-->\n\n";
break;
}

if (null !== ($t = $chapter->getHeader())) {
$text .= $t."\n";
}
if (null !== ($t = $chapter->getContent())) {
$text .= $t."\n";
}

$n = 1;
foreach ($chapter->getChildren() as $child) {
$subLevels = $levels;
if (!empty($subLevels)) {
$subLevels[] = $n++;
}
$text .= $this->getAsText($child, $extension, $subLevels);
}

if (null !== ($t = $chapter->getFooter())) {
$text .= $t."\n";
}

return $text;
}
}
42 changes: 42 additions & 0 deletions databox/api/src/Documentation/ApiDocumentationGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace App\Documentation;

use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\HttpKernel\KernelInterface;

class ApiDocumentationGenerator extends DocumentationGenerator
{
private Application $application;

public function __construct(KernelInterface $kernel)
{
$this->application = new Application($kernel);
$this->application->setAutoExit(false);
}

public function getPath(): string
{
return 'Databox/Api/schema.json';
}

public function getTitle(): string
{
return 'Api Schema';
}

public function getContent(): string
{
$input = new ArrayInput([
'command' => 'api:openapi:export',
]);
$output = new BufferedOutput();
$this->application->run($input, $output);

return $output->fetch();
}
}
41 changes: 41 additions & 0 deletions databox/api/src/Documentation/DocumentationGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace App\Documentation;

abstract class DocumentationGenerator implements DocumentationGeneratorInterface
{
private array $levels = [];

final public function setLevels(array $levels): void
{
$this->levels = $levels;
}

final public function getLevels(): array
{
return $this->levels;
}

public function getHeader(): ?string
{
return null;
}

public function getContent(): ?string
{
return null;
}

public function getFooter(): ?string
{
return null;
}

/** DocumentationGeneratorInterface[] */
public function getChildren(): array
{
return [];
}
}
28 changes: 28 additions & 0 deletions databox/api/src/Documentation/DocumentationGeneratorInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace App\Documentation;

use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;

#[AutoconfigureTag(DocumentationGeneratorInterface::TAG)]
interface DocumentationGeneratorInterface
{
final public const string TAG = 'documentation_generator';

public function getPath(): string;

public function setLevels(array $levels): void;

public function getLevels(): array;

public function getHeader(): ?string;

public function getContent(): ?string;

public function getFooter(): ?string;

/** DocumentationGeneratorInterface[] */
public function getChildren(): array;
}
Loading
Loading