diff --git a/src/Toolkit/.phpunit.cache/test-results b/src/Toolkit/.phpunit.cache/test-results deleted file mode 100644 index 961ffa9787..0000000000 --- a/src/Toolkit/.phpunit.cache/test-results +++ /dev/null @@ -1 +0,0 @@ -{"version":1,"defects":{"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\RepositoryFactoryTest::testItShouldFailWhenComponentDoesNotExist":7,"Symfony\\Ux\\Toolkit\\Tests\\Command\\UxToolkitInstallCommandTest::testShouldAbleToCreateTheBadgeComponent":8,"Symfony\\Ux\\Toolkit\\Tests\\Command\\UxToolkitInstallCommandTest::testByDefaultCannotEraseComponentByMistake":8,"Symfony\\Ux\\Toolkit\\Tests\\Component\\BadgeTest::testDefaultRenderingIsPossible":8,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\RepositoryFactoryTest::testItShouldFactoryRepositoryAccordingToItsName":8,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\RepositoryFactoryTest::testItShouldFactoryRepositoryAccordingToItsName#2":7,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\ComponentIdentifierTest::testItShouldIdentifyGithubComponent":8,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\ComponentIdentifierTest::testItShouldIdentifyGithubComponentWithVersion":8,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\ComponentIdentifierTest::testItShouldIdentifyOfficialComponent":7,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\OfficialRepositoryTest::testOfficialRepositoryGetContentOfExistentComponent":7,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\OfficialRepositoryTest::testOfficialRepositoryGetContentOfNonExistentComponent":8,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\OfficialRepositoryTest::testOfficialRepositoryFailWhenComponentDoesNotExist":7},"times":{"Symfony\\Ux\\Toolkit\\Tests\\Command\\UxToolkitInstallCommandTest::testShouldAbleToCreateTheBadgeComponent":0.016,"Symfony\\Ux\\Toolkit\\Tests\\Command\\UxToolkitInstallCommandTest::testByDefaultCannotEraseComponentByMistake":0.002,"Symfony\\Ux\\Toolkit\\Tests\\Component\\BadgeTest::testDefaultRenderingIsPossible":0.036,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\RepositoryFactoryTest::testItShouldFactoryRepositoryAccordingToItsName":0.016,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\RepositoryFactoryTest::testItShouldFailWhenRepositoryIsNotSupported":0,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\RepositoryFactoryTest::testItShouldFailWhenComponentDoesNotExist":0.01,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\RepositoryFactoryTest::testItShouldFactoryRepositoryAccordingToItsName#0":0.001,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\RepositoryFactoryTest::testItShouldFactoryRepositoryAccordingToItsName#1":0,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\RepositoryFactoryTest::testItShouldFactoryRepositoryAccordingToItsName#2":0,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\RepositoryFactoryTest::testItShouldFactoryRepositoryAccordingToItsName#3":0,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\ComponentIdentifierTest::testItShouldIdentifiyOfficialComponent":0.002,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\ComponentIdentifierTest::testItShouldIdentifyOfficialComponent":0,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\ComponentIdentifierTest::testItShouldIdentifyGithubComponent":0,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\ComponentIdentifierTest::testItShouldIdentifiyGithubComponentEventWithoutScheme":0,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\ComponentIdentifierTest::testItShouldIdentifyGithubComponentWithVersion":0,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\OfficialRepositoryTest::testOfficialRepositoryGetContentOfExistentComponent":0,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\OfficialRepositoryTest::testOfficialRepositoryGetContentOfNonExistentComponent":0.002,"Symfony\\Ux\\Toolkit\\Tests\\ComponentRepository\\OfficialRepositoryTest::testOfficialRepositoryFailWhenComponentDoesNotExist":0.011}} \ No newline at end of file diff --git a/src/Toolkit/composer.json b/src/Toolkit/composer.json index 3a95d51bd0..073a3b4682 100644 --- a/src/Toolkit/composer.json +++ b/src/Toolkit/composer.json @@ -58,5 +58,8 @@ "name": "symfony/ux", "url": "https://github.com/symfony/ux" } + }, + "require-dev": { + "symfony/http-client": "6.4|^7.0" } } diff --git a/src/Toolkit/composer.lock b/src/Toolkit/composer.lock index ed6fd21a0a..d300d95053 100644 --- a/src/Toolkit/composer.lock +++ b/src/Toolkit/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c2568dddd4d88908cb27985a17efa397", + "content-hash": "5f6bb03f6153b3bd376aefec36bb7b5f", "packages": [ { "name": "gehrisandro/tailwind-merge-php", @@ -3516,15 +3516,189 @@ "time": "2025-01-29T07:06:14+00:00" } ], - "packages-dev": [], + "packages-dev": [ + { + "name": "symfony/http-client", + "version": "v7.2.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "7ce6078c79a4a7afff931c413d2959d3bffbfb8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/7ce6078c79a4a7afff931c413d2959d3bffbfb8d", + "reference": "7ce6078c79a4a7afff931c413d2959d3bffbfb8d", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-client-contracts": "~3.4.4|^3.5.2", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "amphp/amp": "<2.5", + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.4" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/http-client": "^4.2.1|^5.0", + "amphp/http-tunnel": "^1.0|^2.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4|^2.0", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/amphp-http-client-meta": "^1.0|^2.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v7.2.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-01-28T15:51:35+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.5.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ee8d807ab20fcb51267fdace50fbe3494c31e645", + "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-07T08:49:48+00:00" + } + ], "aliases": [], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { "php": ">=8.2" }, - "platform-dev": {}, + "platform-dev": [], "plugin-api-version": "2.6.0" } diff --git a/src/Toolkit/src/ComponentRepository/GithubRepository.php b/src/Toolkit/src/ComponentRepository/GithubRepository.php index 9fcde3e03b..7460677358 100644 --- a/src/Toolkit/src/ComponentRepository/GithubRepository.php +++ b/src/Toolkit/src/ComponentRepository/GithubRepository.php @@ -11,6 +11,9 @@ namespace Symfony\Ux\Toolkit\ComponentRepository; +use Symfony\Component\HttpClient\HttpClient; +use Symfony\Contracts\HttpClient\HttpClientInterface; + /** * @author Jean-François Lépine * @@ -18,6 +21,14 @@ */ class GithubRepository implements ComponentRepository { + public function __construct( + private readonly ?HttpClientInterface $httpClient = null, + ) { + if (!class_exists(HttpClient::class)) { + throw new \LogicException('You must install "symfony/http-client" to use ux-toolkit with remote component. Try running "composer require symfony/http-client".'); + } + } + public function getContent(ComponentIdentity $component): string { $url = \sprintf( @@ -28,6 +39,8 @@ public function getContent(ComponentIdentity $component): string $component->getName() ); - return file_get_contents($url); + $response = $this->httpClient->request('GET', $url); + + return $response->getContent(); } } diff --git a/src/Toolkit/src/UxToolkitBundle.php b/src/Toolkit/src/UxToolkitBundle.php index 233d0e10c2..4874ef093c 100644 --- a/src/Toolkit/src/UxToolkitBundle.php +++ b/src/Toolkit/src/UxToolkitBundle.php @@ -25,7 +25,6 @@ */ class UxToolkitBundle extends AbstractBundle { - public function build(ContainerBuilder $container): void { parent::build($container); @@ -35,6 +34,7 @@ public function build(ContainerBuilder $container): void $container->autowire(RepositoryFactory::class); $container->autowire(ComponentIdentifier::class); + // Prepare command $container->autowire(UxToolkitInstallCommand::class); $container ->registerForAutoconfiguration(UxToolkitInstallCommand::class) @@ -45,7 +45,11 @@ public function build(ContainerBuilder $container): void ->setPublic(true) ->addTag('console.command') ; - } + // Inject http client (if exists) to github repository + if($container->has('http_client')) { + $container->getDefinition(GithubRepository::class) + ->setArgument('$httpClient', $container->get('http_client')); + } + } } - diff --git a/src/Toolkit/tests/ComponentRepository/GithubRepositoryTest.php b/src/Toolkit/tests/ComponentRepository/GithubRepositoryTest.php new file mode 100644 index 0000000000..f808ae48c7 --- /dev/null +++ b/src/Toolkit/tests/ComponentRepository/GithubRepositoryTest.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Ux\Toolkit\Tests\ComponentRepository; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\HttpClient\MockHttpClient; +use Symfony\Component\HttpClient\Response\MockResponse; +use Symfony\Ux\Toolkit\ComponentRepository\ComponentIdentity; +use Symfony\Ux\Toolkit\ComponentRepository\GithubRepository; + +/** + * @author Jean-François Lépine + */ +class GithubRepositoryTest extends TestCase +{ + public function testGithubRepositoryUseClientAndTryToDownloadRemoteFile(): void + { + $client = new MockHttpClient(); + $client->setResponseFactory(fn() => new MockResponse('My badge content from github')); + $repository = new GithubRepository($client); + + $component = new ComponentIdentity('Halleck45', 'ux-toolkit', 'Badge', '1.0.0'); + $content = $repository->getContent($component); + + $this->assertEquals('My badge content from github', $content); + } +}