diff --git a/composer.json b/composer.json index 12e8fc8a143..6384250bc36 100644 --- a/composer.json +++ b/composer.json @@ -116,7 +116,7 @@ ], "verify-callmap": "@php phpunit tests/Internal/Codebase/InternalCallMapHandlerTest.php", "psalm": "@php ./psalm", - "psalm-set-baseline": "@php ./psalm --set-baseline=psalm-baseline.xml", + "psalm-set-baseline": "@php ./psalm --set-baseline", "tests": [ "@lint", "@cs", diff --git a/docs/running_psalm/dealing_with_code_issues.md b/docs/running_psalm/dealing_with_code_issues.md index 552dede75bc..84ac39765ee 100644 --- a/docs/running_psalm/dealing_with_code_issues.md +++ b/docs/running_psalm/dealing_with_code_issues.md @@ -95,11 +95,17 @@ If you wish to suppress all issues, you can use `@psalm-suppress all` instead of If you have a bunch of errors and you don't want to fix them all at once, Psalm can grandfather-in errors in existing code, while ensuring that new code doesn't have those same sorts of errors. +``` +vendor/bin/psalm --set-baseline +``` + +will generate a file psalm-baseline.xml containing the current errors. Alternateivly you can specify the name of your baseline file. + ``` vendor/bin/psalm --set-baseline=your-baseline.xml ``` -will generate a file containing the current errors. You should commit that generated file so that Psalm can use it when running in other places (e.g. CI). It won't complain about those errors either. +You should commit that generated file so that Psalm can use it when running in other places (e.g. CI). It won't complain about those errors either. You have two options to use the generated baseline when running psalm: diff --git a/src/Psalm/Config.php b/src/Psalm/Config.php index cc07a42a6bf..ee95eb1b00e 100644 --- a/src/Psalm/Config.php +++ b/src/Psalm/Config.php @@ -132,6 +132,7 @@ final class Config { private const DEFAULT_FILE_NAME = 'psalm.xml'; + final public const DEFAULT_BASELINE_NAME = 'psalm-baseline.xml'; final public const CONFIG_NAMESPACE = 'https://getpsalm.org/schema/config'; final public const REPORT_INFO = 'info'; final public const REPORT_ERROR = 'error'; diff --git a/src/Psalm/Internal/Cli/Psalm.php b/src/Psalm/Internal/Cli/Psalm.php index 4d30075f1aa..6a9a7bb5ed0 100644 --- a/src/Psalm/Internal/Cli/Psalm.php +++ b/src/Psalm/Internal/Cli/Psalm.php @@ -133,7 +133,7 @@ final class Psalm 'report:', 'report-show-info:', 'root:', - 'set-baseline:', + 'set-baseline::', 'show-info:', 'show-snippet:', 'stats', @@ -273,7 +273,6 @@ public static function run(array $argv): void $config->debug_emitted_issues = true; } - setlocale(LC_CTYPE, 'C'); if (isset($options['set-baseline'])) { @@ -641,7 +640,7 @@ private static function initProviders(array $options, Config $config, string $cu } /** - * @param array{"set-baseline": string, ...} $options + * @param array{"set-baseline": mixed, ...} $options * @return array}>> */ private static function generateBaseline( @@ -652,10 +651,13 @@ private static function generateBaseline( ): array { fwrite(STDERR, 'Writing error baseline to file...' . PHP_EOL); + $errorBaseline = ((string) $options['set-baseline']) + ?: $config->error_baseline ?: Config::DEFAULT_BASELINE_NAME; + try { $issue_baseline = ErrorBaseline::read( new FileProvider, - $options['set-baseline'], + $errorBaseline, ); } catch (ConfigException) { $issue_baseline = []; @@ -663,18 +665,20 @@ private static function generateBaseline( ErrorBaseline::create( new FileProvider, - $options['set-baseline'], + $errorBaseline, IssueBuffer::getIssuesData(), $config->include_php_versions_in_error_baseline || isset($options['include-php-versions']), ); - fwrite(STDERR, "Baseline saved to {$options['set-baseline']}."); + fwrite(STDERR, "Baseline saved to $errorBaseline."); - CliUtils::updateConfigFile( - $config, - $path_to_config ?? $current_dir, - $options['set-baseline'], - ); + if ($errorBaseline !== $config->error_baseline) { + CliUtils::updateConfigFile( + $config, + $path_to_config ?? $current_dir, + $errorBaseline, + ); + } fwrite(STDERR, PHP_EOL); @@ -1037,7 +1041,7 @@ private static function initBaseline( ): array { $issue_baseline = []; - if (isset($options['set-baseline']) && is_string($options['set-baseline'])) { + if (isset($options['set-baseline'])) { if ($paths_to_check !== null) { fwrite(STDERR, PHP_EOL . 'Cannot generate baseline when checking specific files' . PHP_EOL); exit(1); @@ -1285,11 +1289,13 @@ private static function getHelpText(): string Output the taint graph using the DOT language – requires --taint-analysis Issue baselines: - --set-baseline=PATH + --set-baseline[=PATH] Save all current error level issues to a file, to mark them as info in subsequent runs Add --include-php-versions to also include a list of PHP extension versions + Default value is `psalm-baseline.xml` + --use-baseline=PATH Allows you to use a baseline other than the default baseline provided in your config diff --git a/tests/EndToEnd/PsalmEndToEndTest.php b/tests/EndToEnd/PsalmEndToEndTest.php index fcb66e2b711..1e1f8124ab6 100644 --- a/tests/EndToEnd/PsalmEndToEndTest.php +++ b/tests/EndToEnd/PsalmEndToEndTest.php @@ -194,6 +194,22 @@ public function testTainting(): void $this->assertSame(2, $result['CODE']); } + public function testPsalmSetBaseline(): void + { + $this->runPsalmInit(1); + $this->runPsalm(['--set-baseline'], self::$tmpDir, true); + + $this->assertSame(0, $this->runPsalm([], self::$tmpDir)['CODE']); + } + + public function testPsalmSetBaselineWithArgument(): void + { + $this->runPsalmInit(1); + $this->runPsalm(['--set-baseline=psalm-custom-baseline.xml'], self::$tmpDir, true); + + $this->assertSame(0, $this->runPsalm([], self::$tmpDir)['CODE']); + } + public function testTaintingWithoutInit(): void { $result = $this->runPsalm(['--taint-analysis'], self::$tmpDir, true, false); @@ -210,7 +226,7 @@ public function testTaintGraphDumping(): void $result = $this->runPsalm( [ '--taint-analysis', - '--dump-taint-graph='.self::$tmpDir.'/taints.dot', + '--dump-taint-graph=' . self::$tmpDir . '/taints.dot', ], self::$tmpDir, true, @@ -219,7 +235,7 @@ public function testTaintGraphDumping(): void $this->assertSame(2, $result['CODE']); $this->assertFileEquals( __DIR__ . '/../fixtures/expected_taint_graph.dot', - self::$tmpDir.'/taints.dot', + self::$tmpDir . '/taints.dot', ); } @@ -263,7 +279,7 @@ private function runPsalmInit(?int $level = null, ?string $php_version = null): if ($level) { $args[] = 'src'; - $args[] = (string) $level; + $args[] = (string)$level; } $ret = $this->runPsalm($args, self::$tmpDir, false, false);