15 个版本 (5 个重大更新)
0.8.0 | 2022年5月6日 |
---|---|
0.5.3 | 2021年11月17日 |
0.4.3 | 2021年11月12日 |
0.3.0 | 2021年11月4日 |
0.1.1 | 2021年10月22日 |
#1867 在 开发工具
每月39 次下载
78KB
1.5K SLoC
Lintrunner
概述
lintrunner
是一个运行代码检查的工具。它负责
- 决定哪些文件需要进行代码检查。
- 根据通用协议调用代码检查器。
- 收集结果并向用户展示。
目的是提供一个通用的方式来配置和调用代码检查器,这在大型多语言项目中非常有用。
lintrunner
的设计受到了 Meta 内部项目 linttool
的极大启发。
安装
pip install lintrunner
使用方法
首先,您需要将配置文件添加到您的代码库中。有关更多信息,请参阅代码检查配置部分。
然后,只需运行 lintrunner
来检查您的更改!
如何控制 lintrunner
检查的路径
当不带参数运行时,lintrunner
将检查
HEAD
提交中更改的文件。- 用户工作树中更改的文件。
它不会检查
- 任何未被
git
跟踪的文件;通过git add
将它们添加到代码检查。
有多种方法可以自定义路径的检查方式
将路径作为位置参数传递
例如
lintrunner foo.py bar.cpp
这自然与 xargs
结合使用,例如检查代码库中每个路径的规范方式是
git grep -Il . | xargs lintrunner
--paths-cmd
某些调用 xargs
的方式会导致运行多个 lintrunner
进程,从而增加代码检查时间(特别是在大型路径集上)。作为替代方案,您可以使用 --paths-cmd
来使 lintrunner
控制并行化。如果指定了 --paths-cmd
,则 lintrunner
将执行该命令,并将其 stdout
的每一行视为一个要检查的文件。
例如,上面的相同命令将是
lintrunner --paths-cmd='git grep -Il .'
--paths-file
如果指定了此选项,lintrunner
将从给定文件中读取路径,每行一个,并检查这些路径。如果您有一些非常复杂的逻辑来确定要检查的路径,这可能会很有用。
--revision
此值可以是git diff-tree
接受的任何<tree-ish>
,例如提交哈希或revspec。如果指定了此选项,lintrunner
将检查
- 从
<tree-ish>
到HEAD
的所有已更改路径 - 用户工作树中的所有已更改路径。
--merge-base-with
与--revision
类似,但版本是通过计算HEAD
和提供的<tree-ish>
的merge-base来确定的。这对于检查特定拉取请求中的所有提交很有用。例如,对于一个针对master的拉取请求,您可以运行
lintrunner -m master
代码检查器配置
lintrunner
通过查看配置文件来确定要运行哪些代码检查器和如何运行,配置文件通常命名为.lintrunner.toml
。
以下是一个代码检查器配置示例
[[linter]]
name = 'FLAKE8'
include_patterns = [
'src/**/*.py', # unix-style globs supported
'test/**/*.py',
]
exclude_patterns = ['src/my_bad_file.py']
command = [
'python3',
'flake8_linter.py',
'—-',
# {{PATHSFILE}} gets rewritten to a tmpfile containing all paths to lint
'@{{PATHSFILE}}',
]
配置架构的完整描述可以在这里找到。
代码检查器协议
大多数代码检查器都有自己的输出格式和参数。为了在代码检查器调用和输出上强制一致性,lintrunner
实现了一个它期望代码检查器遵守的协议。在大多数情况下,需要一个小的脚本(称为代码检查器适配器)来实现特定外部代码检查器的协议。您可以在examples/
中查看一些示例适配器。
调用
代码检查器将根据它们的配置中指定的command
被调用。每个代码检查运行只调用一次。
如果代码检查器需要知道要运行的路径,它应接受一个{{PATHSFILE}}
参数。在调用期间,字符串{{PATHSFILE}}
将被替换为包含代码检查器应运行的路径的临时文件名,每行一个路径。
在代码检查器适配器中实现此功能的一种常见方法是使用argparse
的fromfile_prefix_chars
功能。在上面的Flake8示例中,我们使用@
作为fromfile_prefix_chars
参数,因此argparse
将自动读取{{PATHSFILE}}
并将内容作为参数列表提供。
输出
任何linter想要向用户传达的lint信息都必须表示为 LintMessage
。linter必须将LintMessage
作为JSON Lines打印到stdout
,每行一个信息。输出到stderr
的内容将被忽略。
关于LintMessage模式的完整描述可以在这里找到:这里。
退出
linter应该始终以代码0退出。即使在报告lint错误的情况下也是如此;lintrunner
本身将根据linter的报告来决定如何退出。
为了表示一个通用的linter失败(理想情况下不应该发生!),linter可以返回一个具有path = None
的LintMessage
。
如果linter以非零退出,它将被lintrunner
捕获,并作为一个“通用的linter失败”呈现给用户,同时将stdout/stderr展示给用户。这应该被认为是linter实现此协议的bug。
依赖关系
~11–22MB
~326K SLoC