Skip to content

Commit 92677b9

Browse files
committed
Add GitHub action to check the validators index
When we make changes to the category of a rule, it's easy to forget to update overall list of rules. This commit a GitHub actions that will run a console command to check if the documentation it up-to-date. The job will fail when we need to change the document, but the console command will fix the issues, so there isn't a lot of friction there.
1 parent cd96d01 commit 92677b9

12 files changed

Lines changed: 386 additions & 284 deletions

File tree

.github/workflows/continuous-integration.yml renamed to .github/workflows/continuous-integration-code.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Continuous Integration
1+
name: Continuous Integration (code)
22

33
on:
44
push:
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Continuous Integration (docs)
2+
3+
on:
4+
push:
5+
paths-ignore:
6+
- 'data/**'
7+
- 'tests/**'
8+
pull_request:
9+
paths-ignore:
10+
- 'data/**'
11+
- 'tests/**'
12+
13+
jobs:
14+
docs:
15+
name: Documentation
16+
17+
runs-on: ubuntu-latest
18+
19+
steps:
20+
- name: Checkout
21+
uses: actions/checkout@v6
22+
23+
- name: Install PHP
24+
uses: shivammathur/setup-php@v2
25+
with:
26+
php-version: 8.5
27+
coverage: none
28+
29+
- name: Install dependencies
30+
run: composer install --prefer-dist
31+
32+
- name: Validators' index
33+
run: bin/console docs:validators:index

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ The most awesome validation engine ever created for PHP.
1010

1111
- Complex validation made simple: `v::numericVal()->positive()->between(1, 255)->isValid($input)`.
1212
- [Granularity control](docs/handling-exceptions.md) for advanced reporting.
13-
- [More than 150](docs/list-of-validators-by-category.md) (fully tested) validators.
13+
- [More than 150](docs/validators/index.md) (fully tested) validators.
1414
- [A concrete API](docs/concrete-api.md) for non fluent usage.
1515

1616
Learn More:

bin/console

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,21 @@ declare(strict_types=1);
1111
require __DIR__ . '/../vendor/autoload.php';
1212

1313
use Respect\Dev\Commands\CreateMixinCommand;
14-
use Respect\Dev\Commands\UpdateDocLinksCommand;
14+
use Respect\Dev\Commands\DocsValidatorsListCommand;
1515
use Respect\Dev\Commands\UpdateDomainSuffixesCommand;
1616
use Respect\Dev\Commands\UpdateDomainToplevelCommand;
1717
use Respect\Dev\Commands\UpdatePostalCodesCommand;
18+
use Respect\Dev\Markdown\Differ as MarkdownDiffer;
19+
use SebastianBergmann\Diff\Differ;
20+
use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
1821
use Symfony\Component\Console\Application;
1922

2023
return (static function () {
24+
$differ = new MarkdownDiffer(new Differ(new UnifiedDiffOutputBuilder('', addLineNumbers: true)));
25+
2126
$application = new Application('Respect/Validation', '3.0');
2227
$application->addCommand(new CreateMixinCommand());
23-
$application->addCommand(new UpdateDocLinksCommand());
28+
$application->addCommand(new DocsValidatorsListCommand($differ));
2429
$application->addCommand(new UpdateDomainSuffixesCommand());
2530
$application->addCommand(new UpdateDomainToplevelCommand());
2631
$application->addCommand(new UpdatePostalCodesCommand());

composer.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"psr/http-message": "^1.0 || ^2.0",
4242
"ramsey/uuid": "^4",
4343
"respect/coding-standard": "^5.0",
44+
"sebastian/diff": "^7.0",
4445
"sokil/php-isocodes": "^4.2.1",
4546
"sokil/php-isocodes-db-only": "^4.0",
4647
"squizlabs/php_codesniffer": "^4.0",
@@ -71,11 +72,15 @@
7172
}
7273
},
7374
"scripts": {
75+
"docs:validators:index": "bin/console docs:validators:index",
7476
"docheader": "vendor/bin/docheader check library/ tests/",
7577
"phpcs": "vendor/bin/phpcs",
7678
"phpstan": "vendor/bin/phpstan analyze",
7779
"phpunit": "vendor/bin/phpunit --testsuite=unit",
7880
"pest": "vendor/bin/pest --testsuite=feature --compact",
81+
"docs": [
82+
"@docs:validators:index"
83+
],
7984
"qa": [
8085
"@docheader",
8186
"@phpcs",

docs/getting-started.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,4 @@ $validator->assert('validation');
9999
## Next steps
100100

101101
- Explore the [Feature Guide](feature-guide.md) for more advanced usage.
102-
- Check out the [List of Validators by Category](list-of-validators-by-category.md) for a comprehensive list of available validators.
102+
- Check out the [List of Validators by Category](validators/index.md) for a comprehensive list of available validators.

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ The most awesome validation engine ever created for PHP.
44

55
- Complex validation made simple: `v::numericVal()->positive()->between(1, 255)->isValid($input)`.
66
- [Granularity control](handling-exceptions.md) for advanced reporting.
7-
- [More than 150](list-of-validators-by-category.md) (fully tested) validators.
7+
- [More than 150](validators/index.md) (fully tested) validators.
88
- [A concrete API](concrete-api.md) for non fluent usage.
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
# List of validators by category
1+
# Overviews
2+
3+
In this page you will find a list of validators by their category.
24

35
## Arrays
46

@@ -298,7 +300,6 @@
298300
- [ScalarVal](validators/ScalarVal.md)
299301
- [StringType](validators/StringType.md)
300302
- [StringVal](validators/StringVal.md)
301-
- [Type](validators/Type.md)
302303

303304
## Alphabetically
304305

@@ -449,7 +450,6 @@
449450
- [Time](validators/Time.md)
450451
- [Tld](validators/Tld.md)
451452
- [TrueVal](validators/TrueVal.md)
452-
- [Type](validators/Type.md)
453453
- [Undef](validators/Undef.md)
454454
- [UndefOr](validators/UndefOr.md)
455455
- [Unique](validators/Unique.md)
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
<?php
2+
3+
/*
4+
* Copyright (c) Alexandre Gomes Gaigalas <alganet@gmail.com>
5+
* SPDX-License-Identifier: MIT
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace Respect\Dev\Commands;
11+
12+
use Nette\UnexpectedValueException;
13+
use Respect\Dev\Markdown\Builder;
14+
use Respect\Dev\Markdown\Differ;
15+
use Symfony\Component\Console\Attribute\AsCommand;
16+
use Symfony\Component\Console\Command\Command;
17+
use Symfony\Component\Console\Input\InputInterface;
18+
use Symfony\Component\Console\Output\OutputInterface;
19+
use Symfony\Component\Finder\Finder;
20+
21+
use function array_keys;
22+
use function array_map;
23+
use function dirname;
24+
use function file_get_contents;
25+
use function ksort;
26+
use function preg_match;
27+
use function preg_match_all;
28+
use function sort;
29+
use function sprintf;
30+
31+
#[AsCommand(
32+
name: 'docs:validators:index',
33+
description: 'Update the index of validators by category',
34+
)]
35+
final class DocsValidatorsListCommand extends Command
36+
{
37+
public function __construct(
38+
private readonly Differ $differ,
39+
) {
40+
parent::__construct();
41+
}
42+
43+
protected function execute(InputInterface $input, OutputInterface $output): int
44+
{
45+
$validators = $this->getSortedListOfValidators();
46+
47+
$validatorsByCategory = [];
48+
foreach ($validators as $validator) {
49+
foreach ($this->getCategoriesByValidator($validator) as $category) {
50+
$validatorsByCategory[$category] ??= [];
51+
$validatorsByCategory[$category][] = $validator;
52+
}
53+
}
54+
55+
ksort($validatorsByCategory);
56+
$validatorsByCategory['Alphabetically'] = $validators;
57+
58+
$categories = array_keys($validatorsByCategory);
59+
60+
$build = Builder::fromDocs('validators/index.md');
61+
$build->h1('Overviews');
62+
$build->paragraph('In this page you will find a list of validators by their category.');
63+
$build->newLine();
64+
65+
foreach ($categories as $category) {
66+
$build->h2($category);
67+
if (isset($validatorsByCategory[$category])) {
68+
$categoryValidators = $validatorsByCategory[$category];
69+
sort($categoryValidators);
70+
foreach ($categoryValidators as $validator) {
71+
$build->anchorListItem($validator, sprintf('validators/%1$s.md', $validator));
72+
}
73+
}
74+
75+
$build->newLine();
76+
}
77+
78+
$diff = $this->differ->diff($build);
79+
if ($diff === null) {
80+
$output->writeln('<info>No changes needed.</info>');
81+
82+
return Command::SUCCESS;
83+
}
84+
85+
$build->save();
86+
87+
$output->writeln($diff);
88+
$output->writeln('<comment>Changes needed.</comment>');
89+
90+
return Command::FAILURE;
91+
}
92+
93+
/** @return array<string> */
94+
private function getSortedListOfValidators(): array
95+
{
96+
$finder = new Finder();
97+
$finder->in(dirname(__DIR__, 2) . '/library/Validators')->depth(0)->files()->name('*.php')->sortByName();
98+
99+
$validators = [];
100+
foreach ($finder as $file) {
101+
$validators[] = $file->getBasename('.php');
102+
}
103+
104+
return $validators;
105+
}
106+
107+
/** @return array<string> */
108+
private function getCategoriesByValidator(string $validator): array
109+
{
110+
$docsDirectory = dirname(__DIR__, 2) . '/docs';
111+
$filename = sprintf('%s/validators/%s.md', $docsDirectory, $validator);
112+
$content = file_get_contents($filename);
113+
if ($content === false) {
114+
throw new UnexpectedValueException(sprintf('Could not find content for "%s"', $validator));
115+
}
116+
117+
if (!preg_match('/## Categorization\s*(.*?)\s*## Changelog/s', $content, $matches)) {
118+
throw new UnexpectedValueException(sprintf('Could not find categorization for "%s"', $validator));
119+
}
120+
121+
preg_match_all('/^-\s*(.+)$/m', $matches[1], $categoryMatches);
122+
123+
return array_map('trim', $categoryMatches[1]);
124+
}
125+
}

0 commit comments

Comments
 (0)