Skip to content

Commit

Permalink
Commands install component and its dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
Halleck45 committed Feb 2, 2025
1 parent c3f82c0 commit d404ff5
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 15 deletions.
4 changes: 2 additions & 2 deletions src/Toolkit/src/Command/UxToolkitInstallCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$destination = $input->getOption('destination');
try {
$io->info(\sprintf('Installing component "%s"...', $component->name));
$this->compiler->compile($component, $destination);
$this->compiler->compile($registry, $component, $destination);
} catch (TwigComponentAlreadyExist $e) {
if (!$input->isInteractive()) {
$io->error(\sprintf('The component "%s" already exists.', $component->name));
Expand All @@ -97,7 +97,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}

// again
$this->compiler->compile($component, $destination);
$this->compiler->compile($registry, $component, $destination);
}

$io->success(\sprintf('The component "%s" has been installed.', $component->name));
Expand Down
17 changes: 16 additions & 1 deletion src/Toolkit/src/Compiler/TwigComponentCompiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,45 @@

use Symfony\Component\Filesystem\Filesystem;
use Symfony\UX\Toolkit\Compiler\Exception\TwigComponentAlreadyExist;
use Symfony\UX\Toolkit\Registry\DependenciesResolver;
use Symfony\UX\Toolkit\Registry\Registry;
use Symfony\UX\Toolkit\Registry\RegistryItem;

/**
* @author Jean-François Lépine
*
* @internal
*/
class TwigComponentCompiler
final class TwigComponentCompiler
{
public function __construct(
private readonly ?string $prefix,
private readonly DependenciesResolver $dependenciesResolver,
) {
}

public function compile(
Registry $registry,
RegistryItem $item,
string $directory,
): void {
// resolve dependencies (avoid circular dependencies)
$this->dependenciesResolver->resolve($registry);

$filesystem = new Filesystem();
if (!$filesystem->exists($directory)) {
$filesystem->mkdir($directory);
}

$componentsToInstall = array_merge([$item->name], $item->getDependencies());

foreach ($componentsToInstall as $componentName) {
$this->installComponent($registry->get($componentName), $directory, $filesystem);
}
}

private function installComponent(RegistryItem $item, string $directory, Filesystem $filesystem)
{
$filename = implode(\DIRECTORY_SEPARATOR, [
$directory,
$this->prefix,
Expand Down
6 changes: 1 addition & 5 deletions src/Toolkit/src/Registry/DependenciesResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,8 @@ public function resolve(Registry $registry): array
private function resolveDependency(Registry $registry, string $itemName, array $resolved, array $unresolved)
{
$unresolved[] = $itemName;
$dependencies = [];
if (null !== $registry->get($itemName)->parentName) {
$dependencies[] = $registry->get($itemName)->parentName;
}

foreach ($dependencies as $dep) {
foreach ($registry->get($itemName)->getDependencies() as $dep) {
if (!\in_array($dep, $resolved)) {
if (!\in_array($dep, $unresolved)) {
$unresolved[] = $dep;
Expand Down
10 changes: 10 additions & 0 deletions src/Toolkit/src/Registry/RegistryItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,14 @@ public static function fromFile(SplFileInfo $file): self
// $file->getContents(),
// );
}

public function getDependencies(): array
{
$dependencies = [];
if (null !== $this->parentName) {
$dependencies[] = $this->parentName;
}

return $dependencies;
}
}
2 changes: 2 additions & 0 deletions src/Toolkit/src/UxToolkitBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use Symfony\UX\Toolkit\ComponentRepository\RepositoryFactory;
use Symfony\UX\Toolkit\ComponentRepository\RepositoryIdentifier;
use Symfony\UX\Toolkit\DependencyInjection\ToolkitExtension;
use Symfony\UX\Toolkit\Registry\DependenciesResolver;
use Symfony\UX\Toolkit\Registry\RegistryFactory;

/**
Expand All @@ -45,6 +46,7 @@ public function build(ContainerBuilder $container): void
$container->autowire(RepositoryFactory::class);
$container->autowire(RepositoryIdentifier::class);
$container->autowire(RegistryFactory::class);
$container->autowire(DependenciesResolver::class);

$container->autowire(TwigComponentCompiler::class);
$container->getDefinition(TwigComponentCompiler::class)
Expand Down
60 changes: 53 additions & 7 deletions src/Toolkit/tests/Compiler/TwigComponentCompilerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\UX\Toolkit\Compiler\Exception\TwigComponentAlreadyExist;
use Symfony\UX\Toolkit\Compiler\TwigComponentCompiler;
use Symfony\UX\Toolkit\ComponentRepository\OfficialRepository;
use Symfony\UX\Toolkit\ComponentRepository\RepositoryIdentity;
use Symfony\UX\Toolkit\Registry\DependenciesResolver;
use Symfony\UX\Toolkit\Registry\Registry;
use Symfony\UX\Toolkit\Registry\RegistryItem;
use Symfony\UX\Toolkit\Registry\RegistryItemType;

Expand All @@ -26,18 +26,20 @@ class TwigComponentCompilerTest extends KernelTestCase
{
public function testItShouldCompileComponentToFile(): void
{
$compiler = new TwigComponentCompiler('Acme');
$compiler = new TwigComponentCompiler('Acme', new DependenciesResolver());
$destination = sys_get_temp_dir().\DIRECTORY_SEPARATOR.uniqid('component_');

$registry = new Registry();
$item = new RegistryItem(
'Badge',
RegistryItemType::Component,
'default',
null,
'<button>foo</button>'
);
$registry->add($item);

$compiler->compile($item, $destination);
$compiler->compile($registry, $item, $destination);

$this->assertFileExists($destination);
$this->assertFileExists($destination.'/Acme/Badge.html.twig');
Expand All @@ -48,20 +50,64 @@ public function testItShouldCompileComponentToFile(): void

public function testShouldThrowExceptionIfFileAlreadyExist(): void
{
$compiler = new TwigComponentCompiler('Acme');
$compiler = new TwigComponentCompiler('Acme', new DependenciesResolver());
$destination = sys_get_temp_dir().\DIRECTORY_SEPARATOR.uniqid('component_');

$registry = new Registry();
$item = new RegistryItem(
'Badge',
RegistryItemType::Component,
'default',
null,
'<button>foo</button>'
);
$registry->add($item);

$compiler->compile($item, $destination);
$compiler->compile($registry, $item, $destination);

$this->expectException(TwigComponentAlreadyExist::class);
$compiler->compile($item, $destination);
$compiler->compile($registry, $item, $destination);
}

public function testDependenciesAreAlsoCompiled(): void
{
$compiler = new TwigComponentCompiler('Acme', new DependenciesResolver());
$destination = sys_get_temp_dir().\DIRECTORY_SEPARATOR.uniqid('component_');

$registry = new Registry();
$registry->add(
new RegistryItem(
'Badge',
RegistryItemType::Component,
'default',
null,
'<button>foo</button>'
)
);
$registry->add(
new RegistryItem(
'Table',
RegistryItemType::Component,
'default',
null,
'<table>foo</table>'
)
);
$registry->add(
new RegistryItem(
'Row',
RegistryItemType::Component,
'default',
'Table',
'<tr>foo</tr>'
)
);

$compiler->compile($registry, $registry->get('Row'), $destination);

$this->assertFileExists($destination);
$this->assertFileExists($destination.'/Acme/Table.html.twig');
$this->assertFileExists($destination.'/Acme/Row.html.twig');
$this->assertFileDoesNotExist($destination.'/Acme/Badge.html.twig');
}
}

0 comments on commit d404ff5

Please sign in to comment.