From 26107d122ea1c9fc1e07d375a34b223a803b496b Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:06:15 +0200 Subject: [PATCH 01/24] Normalize documented link in code documentation May want something in HydeStan for this to detect if line uses link to our site but with the HTML extension. --- packages/framework/src/Facades/Author.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/framework/src/Facades/Author.php b/packages/framework/src/Facades/Author.php index 16976036fb5..d9bbbb89084 100644 --- a/packages/framework/src/Facades/Author.php +++ b/packages/framework/src/Facades/Author.php @@ -18,7 +18,7 @@ class Author * Construct a new Post Author. For Hyde to discover this author, * you must call this method from your hyde.php config file. * - * @see https://hydephp.com/docs/1.x/customization.html#authors + * @see https://hydephp.com/docs/1.x/customization#authors * * @param string $username The username of the author. This is the key used to find authors in the config. * @param string|null $name The optional display name of the author, leave blank to use the username. From ce905af8a9c5616435e756519be2b8c27ed035aa Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:20:36 +0200 Subject: [PATCH 02/24] Extract HydeStan contracts to separate file --- monorepo/HydeStan/HydeStan.php | 40 ++---------------------- monorepo/HydeStan/includes/contracts.php | 39 +++++++++++++++++++++++ 2 files changed, 41 insertions(+), 38 deletions(-) create mode 100644 monorepo/HydeStan/includes/contracts.php diff --git a/monorepo/HydeStan/HydeStan.php b/monorepo/HydeStan/HydeStan.php index 570f5fea072..38062366c00 100644 --- a/monorepo/HydeStan/HydeStan.php +++ b/monorepo/HydeStan/HydeStan.php @@ -4,6 +4,8 @@ use Desilva\Console\Console; +require_once __DIR__.'/includes/contracts.php'; + /** * @internal */ @@ -228,30 +230,6 @@ private function analyseTestFile(string $file, string $contents): void } } -abstract class Analyser -{ - protected function fail(string $error): void - { - HydeStan::getInstance()->addError($error); - } -} - -abstract class FileAnalyser extends Analyser implements FileAnalyserContract -{ - public function __construct(protected string $file, protected string $contents) - { - // - } -} - -abstract class LineAnalyser extends Analyser implements LineAnalyserContract -{ - public function __construct(protected string $file, protected int $lineNumber, protected string $line) - { - // - } -} - class NoFixMeAnalyser extends FileAnalyser { public function run(string $file, string $contents): void @@ -426,20 +404,6 @@ public static function getExpressionsAnalysed(): int } } -interface FileAnalyserContract -{ - public function __construct(string $file, string $contents); - - public function run(string $file, string $contents): void; -} - -interface LineAnalyserContract -{ - public function __construct(string $file, int $lineNumber, string $line); - - public function run(string $file, int $lineNumber, string $line): void; -} - function check_str_contains_any(array $searches, string $line): bool { $strContainsAny = false; diff --git a/monorepo/HydeStan/includes/contracts.php b/monorepo/HydeStan/includes/contracts.php new file mode 100644 index 00000000000..b3a73b9c5d7 --- /dev/null +++ b/monorepo/HydeStan/includes/contracts.php @@ -0,0 +1,39 @@ +addError($error); + } +} + +abstract class FileAnalyser extends Analyser implements FileAnalyserContract +{ + public function __construct(protected string $file, protected string $contents) + { + // + } +} + +abstract class LineAnalyser extends Analyser implements LineAnalyserContract +{ + public function __construct(protected string $file, protected int $lineNumber, protected string $line) + { + // + } +} From 35c9c1c149146435561568e1fe0c96fa4163535d Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:21:55 +0200 Subject: [PATCH 03/24] Document class abstract --- monorepo/HydeStan/HydeStan.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monorepo/HydeStan/HydeStan.php b/monorepo/HydeStan/HydeStan.php index 38062366c00..932f774b26f 100644 --- a/monorepo/HydeStan/HydeStan.php +++ b/monorepo/HydeStan/HydeStan.php @@ -7,7 +7,7 @@ require_once __DIR__.'/includes/contracts.php'; /** - * @internal + * @internal Custom static analysis tool for the HydePHP Development Monorepo. */ final class HydeStan { From e963e2b1c8637ed5d1114e98b32ee698a821c74f Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:27:37 +0200 Subject: [PATCH 04/24] Update HydeStan documentation --- monorepo/HydeStan/README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/monorepo/HydeStan/README.md b/monorepo/HydeStan/README.md index 5d9b407be69..f774a6bf9f8 100644 --- a/monorepo/HydeStan/README.md +++ b/monorepo/HydeStan/README.md @@ -1 +1,20 @@ # HydeStan - Experimental Custom Static Analysis Tool for the HydePHP Monorepo + +## About + +HydeStan is a custom static analysis tool in the HydePHP monorepo, designed to provide additional static analysis and code quality checks for the HydePHP framework. + +The tool is in continuous development and is highly specialized, and cannot be relied upon for general purpose static analysis outside this repository. + +## Scope + +The analyser is called through the `run.php` script, and is automatically run on all commits through the GitHub Actions CI/CD pipeline. + +It can also be run manually from the monorepo root: + +```bash +php ./monorepo/HydeStan/run.php +``` + +A subset of HydeStan is also run on the Git patches sent to our custom CI Server at https://ci.hydephp.com to provide immediate feedback on commits. + From f0ee82703d35a2640e814750b2de98bc78d24a2a Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:28:51 +0200 Subject: [PATCH 05/24] Update HydeStan documentation --- monorepo/HydeStan/README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/monorepo/HydeStan/README.md b/monorepo/HydeStan/README.md index f774a6bf9f8..6de50e6d65c 100644 --- a/monorepo/HydeStan/README.md +++ b/monorepo/HydeStan/README.md @@ -6,15 +6,20 @@ HydeStan is a custom static analysis tool in the HydePHP monorepo, designed to p The tool is in continuous development and is highly specialized, and cannot be relied upon for general purpose static analysis outside this repository. -## Scope +## Usage The analyser is called through the `run.php` script, and is automatically run on all commits through the GitHub Actions CI/CD pipeline. +### Running HydeStan + It can also be run manually from the monorepo root: ```bash php ./monorepo/HydeStan/run.php ``` +### GitHub Integration + A subset of HydeStan is also run on the Git patches sent to our custom CI Server at https://ci.hydephp.com to provide immediate feedback on commits. +Example: https://ci.hydephp.com/api/hydestan/status/e963e2b1c8637ed5d1114e98b32ee698a821c74f From da579846c560ccc565db2a7294536e9046534103 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:29:57 +0200 Subject: [PATCH 06/24] Clean up documentation --- monorepo/HydeStan/README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/monorepo/HydeStan/README.md b/monorepo/HydeStan/README.md index 6de50e6d65c..7c0bf6e6f19 100644 --- a/monorepo/HydeStan/README.md +++ b/monorepo/HydeStan/README.md @@ -1,10 +1,9 @@ -# HydeStan - Experimental Custom Static Analysis Tool for the HydePHP Monorepo +# HydeStan - Internal Custom Static Analysis for the HydePHP Monorepo ## About HydeStan is a custom static analysis tool in the HydePHP monorepo, designed to provide additional static analysis and code quality checks for the HydePHP framework. - -The tool is in continuous development and is highly specialized, and cannot be relied upon for general purpose static analysis outside this repository. +It is in continuous development and is highly specialized, and cannot be relied upon for any outside this repository. ## Usage @@ -21,5 +20,4 @@ php ./monorepo/HydeStan/run.php ### GitHub Integration A subset of HydeStan is also run on the Git patches sent to our custom CI Server at https://ci.hydephp.com to provide immediate feedback on commits. - Example: https://ci.hydephp.com/api/hydestan/status/e963e2b1c8637ed5d1114e98b32ee698a821c74f From efa3d717a7c9f09c7cf5202764804e44b0f0ee55 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:30:57 +0200 Subject: [PATCH 07/24] Clean up documentation --- monorepo/HydeStan/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monorepo/HydeStan/README.md b/monorepo/HydeStan/README.md index 7c0bf6e6f19..2e7d18da8ab 100644 --- a/monorepo/HydeStan/README.md +++ b/monorepo/HydeStan/README.md @@ -19,5 +19,5 @@ php ./monorepo/HydeStan/run.php ### GitHub Integration -A subset of HydeStan is also run on the Git patches sent to our custom CI Server at https://ci.hydephp.com to provide immediate feedback on commits. +A subset of HydeStan is also run on the Git patches sent to our custom [CI Server](https://ci.hydephp.com) to provide near-instant immediate feedback on commits. Example: https://ci.hydephp.com/api/hydestan/status/e963e2b1c8637ed5d1114e98b32ee698a821c74f From 0695eb1233dc31764331366a038e97f07d3578f9 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:34:35 +0200 Subject: [PATCH 08/24] Add package annotation --- monorepo/HydeStan/HydeStan.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/monorepo/HydeStan/HydeStan.php b/monorepo/HydeStan/HydeStan.php index 932f774b26f..f1ad08568be 100644 --- a/monorepo/HydeStan/HydeStan.php +++ b/monorepo/HydeStan/HydeStan.php @@ -8,6 +8,8 @@ /** * @internal Custom static analysis tool for the HydePHP Development Monorepo. + * + * @package HydeStan */ final class HydeStan { From 075f842d77c4278e58188458ead800779ad72dea Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:35:02 +0200 Subject: [PATCH 09/24] Revert "Add package annotation" This reverts commit 0695eb1233dc31764331366a038e97f07d3578f9. --- monorepo/HydeStan/HydeStan.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/monorepo/HydeStan/HydeStan.php b/monorepo/HydeStan/HydeStan.php index f1ad08568be..932f774b26f 100644 --- a/monorepo/HydeStan/HydeStan.php +++ b/monorepo/HydeStan/HydeStan.php @@ -8,8 +8,6 @@ /** * @internal Custom static analysis tool for the HydePHP Development Monorepo. - * - * @package HydeStan */ final class HydeStan { From 00d5e1c809db9d0b23cf065c9c8ddc7bd4b1d8c3 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:34:43 +0200 Subject: [PATCH 10/24] Add strict types declaration --- monorepo/HydeStan/includes/contracts.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/monorepo/HydeStan/includes/contracts.php b/monorepo/HydeStan/includes/contracts.php index b3a73b9c5d7..52f64b4dd90 100644 --- a/monorepo/HydeStan/includes/contracts.php +++ b/monorepo/HydeStan/includes/contracts.php @@ -1,5 +1,7 @@ Date: Wed, 10 Jul 2024 13:37:21 +0200 Subject: [PATCH 11/24] Register the analysers through constants --- monorepo/HydeStan/HydeStan.php | 59 ++++++++++++++++------------------ 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/monorepo/HydeStan/HydeStan.php b/monorepo/HydeStan/HydeStan.php index 932f774b26f..37a7fa99550 100644 --- a/monorepo/HydeStan/HydeStan.php +++ b/monorepo/HydeStan/HydeStan.php @@ -13,6 +13,20 @@ final class HydeStan { const VERSION = '0.0.0-dev'; + private const FILE_ANALYSERS = [ + NoFixMeAnalyser::class, + UnImportedFunctionAnalyser::class, + ]; + + private const TEST_FILE_ANALYSERS = [ + NoFixMeAnalyser::class, + NoUsingAssertEqualsForScalarTypesTestAnalyser::class, + ]; + + private const LINE_ANALYSERS = [ + NoTestReferenceAnalyser::class, + ]; + private array $files; private array $testFiles; private array $errors = []; @@ -137,34 +151,28 @@ private function getTestFiles(): array private function analyseFile(string $file, string $contents): void { - $fileAnalysers = [ - new NoFixMeAnalyser($file, $contents), - new UnImportedFunctionAnalyser($file, $contents), - ]; + foreach (self::FILE_ANALYSERS as $fileAnalyserClass) { + $fileAnalyser = new $fileAnalyserClass($file, $contents); - foreach ($fileAnalysers as $analyser) { if ($this->debug) { - $this->console->debugComment('Running '.$analyser::class); + $this->console->debugComment('Running '.$fileAnalyser::class); } - $analyser->run($file, $contents); + $fileAnalyser->run($file, $contents); AnalysisStatisticsContainer::countedLines(substr_count($contents, "\n")); foreach (explode("\n", $contents) as $lineNumber => $line) { - $lineAnalysers = [ - new NoTestReferenceAnalyser($file, $lineNumber, $line), - ]; - - foreach ($lineAnalysers as $analyser) { + foreach (self::LINE_ANALYSERS as $lineAnalyserClass) { + $lineAnalyser = new $lineAnalyserClass($file, $lineNumber, $line); AnalysisStatisticsContainer::countedLine(); - $analyser->run($file, $lineNumber, $line); + $lineAnalyser->run($file, $lineNumber, $line); $this->aggregateLines++; } } } $this->scannedLines += substr_count($contents, "\n"); - $this->aggregateLines += (substr_count($contents, "\n") * count($fileAnalysers)); + $this->aggregateLines += (substr_count($contents, "\n") * count(self::FILE_ANALYSERS)); } private function getFileContents(string $file): string @@ -199,34 +207,23 @@ protected function runTestStan(): void private function analyseTestFile(string $file, string $contents): void { - $fileAnalysers = [ - new NoFixMeAnalyser($file, $contents), - new NoUsingAssertEqualsForScalarTypesTestAnalyser($file, $contents), - ]; + foreach (self::TEST_FILE_ANALYSERS as $fileAnalyserClass) { + $fileAnalyser = new $fileAnalyserClass($file, $contents); - foreach ($fileAnalysers as $analyser) { if ($this->debug) { - $this->console->debugComment('Running '.$analyser::class); + $this->console->debugComment('Running '.$fileAnalyser::class); } - $analyser->run($file, $contents); + $fileAnalyser->run($file, $contents); AnalysisStatisticsContainer::countedLines(substr_count($contents, "\n")); foreach (explode("\n", $contents) as $lineNumber => $line) { - $lineAnalysers = [ - // - ]; - - foreach ($lineAnalysers as $analyser) { - AnalysisStatisticsContainer::countedLine(); - $analyser->run($file, $lineNumber, $line); - $this->aggregateLines++; - } + // No line analysers defined for test files in the original code } } $this->scannedLines += substr_count($contents, "\n"); - $this->aggregateLines += (substr_count($contents, "\n") * count($fileAnalysers)); + $this->aggregateLines += (substr_count($contents, "\n") * count(self::TEST_FILE_ANALYSERS)); } } From 286f33c44bc5830e50d48f2929f8454b791795f8 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:43:05 +0200 Subject: [PATCH 12/24] Extract HydeStan helpers to separate file --- monorepo/HydeStan/HydeStan.php | 59 +------------------------ monorepo/HydeStan/includes/helpers.php | 61 ++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 58 deletions(-) create mode 100644 monorepo/HydeStan/includes/helpers.php diff --git a/monorepo/HydeStan/HydeStan.php b/monorepo/HydeStan/HydeStan.php index 37a7fa99550..028678773c9 100644 --- a/monorepo/HydeStan/HydeStan.php +++ b/monorepo/HydeStan/HydeStan.php @@ -5,6 +5,7 @@ use Desilva\Console\Console; require_once __DIR__.'/includes/contracts.php'; +require_once __DIR__.'/includes/helpers.php'; /** * @internal Custom static analysis tool for the HydePHP Development Monorepo. @@ -364,61 +365,3 @@ public function run(string $file, int $lineNumber, string $line): void } } } - -class AnalysisStatisticsContainer -{ - private static int $linesCounted = 0; - private static float $expressionsAnalysed = 0; - - public static function countedLine(): void - { - self::$linesCounted++; - } - - public static function countedLines(int $count): void - { - self::$linesCounted += $count; - } - - public static function analysedExpression(): void - { - self::$expressionsAnalysed++; - } - - public static function analysedExpressions(float $countOrEstimate): void - { - self::$expressionsAnalysed += $countOrEstimate; - } - - public static function getLinesCounted(): int - { - return self::$linesCounted; - } - - public static function getExpressionsAnalysed(): int - { - return (int) round(self::$expressionsAnalysed); - } -} - -function check_str_contains_any(array $searches, string $line): bool -{ - $strContainsAny = false; - foreach ($searches as $search) { - AnalysisStatisticsContainer::analysedExpression(); - if (str_contains($line, $search)) { - $strContainsAny = true; - } - } - - return $strContainsAny; -} - -function fileLink(string $file, ?int $line = null): string -{ - $path = (realpath(__DIR__.'/../../packages/framework/'.$file) ?: $file).($line ? ':'.$line : ''); - $trim = strlen(getcwd()) + 2; - $path = substr($path, $trim); - - return str_replace('\\', '/', $path); -} diff --git a/monorepo/HydeStan/includes/helpers.php b/monorepo/HydeStan/includes/helpers.php new file mode 100644 index 00000000000..6500658e8e2 --- /dev/null +++ b/monorepo/HydeStan/includes/helpers.php @@ -0,0 +1,61 @@ + Date: Wed, 10 Jul 2024 13:39:02 +0200 Subject: [PATCH 13/24] Remove version constant we never update --- monorepo/HydeStan/HydeStan.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/monorepo/HydeStan/HydeStan.php b/monorepo/HydeStan/HydeStan.php index 028678773c9..e822cb4f1d2 100644 --- a/monorepo/HydeStan/HydeStan.php +++ b/monorepo/HydeStan/HydeStan.php @@ -12,8 +12,6 @@ */ final class HydeStan { - const VERSION = '0.0.0-dev'; - private const FILE_ANALYSERS = [ NoFixMeAnalyser::class, UnImportedFunctionAnalyser::class, @@ -48,7 +46,7 @@ public function __construct(private readonly bool $debug = false) $this->console = new Console(); - $this->console->info(sprintf('HydeStan v%s is running!', self::VERSION)); + $this->console->info(sprintf('HydeStan is running!')); $this->console->newline(); } From de8cdc72d686d2333464488a4c1030fb15c61731 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:44:47 +0200 Subject: [PATCH 14/24] Unwrap function call with single argument --- monorepo/HydeStan/HydeStan.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monorepo/HydeStan/HydeStan.php b/monorepo/HydeStan/HydeStan.php index e822cb4f1d2..e547b6cd649 100644 --- a/monorepo/HydeStan/HydeStan.php +++ b/monorepo/HydeStan/HydeStan.php @@ -46,7 +46,7 @@ public function __construct(private readonly bool $debug = false) $this->console = new Console(); - $this->console->info(sprintf('HydeStan is running!')); + $this->console->info('HydeStan is running!'); $this->console->newline(); } From a8e508f0eef18139016b24539d70a5a362f04b80 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:45:58 +0200 Subject: [PATCH 15/24] Specify nullable parameter for null type --- monorepo/scripts/tests/MicroTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monorepo/scripts/tests/MicroTest.php b/monorepo/scripts/tests/MicroTest.php index 1356b2356da..35c8952a469 100644 --- a/monorepo/scripts/tests/MicroTest.php +++ b/monorepo/scripts/tests/MicroTest.php @@ -51,7 +51,7 @@ public function test(string $name, Closure $callback): void } /** @throws \Exception */ - public function assert(bool $condition, string $message = null): void + public function assert(bool $condition, ?string $message = null): void { if (! $condition) { throw new Exception($message ?? 'Assertion failed'); From 95a3c1b564dec9bff35dbed19d3c2d395c678811 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:46:21 +0200 Subject: [PATCH 16/24] Convert concatenation to 'sprintf()' call --- monorepo/HydeStan/HydeStan.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monorepo/HydeStan/HydeStan.php b/monorepo/HydeStan/HydeStan.php index e547b6cd649..f12dca3b133 100644 --- a/monorepo/HydeStan/HydeStan.php +++ b/monorepo/HydeStan/HydeStan.php @@ -344,7 +344,7 @@ public function run(string $file, string $contents): void foreach ($calledFunctions as $calledFunction) { AnalysisStatisticsContainer::analysedExpression(); if (! in_array($calledFunction, $functionImports)) { - echo("Found unimported function '$calledFunction' in ".realpath(__DIR__.'/../../packages/framework/'.$file))."\n"; + echo sprintf("Found unimported function '$calledFunction' in %s\n", realpath(__DIR__.'/../../packages/framework/'.$file)); } } } From d213fad4845afb5891f7231f073db7cac936ff35 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:47:00 +0200 Subject: [PATCH 17/24] Clean up code --- monorepo/HydeStan/HydeStan.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/monorepo/HydeStan/HydeStan.php b/monorepo/HydeStan/HydeStan.php index f12dca3b133..8fc918f2c2b 100644 --- a/monorepo/HydeStan/HydeStan.php +++ b/monorepo/HydeStan/HydeStan.php @@ -359,7 +359,8 @@ public function run(string $file, int $lineNumber, string $line): void if (str_starts_with($line, ' * @see') && str_ends_with($line, 'Test')) { AnalysisStatisticsContainer::analysedExpressions(1); $this->fail(sprintf('Test class %s is referenced in %s:%s', trim(substr($line, 7)), - realpath(__DIR__.'/../../packages/framework/'.$file) ?: $file, $lineNumber + 1)); + realpath(__DIR__.'/../../packages/framework/'.$file) ?: $file, $lineNumber + 1) + ); } } } From f30a6faccb99aa8a04c72bbc4ff6ab60d0a05839 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:48:47 +0200 Subject: [PATCH 18/24] Extract helper function --- monorepo/HydeStan/HydeStan.php | 24 ++---------------------- monorepo/HydeStan/includes/helpers.php | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/monorepo/HydeStan/HydeStan.php b/monorepo/HydeStan/HydeStan.php index 8fc918f2c2b..330e02f5c6d 100644 --- a/monorepo/HydeStan/HydeStan.php +++ b/monorepo/HydeStan/HydeStan.php @@ -120,32 +120,12 @@ public function addErrors(array $errors): void private function getFiles(): array { - $files = []; - - $directory = new RecursiveDirectoryIterator(BASE_PATH.'/src'); - $iterator = new RecursiveIteratorIterator($directory); - $regex = new RegexIterator($iterator, '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH); - - foreach ($regex as $file) { - $files[] = substr($file[0], strlen(BASE_PATH) + 1); - } - - return $files; + return recursiveFileFinder('src'); } private function getTestFiles(): array { - $files = []; - - $directory = new RecursiveDirectoryIterator(BASE_PATH.'/tests'); - $iterator = new RecursiveIteratorIterator($directory); - $regex = new RegexIterator($iterator, '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH); - - foreach ($regex as $file) { - $files[] = substr($file[0], strlen(BASE_PATH) + 1); - } - - return $files; + return recursiveFileFinder('tests'); } private function analyseFile(string $file, string $contents): void diff --git a/monorepo/HydeStan/includes/helpers.php b/monorepo/HydeStan/includes/helpers.php index 6500658e8e2..f3a9c8dcb31 100644 --- a/monorepo/HydeStan/includes/helpers.php +++ b/monorepo/HydeStan/includes/helpers.php @@ -59,3 +59,18 @@ function fileLink(string $file, ?int $line = null): string return str_replace('\\', '/', $path); } + +function recursiveFileFinder(string $directory): array +{ + $files = []; + + $directory = new RecursiveDirectoryIterator(BASE_PATH.'/'.$directory); + $iterator = new RecursiveIteratorIterator($directory); + $regex = new RegexIterator($iterator, '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH); + + foreach ($regex as $file) { + $files[] = substr($file[0], strlen(BASE_PATH) + 1); + } + + return $files; +} From 881f6b25b74c119c08190da13ffbd6eba5a62b69 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:49:29 +0200 Subject: [PATCH 19/24] Fix formatting --- monorepo/HydeStan/HydeStan.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/monorepo/HydeStan/HydeStan.php b/monorepo/HydeStan/HydeStan.php index 330e02f5c6d..300b29d0bb3 100644 --- a/monorepo/HydeStan/HydeStan.php +++ b/monorepo/HydeStan/HydeStan.php @@ -338,9 +338,11 @@ public function run(string $file, int $lineNumber, string $line): void if (str_starts_with($line, ' * @see') && str_ends_with($line, 'Test')) { AnalysisStatisticsContainer::analysedExpressions(1); - $this->fail(sprintf('Test class %s is referenced in %s:%s', trim(substr($line, 7)), - realpath(__DIR__.'/../../packages/framework/'.$file) ?: $file, $lineNumber + 1) - ); + $this->fail(sprintf('Test class %s is referenced in %s:%s', + trim(substr($line, 7)), + realpath(__DIR__.'/../../packages/framework/'.$file) ?: $file, + $lineNumber + 1 + )); } } } From f725be7f529f340bafc512b50ec6f531028a778b Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 13:59:57 +0200 Subject: [PATCH 20/24] Detect if line uses link to our site but with the HTML extension --- monorepo/HydeStan/HydeStan.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/monorepo/HydeStan/HydeStan.php b/monorepo/HydeStan/HydeStan.php index 300b29d0bb3..6e0d03a827f 100644 --- a/monorepo/HydeStan/HydeStan.php +++ b/monorepo/HydeStan/HydeStan.php @@ -24,6 +24,7 @@ final class HydeStan private const LINE_ANALYSERS = [ NoTestReferenceAnalyser::class, + NoHtmlExtensionInHydePHPLinksAnalyser::class, ]; private array $files; @@ -235,6 +236,23 @@ public function run(string $file, string $contents): void } } +class NoHtmlExtensionInHydePHPLinksAnalyser extends LineAnalyser +{ + public function run(string $file, int $lineNumber, string $line): void + { + AnalysisStatisticsContainer::analysedExpressions(1); + + if (str_contains($line, 'https://hydephp.com/') && str_contains($line, '.html')) { + $this->fail(sprintf('HTML extension used in URL at %s:%s', + realpath(__DIR__.'/../../packages/framework/'.$file) ?: $file, + $lineNumber + 1 + )); + + HydeStan::addActionsMessage('warning', $file, $lineNumber + 1, 'HydeStan: NoHtmlExtensionError', 'URL contains .html extension. Consider removing it.'); + } + } +} + class NoUsingAssertEqualsForScalarTypesTestAnalyser extends FileAnalyser // Todo: Extend line analyser instead? Would allow for checking for more errors after the first error { public function run(string $file, string $contents): void From 02ef405b5ee17953cbae9f387ecf456a13d307e5 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 14:01:19 +0200 Subject: [PATCH 21/24] Detect extra whitespace in compressed PHPDoc comment --- monorepo/HydeStan/HydeStan.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/monorepo/HydeStan/HydeStan.php b/monorepo/HydeStan/HydeStan.php index 6e0d03a827f..d18e20343a9 100644 --- a/monorepo/HydeStan/HydeStan.php +++ b/monorepo/HydeStan/HydeStan.php @@ -25,6 +25,7 @@ final class HydeStan private const LINE_ANALYSERS = [ NoTestReferenceAnalyser::class, NoHtmlExtensionInHydePHPLinksAnalyser::class, + NoExtraWhitespaceInCompressedPhpDocAnalyser::class, ]; private array $files; @@ -253,6 +254,23 @@ public function run(string $file, int $lineNumber, string $line): void } } +class NoExtraWhitespaceInCompressedPhpDocAnalyser extends LineAnalyser +{ + public function run(string $file, int $lineNumber, string $line): void + { + AnalysisStatisticsContainer::analysedExpressions(1); + + if (str_contains($line, '/** ')) { + $this->fail(sprintf('Extra whitespace in compressed PHPDoc comment at %s:%s', + realpath(__DIR__.'/../../packages/framework/'.$file) ?: $file, + $lineNumber + 1 + )); + + HydeStan::addActionsMessage('warning', $file, $lineNumber + 1, 'HydeStan: ExtraWhitespaceInPhpDocError', 'Extra whitespace found in compressed PHPDoc comment.'); + } + } +} + class NoUsingAssertEqualsForScalarTypesTestAnalyser extends FileAnalyser // Todo: Extend line analyser instead? Would allow for checking for more errors after the first error { public function run(string $file, string $contents): void From 46917213d4efd32215abaa1718f618f0df88a426 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 14:05:07 +0200 Subject: [PATCH 22/24] Use the file link helper --- monorepo/HydeStan/HydeStan.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/monorepo/HydeStan/HydeStan.php b/monorepo/HydeStan/HydeStan.php index d18e20343a9..be7d5e63506 100644 --- a/monorepo/HydeStan/HydeStan.php +++ b/monorepo/HydeStan/HydeStan.php @@ -244,9 +244,8 @@ public function run(string $file, int $lineNumber, string $line): void AnalysisStatisticsContainer::analysedExpressions(1); if (str_contains($line, 'https://hydephp.com/') && str_contains($line, '.html')) { - $this->fail(sprintf('HTML extension used in URL at %s:%s', - realpath(__DIR__.'/../../packages/framework/'.$file) ?: $file, - $lineNumber + 1 + $this->fail(sprintf('HTML extension used in URL at %s', + fileLink(BASE_PATH.'/packages/framework/'.$file, $lineNumber + 1) )); HydeStan::addActionsMessage('warning', $file, $lineNumber + 1, 'HydeStan: NoHtmlExtensionError', 'URL contains .html extension. Consider removing it.'); @@ -261,9 +260,8 @@ public function run(string $file, int $lineNumber, string $line): void AnalysisStatisticsContainer::analysedExpressions(1); if (str_contains($line, '/** ')) { - $this->fail(sprintf('Extra whitespace in compressed PHPDoc comment at %s:%s', - realpath(__DIR__.'/../../packages/framework/'.$file) ?: $file, - $lineNumber + 1 + $this->fail(sprintf('Extra whitespace in compressed PHPDoc comment at %s', + fileLink(BASE_PATH.'/packages/framework/'.$file, $lineNumber + 1) )); HydeStan::addActionsMessage('warning', $file, $lineNumber + 1, 'HydeStan: ExtraWhitespaceInPhpDocError', 'Extra whitespace found in compressed PHPDoc comment.'); From 0b7e1c48b0dd4da5379ae20a927c365a0947fe45 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 15:33:23 +0200 Subject: [PATCH 23/24] Fix extra whitespace in compressed PHPDoc comments --- .../src/Foundation/Concerns/HandlesFoundationCollections.php | 2 +- packages/framework/src/Foundation/Facades/Files.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/framework/src/Foundation/Concerns/HandlesFoundationCollections.php b/packages/framework/src/Foundation/Concerns/HandlesFoundationCollections.php index e9ef2625807..3192ee0ced9 100644 --- a/packages/framework/src/Foundation/Concerns/HandlesFoundationCollections.php +++ b/packages/framework/src/Foundation/Concerns/HandlesFoundationCollections.php @@ -15,7 +15,7 @@ */ trait HandlesFoundationCollections { - /** @return \Hyde\Foundation\Kernel\FileCollection */ + /** @return \Hyde\Foundation\Kernel\FileCollection */ public function files(): FileCollection { $this->needsToBeBooted(); diff --git a/packages/framework/src/Foundation/Facades/Files.php b/packages/framework/src/Foundation/Facades/Files.php index 39bbebb6da2..79d2acdc005 100644 --- a/packages/framework/src/Foundation/Facades/Files.php +++ b/packages/framework/src/Foundation/Facades/Files.php @@ -13,7 +13,7 @@ */ class Files extends Facade { - /** @return \Hyde\Foundation\Kernel\FileCollection */ + /** @return \Hyde\Foundation\Kernel\FileCollection */ public static function getFacadeRoot(): FileCollection { return HydeKernel::getInstance()->files(); From a1801ff6e91c5e25546f087f4d3ec8f26115ca22 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Wed, 10 Jul 2024 15:34:01 +0200 Subject: [PATCH 24/24] Count extra condition --- monorepo/HydeStan/HydeStan.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/monorepo/HydeStan/HydeStan.php b/monorepo/HydeStan/HydeStan.php index be7d5e63506..05aa7eafe55 100644 --- a/monorepo/HydeStan/HydeStan.php +++ b/monorepo/HydeStan/HydeStan.php @@ -244,6 +244,8 @@ public function run(string $file, int $lineNumber, string $line): void AnalysisStatisticsContainer::analysedExpressions(1); if (str_contains($line, 'https://hydephp.com/') && str_contains($line, '.html')) { + AnalysisStatisticsContainer::analysedExpressions(1); + $this->fail(sprintf('HTML extension used in URL at %s', fileLink(BASE_PATH.'/packages/framework/'.$file, $lineNumber + 1) ));