Metadata-Version: 2.1
Name: ky-git-log-transfer
Version: 1.0.2
Summary: A tool to convert git log to RPM spec changelog format
Home-page: None
Author: lichangxin
Author-email: lichangxin@kylinos.cn
License: Non open source, The copyright belongs to KylinSoft Co., Ltd.
Keywords: git,changelog,rpm,spec,packaging
Classifier: Development Status :: 3 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Topic :: Software Development :: Version Control :: Git
Classifier: Topic :: System :: Software Distribution
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: POSIX :: Linux
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE

# ky-git-log-transfer

将git log转换为changelog格式的命令行工具。

## 功能特性

- **多格式输出**：spec、文本、Markdown、JSON、XML、HTML、CSV
- **高级过滤**：作者、日期范围、正则表达式、关键词、文件路径、提交类型、标签、分支、合并提交
- **输出目标**：标准输出、文件
- **智能分类**：自动识别提交类型（功能、修复、重构、文档、测试、样式、杂项等）

- **配置系统**：支持多级配置文件（项目级、用户级、系统级）
- **排序选项**：正向/反向排序，限制提交数量

- **批量生成**：按天/周/月自动分段生成多个 changelog 文件
- **模板系统**：支持Jinja2风格模板，自定义输出格式，内置22个过滤器

## 安装

### 从源码安装

```bash
cd /path/to/ky-git-log-transfer
pip install -e .
```

### 从RPM包安装

如果你有RPM包管理系统，可以直接安装预构建的RPM包：

**依赖要求**：
- Python 3.7+
- Git

**安装方法**：
```bash
# 安装RPM包（需要root权限）
sudo rpm -i ky-git-log-transfer-*.noarch.rpm

# 或者使用yum/dnf安装
sudo yum install ky-git-log-transfer-*.noarch.rpm

# 对于Ubuntu/Debian系统，可以使用alien转换
sudo alien -i ky-git-log-transfer-*.rpm
```

安装后，可以直接使用 `ky-git-log-transfer` 命令。

### 直接运行

```bash
python -m src.main --help
```

## 使用方法

### 基本用法

```bash
# 在当前仓库生成changelog并输出到终端
ky-git-log-transfer --repo .

# 生成Markdown格式的changelog并保存到文件
ky-git-log-transfer --repo . --format markdown --output CHANGELOG.md

# 过滤特定作者的提交
ky-git-log-transfer --repo . --author "张三"

# 指定日期范围
ky-git-log-transfer --repo . --since 2023-01-01 --until 2023-12-31

# 限制提交数量
ky-git-log-transfer --repo . --limit 10

# 反向排序（从旧到新）
ky-git-log-transfer --repo . --reverse
```

### 高级用法

```bash
# 使用正则表达式过滤提交
ky-git-log-transfer --repo . --regex "^fix:.*"

# 多关键词过滤
ky-git-log-transfer --repo . --keyword "bug" --keyword "fix"

# 排除特定类型的提交
ky-git-log-transfer --repo . --exclude "chore" --exclude "docs"

# 按提交类型过滤
ky-git-log-transfer --repo . --type feature --type fix

# 生成HTML格式的changelog
ky-git-log-transfer --repo . --format html --output changelog.html


# 使用配置文件
ky-git-log-transfer --repo . --config myconfig.json

# 只显示特定分支的提交
ky-git-log-transfer --repo . --branch main

# 只显示合并提交
ky-git-log-transfer --repo . --merge

# 排除合并提交
ky-git-log-transfer --repo . --no-merge

# 组合多个过滤条件
ky-git-log-transfer --repo . --since 2023-01-01 --type feature --author "张三" --limit 20
```

### 批量生成

```bash
# 按周自动分段生成 changelog
ky-git-log-transfer --repo . --batch --batch-start 2023-01-01 --batch-end 2023-03-31 --batch-interval week --output changelog.txt

# 按月分段，每段一个文件（自动在文件名中追加日期）
ky-git-log-transfer --repo . --batch --batch-start 2023-01-01 --batch-end 2023-06-30 --batch-interval month --output changelog.txt
```

批量模式下，若指定了 `--output changelog.txt`，每个时间段的输出文件将自动命名为 `changelog_20230101.txt`、`changelog_20230201.txt` 等。

### 模板使用

模板系统允许你使用自定义模板生成任意格式的输出。模板使用Jinja2风格的语法，支持变量、条件、循环和过滤器。

#### 基本用法

```bash
# 使用模板文件生成输出
ky-git-log-transfer --repo . --template mytemplate.j2 --output custom_changelog.txt

# 使用内联模板
ky-git-log-transfer --repo . --template "共 {{ total_commits }} 个提交" --output summary.txt


```

#### 模板语法示例

```jinja2
{# 这是一个注释 #}
项目: {{ project|default("Unknown Project") }}

{% if commits %}
共 {{ commits|length }} 个提交：

{% for commit in commits %}
* {{ commit.hash[:8] }} - {{ commit.message|truncate(50) }}
  作者: {{ commit.author }} ({{ commit.email }})
  日期: {{ commit.date|date("%Y-%m-%d") }}
  {% if commit.type == "feature" %}[新功能]{% endif %}
{% endfor %}
{% else %}
没有提交记录
{% endif %}


```

#### 可用上下文变量

- `commits`: 提交对象列表
  - `hash`: 完整的提交哈希
  - `author`: 作者姓名
  - `email`: 作者邮箱
  - `date`: 提交日期 (datetime对象)
  - `message`: 提交信息
  - `type`: 提交类型 (feature/fix/refactor/docs/test/style/chore/other)
- `total_commits`: 提交总数

#### 内置过滤器 (22个)

| 过滤器 | 描述 | 示例 |
|--------|------|------|
| `upper` | 转换为大写 | `{{ text\|upper }}` |
| `lower` | 转换为小写 | `{{ text\|lower }}` |
| `title` | 单词首字母大写 | `{{ text\|title }}` |
| `capitalize` | 首字母大写 | `{{ text\|capitalize }}` |
| `trim` | 去除空白 | `{{ text\|trim }}` |
| `truncate` | 截断文本 | `{{ text\|truncate(50) }}` |
| `date` | 格式化日期 | `{{ date\|date("%Y-%m-%d") }}` |
| `length` | 获取长度 | `{{ list\|length }}` |
| `join` | 连接列表 | `{{ items\|join(", ") }}` |
| `default` | 默认值 | `{{ value\|default("N/A") }}` |
| `escape` | HTML转义 | `{{ html\|escape }}` |
| `tojson` | 转换为JSON | `{{ data\|tojson }}` |
| `replace` | 字符串替换 | `{{ text\|replace("old", "new") }}` |
| `split` | 分割字符串 | `{{ text\|split(",") }}` |
| `format` | 格式化字符串 | `{{ value\|format("Result: {}") }}` |
| `sort` | 排序列表 | `{{ items\|sort }}` |
| `reverse` | 反转列表 | `{{ items\|reverse }}` |
| `first` | 获取第一个元素 | `{{ items\|first }}` |
| `last` | 获取最后一个元素 | `{{ items\|last }}` |
| `int` | 转换为整数 | `{{ "42"\|int }}` |
| `float` | 转换为浮点数 | `{{ "3.14"\|float }}` |
| `str` | 转换为字符串 | `{{ number\|str }}` |
| `bool` | 转换为布尔值 | `{{ value\|bool }}` |

#### 高级功能

- **包含模板**: 使用 `{% include "header.j2" %}` 包含其他模板文件
- **安全求值**: 表达式求值器限制可用的函数和操作，防止代码注入
- **模板缓存**: 自动缓存已加载的模板文件
- **零依赖**: 纯Python实现，无需安装Jinja2等外部库

### 命令行选项

```
通用选项:
  --repo, -r           Git仓库路径 (默认: 当前目录)
  --output, -o         输出文件路径 (如果不指定则输出到标准输出)
  --format, -f         输出格式 [spec|text|markdown|json|xml|html|csv] (默认: spec)
  --limit, -l          限制提交数量
  --reverse            反向排序 (从旧到新)
  --help               显示帮助信息

过滤选项:
  --author, -a         过滤提交作者 (支持部分匹配)
  --since              起始日期 (格式: YYYY-MM-DD)
  --until              结束日期 (格式: YYYY-MM-DD)
  --regex, -x          使用正则表达式过滤提交信息
  --keyword, -k        关键词过滤 (可多次使用)
  --file               过滤涉及的文件路径 (可多次使用)
  --exclude            排除包含关键词的提交 (可多次使用)
  --type               过滤提交类型 [feature|fix|refactor|docs|test|style|chore|other] (可多次使用)
  --branch, -b         指定分支 (默认: 当前分支)
  --tag                过滤包含特定标签的提交
  --tag-range          过滤标签范围内的提交 (例如: v1.0.0..v2.0.0)
  --merge              只包含合并提交
  --no-merge           排除合并提交
  --first-parent       遇到合并提交时只追踪第一个父提交
  --skip               在显示输出之前跳过的提交数量
  --grep-all-match     要求提交满足所有 --regex/--keyword 条件 (AND 逻辑)

高级功能:
  --config             配置文件路径
  --stats              生成统计报告

  --template           模板文件路径或内联模板字符串 (覆盖 --format 选项)

  --batch              启用批量生成模式
  --batch-start        批量起始日期 (格式: YYYY-MM-DD, --batch 时必填)
  --batch-end          批量结束日期 (格式: YYYY-MM-DD, --batch 时必填)
  --batch-interval     批量分段间隔 [day|week|month] (默认: week)
```

## 输出示例

### spec 格式（默认）

适用于 RPM 打包流程中的 `%changelog` 段。

```
%changelog
* Sun Oct 1 2023 张三 <zhangsan@example.com>
- 添加用户登录功能

* Sun Oct 1 2023 李四 <lisi@example.com>
- 修复首页样式问题
```

### 文本格式

```
## 2023-10-01
----------------------------------------
[FEATURE] 添加用户登录功能 (abc123de)
  作者: 张三 <zhangsan@example.com>
[FIX] 修复首页样式问题 (def789gh)
  作者: 李四 <lisi@example.com>
```

### Markdown格式
```markdown
# Changelog

## 2023-10-01

### 新功能
- 添加用户登录功能 (`abc123de`)
- 优化数据库查询性能 (`ghijk123`)

### Bug修复
- 修复首页样式问题 (`def789gh`)
- 修复登录验证逻辑 (`lmno456`)
```

### JSON格式
```json
[
  {
    "hash": "abc123def4567890...",
    "author": "张三",
    "email": "zhangsan@example.com",
    "date": "2023-10-01",
    "time": "14:30:00",
    "timezone": "+0800",
    "message": "添加用户登录功能",
    "type": "feature"
  }
]
```

### XML格式
```xml
<?xml version="1.0" encoding="UTF-8"?>
<changelog>
  <commit>
    <hash>abc123def4567890...</hash>
    <author>张三</author>
    <email>zhangsan@example.com</email>
    <date>2023-10-01</date>
    <time>14:30:00</time>
    <timezone>+0800</timezone>
    <message>添加用户登录功能</message>
    <type>feature</type>
  </commit>
</changelog>
```

### CSV格式
```csv
hash,author,email,date,time,timezone,message,type
abc123def4567890...,张三,zhangsan@example.com,2023-10-01,14:30:00,+0800,添加用户登录功能,feature
```

## 项目结构

```
ky-git-log-transfer/
├── setup.py
├── requirements.txt
├── LICENSE
├── ky-git-log-transfer.spec
├── README.md
├── src/
│   ├── __init__.py
│   ├── main.py
│   ├── config.py                  # 配置系统模块
│   ├── constants.py
│   ├── template_engine.py         # 模板引擎模块
│   ├── cli/
│   │   ├── __init__.py
│   │   └── parser.py
│   ├── core/
│   │   ├── __init__.py
│   │   ├── git_parser.py
│   │   └── stats.py              # 统计模块
│   ├── formatters/
│   │   ├── __init__.py
│   │   ├── base.py
│   │   ├── spec_formatter.py
│   │   ├── text_formatter.py
│   │   ├── markdown_formatter.py
│   │   ├── json_formatter.py
│   │   ├── xml_formatter.py
│   │   ├── html_formatter.py
│   │   └── csv_formatter.py
│   └── utils/
│       ├── __init__.py
│       └── error_handling.py
└── test/                    # 模块化测试套件
    ├── __init__.py
    ├── test_commit.py        # Commit数据类测试
    ├── test_git_parser.py    # Git日志解析器测试
    ├── test_cli_parser.py    # 命令行参数解析测试
    ├── test_config.py        # 配置管理系统测试
    ├── test_stats.py         # 统计功能测试
    ├── test_formatters.py    # 所有7种格式化器测试
    ├── test_template_engine.py # 模板引擎测试
    ├── test_main.py          # 主程序集成测试
    ├── test_integration.py   # 整合测试文件
    ├── test_error_handling.py
    └── conftest.py           # 共享测试工具和fixtures
```

## 模块说明

- **main.py**: 程序入口。负责协调参数解析、调用 git 解析器获取提交列表、选择格式化器生成输出、写入文件或标准输出。支持单次和批量两种运行模式。
- **cli/parser.py**: 基于 `argparse` 实现的命令行解析模块。负责定义全部选项、解析参数为统一的 dict、以及在执行前校验日期格式和批量模式必填字段。
- **core/git_parser.py**: 核心模块。包含 `Commit` 数据类（带 `date_str`、`time_str`、`timezone_str` 属性）和 `GitLogParser` 类。后者通过调用 `git log` 获取原始数据并解析为 `Commit` 对象列表，同时内置提交类型分类逻辑。
- **core/stats.py**: 统计模块，提供详细的提交分析报告，包括作者排名、类型分布、时间线分析等，支持 text、markdown、json、html 四种输出格式。
- **config.py**: 配置管理器，支持多级配置文件（JSON和INI格式），支持项目级、用户级、系统级配置。
- **template_engine.py**: 纯Python模板引擎，支持Jinja2风格语法、变量、条件、循环、22个内置过滤器，安全表达式求值，零依赖。
- **formatters/base.py**: `BaseFormatter` 抽象基类，定义了 `format_commits` 和 `get_file_extension` 两个接口方法。
- **formatters/spec_formatter.py**: 生成 RPM spec 风格的 `%changelog` 输出。空提交列表时仍输出 `%changelog` 头部。
- **formatters/text_formatter.py**: 生成按日期分组、带类型标签的人类可读文本输出。
- **formatters/markdown_formatter.py**: 生成美观的 Markdown 格式输出，支持 emoji 图标和分类展示。
- **formatters/json_formatter.py**: 生成结构化 JSON 输出，便于程序处理。
- **formatters/xml_formatter.py**: 生成结构化 XML 输出，支持标准 XML 格式。
- **formatters/html_formatter.py**: 生成 HTML 表格格式输出，包含样式和颜色标识。
- **formatters/csv_formatter.py**: 生成 CSV 格式输出，便于电子表格处理。

## 配置系统

ky-git-log-transfer 提供灵活的配置系统，支持多级配置文件管理，允许您将常用的命令行参数保存到配置文件中，简化日常使用。

### 配置文件位置和优先级

配置系统按照以下优先级顺序查找配置文件（高优先级覆盖低优先级）：

1. **命令行参数** - 直接在命令行中指定的参数
2. **项目级配置** - Git仓库根目录或当前目录下的配置文件
3. **用户级配置** - 用户家目录下的配置文件
4. **系统级配置** - 系统全局配置文件

#### 具体文件路径

| 级别 | JSON格式 | INI格式 | 说明 |
|------|----------|---------|------|
| 项目级 | `.ky-git-log-transfer.json` | `.ky-git-log-transfer.ini` | Git仓库根目录（或当前目录） |
| 用户级 | `~/.config/ky-git-log-transfer/config.json` | `~/.config/ky-git-log-transfer/config.ini` | 用户配置目录 |
| 系统级 | `/etc/ky-git-log-transfer/config.json` | `/etc/ky-git-log-transfer/config.ini` | 系统全局配置 |

**注意**：配置文件名称统一使用 `ky-git-log-transfer`（不是 `git-log-transfer`）。

### 支持的配置文件格式

#### JSON格式（推荐）

JSON格式配置文件使用标准的JSON语法，顶层必须包含 `"ky-git-log-transfer"` 键，其值为配置对象。

```json
{
  "ky-git-log-transfer": {
    "repo": ".",
    "format": "markdown",
    "output": "CHANGELOG.md",
    "since": "2023-01-01",
    "keyword": ["feat", "fix"],
    "exclude": ["chore"],
    "type": ["feature", "fix"]
  }
}
```

#### INI格式

INI格式配置文件使用标准的INI语法，配置项放在 `[ky-git-log-transfer]` 段落中。

```ini
[ky-git-log-transfer]
repo = .
format = markdown
output = CHANGELOG.md
since = 2023-01-01
keyword = feat, fix
exclude = chore
type = feature, fix
```

**注意**：INI格式中，列表类型的值（如 `keyword`, `exclude`, `type` 等）可以使用逗号分隔的字符串，也可以使用多行重复的键名。

### 配置选项对应关系

配置文件的选项与命令行参数一一对应，以下是所有支持的配置选项：

| 配置选项 | 对应命令行参数 | 类型 | 说明 |
|----------|----------------|------|------|
| `repo` | `--repo`, `-r` | 字符串 | Git仓库路径（默认: "."） |
| `output` | `--output`, `-o` | 字符串 | 输出文件路径 |
| `format` | `--format`, `-f` | 字符串 | 输出格式（spec, text, markdown, json, xml, html, csv） |
| `template` | `--template` | 字符串 | 模板文件路径或内联模板字符串 |
| `limit` | `--limit`, `-l` | 整数 | 限制提交数量 |
| `author` | `--author`, `-a` | 字符串 | 过滤提交作者 |
| `since` | `--since` | 字符串 | 起始日期（YYYY-MM-DD格式） |
| `until` | `--until` | 字符串 | 结束日期（YYYY-MM-DD格式） |
| `regex` | `--regex`, `-x` | 字符串 | 使用正则表达式过滤提交信息 |
| `keyword` | `--keyword`, `-k` | 字符串列表 | 关键词过滤（可多个） |
| `file` | `--file` | 字符串列表 | 过滤涉及的文件路径（可多个） |
| `exclude` | `--exclude` | 字符串列表 | 排除包含关键词的提交（可多个） |
| `type` | `--type` | 字符串列表 | 过滤提交类型（可多个） |
| `branch` | `--branch`, `-b` | 字符串 | 指定分支 |
| `tag` | `--tag` | 字符串 | 过滤包含特定标签的提交 |
| `tag_range` | `--tag-range` | 字符串 | 过滤标签范围内的提交 |
| `merge` | `--merge` | 布尔值 | 只包含合并提交 |
| `no_merge` | `--no-merge` | 布尔值 | 排除合并提交 |
| `first_parent` | `--first-parent` | 布尔值 | 遇到合并提交时只追踪第一个父提交 |
| `skip` | `--skip` | 整数 | 跳过的提交数量 |
| `grep_all_match` | `--grep-all-match` | 布尔值 | 满足所有正则表达式/关键词 |
| `reverse` | `--reverse` | 布尔值 | 反向排序（从旧到新） |
| `batch` | `--batch` | 布尔值 | 启用批量生成模式 |
| `batch_start` | `--batch-start` | 字符串 | 批量起始日期（YYYY-MM-DD格式） |
| `batch_end` | `--batch-end` | 字符串 | 批量结束日期（YYYY-MM-DD格式） |
| `batch_interval` | `--batch-interval` | 字符串 | 批量分段间隔（day, week, month） |
| `config` | `--config` | 字符串 | 指定配置文件路径（覆盖自动查找） |
| `stats` | `--stats` | 布尔值 | 生成统计报告 |

### 高级配置示例

#### 复杂过滤配置
```json
{
  "ky-git-log-transfer": {
    "repo": "/path/to/project",
    "format": "markdown",
    "output": "docs/CHANGELOG.md",
    "since": "2024-01-01",
    "until": "2024-12-31",
    "author": "张三",
    "type": ["feature", "fix"],
    "keyword": ["重要", "紧急"],
    "exclude": ["chore", "docs"],
    "branch": "main",
    "merge": false,
    "reverse": true
  }
}
```

#### 批量生成配置
```json
{
  "ky-git-log-transfer": {
    "repo": ".",
    "format": "text",
    "batch": true,
    "batch_start": "2024-01-01",
    "batch_end": "2024-03-31",
    "batch_interval": "week",
    "output": "changelogs/changelog.txt"
  }
}
```

#### INI格式示例
```ini
[ky-git-log-transfer]
repo = /path/to/project
format = html
output = report/changelog.html
since = 2024-01-01
until = 2024-06-30
author = 李四
type = feature, fix, refactor
keyword = 优化, 性能
exclude = chore, style
branch = develop
merge = false
no_merge = true
reverse = false
```

### 使用配置文件

#### 自动加载
如果不指定 `--config` 参数，程序会自动按照优先级查找并使用配置文件：

```bash
# 自动查找并使用配置文件
ky-git-log-transfer --repo .
```

#### 显式指定
使用 `--config` 参数显式指定配置文件：

```bash
# 使用指定的配置文件
ky-git-log-transfer --config myconfig.json

# 使用INI格式配置文件
ky-git-log-transfer --config myconfig.ini
```

#### 覆盖配置
命令行参数始终优先于配置文件，可以用于临时覆盖配置：

```bash
# 使用配置文件，但临时覆盖格式和输出
ky-git-log-transfer --config myconfig.json --format json --output /tmp/changelog.json
```

### 注意事项

1. **列表字段处理**：在INI格式中，列表字段（如 `keyword`, `exclude`, `type` 等）可以使用逗号分隔的字符串。单个值时也会自动转换为列表。

2. **Git参数语法**：在配置文件中指定分支和标签过滤时，使用正确的语法：
   - `branch`: "main"
   - `branches`: "feature/*" (使用 `--branches=feature/*` 语法)
   - `tags`: "v1.*" (使用 `--tags=v1.*` 语法)

3. **布尔值**：在JSON中使用 `true`/`false`，在INI中使用 `true`/`false`、`yes`/`no`、`1`/`0`。

4. **日期格式**：始终使用 `YYYY-MM-DD` 格式。

5. **错误处理**：如果配置文件格式错误或包含无效值，程序会显示警告并忽略该配置项。

## 提交类型分类规则

分类器分两步完成：

1. **conventional commit 前缀匹配**（优先级高）：消息以下列前缀开头时直接确定类型，不再继续扫描。

   | 前缀 | 类型 |
   |---|---|
   | `feat:` / `feature:` | feature |
   | `fix:` | fix |
   | `refactor:` | refactor |
   | `docs:` | docs |
   | `test:` | test |
   | `style:` | style |
   | `chore:` / `ci:` / `build:` | chore |

2. **关键词回落**（前缀未匹配时）：消息中包含以下关键词则归入对应类型，未匹配则归入 `other`。

   | 类型 | 关键词 |
   |---|---|
   | feature | add, new, implement |
   | fix | bug, error, issue |
   | refactor | refactoring, cleanup |
   | docs | documentation, readme |
   | test | testing, coverage |
   | style | formatting, lint |



## 测试

### 测试基础设施

项目拥有完整的模块化测试套件：

```
ky-git-log-transfer/
├── test/                          # 模块化测试套件（77个测试）
│   ├── test_commit.py             # Commit数据类测试
│   ├── test_git_parser.py         # Git日志解析器测试（分类+过滤）
│   ├── test_cli_parser.py         # 命令行参数解析测试
│   ├── test_config.py             # 配置管理系统测试
│   ├── test_stats.py              # 统计功能测试
│   ├── test_formatters.py         # 所有7种格式化器测试
│   ├── test_template_engine.py    # 模板引擎测试
│   ├── test_main.py               # 主程序集成测试
│   ├── test_integration.py        # 整合测试文件（35个测试）
│   └── conftest.py                # 共享测试工具和fixtures
```

### 运行测试

#### 模块化测试套件
```bash
cd /path/to/ky-git-log-transfer

# 运行所有测试
python -m pytest test/ -v

# 运行特定模块测试
python -m pytest test/test_formatters.py -v

# 运行带覆盖率的测试
pip install coverage pytest-cov
python -m pytest test/ --cov=src --cov-report=html
```

#### 整合测试
```bash
# 运行整合测试文件（包含35个测试）
python -m pytest test/test_integration.py -v

# 运行所有测试（模块化+整合）
python -m pytest test/ -v
```

#### 覆盖率报告
```bash
# 生成HTML覆盖率报告
python -m pytest test/ --cov=src --cov-report=html
open coverage_html_report/index.html
```

## 许可证
Non opensource, The copyright belongs to KylinSoft Co., Ltd.
