RakullApp 现在是单一大仓库,整个仓库只有一个 git 钩子、一份 pre-commit 配置(根目录的 .pre-commit-config.yaml)。git commit 时它会自动对本次暂存的文件跑对应检查:后端 Python 用 Ruff 做 lint 和格式化,客户端 Dart 用 dart format + dart analyze

根配置都跑些什么

根目录那份 .pre-commit-config.yaml 按文件路径分流:
命中的文件钩子作用
rakull_server/<服务>/**/*.pyruff-check(带 --fixlint,并自动修可安全修复的问题(未用 import、import 排序等)
同上ruff-format按 Ruff 格式化器统一风格(与 Black 兼容)
rakullapp_core/**/*.dartdart format按官方风格格式化 Dart(生成文件除外)
同上dart analyze静态分析 / lint(读 analysis_options.yaml 里的 flutter_lints
Ruff 版本锁在 v0.15.17。每个后端服务各自带一份 pyproject.toml,所以 Ruff 会按文件就近找到对应服务的 [tool.ruff]——根配置只管「哪些文件要跑」,具体规则还是各服务自己说了算。
各服务目录下原来那几份 .pre-commit-config.yaml 依然保留,但它们是给下游镜像仓库用的(镜像是独立仓库,配置放在各自根部才生效)。日常在 monorepo 里开发,跑的始终是根目录这一份。

安装

一次性设置。先装 pre-commit CLI(仓库统一用 uv):
uv tool install pre-commit
如果它提示 ~/.local/bin 不在 PATH 上,跑一下 uv tool update-shell 再重开终端。注意:git commit 触发钩子不依赖 PATH(生成的钩子里写死了解释器的绝对路径),只有手动敲 pre-commit 命令时才需要它在 PATH 上。 再把钩子装进仓库:
bash scripts/install_precommit_all.sh
脚本做的就是在仓库根目录跑一次 pre-commit install——monorepo 只有一个 .git,装一次就够了。

日常使用

装好之后,不管改的是哪个目录,git commit 都会自动对暂存的文件跑对应检查:
git add rakull_server/agent_server/app/llm/openrouter.py
git commit -m "..."   # 命中 .py → 自动跑 ruff-check + ruff-format
想手动把整个仓库过一遍(初次接入或大改之后很有用):
pre-commit run --all-files
只跑某一个钩子:
pre-commit run ruff-format --all-files
pre-commit run dart-analyze --all-files
pre-commit run --all-files 只处理已被 git 跟踪的文件;新加的、还没 git add 的文件不会被检查。

Ruff 配置

规则写在每个服务的 pyproject.toml 里:
[tool.ruff]
target-version = "py311"
line-length = 88

[tool.ruff.lint]
select = ["E", "F", "I"]
ignore = ["E501"]
说明
target-versionpy311各服务都是 Python 3.11
line-length88行宽(和格式化器一致)
lint.selectEFIpycodestyle 错误、Pyflakes、import 排序
lint.ignoreE501行长交给格式化器,不单独报
想更严(比如加上 UP/B 等规则集),改对应服务的这一段就行——这就是各服务收紧规则的入口。

提交被拦下来怎么办

  • 钩子改了文件ruff-check --fixruff-formatdart format 改动文件后,本次提交会中止。把改动 git add 一下再提交即可。
  • 有修不了的 lint(比如 F841 未用变量):手动改代码、在那行加 # noqa: <规则号>,或临时在 pyproject.tomllint.ignore 里放行。
  • 想跳过这一次(不推荐):git commit --no-verify

Flutter 客户端(rakullapp_core)

客户端走的是 Dart 自带工具,不是 Ruff。pre-commit 没有内置 Dart 工具链,所以这两个是 language: system 钩子,直接调 Flutter 附带的 Dart SDK。前置条件:
  • dartPATH 上(随 Flutter 安装,位于 <flutter>/bin);
  • 至少跑过一次 flutter pub get,否则 dart analyze 解析不了依赖。
生成文件(*.g.dart*.freezed.dart、插件注册文件)已在配置里排除。dart format 会就地改文件,一旦它重排了某个文件,本次提交就会中止——git add 后再提交即可。

升级 Ruff 版本

改根目录 .pre-commit-config.yaml 里锁定的 rev 即可(顺手把各服务的镜像配置也对齐一下更好):
pre-commit autoupdate
改完的配置、以及被重新格式化的代码,一起提交进 monorepo 就行——不用再像以前那样分仓分别提交。