blablatdinov/ondivi
GitHub: blablatdinov/ondivi
一个基于 Git diff 过滤静态分析违规的 Python 工具,帮助遗留项目以增量方式逐步落地代码规范,而不被历史技术债阻塞。
Stars: 39 | Forks: 2
# Ondivi (仅差异违规)
[](https://github.com/wemake-services/wemake-python-styleguide)
[](https://badge.fury.io/py/ondivi)

[](https://github.com/XAMPPRocky/tokei_rs)
[](https://hitsofcode.com/github/blablatdinov/quranbot-aiogram/view)
厌倦了 10,000 条 lint 错误阻碍你的团队采用代码质量工具?
Ondivi 让你仅针对新的更改强制执行编码标准,
使在任何遗留项目中采用 linter 成为可能。
此工具适用于任何 linter 或静态代码分析器,包括但不限于:
- [Flake8](https://github.com/PyCQA/flake8)
- [Ruff](https://github.com/astral-sh/ruff)
- [Pylint](https://github.com/pylint-dev/pylint)
- [Mypy](https://github.com/python/mypy)
- [Eslint](https://github.com/eslint/eslint)
- [Rubocop](https://github.com/rubocop/rubocop)
- [Stylelint](https://github.com/stylelint/stylelint)
## 在遗留代码中采用 Linter
**问题**:
- 你的 20 万行代码项目有 5,000 多个 lint 违规
- 强制使用 linter 将会阻碍所有开发进度
- 技术债不断累积
**Ondivi 的解决方案**:
1. 像往常一样运行你的 linter:`flake8 .`
2. 通过管道传递给 ondivi:`flake8 . | ondivi --baseline=main`
3. 只有在新更改引入违规时,CI 才会失败
4. 旧的违规会被忽略(暂时)
**结果**:干净的新代码,遗留代码逐步重构。
## 前置条件:
- [Python](https://python.org) 3.9 或更高版本
- [Git](https://git-scm.com/)
## 安装
```
pip install ondivi
```
## 使用方法
确保你位于 Git 仓库的根目录中。
运行脚本:
```
flake8 script.py | ondivi
# 使用 ruff:
ruff check file.py --output-format=concise | ondivi
```
或者:
```
flake8 script.py > violations.txt
ondivi --fromfile=violations.txt
```
```
$ ondivi --help
Usage: ondivi [OPTIONS]
Ondivi (Only diff violations).
Python script filtering coding violations, identified by static analysis,
only for changed lines in a Git repo. Usage example:
flake8 script.py | ondivi
Options:
--baseline TEXT Commit or branch which will contain legacy code. Program
filter out violations on baseline (default: "master")
--fromfile TEXT Path to file with violations. Expected "utf-8" encoding
--format TEXT Template for parsing linter messages. The template should
include the following named parts:
{filename} The name of the file with the error/warning
{line_num} The line number with the error/warning
(integer)
Example usage:
--format "{filename}:{line_num:d}{other}"
In this example, the linter message
"src/app_types/listable.py:23:1: UP035 Import from
collections.abc instead: Sequence"
will be recognized and parsed into the following
components:
- filename: "src/app_types/listable.py"
- line_num: 23
- other: :1: "UP035 Import from collections.abc instead:
Sequence"
Ensure that the template matches the format of the
messages generated by your linter.
(default: "{filename}:{line_num:d}{other}")
--only-violations Show only violations
--help Show this message and exit.
```
## 工作原理
该脚本解析 Git diff 输出,以识别每个文件中更改的行。
然后它过滤给定的代码违规,仅包含与更改行相对应的违规。
[flakeheaven](https://github.com/flakeheaven/flakeheaven) 和 [flakehell](https://github.com/flakehell/flakehell)
不受支持,因为它们依赖于 flake8 的内部 API,随着 flake8 的
发展,这可能会导致兼容性问题。相比之下,ondivi 仅使用违规的文本输出和 Git 仓库的状态,这使其
更加健壮且易于维护。
文件上的 Flake8:
```
$ flake8 file.py
file.py:3:1: E302 expected 2 blank lines, found 1
file.py:9:1: E302 expected 2 blank lines, found 1
file.py:10:121: E501 line too long (123 > 120 characters)
file.py:14:1: E305 expected 2 blank lines after class or function definition, found 1
```
更改示例:
```
from dataclasses import dataclass
@dataclass
class User(object):
name: str
age: int
def greet(user: User):
print('Long string in initial commit ################################################################################')
print(f'Hello, {user.name}!')
+ print('Long string in new commit ################################################################################')
if __name__ == '__main__':
greet(User(345, 23))
+ greet(User('Bob', '23'))
```
通过 git diff 我们可以看到,新增了两行(12 行和 16 行):
Ondivi 过滤违规,并且只显示第 12 行的一个违规:
```
$ flake8 script.py | ondivi
file.py:12:80: E501 line too long (119 > 79 characters)
```
## 许可证
本项目基于 MIT 许可证授权。详情请参见 [LICENSE](./LICENSE) 文件。
标签:Apache Flink, DevOps工具, ESLint, Flake8, Git差异过滤, lint过滤工具, LNA, Mypy, Pylint, RuboCop, Ruff, Stylelint, 代码审查, 代码规范化, 代码规范检查, 开源框架, 技术债务管理, 持续集成, 网络安全研究, 逆向工具, 遗留代码重构, 错误基检测, 静态代码分析