diff --git a/source/_daily_emails/2024-02-20.md b/source/_daily_emails/2024-02-20.md new file mode 100644 index 000000000..6c4edbaa7 --- /dev/null +++ b/source/_daily_emails/2024-02-20.md @@ -0,0 +1,89 @@ +--- +title: Which level is right for you? +date: 2024-02-20 +permalink: archive/2024/02/20/which-level-is-right-for-you +snippet: | + TODO +tags: + - software-development + - static-analysis + - php + - phpstan +--- + +Today, whilst working on [Versa], I was experimenting with different PHPStan levels. + +Level 1 is the least strict level, and applies the fewest rules and returns the fewest results. + +As you increase the level, the stricter PHPStan is. + +## Levelling up to 9 + +Here is the code to get the values of the `--extra-args` and `--working-dir` options: + +```language-php +$extraArgs = $input->getOption('extra-args'); +$workingDir = $input->getOption('working-dir'); +``` + +This passed PHPStan level 8, but these are the errors I get when running level 9: + +```language-plain +------ ------------------------------------------------------------------------------------------------------- + Line versa +------ ------------------------------------------------------------------------------------------------------- + 61 Parameter $extraArgs of static method App\Process\Process::create() expects string|null, mixed given. + 62 Parameter $workingDir of static method App\Process\Process::create() expects string, mixed given. + 72 Parameter $extraArgs of static method App\Process\Process::create() expects string|null, mixed given. + 73 Parameter $workingDir of static method App\Process\Process::create() expects string, mixed given. + 84 Parameter $extraArgs of static method App\Process\Process::create() expects string|null, mixed given. + 85 Parameter $workingDir of static method App\Process\Process::create() expects string, mixed given. + 94 Parameter $extraArgs of static method App\Process\Process::create() expects string|null, mixed given. + 95 Parameter $workingDir of static method App\Process\Process::create() expects string, mixed given. + 104 Parameter $extraArgs of static method App\Process\Process::create() expects string|null, mixed given. + 105 Parameter $workingDir of static method App\Process\Process::create() expects string, mixed given. + 119 Parameter $extraArgs of static method App\Process\Process::create() expects string|null, mixed given. + 120 Parameter $workingDir of static method App\Process\Process::create() expects string, mixed given. +------ ------------------------------------------------------------------------------------------------------- + +[ERROR] Found 12 errors +``` + +The issue is that `$input->getOption()` from Symfony's `InputInterface` returns `mixed` - even though it always returns `null` or a string. + +If I did `--working-dir 2`, it would return the string `"2"`. + +An empty string throws an error, and an empty value (if there are no extra arguments) returns `null`. + +So, I know `$workingDir` will always be a string and `$extraArgs` will either a string or `null`. + +## Passing level 8 + +To pass level 8, PHPStan needs to be sure the variables are what I think they are. + +Here's the code I can use to get it to pass: + +```language-php +$extraArgs = $input->getOption('extra-args'); +$workingDir = $input->getOption('working-dir'); +assert(is_string($extraArgs) || is_null($extraArgs)); +assert(is_string($workingDir)); +``` + +By using `assert()` and throwing an Exception if the condition fails, PHPStan is now happy with the code and my code passes level 9. + +## Here's the thing + +Although the extra code gets PHPStan to pass, it it worth it? + +Is this extra code adding value? Does it make the code more readable or is it likely to prevent a bug? + +In this case, I know the value will always be the type I expect. + +I can work around this using a baseline or annotations for PHPStan to ignore these lines, **or is level 8 good enough for this project**? + +Similar to 100% test coverage, is aiming for the highest PHPStan level an objective to be met, or is enough value being added added by the lower level? + +Which level is right for you and this codebase? + +[versa]: {{site.url}}