一、工作流概述
代码质量检查是软件开发流程中不可或缺的环节。在AI辅助编程时代,代码产出量大幅提升,但质量管控的挑战也随之增大。Claude Code 作为新一代AI编程助手,可以通过精心设计的CLAUDE.md配置文件,将代码质量检查嵌入开发工作流的每一个环节,实现从"人治"到"制治"的转变。
本工作流体系包含六大核心模块:质量门禁、静态分析集成、代码风格统一、代码异味检测、圈复杂度控制以及质量报告生成。每个模块既可独立运作,又能协同配合,形成完整的质量保障闭环。
编码
→
质量门禁
→
静态分析
→
风格检查
→
异味检测
→
复杂度
→
通过
↔
阻断
核心理念
代码质量检查不应是事后的"补救措施",而应是贯穿开发全流程的"预防机制"。通过将检查规则自动化、标准化、透明化,团队可以在最早的时间点发现并修复问题,大幅降低修复成本。
二、质量门禁(Quality Gate)
质量门禁是代码质量的第一道防线,它定义了代码进入下一阶段(如合并到主分支、发布到生产环境)之前必须满足的最低质量标准。质量门禁的核心在于"量化"——将模糊的"代码质量不错"转化为可度量、可验证的具体指标。
2.1 质量阈值定义
质量阈值是门禁系统的度量标尺。每个项目应根据技术栈、团队规模和业务特点设定合理的阈值。阈值不宜过低(丧失把关意义),也不宜过高(造成开发阻塞)。
| 度量指标 | 阻断阈值 | 警告阈值 | 说明 |
| 圈复杂度 | > 15 | > 10 | 单个函数的复杂度上限 |
| 代码重复率 | > 5% | > 3% | 项目中重复代码的比例 |
| 单文件行数 | > 500 | > 300 | 单个源文件最大行数 |
| 函数参数个数 | > 5 | > 4 | 单个函数参数上限 |
| 嵌套深度 | > 4 | > 3 | 条件/循环嵌套层数 |
| 测试覆盖率 | < 70% | < 80% | 单元测试行覆盖率 |
| lint错误数 | > 0 | > 5 | 静态分析发现的错误数 |
| 技术债务比率 | > 10% | > 5% | 需要重构的代码占比 |
2.2 阻断规则与警告规则
质量门禁分为阻断(Blocking)和警告(Warning)两个级别。阻断规则一旦触发,CI/CD流水线将终止并拒绝合并;警告规则仅记录提示,由开发者自行决定是否修复。
# ============================================
# 质量门禁规则 —— 阻断 / 警告
# ============================================
quality_gates:
blocking:
- rule: "圈复杂度超过15"
check: "cyclomatic_complexity > 15"
action: "阻断合并,要求重构"
- rule: "存在语法错误或lint错误"
check: "lint_errors > 0"
action: "阻断合并,要求修复所有lint错误"
- rule: "单函数超过80行"
check: "function_lines > 80"
action: "阻断,要求拆分函数"
- rule: "测试覆盖率低于70%"
check: "coverage < 70%"
action: "阻断,要求补充测试用例"
warning:
- rule: "圈复杂度在10~15之间"
check: "10 < cyclomatic_complexity <= 15"
action: "告警,建议重构"
- rule: "函数参数超过4个"
check: "param_count > 4"
action: "告警,建议使用参数对象"
- rule: "文件超过300行"
check: "file_lines > 300"
action: "告警,建议拆分文件"
- rule: "存在TODO或FIXME注释"
check: "contains 'TODO|FIXME'"
action: "告警,提醒处理遗留事项"
2.3 度量指标详解
度量指标的选择直接影响门禁的有效性。好的度量指标应当具备可自动化采集、客观无歧义、与质量正相关三个特征。以下为推荐的核心指标集:
推荐核心指标集
- 代码复杂度 — 圈复杂度、认知复杂度、继承深度
- 代码规模 — 函数行数、文件行数、参数个数、类方法数
- 代码重复 — 重复率、重复块数、重复文件数
- 测试质量 — 行覆盖率、分支覆盖率、测试与代码比率
- 静态缺陷 — lint错误、安全漏洞、不推荐用法
- 文档完整性 — 公共API文档覆盖率、类型注解覆盖率
三、静态分析集成
静态分析工具(Linter)是代码质量检查的"守门员"。它们在不运行代码的情况下,通过语法分析、模式匹配和数据流分析,发现代码中的潜在缺陷、风格问题和安全隐患。不同语言生态有各自的成熟工具链。
3.1 多语言Linter配置
Python — Flake8 + Pylint + Black
[flake8]
max-line-length = 100
max-complexity = 10
exclude = .git,__pycache__,venv,node_modules
ignore = E203, W503
select = C,E,F,W,B,B9
statistics = True
count = True
output-file = reports/flake8-report.txt
[tool.black]
line-length = 100
target-version = ["py39", "py310", "py311"]
include = '\.pyw?$'
extend-exclude = '''
/(
\.git
| __pycache__
| venv
| node_modules
)/
'''
[tool.pylint.messages_control]
disable = ["C0114", "C0115", "C0116", "R0903"]
max-line-length = 100
max-args = 5
max-returns = 3
max-branches = 12
max-statements = 50
max-parents = 7
max-attributes = 7
min-public-methods = 1
max-public-methods = 20
JavaScript/TypeScript — ESLint + Prettier
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": ["@typescript-eslint", "prettier"],
"rules": {
"prettier/prettier": "error",
"max-lines": ["warn", { "max": 300, "skipBlankLines": true }],
"max-params": ["warn", 4],
"max-depth": ["warn", 4],
"complexity": ["warn", { "max": 10 }],
"no-duplicate-imports": "error",
"no-console": "warn",
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/explicit-function-return-type": "warn"
}
}
{
"semi": true,
"trailingComma": "all",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true,
"arrowParens": "always",
"endOfLine": "lf",
"quoteProps": "as-needed"
}
3.2 集成到CLAUDE.md
在Claude Code中,通过CLAUDE.md可以将静态分析工具无缝集成到开发工作流中。Claude在生成代码后会主动调用这些工具进行检查并修复发现问题。
# ============================================
# 静态分析集成
# ============================================
## Python 代码检查
## 每次生成Python代码后执行
pre_commit_hooks:
- name: "Python Lint & Format"
run: |
flake8 . --count --statistics --exit-zero
pylint **/*.py --exit-zero
black --check .
auto_fix: |
black .
isort .
## JavaScript/TypeScript 代码检查
pre_commit_hooks:
- name: "ESLint & Prettier"
run: |
npx eslint "src/**/*.{js,ts,tsx}" --max-warnings=0
npx prettier --check "src/**/*.{js,ts,tsx}"
auto_fix: |
npx eslint "src/**/*.{js,ts,tsx}" --fix
npx prettier --write "src/**/*.{js,ts,tsx}"
## 规则说明
## - 所有lint错误必须修复(阻断级别)
## - 警告数超过5个触发告警
## - 自动格式化由Claude在写文件后执行
## - 提交前必须确保lint检查通过
最佳实践
- 不要一次性启用所有规则 —— 从最关键的规则开始,逐步补充
- 团队应统一linter版本和配置,避免不同成员的检查结果不一致
- 将lint检查集成到pre-commit hook中,在本地提交前拦截问题
- 对于遗留代码,可以先以警告级别引入,逐步修复后升为阻断
- 定期审查lint规则集,移除不再适用的规则,补充新的最佳实践
四、代码风格统一
代码风格不一致是团队协作中最常见也最令人困扰的问题。缩进用空格还是Tab、行尾要不要分号、单引号还是双引号——这些看似细微的差异累积起来会让代码库变得混乱不堪。自动化格式化工具是解决这一问题的终极方案。
4.1 自动格式化配置
选择自动格式化工具时,应遵循"零配置可用、配置即声明"的原则。好的格式化工具不需要开发者记忆规则,每次保存时自动将代码调整为标准格式。
| 语言 | 格式化工具 | 配置文件 | 集成方式 |
| Python | Black | pyproject.toml | pre-commit / Claude自动调用 |
| JavaScript/TypeScript | Prettier | .prettierrc | pre-commit / ESLint集成 |
| Go | gofmt | 语言内置 | go fmt 自动执行 |
| Rust | rustfmt | rustfmt.toml | cargo fmt |
| Java | Google Java Format | XML配置 | Spotless Maven/Gradle插件 |
| Ruby | RuboCop | .rubocop.yml | gem集成 |
| PHP | PHP-CS-Fixer | .php-cs-fixer.php | Composer脚本 |
| Swift | swift-format | .swift-format | SwiftPM |
4.2 风格规则与编辑器配置
团队级别的风格一致性需要三层保障:代码库级别的配置文件、编辑器级别的自动格式化、以及CI级别的强制检查。
# EditorConfig 确保不同编辑器保持一致的缩进和编码设置
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.{js,ts,tsx,json,yml,yaml}]
indent_size = 2
[*.md]
trim_trailing_whitespace = false
[Makefile]
indent_style = tab
# ============================================
# 代码风格统一指令
# ============================================
## 输出格式要求
## Claude Code在生成代码时必须遵守以下风格规则:
style_rules:
- "所有缩进使用空格,不使用Tab"
- "Python缩进为4空格,JS/TS/JSON为2空格"
- "文件末尾保留一个空行"
- "行尾不能有空格"
- "每行不超过100个字符"
- "始终使用有意义的命名(禁止单字母变量名)"
- "Python使用 snake_case,JavaScript使用 camelCase"
- "类名使用 PascalCase"
- "常量使用 UPPER_SNAKE_CASE"
## 自动格式化流程
## 每次写入文件后执行
after_write:
- name: "auto_format"
python: |
import subprocess
import sys
file_path = "{{FILE_PATH}}"
ext = file_path.split('.')[-1]
if ext == 'py':
subprocess.run(['black', file_path])
subprocess.run(['isort', file_path])
elif ext in ['js', 'ts', 'tsx', 'json']:
subprocess.run(['npx', 'prettier', '--write', file_path])
on_failure: "警告开发者并给出修复建议"
4.3 项目级统一策略
要在整个项目中实现风格统一,需要从三个层面协同推进:
- 工具层:在项目根目录放置.editorconfig、.prettierrc、pyproject.toml等配置文件,确保所有参与者的开发环境行为一致
- 流程层:通过pre-commit hook和CI流水线强制执行风格检查,不满足风格要求的代码无法提交或合并
- 文化层:建立代码审查中的风格共识,将风格问题交由工具处理,审查聚焦于逻辑和设计
风格的"铁三角"
EditorConfig 解决"编辑器"层面的统一(缩进、编码、换行符)
Prettier / Black 解决"代码"层面的统一(格式、排版、引号)
ESLint / Pylint 解决"质量"层面的统一(最佳实践、潜在bug、代码异味)
三者协同,缺一不可。只用其中一两个工具,风格统一的覆盖面和效果都会打折扣。
五、代码异味检测
代码异味(Code Smell)是指代码中那些不明显的、但预示着更深层次设计问题的表面迹象。它们不是bug,但长期存在会显著降低代码的可维护性,最终导致bug丛生。Martin Fowler在《重构》一书中系统性地归纳了20余种代码异味。
5.1 常见代码异味及其检测
过长函数(Long Method)
函数应该只做一件事,并把它做好。当一个函数需要滚动屏幕才能看完时,它很可能承担了过多的职责。
# ⚠ 异味:过长函数(42行,包含3个不同职责)
def process_order(order_id):
"""处理订单的全部流程 —— 验证、计算、通知全在一个函数里"""
# 第1部分:订单验证
order = get_order(order_id)
if not order:
raise ValueError("订单不存在")
if order.status != "pending":
raise ValueError("订单状态不允许处理")
if order.total <= 0:
raise ValueError("订单金额异常")
user = get_user(order.user_id)
if user.status == "disabled":
raise ValueError("用户已被禁用")
if user.balance < order.total:
raise ValueError("余额不足")
# 第2部分:价格计算
subtotal = order.total
discount = 0
if user.level == "vip":
discount = subtotal * 0.1
elif user.level == "svip":
discount = subtotal * 0.2
if order.coupon_id:
coupon = get_coupon(order.coupon_id)
if coupon and coupon.is_valid():
discount = max(discount, coupon.amount)
tax = (subtotal - discount) * 0.13
shipping = 0 if subtotal > 99 else 8
final_total = subtotal - discount + tax + shipping
# 第3部分:通知发送
order.final_total = final_total
order.status = "processed"
save_order(order)
if user.email:
send_email(user.email, f"订单已处理,金额:{final_total}")
if user.phone:
send_sms(user.phone, f"订单{order_id}已处理")
log_action(f"订单{order_id}处理完成,金额{final_total}")
return order
# ✅ 重构:拆分为3个职责清晰的函数
def process_order(order_id):
"""处理订单 —— 仅编排子流程,不包含实现细节"""
order = _validate_and_get_order(order_id)
final_total = _calculate_final_total(order)
_finalize_order(order, final_total)
_send_notifications(order, final_total)
log_action(f"订单{order_id}处理完成,金额{final_total}")
return order
def _validate_and_get_order(order_id):
"""验证订单状态和用户资格"""
order = get_order(order_id)
if not order or order.status != "pending":
raise ValueError("订单无法处理")
user = get_user(order.user_id)
if user.status == "disabled" or user.balance < order.total:
raise ValueError("用户或余额异常")
return order
def _calculate_final_total(order):
"""计算订单最终金额(含折扣、税费、运费)"""
discount = _compute_discount(order)
tax = (order.total - discount) * 0.13
shipping = 0 if order.total > 99 else 8
return order.total - discount + tax + shipping
def _compute_discount(order):
"""计算折扣金额"""
user = get_user(order.user_id)
base = order.total * 0.2 if user.level == "svip" else order.total * 0.1
if order.coupon_id:
coupon = get_coupon(order.coupon_id)
if coupon and coupon.is_valid():
return max(base, coupon.amount)
return base if user.level in ("vip", "svip") else 0
def _send_notifications(order, amount):
"""发送订单处理通知"""
user = get_user(order.user_id)
if user.email:
send_email(user.email, f"订单已处理,金额:{amount:.2f}")
if user.phone:
send_sms(user.phone, f"订单{order.id}已处理,金额{amount:.2f}")
过多参数(Long Parameter List)
函数参数过多不仅调用不便,更暗示函数承担了过多的依赖。推荐将相关参数封装为对象。
// ⚠ 异味:7个参数,调用者极易出错
function createUser(
name: string,
email: string,
age: number,
phone: string,
address: string,
role: string,
departmentId: number
): User {
// ... 实现省略
}
// ✅ 重构:使用参数对象
interface CreateUserRequest {
name: string;
email: string;
age: number;
phone?: string;
address?: string;
role: 'admin' | 'editor' | 'viewer';
departmentId: number;
}
function createUser(request: CreateUserRequest): User {
const { name, email, age, phone, address, role, departmentId } = request;
// ... 实现省略
}
// 调用方式更加清晰
createUser({
name: '张三',
email: 'zhangsan@example.com',
age: 28,
role: 'editor',
departmentId: 101,
});
重复代码(Duplicated Code)
重复代码是软件维护的头号杀手。"改了一处忘了改另一处"是最常见的生产事故根源。
# ⚠ 异味:重复代码 —— 两处查询逻辑几乎完全相同
def get_active_users():
return session.query(User)\
.filter(User.status == 'active')\
.filter(User.deleted_at.is_(None))\
.order_by(User.created_at.desc())\
.all()
def get_vip_users():
return session.query(User)\
.filter(User.status == 'active')\
.filter(User.level == 'vip')\
.filter(User.deleted_at.is_(None))\
.order_by(User.created_at.desc())\
.all()
# ✅ 重构:提取公共基础和可组合的过滤条件
def get_users_base():
return session.query(User)\
.filter(User.deleted_at.is_(None))\
.filter(User.status == 'active')
def get_active_users():
return get_users_base()\
.order_by(User.created_at.desc())\
.all()
def get_vip_users():
return get_users_base()\
.filter(User.level == 'vip')\
.order_by(User.created_at.desc())\
.all()
深度嵌套(Deep Nesting)
嵌套的if/for/while超过3层将极大降低代码可读性。每增加一层嵌套,阅读者的认知负担翻倍。
// ⚠ 异味:4层嵌套,逻辑难以追踪
function processData(items) {
let result = [];
for (let i = 0; i < items.length; i++) {
if (items[i].isValid) {
if (items[i].type === 'special') {
for (let j = 0; j < items[i].subItems.length; j++) {
if (items[i].subItems[j].active) {
result.push(transform(items[i].subItems[j]));
}
}
} else {
result.push(transform(items[i]));
}
}
}
return result;
}
// ✅ 重构:使用提前返回和函数提取
function processData(items) {
return items
.filter(item => item.isValid)
.flatMap(item =>
item.type === 'special'
? item.subItems.filter(sub => sub.active).map(transform)
: [transform(item)]
);
}
上帝类(God Class)
当一个类变得过于庞大,承担了十几个不同职责时,它就变成了"上帝类"。上帝类极度耦合、难以测试、修改风险极高。
// ⚠ 异味:上帝类 —— 包含用户管理、订单处理、支付、通知等职责
class OrderManager {
createUser() { /* ... */ }
updateUser() { /* ... */ }
deleteUser() { /* ... */ }
createOrder() { /* ... */ }
cancelOrder() { /* ... */ }
refundOrder() { /* ... */ }
processPayment() { /* ... */ }
processRefund() { /* ... */ }
sendEmail() { /* ... */ }
sendSMS() { /* ... */ }
generateReport() { /* ... */ }
exportData() { /* ... */ }
}
// ✅ 重构:按职责拆分为独立的Service
class UserService {
create() { /* ... */ }
update() { /* ... */ }
delete() { /* ... */ }
}
class OrderService {
constructor(
private payment: PaymentService,
private notification: NotificationService
) {}
create() { /* ... */ }
cancel() { /* ... */ }
refund() { /* ... */ }
}
class PaymentService {
processPayment() { /* ... */ }
processRefund() { /* ... */ }
}
class NotificationService {
sendEmail() { /* ... */ }
sendSMS() { /* ... */ }
}
class ReportService {
generate() { /* ... */ }
export() { /* ... */ }
}
5.2 代码异味检测规则配置
# ============================================
# 代码异味检测规则
# ============================================
code_smell_rules:
# 过长函数
long_method:
threshold_lines: 30
action: "建议拆分为多个小函数,每个函数只做一件事"
# 过多参数
long_parameter_list:
threshold_count: 5
action: "建议将参数封装为对象或使用Builder模式"
# 重复代码
duplicated_code:
threshold_similarity: 0.8
min_block_lines: 10
action: "建议提取为公共函数或基类方法"
# 深度嵌套
deep_nesting:
threshold_depth: 4
action: "建议使用提前返回、策略模式或职责链模式"
# 过大的类(上帝类)
god_class:
threshold_methods: 15
threshold_lines: 500
action: "建议按职责拆分为多个独立的类"
# 数据类
data_class:
check: "类只有公开字段,没有行为"
action: "建议将相关行为移入类中,或使用Value Object模式"
# 霰弹式修改
shotgun_surgery:
check: "一个变更需要修改N个文件"
threshold_files: 5
action: "建议将分散的逻辑集中到单一职责的模块中"
## 检测时机
## Claude Code 在以下时机执行异味检测:
## 1. 每次写入新文件后
## 2. 每次修改现有函数后
## 3. 代码审查开始时
## 4. 合并请求创建前
六、圈复杂度控制
圈复杂度(Cyclomatic Complexity)由Thomas McCabe于1976年提出,通过计算代码中线性独立路径的数量来衡量程序的复杂程度。计算公式为 M = E - N + 2P(E为边数,N为节点数,P为连通分量数)。对于实际开发者而言,更直观的理解是:圈复杂度 = 判断语句数量 + 1。
6.1 复杂度阈值与解读
| 圈复杂度值 | 风险等级 | 解读 | 建议 |
| 1 - 5 | 低风险 | 代码简单,可读性好 | 无需处理 |
| 6 - 10 | 中等风险 | 代码有一定复杂度 | 考虑是否需要简化 |
| 11 - 15 | 高风险 | 代码复杂,难以维护 | 建议重构拆分 |
| 16 - 25 | 极高风险 | 代码非常复杂,容易引入bug | 必须重构 |
| > 25 | 不可维护 | 测试几乎不可能覆盖所有路径 | 立即重写 |
6.2 复杂度分析实战
def calculate_shipping_cost(order, user, promo_code=None):
"""计算运费 —— 圈复杂度 = 11,高风险"""
cost = 0
if not order or not user: # +1 (if)
return cost
base_fee = 5.0
if order.weight > 10: # +1 (if)
base_fee += 3.0
elif order.weight > 5: # +1 (elif)
base_fee += 1.5
if order.is_express: # +1 (if)
base_fee *= 1.5
if user.level == 'vip': # +1 (if)
base_fee *= 0.8
elif user.level == 'svip': # +1 (elif)
base_fee *= 0.6
if promo_code: # +1 (if)
promo = get_promo(promo_code)
if promo and promo.is_valid: # +1 (if, 嵌套)
if promo.type == 'percent': # +1 (if, 嵌套)
base_fee *= (1 - promo.value / 100)
elif promo.type == 'fixed': # +1 (elif, 嵌套)
base_fee = max(0, base_fee - promo.value)
if user.has_membership: # +1 (if)
base_fee = max(0, base_fee - user.membership_discount)
return base_fee
# 圈复杂度 = 11 (if/elif判断数 + 1)
# ✅ 重构:将不同维度的逻辑拆分为独立函数
def calculate_shipping_cost(order, user, promo_code=None):
"""计算运费 —— 总圈复杂度降低:编排函数 = 1"""
base_fee = _compute_base_fee(order)
base_fee = _apply_user_discount(base_fee, user)
base_fee = _apply_promo_discount(base_fee, promo_code)
base_fee = _apply_membership_discount(base_fee, user)
return max(0, base_fee)
def _compute_base_fee(order):
"""基础运费计算 —— 圈复杂度 = 3"""
# +2 (if/elif分支)
if order.weight > 10:
extra = 3.0
elif order.weight > 5:
extra = 1.5
else:
extra = 0
fee = 5.0 + extra
# +1 (if)
return fee * 1.5 if order.is_express else fee
def _apply_user_discount(fee, user):
"""用户等级折扣计算 —— 圈复杂度 = 2"""
# +1 (if/elif分支)
if user.level == 'svip':
return fee * 0.6
elif user.level == 'vip':
return fee * 0.8
return fee
def _apply_promo_discount(fee, promo_code):
"""优惠码折扣计算 —— 圈复杂度 = 3"""
# +1 (if)
if not promo_code:
return fee
promo = get_promo(promo_code)
# +1 (if, 嵌套)
if promo and promo.is_valid:
# +1 (嵌套if/elif)
if promo.type == 'percent':
return fee * (1 - promo.value / 100)
elif promo.type == 'fixed':
return max(0, fee - promo.value)
return fee
6.3 模块化检查策略
模块化检查将系统视为相互连接的模块集合,从宏观层面评估代码的健康状况。推荐以下检查维度:
模块化检查维度
- 模块内聚度:模块内部的元素是否高度相关?(高内聚 = 好设计)
- 模块耦合度:模块之间的依赖关系是否合理?(低耦合 = 好设计)
- 循环依赖:是否存在A依赖B、B又依赖A的情况?(必须消除)
- 扇入/扇出:一个模块被多少模块调用(扇入)、调用多少其他模块(扇出)
- 包/目录结构:模块的组织方式是否反映业务领域结构?
# ============================================
# 圈复杂度控制规则
# ============================================
complexity_control:
# 函数级别阈值
function_level:
warning_threshold: 10
blocking_threshold: 15
metric: "McCabe Cyclomatic Complexity"
check_tool: |
# Python: 使用 radon
# 安装: pip install radon
# 命令: radon cc . -s -n 10
# JavaScript/TypeScript: 使用 eslint
# 配置: complexity: ["warn", { "max": 10 }]
# 通用: lizard
# 安装: pip install lizard
# 命令: lizard . --threshold 10
# 模块级别阈值
module_level:
warning_threshold: 30
blocking_threshold: 50
metric: "模块内所有函数的总圈复杂度"
# 重构建议生成规则
refactor_suggestions:
min_complexity: 8
max_suggestions: 3
output_format: |
## 复杂度分析结果
- 文件: {file_path}
- 高风险函数: {function_name} (复杂度: {complexity})
- 建议: {suggestion}
- 重构方案: {refactor_example}
# 复杂度报告
reporting:
format: "table"
include: ["function_name", "complexity", "file", "line", "risk_level"]
sort_by: "complexity"
sort_order: "desc"
output_file: "reports/complexity-report.md"
七、质量报告生成
质量报告是代码质量检查工作流的"输出层",将所有检查数据汇总为可视化的、可追溯的报告文档。好的质量报告不仅要指出问题,还要提供趋势分析和改进建议,帮助团队持续提升代码质量。
7.1 质量评分模型
综合评分模型将多个维度的质量数据归一化为0-100的分数,便于直观理解代码库的整体健康状况。
| 维度 | 权重 | 评分方式 |
| 圈复杂度达标率 | 20% | 复杂度 ≤ 10的函数占比 |
| lint通过率 | 20% | 零错误文件的占比 |
| 测试覆盖率 | 15% | 实际覆盖率 / 目标覆盖率 |
| 代码重复率 | 15% | 100% - 重复代码比例 |
| 文档覆盖率 | 10% | 公有API有文档注释的比例 |
| 类型注解覆盖率 | 10% | 有类型注解的函数占比 |
| 技术债务比率 | 10% | 100% - 技术债务代码比例 |
7.2 质量报告模板
# 代码质量报告 - {project_name}
报告时间: {report_date} | 分支: {branch} | 提交: {commit_hash}
---
## 一、总体评分
| 维度 | 分数 | 状态 | 趋势 |
|------------------|-------|----------|--------|
| 圈复杂度达标率 | {val} | {status} | {trend}|
| Lint通过率 | {val} | {status} | {trend}|
| 测试覆盖率 | {val} | {status} | {trend}|
| 代码重复率 | {val} | {status} | {trend}|
| 文档覆盖率 | {val} | {status} | {trend}|
| 类型注解覆盖率 | {val} | {status} | {trend}|
| **综合评分** | **{总分}** | **{status}** | **{trend}** |
> 评分等级:Excellent (90-100) | Good (75-89) | Fair (60-74) | Poor (<60)
---
## 二、质量门禁检查结果
### ⚠ 阻断项(必须修复)
{blocking_items}
### ⚟ 警告项(建议修复)
{warning_items}
---
## 三、代码异味统计
| 异味类型 | 出现次数 | 严重程度 | 涉及文件 |
|--------------|----------|----------|--------------------------|
| 过长函数 | {count} | {level} | {file_list} |
| 过多参数 | {count} | {level} | {file_list} |
| 重复代码 | {count} | {level} | {file_list} |
| 深度嵌套 | {count} | {level} | {file_list} |
| 上帝类 | {count} | {level} | {file_list} |
---
## 四、圈复杂度 TOP 10
| 排名 | 函数名 | 复杂度 | 行数 | 文件 | 风险 |
|------|-------------------------------|--------|------|--------------|--------|
| 1 | `process_large_data_batch` | 18 | 85 | data.py:120 | 极高 |
| 2 | `handle_payment_webhook` | 15 | 72 | pay.py:45 | 高 |
| 3 | `validate_and_transform` | 13 | 60 | utils.py:88 | 高 |
| ... | ... | ... | ... | ... | ... |
---
## 五、改进建议
### 高优先级
1. `data.py:120` - `process_large_data_batch` (复杂度18)
→ 建议拆分为 3~4 个子函数,降低复杂度至 10 以下
2. `utils.py:35-95` - 检测到 2 段重复代码(相似度 85%)
→ 建议提取公共函数,消除重复
### 中优先级
3. `api.py:12` - `create_user` 函数参数过多(6个)
→ 建议封装为 CreateUserRequest 对象
4. ...
---
## 六、历史趋势
| 日期 | 综合评分 | 复杂度 | 覆盖率 | 重复率 |
|------------|----------|--------|--------|--------|
| 2026-05-01 | 78 | 良好 | 72% | 3.2% |
| 2026-05-02 | 79 | 良好 | 73% | 3.1% |
| 2026-05-03 | 82 | 优秀 | 75% | 2.8% |
| 2026-05-04 | 81 | 优秀 | 74% | 3.0% |
| 今日 | 83 | 优秀 | 76% | 2.7% |
> 趋势:▲ 持续改善中 | ▼ 需要关注 | ▶ 保持稳定
7.3 代码黄牌机制
"代码黄牌"是一种软性警告机制。当代码质量指标持续下滑或出现特定模式时,系统会给出"黄牌"提醒,但不阻断流程。连续获得多张黄牌可能触发更严格的审查流程。
触发黄牌的典型场景
- 同一函数连续3次修改导致圈复杂度上升
- 新增代码的测试覆盖率为 0
- PR中引入的新lint警告超过5个
- 使用了已被标记为废弃的API
- 重复代码比例在1周内上升超过0.5%
- FIXME和TODO注释数量超过10个
# ============================================
# 质量报告生成配置
# ============================================
quality_report:
enabled: true
format: "markdown"
output_path: "reports/quality-report-{date}.md"
sections:
- "总体评分"
- "质量门禁检查结果"
- "代码异味统计"
- "圈复杂度 TOP 10"
- "改进建议"
- "历史趋势"
# 自动生成时机
generate_on:
- "每次PR创建时"
- "每周一上午10点(定期报告)"
- "质量评分下降超过5分时"
notifications:
- type: "slack"
webhook: "https://hooks.slack.com/services/xxx"
template: |
:clipboard: *{project} 代码质量周报*
> 综合评分: {score} | 趋势: {trend}
> 高风险函数: {high_risk_count} | 需修复: {blocking_count}
> 查看完整报告: {report_url}
# 质量门禁阻断规则(报告生成阶段)
gates:
- metric: "综合评分 < 60"
action: "标记为 FAILED,通知技术负责人"
- metric: "阻断项 > 0"
action: "在报告中高亮显示,要求优先修复"
- metric: "连续3次评分下降"
action: "自动创建质量改进工单"
# 改进建议引擎
suggestion_engine:
enabled: true
categories:
- "复杂度优化"
- "重复代码消除"
- "测试补充"
- "文档补全"
- "类型注解完善"
max_suggestions: 10
priority_levels: ["高", "中", "低"]
八、CLAUDE.md完整配置示例
以下是一个完整的CLAUDE.md配置文件,集成本文所述的所有质量检查功能,可以直接作为项目模板使用。
# ============================================
# 项目代码质量检查工作流配置
# ============================================
## 项目信息
project_name: "my-awesome-project"
language: python 3.11
framework: fastapi
test_framework: pytest
## ============================================
## 一、质量门禁
## ============================================
quality_gates:
blocking:
- rule: "圈复杂度超过15"
check: "cc > 15"
action: "阻断合并,要求重构"
- rule: "lint错误数 > 0"
check: "lint_errors > 0"
action: "阻断合并,要求修复"
- rule: "测试覆盖率 < 70%"
check: "coverage < 70"
action: "阻断合并,要求补充测试"
- rule: "单函数超过80行"
check: "func_lines > 80"
action: "阻断,要求拆分函数"
warning:
- rule: "圈复杂度在10~15之间"
check: "10 < cc <= 15"
action: "告警,建议重构"
- rule: "函数参数超过4个"
check: "params > 4"
action: "告警,建议使用参数对象"
- rule: "文件超过300行"
check: "file_lines > 300"
action: "告警,建议拆分文件"
## ============================================
## 二、静态分析集成
## ============================================
linting:
python:
tools: ["flake8", "pylint", "black", "isort", "mypy"]
config_files: [".flake8", "pyproject.toml"]
auto_fix: "black . && isort ."
javascript:
tools: ["eslint", "prettier"]
config_files: [".eslintrc.json", ".prettierrc"]
auto_fix: "npx eslint --fix . && npx prettier --write ."
## ============================================
## 三、代码风格统一
## ============================================
style_rules:
- "所有缩进使用空格(Python: 4, JS/TS: 2)"
- "文件末尾保留一个空行"
- "每行不超过100个字符"
- "Python使用snake_case, JS使用camelCase"
- "类名使用PascalCase"
- "常量使用UPPER_SNAKE_CASE"
after_write:
- name: "auto_format_python"
run: "black {{FILE_PATH}} && isort {{FILE_PATH}}"
condition: "ends_with .py"
- name: "auto_format_js"
run: "npx prettier --write {{FILE_PATH}}"
condition: "ends_with .js or .ts or .tsx"
## ============================================
## 四、代码异味检测
## ============================================
code_smell_rules:
long_method: { threshold: 30, action: "拆分函数" }
long_parameter_list: { threshold: 5, action: "封装参数对象" }
duplicated_code: { threshold_similarity: 0.8, action: "提取公共函数" }
deep_nesting: { threshold_depth: 4, action: "使用提前返回" }
god_class: { threshold_methods: 15, threshold_lines: 500, action: "拆分职责" }
detection_triggers:
- "每次写入新文件后"
- "每次修改现有函数后"
- "代码审查开始时"
- "合并请求创建前"
## ============================================
## 五、圈复杂度控制
## ============================================
complexity_control:
function_level:
warning_threshold: 10
blocking_threshold: 15
module_level:
warning_threshold: 30
blocking_threshold: 50
check_command: "radon cc . -s -n 10"
refactor_suggestions:
min_complexity: 8
max_suggestions: 3
## ============================================
## 六、质量报告生成
## ============================================
quality_report:
enabled: true
format: "markdown"
output_path: "reports/quality-report-{date}.md"
generate_on:
- "每次PR创建时"
- "每周一上午10点"
suggestion_engine:
categories: ["复杂度优化", "重复代码消除", "测试补充", "文档补全"]
## ============================================
## 七、工作流钩子
## ============================================
hooks:
pre_commit:
- name: "quality_check"
run: |
flake8 . --count --statistics --exit-zero
pylint **/*.py --exit-zero
black --check .
mypy .
on_fail: "输出详细报告,列出所有违规项"
post_commit:
- name: "update_trend"
run: "python scripts/update_quality_trend.py"
pre_pr:
- name: "full_quality_gate"
run: |
echo "正在执行全量质量门禁检查..."
echo "1/4 运行静态分析..."
flake8 . --count --statistics
echo "2/4 运行代码异味检测..."
radon cc . -s -n 10
echo "3/4 运行测试覆盖率检查..."
pytest --cov=. --cov-fail-under=70
echo "4/4 生成质量报告..."
python scripts/generate_report.py
on_pass: "全部检查通过,生成绿色报告"
on_fail: "阻断合并请求,生成红色报告并评论到PR中"
## ============================================
## 八、工具安装命令
## ============================================
setup_commands:
python: |
pip install flake8 pylint black isort mypy radon pytest pytest-cov
javascript: |
npm install --save-dev eslint prettier @typescript-eslint/parser @typescript-eslint/eslint-plugin
十、常见问题
Q: 质量门禁是否会拖慢开发速度?
A: 短期来看,引入质量门禁确实会增加一些检查时间。但长期来看,预防性检查能大幅减少后期修复缺陷的时间,总体开发效率是提升的。建议合理设置阈值的宽松度,避免过度门禁导致开发阻塞。
Q: 如何处理存量代码的质量问题?
A: 对存量代码区分对待。对于新增代码和修改过的代码严格执行质量标准;对于存量代码,先以警告级别标记,制定分批重构计划,逐步提升质量基线。
Q: Claude Code如何处理与现有CI/CD工具的关系?
A: Claude Code的质量检查功能与CI/CD工具是互补关系。Claude负责开发阶段的实时检查和反馈,CI/CD负责提交和合并前的最终验证。两者配合使用效果最佳。
Q: 不同项目是否需要不同的质量配置?
A: 是的。CLAUDE.md是项目级别的配置文件,每个项目应根据自身技术栈、团队规模和业务特点定制质量规则。本教程提供的配置是通用模板,需要根据实际情况调整。