saropa/saropa_lints
GitHub: saropa/saropa_lints
1700 多条针对 Flutter 和 Dart 的高级静态分析规则,可捕获标准 linter 遗漏的内存泄漏、安全漏洞和运行时崩溃。
Stars: 5 | Forks: 2

**捕获标准静态分析工具遗漏的内存泄漏、安全漏洞和运行时崩溃。**
由 [Saropa](https://saropa.com) 开发,旨在让 Dart 和 Flutter 生态变得更好。
## VS Code 扩展(推荐) **安装 [Saropa Lints VS Code 扩展](https://marketplace.visualstudio.com/items?itemName=saropa.saropa-lints)** 以获得完整体验。也可在 [Open VSX](https://open-vsx.org/extension/saropa/saropa-lints) 上获取(适用于 Cursor、VSCodium)。 Dart 工作区的静态分析集成默认**开启**(`saropaLints.enabled`)。即使关闭集成,概览、配置和规则包仍然可用;如需仅使用侧边栏而不运行分析器,请使用 **Saropa Lints: Turn Off Lint Integration** 关闭。 该扩展是主要的设置和配置界面: - **健康评分** — 状态栏显示 0–100 分;绿/黄/红区间 - **问题树** — 按严重程度和文件分组的违规项,带 Error Lens 风格的内联注释;支持多选并可**复制为 JSON** - **安全态势** — OWASP Top 10 覆盖矩阵、合规导出 - **整理** — 从 UI 中禁用扰人的规则;查看执行前的预估评分影响 - **规则包** — 从侧边栏 Webview 启用栈组合(Riverpod、Drift 等)(每个包可单独开关、查看规则列表、目标平台);参见 [`doc/guides/rule_packs.md`](doc/guides/rule_packs.md) - **包活力** — 依赖健康状况、警报和可选的**版本差距** PR/问题整理(使用 `saropaLints.packageVibrancy.enableVersionGap` 启用;GitHub token 可改善结果) - **TODO 与 Hack** — 侧边栏扫描 TODO/FIXME/HACK 风格标记;全工作区扫描是**可选的**(`saropaLints.todosAndHacks.workspaceScanEnabled`,默认关闭),通过 **TODOs & Hacks: Enable workspace scan** 启用 - **文件风险** — 按违规密度排名的文件;优先处理高风险文件 - **趋势** — 评分随时间的演进及里程碑庆祝  **设置项目**会自动配置 `pubspec.yaml`、`analysis_options.yaml` 和分析。无需终端命令。 ## 快速开始 **要求:** Dart SDK `>=3.9.0 <4.0.0`(与本包的 [`pubspec.yaml`](https://github.com/saropa/saropa_lints/blob/main/pubspec.yaml) 约束相同)。 ### 选项 A — VS Code 扩展(推荐) 1. 从 VS Code Marketplace 安装 [Saropa Lints](https://marketplace.visualstudio.com/items?itemName=saropa.saropa-lints) 2. 打开 **Saropa Lints** 侧边栏(活动栏中的复选框图标) 3. 运行 **Saropa Lints: Set Up Project**(或使用概览中的相应控件)以添加包和分析配置 该扩展会将 `saropa_lints` 添加到您的项目、配置分析选项并运行分析。使用配置视图可更改级别、禁用规则以及管理平台/包。从命令面板运行 **Saropa Lints: Getting Started** 可获取导览。 ### 选项 B — 级别预设(零配置,无需扩展) ``` dart pub add --dev saropa_lints ``` 在您的 `analysis_options.yaml` 中添加一行: ``` include: package:saropa_lints/tiers/recommended.yaml ``` 运行 `dart analyze`,问题会显示在您的 IDE 和终端中。 可用预设:`essential.yaml` · `recommended.yaml` · `professional.yaml` · `comprehensive.yaml` · `pedantic.yaml` ### 选项 C — CLI 初始化(完全控制,CI/脚本) ``` dart pub add --dev saropa_lints dart run saropa_lints:init --tier recommended # 可选:来自 pubspec + lockfile 的规则包(参见 doc/guides/rule_packs.md) dart run saropa_lints:init --list-packs dart run saropa_lints:init --tier recommended --enable-pack riverpod --enable-pack drift # IDs must match packs applicable to your pubspec ``` 这会更新(或创建)两个文件: - **`analysis_options.yaml`** — `plugins: saropa_lints: diagnostics:` 部分会为您的级别重新生成,每个规则都设置为 `true`/`false`。其他部分保持不变。 - **`analysis_options_custom.yaml`** — 您的项目设置(平台、分析输出)。首次运行时创建;永不覆盖。 ### 运行分析 ``` dart analyze ``` 问题会显示在您 IDE 的 Problems 面板和终端中。Saropa Lints 作为原生 Dart 分析器插件运行。 ## 工作原理 ``` Dart package VS Code extension │ │ ▼ ▼ analysis_options.yaml ◄─── Set Up Project / Set Tier / Triage │ │ ▼ ▼ dart analyze ◄─── Run Analysis (from UI) │ │ ▼ ▼ violations.json ───► Health Score, Issues, Security, File Risk, Trends, Inline Annotations ``` **Dart 包**通过原生分析器插件提供 **2134** 条静态分析规则。**VS Code 扩展**读取 `violations.json` 并提供 UI:健康评分、问题树、安全态势、文件风险、配置/整理及相关视图。可选的 **Drift Advisor** 集成会在专用侧边栏视图和 Problems 中显示正在运行的 Drift Advisor 服务器的索引建议和数据质量异常。两者一起发布并同步版本。 **规则元数据:** 每条规则可暴露可选语义 — `RuleType`(bug、漏洞、代码异味、安全热点)、`tags`、MITRE **CWE** ID 和 `RuleStatus`(如 beta)— 用于合规和未来的质量门控。默认向后兼容;参见 [CONTRIBUTING.md]( _data = data); // boom
// State loss — new GlobalKey every build
Widget build(context) {
final key = GlobalKey(); // wrong
return Form(key: key, ...);
}
```
Saropa Lints 检测这些模式以及数百种更多:
- **安全** — 硬编码凭证、日志中的敏感数据、不安全的反序列化
- **无障碍** — 缺少语义、不充分的触摸目标、屏幕阅读器问题
- **性能** — 不必要的重建、内存泄漏、build 中的昂贵操作
- **生命周期** — dispose 后调用 setState、缺少 mounted 检查、未释放的资源
**专注于准确性**:规则使用正确的 AST 类型检查而非字符串匹配,减少了像 "upstream" 或 "spinning" 这样的变量名产生的误报。
### 停止调试已知问题
Saropa Lints 专门针对开发者应用崩溃时搜索的错误消息进行静态分析和预防:
- **内存泄漏:** `TextEditingController`、`AnimationController` 和 `StreamSubscription` 创建后从未释放。
- **并发错误:** 异步中的 `BuildContext` 使用和 `initState` 中未等待的 futures。
- **安全缺陷:** 硬编码的 API 密钥、不安全的 HTTP(明文)和弱加密。
- **UI 崩溃:** `setState() called after dispose()`、布局溢出风险、后端数据的空断言。
- **状态错误:** `Riverpod` providers 在 `build` 中读取或在 `Bloc` 构造函数中添加事件。
### 流行包的必备工具
如果您使用 **GetX**、**Riverpod**、**Provider**、**Bloc**、**Isar**、**Hive** 或 **Firebase**,这些审计至关重要。这些库很强大,但有些模式会在运行时静默失败:
| 库 | 捕获的常见问题 | 指南 |
| ------------ | ------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| **GetX** | 未释放的控制器、workers 的内存泄漏、缺少 super 调用 | [Using with GetX](doc/guides/using_with_getx.md) |
| **Riverpod** | 循环 provider 依赖、build 中的 ref.read()、缺少 ProviderScope | [Using with Riverpod](doc/guides/using_with_riverpod.md) |
| **Provider** | build 中的 Provider.of 导致重建、重新创建的 providers 丢失状态 | [Using with Provider](doc/guides/using_with_provider.md) |
| **Bloc** | 构造函数中的事件、可变状态、未关闭的 Blocs、build 中的 BlocListener | [Using with Bloc](doc/guides/using_with_bloc.md) |
| **Isar** | 枚举字段导致模式变更时的数据损坏;缓存 Isar 流(运行时崩溃风险) | [Using with Isar](doc/guides/using_with_isar.md) |
| **Hive** | 缺少 init、未关闭的 boxes、硬编码的加密密钥、类型适配器问题 | [Using with Hive](doc/guides/using_with_hive.md) |
| **Firebase** | 无界查询、缺少批量写入、无效的 Analytics 事件、FCM token 泄漏 | [Using with Firebase](doc/guides/using_with_firebase.md) |

标准 linter 不理解这些库。他们看到的是有效的 Dart 代码。Saropa Lints 有 50 多条专门针对库特定反模式的规则,这些规则会导致生产环境中的崩溃、内存泄漏、成本超支和数据损坏。最近的更新:`require_camera_permission_check` 不再对非相机控制器(如 IsarStreamController)触发,为 Isar 用户消除了一个关键的误报。新规则 `avoid_cached_isar_stream`(带快速修复)可防止常见的 Isar 运行时错误。
### 极致的透明度
我们公开开发。我们不仅展示什么有效,还明确记录什么**还不起作用**。
- [**ROADMAP.md**](ROADMAP.md):我们的活跃待办事项。查看接下来会添加哪些规则并投票决定优先级。
- **推迟的规则**(位于 [ROADMAP.md](ROADMAP.md)#part-2-deferred-rules--technical-limitations):"难题"。由于技术限制(跨文件分析、启发式)我们暂时**无法实现**的规则。我们邀请社区帮助突破这些障碍。
| 标记 | 含义 | 示例 |
| ------ | ----------------------------- | --------------------------------------------------------------------------------------- |
| 🐙 | 作为 GitHub issue 跟踪 | [Open Issues](https://github.com/saropa/saropa_lints/issues) |
| 💭 | 公告、问答和想法 | [Discussion: Diagnostic Statistics](https://github.com/saropa/saropa_lints/discussions) |

### 合规:EAA 和 OWASP 安全
[欧洲无障碍法案](https://accessible-eu-centre.ec.europa.eu/content-corner/news/eaa-comes-effect-june-2025-are-you-ready-2025-01-31_en) 将于 2025 年 6 月生效,要求零售、银行和旅游应用无障碍。GitHub 在 2024 年期间在仓库中检测到 [3900 万个泄露的密钥](https://github.blog/security/application-security/next-evolution-github-advanced-security/)。
这些不是边缘情况。它们是标准 linter 遗漏的合规要求和安全基础。
### 与标准工具对比
为什么切换?Saropa Lints 涵盖标准工具中的所有内容 plus 严格的行为分析。
| 功能 | `flutter_lints` | `very_good_analysis` | **Saropa Lints** |
| :----------------------------------- | :-------------: | :------------------: | :--------------------- |
| **语法检查** | ✅ | ✅ | ✅ |
| **严格/固执己见的风格** | ❌ | ✅ | ✅ |
| **零配置设置** | ✅ | ✅ | ✅ **(级别预设)** |
| **控制器泄漏检测** | ❌ | ❌ | ✅ **(深度分析)** |
| **运行时崩溃预防** | ❌ | ❌ | ✅ **(行为分析)** |
| **安全(OWASP 映射)** | ❌ | ❌ | ✅ **(ISO/OWASP)** |
| **库特定(Riverpod/Bloc)** | ❌ | ❌ | ✅ **(50+ 规则)** |
| **AI 就绪诊断** | ❌ | ❌ | ✅ |
| **依赖扫描** | ❌ | ❌ | 🚧 **(即将推出)** |
### OWASP 合规映射
安全规则映射到 **OWASP Mobile Top 10 (2024)** 和 **OWASP Top 10 (2021)** 标准。这支持:
- **合规报告**用于安全审计
- **风险分类**与行业标准一致
- **覆盖分析**跨 OWASP 类别
| OWASP Mobile | 覆盖 | OWASP Web | 覆盖 |
| --------------------- | -------- | -------------------------- | --------- |
| M1 凭证使用 | 5+ 规则 | A01 访问控制失效 | 4+ 规则 |
| M2 供应链 | 2+ 规则 | A02 加密失败 | 10+ 规则 |
| M3 认证 | 5+ 规则 | A03 注入 | 6+ 规则 |
| M4 输入验证 | 6+规则 | A05 错误配置 | 4+ 规则 |
| M5 通信 | 2+ 规则 | A07 认证 | 8+ 规则 |
| M6 隐私控制 | 5+ 规则 | A09 日志记录失败 | 2+ 规则 |
| M7 二进制保护 | 2+ 规则 | | |
| M8 错误配置 | 4+ 规则 | | |
| M9 数据存储 | 7+ 规则 | | |
| M10 加密 | 4+ 规则 | | |
**差距**:A06(过时组件)需要依赖扫描工具。
规则以编程方式暴露其 OWASP 映射:
```
// Query a rule's OWASP categories
final rule = AvoidHardcodedCredentialsRule();
print(rule.owasp); // Mobile: M1 | Web: A07
```
### 开源与社区驱动
与"黑盒"付费工具不同,Saropa Lints 是 100% 开源(MIT)。您可以检查每条规则背后的逻辑,自己验证安全检查,如果不同意可以 fork。
- **无隐藏逻辑:** 准确查看我们如何检测漏洞。
- **无供应商锁定:** 这是标准 Dart 代码。
- **社区驱动:** 规则通常由 Flutter 社区建议、讨论和改进,而不仅仅是单一供应商。
### 为 AI 构建
像 Cursor、Windsurf 和 Copilot 这样的 AI 编码助手发展很快,但它们经常产生能编译但生产中会失败的代码。它们可能忘记释放控制器、使用弃用的 API 或忽略安全最佳实践。
Saropa Lints 作为您的 AI 的护栏。通过提供即时的**行为**语义反馈 — 而不仅仅是语法 — 它迫使 AI 实时纠正自己的错误。
**专为 AI 修复优化**
该工具也可用于**修复**。Saropa Lints 诊断被设计为"粘贴即可使用",提供深度上下文和具体失败点。当您将问题报告直接复制到 AI 工具窗口时,它会充当完美的提示 — 给 AI 所需的确切信息以重构代码并立即解决问题,而无需您解释上下文。

### 从其他工具迁移?
- [从 very_good 迁移](https://github.com/saropa/saropa_lints/blob/main/doc/guides/migration_from_vga.md)(也涵盖 `lints`、`lint`、`pedantic`)
- [从 DCM(Dart Code Metrics)迁移](https://github.com/saropa/saropa_lints/blob/main/doc/guides/migration_from_dcm.md)
- [从 solid_lints 迁移](https://github.com/saropa/saropa_lints/blob/main/doc/guides/migration_from_solid_lints.md)
- [与 flutter_lints 一起使用](https://github.com/saropa/saropa_lints/blob/main/doc/guides/using_with_flutter_lints.md)(补充设置)
## 五个级别
选择符合您团队需求的级别。每个级别都建立在前一个级别之上。
| 级别 | 目的 | 目标用户 | 示例规则 |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Essential** | **防止崩溃、数据丢失、安全漏洞和内存泄漏。** 这些是单次违规就可能造成真正损害的规则 — 应用崩溃、用户数据泄露、资源永不释放。如果您的应用违反这些规则,糟糕的事情**必然**会发生。 | 每个项目、每个团队。不可协商的基准。 | `require_field_dispose`(内存泄漏)、`avoid_hardcoded_credentials`(安全漏洞)、`check_mounted_after_async`(崩溃)、`avoid_null_assertion`(运行时异常)、`require_firebase_init_before_use`(崩溃) |
| **Recommended** | **捕获常见错误、基本性能问题和无障碍基础。** 这些是造成真正问题但可能不会立即导致应用崩溃的错误 — 糟糕的 UX、缓慢的性能、不可访问的接口、静默失败。 | 大多数团队。生产应用的合理默认值。 | `require_semantics_label`(无障碍)、`avoid_expensive_build`(性能)、`require_json_decode_try_catch`(错误处理)、`avoid_shrinkwrap_in_scrollview`(性能)、`require_image_error_builder`(UX) |
| **Professional** | **强制架构、可测试性、可维护性和文档标准。** 代码能工作但难以测试、难以更改或难以理解。随时间推移拖累团队的技术债务。 | 企业团队、长期存在的代码库、多开发者团队。 | `avoid_god_class`(架构)、`require_public_api_documentation`(文档)、`prefer_result_pattern`(错误处理)、`require_test_cleanup`(测试)、`avoid_hardcoded_strings_in_ui`(i18n) |
| **Comprehensive** | **更严格的模式、优化提示和全面的边缘情况覆盖。** 捕获微妙问题、强制一致性并推动最佳模式的规则。有帮助但非关键。 | 追求质量的团队、库/包团队、希望最大覆盖的团队。 | `prefer_element_rebuild`(微妙性能)、`prefer_immutable_bloc_state`(严格模式)、`require_test_documentation`(可维护性)、`prefer_fake_platform`(测试质量) |
| **Pedantic** | **一切,包括吹毛求疵和高度固执己见的规则。** 大多数团队会觉得过度的规则,但对新项目或希望从第一天就最大程度严格的团队很有价值。 | 全新开始的新项目、从第一天就希望最大严格性的团队。 | `prefer_custom_single_child_layout`(微优化)、`prefer_feature_folder_structure`(固执己见的架构)、`avoid_returning_widgets`(吹毛求疵) |
### 风格规则(独立轨道)
**[175+ 条风格规则](https://github.com/saropa/saropa_lints/blob/main/README_STYLISTIC.md)** 用于格式化、排序和命名约定。
在配置中单独启用风格规则,或使用 VS Code 扩展的配置/整理视图来启用/禁用它们并查看预估评分影响。
对于 CI/脚本,使用 `--no-stylistic`(默认)或 `--stylistic-all` 批量启用:
```
dart run saropa_lints:init --tier recommended --stylistic-all
```
冲突的规则对(如 `prefer_single_quotes` vs `prefer_double_quotes`)必须单独启用 — 您选择您的团队偏好的风格。
风格规则与正确性正交。您的代码可能完全正确而违反每条风格规则,也可能格式完美但在每个屏幕上崩溃。这就是为什么它们是分开的。
### 配置模板
请参阅 [example/analysis_options_template.yaml](https://github.com/saropa/saropa_lints/blob/main/example/analysis_options_template.yaml) 获取完整参考,包含按类别、级别成员资格和示例组织的所有 **2118** 条规则。
### 使用级别
**VS Code 扩展:** 从命令面板使用 **Set Tier** 或点击状态栏中的级别徽章。
**级别预设(零配置):**
```
# 在 analysis_options.yaml 中 — 只需选择你的层级:
include: package:saropa_lints/tiers/recommended.yaml
```
**CLI 初始化(完全控制,CI/脚本):**
```
dart run saropa_lints:init --tier recommended
dart run saropa_lints:init --target /path/to/project
dart run saropa_lints:init --help
```
可用级别:`essential` (1)、`recommended` (2)、`professional` (3)、`comprehensive` (4)、`pedantic` (5)
### 自定义规则
生成配置后,通过编辑 `analysis_options.yaml` 自定义规则:
```
plugins:
saropa_lints:
diagnostics:
# The init tool generates explicit true/false for every rule
avoid_hardcoded_strings_in_ui: true # change to false to disable
require_public_api_documentation: false # change to true to enable
# Stylistic rules (enable the ones your team prefers)
prefer_single_quotes: true
prefer_trailing_comma_always: true
```
规则使用标准 YAML 映射格式(不需要 `-` 前缀)。
要更改级别,请切换 `include:` 预设或重新运行初始化工具:
```
dart run saropa_lints:init --tier professional
```
### 平台配置
`analysis_options_custom.yaml` 文件包含一个 `platforms` 部分,控制哪些平台特定规则处于活动状态。默认仅启用 iOS 和 Android。启用您项目针对的平台:
```
# 在 analysis_options_custom.yaml 中
platforms:
ios: true # enabled by default
android: true # enabled by default
macos: false # enable if targeting macOS
web: false # enable if targeting web
windows: false # enable if targeting Windows
linux: false # enable if targeting Linux
```
每个平台都有专门捕获平台特定问题的规则:
| 平台 | 规则数 | 示例 |
| ----------- | -------------- | ------------------------------------------------------------------------------------ |
| **iOS** | 90+ | 安全区域、隐私清单、应用追踪透明度、Face ID、HealthKit、钥匙串 |
| **Android** | 11+ | 运行时权限、通知渠道、PendingIntent 标志、明文流量 |
| **macOS** | 15+ | 沙盒化、签名公证、硬化运行时、窗口恢复、权利 |
| **Web** | 10+ | CORS 处理、平台通道、延迟加载、URL 策略、Web 渲染器 |
| **Windows** | 桌面共享 | 菜单栏、窗口关闭确认、本机文件对话框、焦点指示器 |
| **Linux** | 桌面共享 | 与 Windows 相同的桌面规则 |
某些规则在平台组之间共享:
- **Apple 规则**(iOS + macOS):Apple Sign In、nonce 验证
- **桌面规则**(macOS + Windows + Linux):菜单栏、窗口管理、键盘/鼠标交互模式
当平台设置为 `false` 时,其规则会移至禁用部分。共享规则(如 iOS + macOS 的 Apple Sign In)仅在**所有**平台都被禁用时才被禁用。
**用户覆盖始终优先** — 如果您在覆盖部分强制启用规则,即使其平台被禁用,它也会保持启用。
`init` 工具记录哪些平台被禁用以及受影响的规则数量:
```
Platforms disabled: web, windows, linux (23 rules affected)
```
### 包配置
`analysis_options_custom.yaml` 文件包含一个 `packages` 部分,控制哪些库特定规则处于活动状态。默认启用所有包。禁用您不使用的包以减少干扰:
```
# 在 analysis_options_custom.yaml 中
packages:
# State Management
bloc: true
provider: true
riverpod: true
getx: true
# UI & Utilities
flutter_hooks: true
# Data Classes
equatable: true
freezed: true
# Storage & Database
firebase: true
isar: true
hive: true
shared_preferences: true
sqflite: true
# Networking
dio: true
graphql: true
supabase: true
# DI & Services
get_it: true
workmanager: true
# Device & UI
url_launcher: true
geolocator: true
qr_scanner: true
# Gaming
flame: true
```
将包设置为 `false` 会将其所有规则移至禁用部分。例如,如果您不使用 Riverpod,请设置 `riverpod: false` 以从分析中移除 24+ 条 Riverpod 特定规则。
包之间共享的规则(如 Firebase、Isar、Hive 和 sqflite 共享的数据库规则)仅在**所有**使用它们的包都被禁用时才被禁用。
更改平台或包设置后,重新运行 init 以应用:
```
dart run saropa_lints:init
```
### 配置键名和别名
规则配置键与 lint 消息中显示的规则名称匹配(方括号中的部分):
```
lib/my_file.dart:42 - [prefer_arguments_ordering] Named arguments should be in alphabetical order.
^^^^^^^^^^^^^^^^^^^^^^^^^ This is the config key
```
要禁用此规则:`prefer_arguments_ordering: false`
**别名**:某些规则支持更短的别名以方便使用。例如,`prefer_arguments_ordering` 也接受 `arguments_ordering`:
```
plugins:
saropa_lints:
diagnostics:
# Both of these work:
prefer_arguments_ordering: false # canonical name
arguments_ordering: false # alias
```
别名为可能常被省略前缀(`enforce_`、`require_`)的规则提供。
### 启用所有规则
使用 `pedantic` 级别预设或初始化工具启用所有规则:
```
# 选项 A:层级预设
include: package:saropa_lints/tiers/pedantic.yaml
# 选项 B:初始化工具
# dart run saropa_lints:init --tier pedantic --stylistic-all
```
**这是故意的。** 它迫使团队明确审查并禁用他们不同意的规则,确保:
- 不会意外忽略任何规则
- 您的配置成为团队风格决策的完整记录
- 互斥的规则(如 `prefer_single_quotes` vs `prefer_double_quotes`)需要明确选择
如果您启用所有规则,您将需要从每对冲突规则中禁用一个。
### 严重级别
每条规则都有固定的严重级别(ERROR、WARNING 或 INFO),在规则本身中定义。严重级别不能按项目覆盖。如果规则的严重级别不符合您的需求:
- 使用 `// ignore: rule_name` 抑制单个实例
- 使用 `rule_name: false` 完全禁用规则
-您认为默认严重级别应该更改,请[打开 issue](https://github.com/saropa/saropa_lints/issues)
### 存量项目的基线
#### 问题
您想在现有项目上采用 saropa_lints。您运行 `dart analyze` 并看到:
```
lib/old_widget.dart:42 - avoid_print
lib/old_widget.dart:87 - no_empty_block
lib/legacy/api.dart:15 - avoid_dynamic
... 500 more violations
```
**这让人望而生畏。** 您无法在下一个 sprint 之前修复 500 个问题。但您也不能完全忽略 linting — 新代码应该是干净的。
#### 解决方案:基线
**基线功能**记录所有现有违规并隐藏它们,同时仍能捕获新代码中的违规。
- **旧代码**:违规被隐藏(基线化)
- **新代码**:违规正常报告
这让您今天就能采用 linting,无需先修复遗留代码。
#### 快速开始(一条命令)
```
dart run saropa_lints:baseline
```
此命令:
1. 运行分析以查找所有当前违规
2. 创建包含这些违规的 `saropa_baseline.json`
3. 自动更新您的 `analysis_options.yaml`
**结果**:旧违规被隐藏,新代码仍被检查。
#### 可组合的基线类型
| 类型 | 配置 | 描述 | 适用于 |
| -------------- | --------------- | -------------------------------- | ---------------------- |
| **基于文件** | `baseline.file` | 列出特定违规的 JSON | "暂不修复" |
| **基于日期** | `baseline.date` | Git blame - 忽略旧代码 | "按年龄逐步修复" |
两种类型可组合:任何匹配都会抑制违规。
#### 完整配置
基线 CLI 支持这些选项:
| 选项 | 描述 |
| ---------------- | ------------------------------------------------------ |
| `--file` | 输出文件(默认:`saropa_baseline.json`) |
| `--date` | 忽略此日期以来未更改的代码(使用 git blame) |
| `--paths` | 忽略整个目录(glob 模式) |
| `--only-impacts` | 仅基线某些严重级别(例如 `low,medium`) |
#### 路径模式示例
| 模式 | 匹配 |
| ------------------- | ------------------------------------ |
| `lib/legacy/` | `lib/legacy/` 下的所有文件 |
| `*.g.dart` | 所有以 `.g.dart` 结尾的文件 |
| `lib/**/old_*.dart` | 类似 `lib/foo/old_widget.dart` 的文件 |
#### 优先级过滤
使用 `only_impacts` 仅基线某些严重级别,同时仍能看到关键问题:
```
baseline:
file: "saropa_baseline.json"
only_impacts: [low, medium, opinionated] # Still see critical and high
```
#### 随时间清理
当您修复违规时,更新基线以移除已修复的项目:
```
dart run saropa_lints:baseline --update
```
输出显示已修复的内容:
```
Baseline Update Summary:
Previous: 150 violations
Current: 120 violations
Fixed: 30 violations removed!
```
#### CLI 参考
```
dart run saropa_lints:baseline # Generate new baseline
dart run saropa_lints:baseline --update # Refresh, remove fixed violations
dart run saropa_lints:baseline --dry-run # Preview without changes
dart run saropa_lints:baseline --skip-config # Don't update analysis_options.yaml
dart run saropa_lints:baseline -o custom.json # Custom output path
dart run saropa_lints:baseline ./my_project # Run on specific directory
dart run saropa_lints:baseline --help # See all options
```
### 跨文件分析 CLI
查找未使用的文件和循环导入链(无 IDE 集成;仅 CLI):
```
dart run saropa_lints:cross_file unused-files # Files not imported by any other file
dart run saropa_lints:cross_file circular-deps # Circular import chains
dart run saropa_lints:cross_file import-stats # Import graph statistics
dart run saropa_lints:cross_file report # HTML report (default: reports/)
dart run saropa_lints:cross_file --help
# JSON 输出到文件(例如用于 CI 或工具)
dart run saropa_lints:cross_file unused-files --output json > unused.json
# 基线:抑制已知问题,仅在新违规时失败
dart run saropa_lints:cross_file unused-files --baseline cross_file_baseline.json
dart run saropa_lints:cross_file unused-files --update-baseline
```
选项:`--path `、`--output text|json`、`--output-dir `(用于报告)、`--baseline `、`--update-baseline`、`--exclude `(保留)。退出代码:0 = 无问题,1 = 发现问题,2 = 错误。CI 的[示例 GitHub Actions 工作流](doc/cross_file_ci_example.md)。请参阅 [ROADMAP Part 3](ROADMAP.md)。
### 独立扫描器
对**任何 Dart 项目**运行 saropa_lints 规则 — 即使该项目没有将 saropa_lints 作为依赖项。在采用包之前评估项目或扫描 saropa_lints 代码库本身很有用。
扫描器读取项目的 `analysis_options.yaml`(由 `init` 生成)以确定要运行的规则,除非您传递 `--tier`。两个步骤:
```
# 1. 配置规则(一次)
dart run saropa_lints init --target /path/to/project --tier recommended
# 2. 扫描
dart run saropa_lints scan /path/to/project
```
**CLI 选项:** `--tier `(essential | recommended | professional | comprehensive | pedantic)覆盖该运行的项目配置。`--files ...` 仅扫描列出的 Dart 文件;`--files-from-stdin` 从 stdin 每行读取一个路径。`--format json` 将机器可读的 JSON 写入 stdout(无报告文件)。否则结果写入 `reports//_scan_report.log`,并在终端打印紧凑摘要。
**编程扫描:** 导入 `package:saropa_lints/scan.dart` 以从代码运行扫描(例如从另一个包或脚本),无需调用 CLI。公共 API 包括 `ScanRunner`、`ScanConfig`、`ScanDiagnostic`、`loadScanConfig`、`scanDiagnosticsToJson` 和 `scanDiagnosticsToJsonString`。示例:
```
import 'package:saropa_lints/scan.dart';
final runner = ScanRunner(
targetPath: '/path/to/project',
tier: 'recommended', // optional: override config with a tier
dartFiles: ['lib/main.dart'], // optional: scan only these files
messageSink: (msg) => log(msg), // optional: redirect or suppress output
);
final diagnostics = runner.run();
if (diagnostics != null) {
final json = scanDiagnosticsToJsonString(diagnostics);
// ...
}
```
JSON 输出(来自 `--format json` 或 `scanDiagnosticsToJson`)包含 `version`、`diagnostics`(每个包含 filePath、line、column、ruleName、severity、problemMessage、correctionMessage?)和 `summary`(totalCount、byFile、byRule)。
## 规则类别
| 类别 | 描述 |
| ------------------------ | ------------------------------------------------------------------------------------- |
| **Flutter Widgets** | 生命周期、setState、键、性能 |
| **Modern Dart 3.0+** | 类修饰符、模式、记录、when 守卫 |
| **Modern Flutter** | TapRegion、OverlayPortal、SearchAnchor、CarouselView |
| **State Management** |Provider、Riverpod、Bloc 模式 |
| **Performance** |构建优化、内存、缓存 |
| **Security** |凭证、加密、输入验证 — [OWASP 映射](#owasp-compliance-mapping) |
| **Accessibility** |屏幕阅读器、触摸目标、语义 |
| **Testing** |断言、模拟、防止 flaky 测试 |
| **Architecture** |Clean 架构、DI、SOLID 原则 |
| **Error Handling** |异常、日志、恢复 |
| **Async** |Futures、Streams、取消 |
| **API & Network** |超时、重试、缓存 |
| **Internationalization** |本地化、RTL、复数 |
| **Documentation** |公共 API、示例、弃用 |
## 风格规则
175+ 条团队偏好规则 — 不包含在任何正确性级别中。在配置中单独启用、通过 VS Code 扩展的配置/整理视图,或使用 `--stylistic-all` 批量启用。
示例:`prefer_relative_imports`、`prefer_single_quotes`、`prefer_arrow_functions`、`prefer_trailing_comma_always`、`prefer_for_in`、`prefer_boolean_prefixes_for_params`
**请参阅 [README_STYLISTIC.md](https://github.com/saropa/saropa_lints/blob/main/README_STYLISTIC.md)** 获取包含示例、优缺点和快速修复的完整列表。
## 性能
Saropa Lints 作为原生 Dart 分析器插件运行 — 无需单独进程。级别系统有助于管理分析范围:
- 设置为 `false` 的规则不会加载
- 从 `essential` 或 `recommended` 开始
- 修复警告后升级级别
```
# 好:从推荐的层级开始
dart run saropa_lints:init --tier recommended
# 警告:在遗留代码库上启用所有规则可能会显示数千个警告
dart run saropa_lints:init --tier pedantic
```
### 性能提示:开发期间使用较低级别
为了在开发期间更快迭代:
1. **本地使用 `essential` 级别** — 用更少的规则捕获关键 bug
2. **CI 中使用 `professional` 或更高** — 在速度不那么重要的地方进行彻底检查
3. **逐步升级级别** — 在启用更多规则之前修复警告
您选择的级别直接影响分析速度(来自 `getRulesForTier` 的近似规则数;风格规则是单独的,除非您传递 `--stylistic-all`):
- `essential`:~300 条规则 → **最快**(内存泄漏、安全、崩溃)
- `recommended`:~950 条规则 → 中等(+ 无障碍、性能)
- `professional`:~1800 条规则 → 较慢(+ 架构、文档)
- `comprehensive`:~1870 条规则 → 更严格的模式和边缘情况
- `pedantic`:~1880 条规则 → **最慢**的正确性级别(风格规则之前的一切)
## 采用策略
静态分析不会创建问题 — 它揭示已经存在的问题。分级系统让您从任何级别开始并按自己的节奏前进。发现结果是为了您的工作流程。您控制您处理什么以及何时处理。
### 新项目
从 `professional` 或 `comprehensive` 开始。编写代码时修复问题。
### 现有项目
1. 启用 `essential`。首先修复关键问题。
2. 转到 `recommended`。处理文件时修复警告。
3. 当噪音可控时启用更高级别。
### 抑制警告
当规则不适用于特定代码时:
```
// ignore: avoid_hardcoded_strings_in_ui
const debugText = 'DEBUG MODE';
// For entire files:
// ignore_for_file: avoid_print_in_production
```
始终添加注释解释**为什么**您要抑制。
### 自动跳过文件
规则自动跳过无法手动修复的文件:
| 文件模式 |跳过 |
| --------------------------------------------- | ------------------------------------- |
| `*.g.dart`、`*.freezed.dart`、`*.gen.dart` | 是(生成的代码) |
| `*_fixture.dart`、`fixture/**`、`fixtures/**` | 是(测试 fixtures) |
| `*_test.dart`、`test/**` | 是(使用 `testRelevance` 覆盖) |
| `example/**` | 否(使用 `skipExampleFiles` 覆盖) |
默认跳过测试文件,因为大多数面向生产的规则会在测试代码中产生噪音。覆盖 `testRelevance` 以更改每条规则的行为:
- `TestRelevance.never` — 跳过测试文件(默认)
- `TestRelevance.always` — 在所有文件上运行,包括测试
- `TestRelevance.testOnly` — 仅在测试文件上运行
## 限制
- **范围**:Saropa Lints 作为原生分析器插件在配置它的包上运行。对于多包工作区,请将 `saropa_lints` 添加到每个包的 `analysis_options.yaml`。
- **文件类型**:仅分析 Dart 源文件(`.dart`)。非 Dart 资产(JSON、XML、YAML、脚本等)不在范围内。
## 运行 Linter
**命令行:**
```
dart analyze
```
Saropa Lints 作为原生 Dart 分析器插件运行。问题会自动显示在您 IDE 的 Problems 面板和 `dart analyze` 输出中。
当启用报告的分析运行时,插件还会在 `reports//` 下写入合并日志(文件名包含 `_saropa_lint_report`)。该文件包括 **FILE IMPORTANCE**(扇入 × 层)、**FIX PRIORITY**(按影响 × 重要性排序的违规)和 **PROJECT STRUCTURE**(导入树),这些都基于分析期间收集的导入数据。
### 影响报告
按业务影响分组运行 lint:
```
dart run saropa_lints:impact_report
```
输出首先显示关键问题,并提供可操作的指导:
```
--- CRITICAL (2) ---
lib/main.dart:45 - avoid_hardcoded_credentials
lib/auth.dart:23 - require_dispose
--- HIGH (5) ---
lib/widget.dart:89 - avoid_icon_buttons_without_tooltip
...
Impact Summary
==============
CRITICAL: 2 (fix immediately!)
HIGH: 5 (address soon)
MEDIUM: 12 (tech debt)
LOW: 34 (style)
Total: 53 issues
```
**影响级别:**
-
由 [Saropa](https://saropa.com) 开发,旨在让 Dart 和 Flutter 生态变得更好。
[](https://pub.dev/packages/saropa_lints) [](https://pub.dev/packages/saropa_lints/score) [](https://pub.dev/packages/saropa_lints/score) [](https://github.com/saropa/saropa_lints/actions) [](https://github.com/saropa/saropa_lints) [](https://github.com/saropa/saropa_lints) [](https://github.com/saropa/saropa_lints/issues) [](https://github.com/saropa/saropa_lints/commits)
[](https://pub.dev/packages/saropa_lints) [](https://flutter.dev/) [](https://opensource.org/licenses/MIT)
## VS Code 扩展(推荐) **安装 [Saropa Lints VS Code 扩展](https://marketplace.visualstudio.com/items?itemName=saropa.saropa-lints)** 以获得完整体验。也可在 [Open VSX](https://open-vsx.org/extension/saropa/saropa-lints) 上获取(适用于 Cursor、VSCodium)。 Dart 工作区的静态分析集成默认**开启**(`saropaLints.enabled`)。即使关闭集成,概览、配置和规则包仍然可用;如需仅使用侧边栏而不运行分析器,请使用 **Saropa Lints: Turn Off Lint Integration** 关闭。 该扩展是主要的设置和配置界面: - **健康评分** — 状态栏显示 0–100 分;绿/黄/红区间 - **问题树** — 按严重程度和文件分组的违规项,带 Error Lens 风格的内联注释;支持多选并可**复制为 JSON** - **安全态势** — OWASP Top 10 覆盖矩阵、合规导出 - **整理** — 从 UI 中禁用扰人的规则;查看执行前的预估评分影响 - **规则包** — 从侧边栏 Webview 启用栈组合(Riverpod、Drift 等)(每个包可单独开关、查看规则列表、目标平台);参见 [`doc/guides/rule_packs.md`](doc/guides/rule_packs.md) - **包活力** — 依赖健康状况、警报和可选的**版本差距** PR/问题整理(使用 `saropaLints.packageVibrancy.enableVersionGap` 启用;GitHub token 可改善结果) - **TODO 与 Hack** — 侧边栏扫描 TODO/FIXME/HACK 风格标记;全工作区扫描是**可选的**(`saropaLints.todosAndHacks.workspaceScanEnabled`,默认关闭),通过 **TODOs & Hacks: Enable workspace scan** 启用 - **文件风险** — 按违规密度排名的文件;优先处理高风险文件 - **趋势** — 评分随时间的演进及里程碑庆祝  **设置项目**会自动配置 `pubspec.yaml`、`analysis_options.yaml` 和分析。无需终端命令。 ## 快速开始 **要求:** Dart SDK `>=3.9.0 <4.0.0`(与本包的 [`pubspec.yaml`](https://github.com/saropa/saropa_lints/blob/main/pubspec.yaml) 约束相同)。 ### 选项 A — VS Code 扩展(推荐) 1. 从 VS Code Marketplace 安装 [Saropa Lints](https://marketplace.visualstudio.com/items?itemName=saropa.saropa-lints) 2. 打开 **Saropa Lints** 侧边栏(活动栏中的复选框图标) 3. 运行 **Saropa Lints: Set Up Project**(或使用概览中的相应控件)以添加包和分析配置 该扩展会将 `saropa_lints` 添加到您的项目、配置分析选项并运行分析。使用配置视图可更改级别、禁用规则以及管理平台/包。从命令面板运行 **Saropa Lints: Getting Started** 可获取导览。 ### 选项 B — 级别预设(零配置,无需扩展) ``` dart pub add --dev saropa_lints ``` 在您的 `analysis_options.yaml` 中添加一行: ``` include: package:saropa_lints/tiers/recommended.yaml ``` 运行 `dart analyze`,问题会显示在您的 IDE 和终端中。 可用预设:`essential.yaml` · `recommended.yaml` · `professional.yaml` · `comprehensive.yaml` · `pedantic.yaml` ### 选项 C — CLI 初始化(完全控制,CI/脚本) ``` dart pub add --dev saropa_lints dart run saropa_lints:init --tier recommended # 可选:来自 pubspec + lockfile 的规则包(参见 doc/guides/rule_packs.md) dart run saropa_lints:init --list-packs dart run saropa_lints:init --tier recommended --enable-pack riverpod --enable-pack drift # IDs must match packs applicable to your pubspec ``` 这会更新(或创建)两个文件: - **`analysis_options.yaml`** — `plugins: saropa_lints: diagnostics:` 部分会为您的级别重新生成,每个规则都设置为 `true`/`false`。其他部分保持不变。 - **`analysis_options_custom.yaml`** — 您的项目设置(平台、分析输出)。首次运行时创建;永不覆盖。 ### 运行分析 ``` dart analyze ``` 问题会显示在您 IDE 的 Problems 面板和终端中。Saropa Lints 作为原生 Dart 分析器插件运行。 ## 工作原理 ``` Dart package VS Code extension │ │ ▼ ▼ analysis_options.yaml ◄─── Set Up Project / Set Tier / Triage │ │ ▼ ▼ dart analyze ◄─── Run Analysis (from UI) │ │ ▼ ▼ violations.json ───► Health Score, Issues, Security, File Risk, Trends, Inline Annotations ``` **Dart 包**通过原生分析器插件提供 **2134** 条静态分析规则。**VS Code 扩展**读取 `violations.json` 并提供 UI:健康评分、问题树、安全态势、文件风险、配置/整理及相关视图。可选的 **Drift Advisor** 集成会在专用侧边栏视图和 Problems 中显示正在运行的 Drift Advisor 服务器的索引建议和数据质量异常。两者一起发布并同步版本。 **规则元数据:** 每条规则可暴露可选语义 — `RuleType`(bug、漏洞、代码异味、安全热点)、`tags`、MITRE **CWE** ID 和 `RuleStatus`(如 beta)— 用于合规和未来的质量门控。默认向后兼容;参见 [CONTRIBUTING.md](
标签:AI编码助手, Dart, Dart开发, Flutter, Flutter开发, Flutter生态, Lint规则, SOC Prime, Subfinder, 云安全监控, 代码审查, 代码检查工具, 代码规范, 内存泄漏检测, 安全扫描, 安全漏洞检测, 开发工具, 性能优化, 时序注入, 检测绕过, 运行时崩溃, 错误基检测, 静态代码分析, 静态分析