[BUGFIX] Apply enableFields in JOIN's ON condition
[Packages/TYPO3.CMS.git] / Build / Scripts / extensionScannerRstFileReferences.php
1 #!/usr/bin/env php
2 <?php
3 declare(strict_types=1);
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 require __DIR__ . '/../../vendor/autoload.php';
18
19 if (PHP_SAPI !== 'cli') {
20 die('Script must be called from command line.' . chr(10));
21 }
22
23 /**
24 * Core integrity test script:
25 *
26 * Find all ReST files configured in EXT:install/Configuration/ExtensionScanner/Php
27 * and verify they exist in EXT:core/Documentation/Changelog
28 */
29 class ExtensionScannerRstFileReferencesChecker
30 {
31 /**
32 * @var array<string, string>
33 */
34 private $invalidRestFiles = [];
35
36 /**
37 * @var array<string, string>
38 */
39 private $validRestFiles = [];
40
41 /**
42 * @var array<string, int>
43 */
44 private $existingRestFiles = [];
45
46 public function check(): int
47 {
48 $this->existingRestFiles = $this->fetchExistingRstFiles();
49
50 $finder = new Symfony\Component\Finder\Finder();
51 $matcherConfigurationFiles = $finder->files()
52 ->in(__DIR__ . '/../../typo3/sysext/install/Configuration/ExtensionScanner/Php');
53
54 foreach ($matcherConfigurationFiles as $matcherConfigurationFile) {
55 /** @var SplFileInfo $matcherConfigurationFile */
56 $matcherConfigurations = require $matcherConfigurationFile->getPathname();
57 foreach ($matcherConfigurations as $matcherConfiguration) {
58 if (!isset($matcherConfiguration['restFiles'])) {
59 // `ConstructorArgumentsMatcher` is using an additional level which has to be checked
60 foreach ($matcherConfiguration as $nestedMatcherConfiguration) {
61 $this->checkRstFiles($nestedMatcherConfiguration, $matcherConfigurationFile);
62 }
63 } else {
64 $this->checkRstFiles($matcherConfiguration, $matcherConfigurationFile);
65 }
66 }
67 }
68
69 if (empty($this->invalidRestFiles)) {
70 return 0; // we are done, nothing found. Script will exit with 0
71 }
72 echo "ReST files references in extension scanner configuration that could not be found:\n";
73 foreach ($this->invalidRestFiles as $invalid) {
74 printf(
75 " - '%s' in file '%s'\n",
76 $invalid['invalidFile'],
77 $invalid['configurationFile']
78 );
79 }
80 echo "\n";
81 return 1; // we got findings, script will exit with 1
82 }
83
84 private function fetchExistingRstFiles(): array
85 {
86 $finder = new Symfony\Component\Finder\Finder();
87 $finder->files()
88 ->name('*.rst')
89 ->notName(['Changelog-*.rst', 'Index.rst', 'Master.rst'])
90 ->in(__DIR__ . '/../../typo3/sysext/core/Documentation/Changelog');
91 $fileNames = array_map(
92 function (SplFileInfo $file) {
93 return $file->getFilename();
94 },
95 iterator_to_array($finder)
96 );
97 // remove array keys containing the full file path again
98 $fileNames = array_values($fileNames);
99 // e.g. `['SomeFileA.rst' => 1, 'SomeOtherFile.rst' => 4]` counting occurrences
100 return array_count_values($fileNames);
101 }
102
103 private function checkRstFiles($matcherConfiguration, $matcherConfigurationFile): void
104 {
105 if (!is_array($matcherConfiguration['restFiles'] ?? null)) {
106 throw new \InvalidArgumentException(sprintf(
107 'Configuration has no `restFiles` section defined in %s',
108 $matcherConfigurationFile
109 ));
110 }
111 foreach ($matcherConfiguration['restFiles'] as $restFile) {
112 if (in_array($restFile, $this->validRestFiles, true)) {
113 // Local cache as guard to not check same file over and over again
114 continue;
115 }
116 if (($this->existingRestFiles[$restFile] ?? 0) === 1) {
117 $this->validRestFiles[] = $restFile;
118 } else {
119 $this->invalidRestFiles[] = [
120 'configurationFile' => $matcherConfigurationFile->getPathname(),
121 'invalidFile' => $restFile,
122 ];
123 }
124 }
125 }
126 }
127
128 $checker = new ExtensionScannerRstFileReferencesChecker();
129 exit($checker->check());