Skip to content

Commit e052c25

Browse files
committed
[Toolkit] Big refactoring about the registry & kits system, kits architecture, and value-objects
- The registry system and JSON serialization were fully reworked, no more useless compilation to JSON - Rename "default" theme to "shadcn" - The "theme" term is now known as "kit" useless JSON serialization - Abuse ValueObjects usage for File, Example, Dependency, ... - Add binary for vendors
1 parent a45fb12 commit e052c25

File tree

183 files changed

+3521
-3039
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

183 files changed

+3521
-3039
lines changed

.github/workflows/test.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ jobs:
9090
php-version: '8.1'
9191
- component: Map/src/Bridge/Leaflet # does not support PHP 8.1
9292
php-version: '8.1'
93+
- component: Toolkit # does not support PHP 8.1
94+
php-version: '8.1'
9395
- component: Swup # has no tests
9496
- component: Turbo # has its own workflow (test-turbo.yml)
9597
- component: Typed # has no tests

biome.json

+1-8
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,7 @@
1515
"src/*/src/Bridge/*/assets/src/**",
1616
"src/*/src/Bridge/*/assets/test/**"
1717
],
18-
"ignore": [
19-
"**/composer.json",
20-
"**/vendor",
21-
"**/package.json",
22-
"**/node_modules",
23-
"**/var",
24-
"**/registry/default/**"
25-
]
18+
"ignore": ["**/composer.json", "**/vendor", "**/package.json", "**/node_modules", "**/var"]
2619
},
2720
"linter": {
2821
"rules": {

src/Toolkit/Makefile

-6
This file was deleted.

src/Toolkit/bin/build-registry.php

-19
This file was deleted.

src/Toolkit/bin/ux-toolkit-kit-create

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
/*
5+
* This file is part of the Symfony package.
6+
*
7+
* (c) Fabien Potencier <[email protected]>
8+
*
9+
* For the full copyright and license information, please view the LICENSE
10+
* file that was distributed with this source code.
11+
*/
12+
13+
if ('cli' !== \PHP_SAPI) {
14+
throw new Exception('This script must be run from the command line.');
15+
}
16+
17+
use Symfony\Component\Console\Application;
18+
use Symfony\Component\Filesystem\Filesystem;
19+
use Symfony\UX\Toolkit\Command\CreateKitCommand;
20+
21+
function includeIfExists(string $file): bool
22+
{
23+
return file_exists($file) && include $file;
24+
}
25+
26+
if (
27+
!includeIfExists(__DIR__ . '/../../../autoload.php') &&
28+
!includeIfExists(__DIR__ . '/../vendor/autoload.php')
29+
) {
30+
fwrite(STDERR, 'Install dependencies using Composer.'.PHP_EOL);
31+
exit(1);
32+
}
33+
34+
if (!class_exists(Application::class)) {
35+
fwrite(STDERR, 'You need the "symfony/console" component in order to run the UX Toolkit kit linter.'.PHP_EOL);
36+
exit(1);
37+
}
38+
39+
$filesystem = new Filesystem();
40+
41+
(new Application())->add($command = new CreateKitCommand($filesystem))
42+
->getApplication()
43+
->setDefaultCommand($command->getName(), true)
44+
->run()
45+
;

src/Toolkit/bin/ux-toolkit-kit-debug

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
/*
5+
* This file is part of the Symfony package.
6+
*
7+
* (c) Fabien Potencier <[email protected]>
8+
*
9+
* For the full copyright and license information, please view the LICENSE
10+
* file that was distributed with this source code.
11+
*/
12+
13+
if ('cli' !== \PHP_SAPI) {
14+
throw new Exception('This script must be run from the command line.');
15+
}
16+
17+
use Symfony\Component\Console\Application;
18+
use Symfony\Component\Filesystem\Filesystem;
19+
use Symfony\Component\HttpClient\HttpClient;
20+
use Symfony\Contracts\Service\ServiceLocatorTrait;
21+
use Symfony\Contracts\Service\ServiceProviderInterface;
22+
use Symfony\UX\Toolkit\Command\DebugKitCommand;
23+
use Symfony\UX\Toolkit\Dependency\DependenciesResolver;
24+
use Symfony\UX\Toolkit\Kit\KitFactory;
25+
use Symfony\UX\Toolkit\Registry\GitHubRegistry;
26+
use Symfony\UX\Toolkit\Registry\LocalRegistry;
27+
use Symfony\UX\Toolkit\Registry\RegistryFactory;
28+
use Symfony\UX\Toolkit\Registry\Type;
29+
30+
function includeIfExists(string $file): bool
31+
{
32+
return file_exists($file) && include $file;
33+
}
34+
35+
if (
36+
!includeIfExists(__DIR__ . '/../../../autoload.php') &&
37+
!includeIfExists(__DIR__ . '/../vendor/autoload.php')
38+
) {
39+
fwrite(STDERR, 'Install dependencies using Composer.'.PHP_EOL);
40+
exit(1);
41+
}
42+
43+
if (!class_exists(Application::class)) {
44+
fwrite(STDERR, 'You need the "symfony/console" component in order to run the UX Toolkit kit linter.'.PHP_EOL);
45+
exit(1);
46+
}
47+
48+
$filesystem = new Filesystem();
49+
$kitFactory = new KitFactory($filesystem, new DependenciesResolver($filesystem));
50+
$registryFactory = new RegistryFactory(new class([
51+
Type::Local->value => fn () => new LocalRegistry($kitFactory, $filesystem, getcwd() ?? throw new \RuntimeException('The current working directory could not be determined.')),
52+
Type::GitHub->value => fn () => new GitHubRegistry($kitFactory, $filesystem, class_exists(HttpClient::class) ? HttpClient::create() : null),
53+
]) implements ServiceProviderInterface {
54+
use ServiceLocatorTrait;
55+
});
56+
57+
(new Application())->add($command = new DebugKitCommand($registryFactory))
58+
->getApplication()
59+
->setDefaultCommand($command->getName(), true)
60+
->run()
61+
;

src/Toolkit/bin/ux-toolkit-kit-lint

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
/*
5+
* This file is part of the Symfony package.
6+
*
7+
* (c) Fabien Potencier <[email protected]>
8+
*
9+
* For the full copyright and license information, please view the LICENSE
10+
* file that was distributed with this source code.
11+
*/
12+
13+
if ('cli' !== \PHP_SAPI) {
14+
throw new Exception('This script must be run from the command line.');
15+
}
16+
17+
use Symfony\Component\Console\Application;
18+
use Symfony\Component\Filesystem\Filesystem;
19+
use Symfony\Component\HttpClient\HttpClient;
20+
use Symfony\Contracts\Service\ServiceLocatorTrait;
21+
use Symfony\Contracts\Service\ServiceProviderInterface;
22+
use Symfony\UX\Toolkit\Command\LintKitCommand;
23+
use Symfony\UX\Toolkit\Dependency\DependenciesResolver;
24+
use Symfony\UX\Toolkit\Kit\KitFactory;
25+
use Symfony\UX\Toolkit\Registry\GitHubRegistry;
26+
use Symfony\UX\Toolkit\Registry\LocalRegistry;
27+
use Symfony\UX\Toolkit\Registry\RegistryFactory;
28+
use Symfony\UX\Toolkit\Registry\Type;
29+
30+
function includeIfExists(string $file): bool
31+
{
32+
return file_exists($file) && include $file;
33+
}
34+
35+
if (
36+
!includeIfExists(__DIR__ . '/../../../autoload.php') &&
37+
!includeIfExists(__DIR__ . '/../vendor/autoload.php')
38+
) {
39+
fwrite(STDERR, 'Install dependencies using Composer.'.PHP_EOL);
40+
exit(1);
41+
}
42+
43+
if (!class_exists(Application::class)) {
44+
fwrite(STDERR, 'You need the "symfony/console" component in order to run the UX Toolkit kit linter.'.PHP_EOL);
45+
exit(1);
46+
}
47+
48+
$filesystem = new Filesystem();
49+
$kitFactory = new KitFactory($filesystem, new DependenciesResolver($filesystem));
50+
$registryFactory = new RegistryFactory(new class([
51+
Type::Local->value => fn () => new LocalRegistry($kitFactory, $filesystem, getcwd() ?? throw new \RuntimeException('The current working directory could not be determined.')),
52+
Type::GitHub->value => fn () => new GitHubRegistry($kitFactory, $filesystem, class_exists(HttpClient::class) ? HttpClient::create() : null),
53+
]) implements ServiceProviderInterface {
54+
use ServiceLocatorTrait;
55+
});
56+
57+
(new Application())->add($command = new LintKitCommand($registryFactory))
58+
->getApplication()
59+
->setDefaultCommand($command->getName(), true)
60+
->run()
61+
;

src/Toolkit/composer.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@
3131
"php": ">=8.3",
3232
"twig/twig": "^2.12|^3.0",
3333
"symfony/console": "^6.4|^7.0",
34+
"symfony/filesystem": "^6.4|^7.0",
3435
"symfony/framework-bundle": "^6.4|^7.0",
3536
"symfony/twig-bundle": "^6.4|^7.0",
3637
"symfony/ux-twig-component": "^2.23",
37-
"symfony/filesystem": "^6.4|^7.0"
38+
"symfony/yaml": "^6.4|^7.0"
3839
},
3940
"require-dev": {
4041
"symfony/finder": "6.4|^7.0",
@@ -46,6 +47,11 @@
4647
"symfony/stopwatch": "^6.4|^7.0",
4748
"symfony/phpunit-bridge": "^6.4|^7.0"
4849
},
50+
"bin": [
51+
"bin/ux-toolkit-kit-create",
52+
"bin/ux-toolkit-kit-lint",
53+
"bin/ux-toolkit-kit-debug"
54+
],
4955
"autoload": {
5056
"psr-4": {
5157
"Symfony\\UX\\Toolkit\\": "src"

src/Toolkit/config/services.php

+64-47
Original file line numberDiff line numberDiff line change
@@ -11,86 +11,103 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
1313

14+
use Symfony\UX\Toolkit\Command\DebugKitCommand;
15+
use Symfony\UX\Toolkit\Command\InstallComponentCommand;
16+
use Symfony\UX\Toolkit\Command\InstallKitCommand;
17+
use Symfony\UX\Toolkit\Command\LintKitCommand;
18+
use Symfony\UX\Toolkit\Component\ComponentInstaller;
19+
use Symfony\UX\Toolkit\Dependency\DependenciesResolver;
20+
use Symfony\UX\Toolkit\Kit\KitFactory;
21+
use Symfony\UX\Toolkit\Registry\GitHubRegistry;
22+
use Symfony\UX\Toolkit\Registry\LocalRegistry;
23+
use Symfony\UX\Toolkit\Registry\RegistryFactory;
24+
use Symfony\UX\Toolkit\Registry\Type;
25+
1426
/*
1527
* @author Hugo Alliaume <[email protected]>
1628
*/
17-
18-
use Symfony\UX\Toolkit\Command\BuildRegistryCommand;
19-
use Symfony\UX\Toolkit\Command\DebugUxToolkitCommand;
20-
use Symfony\UX\Toolkit\Command\UxToolkitInstallCommand;
21-
use Symfony\UX\Toolkit\Compiler\RegistryCompiler;
22-
use Symfony\UX\Toolkit\Compiler\TwigComponentCompiler;
23-
use Symfony\UX\Toolkit\ComponentRepository\CurrentTheme;
24-
use Symfony\UX\Toolkit\ComponentRepository\GithubRepository;
25-
use Symfony\UX\Toolkit\ComponentRepository\OfficialRepository;
26-
use Symfony\UX\Toolkit\ComponentRepository\RepositoryFactory;
27-
use Symfony\UX\Toolkit\ComponentRepository\RepositoryIdentifier;
28-
use Symfony\UX\Toolkit\Registry\DependenciesResolver;
29-
use Symfony\UX\Toolkit\Registry\RegistryFactory;
30-
3129
return static function (ContainerConfigurator $container): void {
3230
$container->services()
33-
->set('.ux_toolkit.compiler.registry_compiler', RegistryCompiler::class)
31+
// Commands
32+
33+
->set('.ux_toolkit.command.debug_kit', DebugKitCommand::class)
3434
->args([
35-
service('filesystem')
35+
service('.ux_toolkit.registry.factory'),
3636
])
37+
->tag('console.command')
3738

38-
->set('.ux_toolkit.compiler.twig_component_compiler', TwigComponentCompiler::class)
39+
->set('.ux_toolkit.command.install', InstallComponentCommand::class)
3940
->args([
40-
param('ux_toolkit.prefix'),
41-
service('.ux_toolkit.registry.dependencies_resolver'),
42-
service('filesystem'),
41+
param('ux_toolkit.kit'),
42+
service('.ux_toolkit.registry.factory'),
43+
service('.ux_toolkit.component.component_installer'),
4344
])
45+
->tag('console.command')
4446

45-
->set('.ux_toolkit.component_repository.official_repository', OfficialRepository::class)
47+
->set('.ux_toolkit.command.install_kit', InstallKitCommand::class)
4648
->args([
47-
service('filesystem')
49+
param('ux_toolkit.kit'),
50+
service('.ux_toolkit.registry.factory'),
51+
service('.ux_toolkit.component.component_installer'),
4852
])
53+
->tag('console.command')
4954

50-
->set('.ux_toolkit.component_repository.github_repository', GithubRepository::class)
55+
->set('.ux_toolkit.command.lint_kit', LintKitCommand::class)
5156
->args([
52-
service('filesystem'),
53-
service('http_client')->nullOnInvalid(),
57+
service('.ux_toolkit.registry.factory'),
5458
])
59+
->tag('console.command')
60+
61+
// Registry
5562

56-
->set('.ux_toolkit.component_repository.repository_factory', RepositoryFactory::class)
63+
->set('.ux_toolkit.registry.factory', RegistryFactory::class)
5764
->args([
58-
service('.ux_toolkit.component_repository.official_repository'),
59-
service('.ux_toolkit.component_repository.github_repository'),
65+
service_locator([
66+
Type::Local->value => service('.ux_toolkit.registry.local'),
67+
Type::GitHub->value => service('.ux_toolkit.registry.github'),
68+
]),
6069
])
6170

62-
->set('.ux_toolkit.component_repository.current_theme', CurrentTheme::class)
71+
->set('.ux_toolkit.registry.local', LocalRegistry::class)
6372
->args([
64-
param('ux_toolkit.theme'),
65-
service('.ux_toolkit.component_repository.repository_factory'),
66-
service('.ux_toolkit.component_repository.repository_identifier'),
73+
service('.ux_toolkit.kit.kit_factory'),
74+
service('filesystem'),
75+
param('kernel.project_dir'),
6776
])
6877

69-
->set('.ux_toolkit.component_repository.repository_identifier', RepositoryIdentifier::class)
78+
->set('.ux_toolkit.registry.github', GitHubRegistry::class)
79+
->args([
80+
service('.ux_toolkit.kit.kit_factory'),
81+
service('filesystem'),
82+
service('http_client')->nullOnInvalid(),
83+
])
7084

71-
->set('.ux_toolkit.registry.dependencies_resolver', DependenciesResolver::class)
85+
// Kit
7286

73-
->set('.ux_toolkit.registry.registry_factory', RegistryFactory::class)
87+
->set('.ux_toolkit.kit.factory', KitFactory::class)
88+
->args([
89+
service('filesystem'),
90+
service('.ux_toolkit.dependency.dependencies_resolver'),
91+
])
7492

75-
->set('.ux_toolkit.command.build_registry', BuildRegistryCommand::class)
93+
->set('.ux_toolkit.kit.kit_factory', KitFactory::class)
7694
->args([
77-
service('.ux_toolkit.compiler.registry_compiler')
95+
service('filesystem'),
96+
service('.ux_toolkit.dependency.dependencies_resolver'),
7897
])
79-
->tag('console.command')
8098

81-
->set('.ux_toolkit.command.install', UxToolkitInstallCommand::class)
99+
// Component
100+
->set('.ux_toolkit.component.component_installer', ComponentInstaller::class)
82101
->args([
83-
service('.ux_toolkit.component_repository.current_theme'),
84-
service('.ux_toolkit.registry.registry_factory'),
85-
service('.ux_toolkit.compiler.twig_component_compiler'),
102+
service('filesystem'),
86103
])
87-
->tag('console.command')
88104

89-
->set('.ux_toolkit.command.debug', DebugUxToolkitCommand::class)
105+
// Dependency
106+
107+
->set('.ux_toolkit.dependency.dependencies_resolver', DependenciesResolver::class)
90108
->args([
91-
service('.ux_toolkit.component_repository.current_theme'),
92-
service('.ux_toolkit.registry.registry_factory'),
109+
service('filesystem'),
93110
])
94-
->tag('console.command')
111+
95112
;
96113
};

0 commit comments

Comments
 (0)