forrest79 / phpcs-ignores
PHPCS-Ignores 提供了为原始 PHPCS 使用基线或其他忽略功能。
Requires
- php: ^8.0
- nette/neon: ^3.3
- squizlabs/php_codesniffer: ^3.8
Requires (Dev)
- forrest79/phpcs: ^1.1
- phpstan/phpstan: ^1.10
- phpstan/phpstan-strict-rules: ^1.5
README
介绍
此包提供了为 PHPCS 忽略具体错误的能力。您可以在 PHPCS 中通过 XML 设置或 PHP 代码中的注解来实现。使用此包,您可以在外部文件中定义错误列表。灵感来自 PHPStan 基线。如果您熟悉这个(您应该熟悉),那么定义和使用您自己的忽略/基线将很容易。主要区别是消息必须与 PHPCS 提供的完全相同(在 PHPStan 中消息是正则表达式),并且您必须始终为单个忽略使用所有属性(message
、sniff
、path
和 count
- 您不能定义全局忽略)。这种方法的最佳优势是,在文件重构期间,您不需要更新您的定义文件。
安装
要使用此扩展,请在 Composer 中引入它
composer require --dev forrest79/phpcs-ignores
使用
忽略列表使用 neon 格式,如下所示
ignoreErrors: - sniff: SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint message: 'Method \Forrest79\PhpCsIgnores\Tests\File1::method1() does not have native type hint for its parameter $report but it should be possible to add it based on @param annotation "bool".' count: 1 path: File1.php - sniff: SlevomatCodingStandard.TypeHints.ReturnTypeHintSpacing.WhitespaceBeforeColon message: There must be no whitespace between closing parenthesis and return type colon. count: 1 path: File2.php
第一行 ignoreErrors:
定义了一个结构/数组。数组中的项是一个错误。您必须提供具体的 sniff
、message
、path
和 count
。
sniff
和 message
由 PHPCS 报告提供。file
是从 neon 文件目录到检查文件的绝对路径或相对路径,count
是此错误在文件中出现的次数。
neon 文件在包含您的 XML 设置的目录(以及每个包含的 XML)中搜索,或在当前目录中,名称必须以 XML 设置的名称开头(或 phpcs
/.phpcs
),前缀可以是您想要的任何内容,扩展名必须是 .neon
。您可以使用多个 neon
文件,并且设置将合并(我个人在遗留项目中使用 phpcs-baseline.neon
来修复未来的错误,并使用 phpcs-ignores.neon
来定义有效的忽略)。
示例
- PHPCS 设置在
phpcs.xml
中 - neon 可以是phpcsignores.neon
或phpcs-baseline.neon
或phpcs-whateveryouwant.neon
- PHPCS 设置在
mysettings.xml
中 - neon 可以是mysettings.neon
或mysettings-baseline.neon
或mysettings-whateveryouwant.neon
如何在 PHPCS 中使用您的基线/忽略
这非常简单(如果您没有使用自己的引导文件 - 如果您正在使用一个,您必须手动在您的 PHP 引导文件中包含我们的引导文件),只需使用您的 PHPCS 设置/命令行参数并添加我们的引导文件。在命令行中如下所示
vendor/bin/phpcs --bootstrap=vendor/forrest79/phpcs-ignores/src/bootstrap.php -sp src tests
只需使用正确的路径。这应该可以与所有其他 PHPCS 设置(如 cache
和 parellel
)一起工作。
默认情况下,您将被告知已处理的文件中所有过时的忽略,因此您可以从 neon 文件中简单地删除这些定义。但如果您还希望了解在分析期间未匹配的整个文件,则必须使用第二个引导 bootstrap-outdated.php
,并且您必须确保您正在对整个存储库进行分析。如果您例如仅使用 PHPCS 对更改的文件进行分析(通过 GIT),则不能使用此检测,因为您将收到许多假阳性消息。
如果您想忽略关于过时错误和文件的通知,可以使用第三方 Bootstrap bootstrap-hide-outdated-warnings.php
。
已知限制
- 由于消息不是正则表达式,而是具体的字符串,因此在您想在其他环境中运行 PHPCS 的情况下,包含绝对文件路径的消息的 sniffs 将不会正常工作。
- PHPCBF(修复器)- 如果某些错误在一个文件中多次出现,并且其中一些
count
被忽略,则修复的总是最后一个错误。前count
个错误将被忽略,其余的错误将被修复。因此,可能会修复您不想要的错误。目前对此无能为力 - 您必须在修复后手动更新这些文件。
生成基线
您可以直接从现有错误生成基线 neon
文件。只需使用我们的 BaselineReport
vendor/bin/phpcs --report=\\Forrest79\\PhpCsIgnores\\BaselineReport -s src tests
生成的 neon 文件将输出到标准输出,因此您可能希望直接将其数据发送到某个文件。
vendor/bin/phpcs --report=\\Forrest79\\PhpCsIgnores\\BaselineReport -s src tests > phpcs-baseline.neon
您可能需要更新生成的列表中的路径(路径可能是绝对路径或相对路径,具体取决于您的源文件以及您在哪个目录下运行 PHPCS) - 这可以在您喜欢的编辑器中通过查找和替换功能简单地完成。
它是如何工作的?
好的,PHPCS 是一个真正古老的(但很好的!)软件,不能轻易扩展,所以必须进行一些破解和一些魔法,并祈祷这仍然能在下一个版本中工作。我走过很多死胡同,其中一些可以在第一次提交中看到。我希望这个包能在所有未来的 v3 版本中幸存下来,并希望在未来 v4 中,将有一些内部能力来实现这一点。
我不想在 vendor
中实际更改文件(如我的灵感包 https://github.com/123inkt/php-codesniffer-baseline),所以我决定使用像 bypassFinal
一样的动态更改 PHP 文件的方法,在我的最爱 PHP 测试器 Nette Tester 中。所以我找到了原始 PHPCS 中处理错误的地方 - 它在这个对象 PHP_CodeSniffer\Files\LocalFile
中。我需要扩展这个对象并添加自己的逻辑。我找到了创建此对象的地方,并通过 PhpCsInjections.php
更新了这个文件 - 所以我的对象 File
是创建的,而不是原始的 PHP_CodeSniffer\Files\LocalFile
。
这是主要的魔法。注入只适用于尚未通过 PHP 加载的文件,所以我希望尽可能早地启用它。为此,我使用了引导文件。PHPCS 在生命周期开始时直接将此包含在主 PHP_CodeSniffer\Runner
中。这将注册注入,加载 neon 设置并设置 config->recordErrors = TRUE
- 我们始终需要启用 recordErrors
(它可以通过设置禁用,并且修复器已禁用),没有这个,错误消息不会生成,我们无法检查是否有忽略。
最后,检查处理文件中的错误,设置忽略的消息,并添加有关过时消息的信息。对于 PHPCS,这是在 process()
方法完成后完成的。这是因为我们想要缓存完全写入,这是在原始的 process()
方法中完成的。因此,我们检查现有的错误,删除被忽略的错误,更新计数,并检查哪些错误是过时的,并将这些添加为警告。
对于 PHPCBF,我们需要在 addMessage()
方法中检查错误,因为对于忽略的错误,我们需要立即返回 FALSE
以不修复这个忽略的错误。修复是在多个循环中运行的,并且在每个循环中我们都需要忽略相同的错误,因此在每个处理后,忽略错误都会为修复器重置。
通过 OutdatedFiles
对象检查过时文件,该对象通过 bootstrap-outdated.php
激活。这里没有特别需要写的内容,只是确保在并行模式下正确工作的代码(使用 /tmp
中的临时文件)。
如果您是 PHPCS 的专家用户,请随时添加问题或 PR,提出建议和改进。谢谢!