Skip to content

Commit 9bd4ca5

Browse files
smnandreKocal
authored andcommitted
Add changelog / requirement / install .. for every package
1 parent 2e6a24c commit 9bd4ca5

File tree

6 files changed

+307
-5
lines changed

6 files changed

+307
-5
lines changed

ux.symfony.com/src/Controller/ChangelogController.php

+40-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
namespace App\Controller;
1313

1414
use App\Service\Changelog\ChangelogProvider;
15+
use App\Service\Packagist\PackagistDataProvider;
16+
use App\Service\UxPackageRepository;
17+
use App\Twig\Components\ChangelogItem;
18+
use DateTimeImmutable;
1519
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
1620
use Symfony\Component\HttpFoundation\Response;
1721
use Symfony\Component\Routing\Attribute\Route;
@@ -20,7 +24,8 @@ class ChangelogController extends AbstractController
2024
{
2125
public function __construct(
2226
private readonly ChangelogProvider $changeLogProvider,
23-
) {
27+
)
28+
{
2429
}
2530

2631
#[Route('/changelog', name: 'app_changelog')]
@@ -32,4 +37,38 @@ public function __invoke(): Response
3237
'changelog' => $changelog,
3338
]);
3439
}
40+
41+
#[Route('/{package}/changelog', name: 'app_changelog_package')]
42+
public function package(string $package, UxPackageRepository $packageRepository, PackagistDataProvider $packagistData): Response
43+
{
44+
$uxPackage = $packageRepository->find($package);
45+
46+
$packageLog = $this->changeLogProvider->getPackageChangelog('ux-'.$uxPackage->getName());
47+
$packageData = $packagistData->getPackageData($uxPackage->getComposerName());
48+
49+
$firstLine = array_shift($packageLog);
50+
51+
$changelog = [];
52+
foreach ($packageLog as $a) {
53+
$lines = explode("\n", $a);
54+
$version = array_shift($lines);
55+
56+
$versionData = $packageData['versions']['v'.$version] ?? [];
57+
if ([] === $versionData) {
58+
continue;
59+
}
60+
61+
$changelog[] = [
62+
'body' => implode("\n", $lines),
63+
'version' => $version,
64+
'name' => 'v'.$version,
65+
'date' => $versionData['time'] ?? null,
66+
];
67+
}
68+
69+
return $this->render('ux_packages/package_changelog.html.twig', [
70+
'package' => $uxPackage,
71+
'changelog' => $changelog,
72+
]);
73+
}
3574
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace App\Controller;
13+
14+
use App\Service\Changelog\ChangelogProvider;
15+
use App\Service\Packagist\PackagistDataProvider;
16+
use App\Service\UxPackageRepository;
17+
use App\Twig\Components\ChangelogItem;
18+
use DateTimeImmutable;
19+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
20+
use Symfony\Component\HttpFoundation\Response;
21+
use Symfony\Component\Routing\Attribute\Route;
22+
23+
#[Route('/{package}', name: 'app_package')]
24+
class UxPackageController extends AbstractController
25+
{
26+
public function __construct(
27+
private readonly UxPackageRepository $packageRepository,
28+
private readonly ChangelogProvider $changeLogProvider,
29+
private readonly PackagistDataProvider $packagistData,
30+
)
31+
{
32+
}
33+
34+
#[Route('/changelog', name: 'app_package_changelog')]
35+
public function changelog(string $package): Response
36+
{
37+
$uxPackage = $this->packageRepository->find($package) ?? throw $this->createNotFoundException(sprintf('Package "%s" not found', $package));
38+
39+
$packageLog = $this->changeLogProvider->getPackageChangelog('ux-'.$uxPackage->getName());
40+
$packageData = $this->packagistData->getPackageData($uxPackage->getComposerName());
41+
42+
$firstLine = array_shift($packageLog);
43+
44+
$changelog = [];
45+
foreach ($packageLog as $a) {
46+
47+
$lines = explode("\n", $a);
48+
$version = array_shift($lines);
49+
50+
$versionData = $packageData['versions']['v'.$version] ?? [];
51+
if ([] === $versionData) {
52+
continue;
53+
}
54+
55+
$changelog[] = [
56+
'body' => implode("\n", $lines),
57+
'version' => $version,
58+
'name' => 'v'.$version,
59+
'date' => $versionData['time'] ?? null,
60+
];
61+
}
62+
63+
return $this->render('ux_packages/package_changelog.html.twig', [
64+
'package' => $uxPackage,
65+
'changelog' => $changelog,
66+
]);
67+
}
68+
69+
#[Route('/requirements', name: 'app_package_requirements')]
70+
public function requirements(string $package): Response
71+
{
72+
$uxPackage = $this->packageRepository->find($package) ?? throw $this->createNotFoundException(sprintf('Package "%s" not found', $package));
73+
74+
$packageData = $this->packagistData->getPackageData($uxPackage->getComposerName());
75+
76+
$packageVersions = $packageData['versions'] ?? [];
77+
$currentVersion = array_shift($packageVersions);
78+
79+
return $this->render('ux_packages/package_requirements.html.twig', [
80+
'package' => $uxPackage,
81+
'requirements' => [
82+
'requires' => $currentVersion['require'] ?? [],
83+
'devRequires' => $currentVersion['require-dev'] ?? [],
84+
],
85+
]);
86+
}
87+
}

ux.symfony.com/src/Service/Changelog/ChangelogProvider.php

+32-4
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,48 @@ public function getChangelog(int $page = 1): array
3030
{
3131
$changelog = [];
3232

33-
foreach ($this->getReleases($page) as $release) {
33+
foreach ($this->getReleases('ux', $page) as $release) {
3434
$changelog[] = $release;
3535
}
3636

3737
return $changelog;
3838
}
3939

40-
private function getReleases(int $page = 1): array
40+
public function getPackageChangelog(string $repo, int $page = 1): array
4141
{
42-
return $this->cache->get('releases-symfony-ux-'.$page, function (CacheItemInterface $item) use ($page) {
42+
$changelogMd = $this->cache->get('changelog-symfony-'.$repo.'-'.$page, function (CacheItemInterface $item) use ($repo, $page) {
4343
$item->expiresAfter(604800); // 1 week
4444

45-
return $this->fetchReleases('symfony', 'ux', $page);
45+
return $this->fetchPackageChangelog('symfony', $repo, $page);
4646
});
47+
48+
$changelog = [];
49+
$changelogMarkdown = explode("\n## ", $changelogMd);
50+
51+
return $changelogMarkdown;
52+
}
53+
54+
private function getReleases(string $repo, int $page = 1): array
55+
{
56+
return $this->cache->get('releases-symfony-'.$repo.'-'.$page, function (CacheItemInterface $item) use ($repo, $page) {
57+
$item->expiresAfter(604800); // 1 week
58+
59+
return $this->fetchReleases('symfony', $repo, $page);
60+
});
61+
}
62+
63+
/**
64+
* @return string
65+
*
66+
* @internal
67+
*/
68+
private function fetchPackageChangelog(string $owner, string $repo): string
69+
{
70+
// https://github.com/symfony/ux-twig-component/blob/2.x/CHANGELOG.md
71+
// https://raw.githubusercontent.com/symfony/ux-twig-component/2.x/CHANGELOG.md
72+
$response = $this->httpClient->request('GET', sprintf('https://raw.githubusercontent.com/%s/%s/2.x/CHANGELOG.md', $owner, $repo));
73+
74+
return $response->getContent();
4775
}
4876

4977
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace App\Service\Packagist;
4+
5+
use Symfony\Contracts\Cache\CacheInterface;
6+
use Symfony\Contracts\Cache\ItemInterface;
7+
use Symfony\Contracts\HttpClient\HttpClientInterface;
8+
9+
class PackagistDataProvider
10+
{
11+
public function __construct(
12+
private HttpClientInterface $httpClient,
13+
private CacheInterface $cache,
14+
)
15+
{
16+
}
17+
18+
public function getPackageData(string $packageName): array
19+
{
20+
return $this->cache->get('package-data-'.str_replace('/', '--', $packageName), function (ItemInterface $item) use ($packageName) {
21+
$item->expiresAfter(604800); // 1 week
22+
23+
return $this->fetchPackageData($packageName);
24+
});
25+
}
26+
27+
private function fetchPackageData(string $packageName): array
28+
{
29+
$response = $this->httpClient->request('GET', 'https://packagist.org/packages/'.$packageName.'.json');
30+
31+
$packageData = $response->toArray();
32+
33+
return $packageData['package'] ?? [];
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{% extends 'base.html.twig' %}
2+
3+
{% set meta = {
4+
title: package.humanName,
5+
description: package.description,
6+
canonical: url(package.route),
7+
} %}
8+
9+
{% block header %}
10+
{{ include('_header.html.twig', {
11+
theme: 'white'
12+
}) }}
13+
{% endblock %}
14+
15+
{% block content %}
16+
17+
<article>
18+
19+
{% block package_header %}
20+
{{ block('package_header', 'ux_packages/%s.html.twig'|format(package.name|u.snake)) }}
21+
22+
<nav style="display: flex; align-items: center; justify-content: center; background: #0A0A0A; color:#fff; padding: 1rem; gap: 2rem;">
23+
<a href="{{ url(package.route) }}" style="color:#fff;">{{ package.humanName }}</a>
24+
25+
<a href="{{ url('app_packageapp_package_requirements', {package: package.name}) }}" style="color:#fff;">Requirements</a>
26+
<a href="{{ url('app_packageapp_package_changelog', {package: package.name}) }}" style="color:#fff;">Install</a>
27+
28+
<a href="{{ url('app_packageapp_package_changelog', {package: package.name}) }}" style="color:#fff;">Install</a>
29+
30+
<a href="{{ url('app_packageapp_package_changelog', {package: package.name}) }}" style="color:#fff;">Doc</a>
31+
<a href="{{ url('app_packageapp_package_changelog', {package: package.name}) }}" style="color:#fff;">Demos</a>
32+
33+
<a href="{{ url('app_packageapp_package_changelog', {package: package.name}) }}" style="color:#fff;">Changelog</a>
34+
<a href="{{ url('app_packageapp_package_changelog', {package: package.name}) }}" style="color:#fff;">Issue</a>
35+
</nav>
36+
{% endblock %}
37+
38+
{% block package_content %}
39+
40+
<div class="hero">
41+
<div class="container-fluid container-xxl px-4 pt-4 px-md-5">
42+
<h1 class="text-center mt-5"><a href="{{ url('app_changelog') }}">Changelog</a></h1>
43+
<p class="text-center mt-2 mb-5">New features, bug fixes, performances and security improvements.</p>
44+
</div>
45+
</div>
46+
47+
<div class="container-fluid container-xxl px-4 pt-4 px-md-5">
48+
<div class="Changelog">
49+
{% for entry in changelog %}
50+
<twig:ChangelogItem item="{{ entry }}" isOpen="{{ loop.index < 4 }}" />
51+
{% endfor %}
52+
</div>
53+
</div>
54+
55+
{% endblock %}
56+
</article>
57+
58+
{% endblock %}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{% extends 'base.html.twig' %}
2+
3+
{% set meta = {
4+
title: package.humanName,
5+
description: package.description,
6+
canonical: url(package.route),
7+
} %}
8+
9+
{% block header %}
10+
{{ include('_header.html.twig', {
11+
theme: 'white'
12+
}) }}
13+
{% endblock %}
14+
15+
{% block content %}
16+
17+
<article>
18+
19+
{% block package_header %}
20+
{{ block('package_header', 'ux_packages/%s.html.twig'|format(package.name|u.snake)) }}
21+
22+
<nav style="display: flex; align-items: center; justify-content: center; background: #0A0A0A; color:#fff; padding: 1rem; gap: 2rem;">
23+
<a href="{{ url(package.route) }}" style="color:#fff;">{{ package.humanName }}</a>
24+
25+
<a href="{{ url('app_packageapp_package_requirements', {package: package.name}) }}" style="color:#fff;">Requirements</a>
26+
<a href="{{ url('app_packageapp_package_changelog', {package: package.name}) }}" style="color:#fff;">Install</a>
27+
28+
<a href="{{ url('app_packageapp_package_changelog', {package: package.name}) }}" style="color:#fff;">Install</a>
29+
30+
<a href="{{ url('app_packageapp_package_changelog', {package: package.name}) }}" style="color:#fff;">Doc</a>
31+
<a href="{{ url('app_packageapp_package_changelog', {package: package.name}) }}" style="color:#fff;">Demos</a>
32+
33+
<a href="{{ url('app_packageapp_package_changelog', {package: package.name}) }}" style="color:#fff;">Changelog</a>
34+
<a href="{{ url('app_packageapp_package_changelog', {package: package.name}) }}" style="color:#fff;">Issue</a>
35+
</nav>
36+
{% endblock %}
37+
38+
{% block package_content %}
39+
40+
<div class="hero">
41+
<div class="container-fluid container-xxl px-4 pt-4 px-md-5">
42+
<h1 class="text-center mt-5"><a href="{{ url('app_changelog') }}">{{ package.name }} Requirements</a></h1>
43+
<p class="text-center mt-2 mb-5">New features, bug fixes, performances and security improvements.</p>
44+
</div>
45+
</div>
46+
47+
<div class="container-fluid container-xxl px-4 pt-4 px-md-5">
48+
49+
{{ dump(requirements) }}
50+
</div>
51+
52+
{% endblock %}
53+
</article>
54+
55+
{% endblock %}

0 commit comments

Comments
 (0)