Home Assistant 开发环境如何用 script/lint 与 script/check_format 检查并提交代码?
【免费下载链接】core:house_with_garden: Open source home automation that puts local control and privacy first.项目地址: https://gitcode.com/GitHub_Trending/co/core
你修改了 Home Assistant core 仓库里的 Python 代码,想确认改动满足项目的格式与 lint 标准后再提交、发 PR。这个仓库在script/目录下提供了固定的开发检查入口:script/check_format 检查代码格式,script/lint 对相对上游dev分支改动的文件跑 lint,配合 AGENTS.md 与 CONTRIBUTING.md 中的提交规范即可完成“本地检查 → 提交 → 发起 PR”的完整流程。本文只覆盖这条路径,不涉及功能开发本身。
准备:用 script/setup 搭建开发环境
仓库要求 Python 3.14(根目录 .python-version 固定为3.14.5),并使用uv管理虚拟环境。AGENTS.md 明确要求:进入新的环境或 worktree 时先运行script/setup,这是提交代码前的必要步骤。
script/setupscript/setup 脚本按顺序做以下几件事,中途出错即停止:
- 若
.vscode/settings.json不存在,从.vscode/settings.default.jsonc复制一份; - 创建
config/目录; - 若当前没有激活的虚拟环境(
VIRTUAL_ENV为空),优先用uv venv .venv创建,否则回退到python3 -m venv .venv,然后激活.venv; - 若系统没有
uv,用python3 -m pip install uv安装; - 执行 script/bootstrap:安装开发依赖(
uv pip install -e . -r requirements_all.txt -r requirements_test.txt colorlog),并把全部英文翻译编译到翻译目录; - 执行
prek install,安装 pre-commit 钩子(prek即 pre-commit 的入口); - 运行
hass --script ensure_config -c config生成配置,并在config/configuration.yaml中缺少 logger 配置时追加一段logger配置块。
已知问题:如果uv报告找不到所需的 Python 版本,说明你的 uv 版本过旧。AGENTS.md 给出的处理方式是先升级 uv 再重跑 setup:
curl -LsSf https://astral.sh/uv/install.sh | sh script/setup检查代码格式:script/check_format
格式检查入口是 script/check_format,它固定检查仓库内的四个位置:
script/check_format脚本内部执行的是:
ruff format --check --quiet homeassistant tests script *.py注意两点:--check表示只检查不修改,所以它不会改动你的文件;--quiet表示格式全部通过时基本无输出,有不符合格式的文件时才会列出文件名。因此判断方式很简单:无输出即通过,列出文件即需要重新格式化。
需要修复格式时,不必手工逐文件处理:仓库的 .pre-commit-config.yaml 注册了ruff-format钩子(以及带--fix参数的ruff-check钩子),提交时会自动修正格式问题。也可以等提交阶段由钩子统一处理,但建议提交前再跑一次script/check_format确认干净。
对改动文件运行 lint:script/lint
script/lint 只检查“你这次改动的 Python 文件”,而不是整个仓库。它先执行git diff $(git merge-base upstream/dev HEAD)取出改动文件列表,因此有两个前置条件:
- 本地必须配置名为
upstream的远端,且分支基于upstream/dev; - 改动必须已经
git add并git commit——未提交的改动不在 diff 结果里,脚本会直接打印No python file changed.退出。
script/lint脚本按两步输出结果:
- 先打印
FILES CHANGED区块,列出参与检查的.py文件; - 再打印
LINT with ruff区块,对这些文件执行prek run ruff-check --files ...; - 最后打印
LINT with pylint区块,对其中非测试文件执行pylint。如果改动只有tests/下的文件,脚本打印Only test files changed. Skipping并退出——这与 script/lint_and_test.py 中的注释一致:tests/* does not have to pass lint。
任一步报错都会出现在对应区块下,按文件与行号修改后重跑即可。
提交前的完整钩子检查(可选)
如果你希望比script/lint覆盖更多检查项(ruff 修复与格式化、codespell 拼写检查、yamllint、prettier、mypy、pylint、gen_requirements_all、hassfest 等),AGENTS.md 建议在一次代码会话结束后运行:
uv run --no-sync prek run --all-filesVS Code 用户也可以使用 .vscode/tasks.json 里预置的任务,其中Prek任务执行的正是prek run --show-diff-on-failure,Ruff任务执行prek run ruff-check --all-files,失败时会显示 diff 便于定位。
快速自查 PR 标准(可选)
script/lint_and_test.py 用于“快速检查分支是否达到 PR 标准”,它明确说明自己不是完整 CI 的替代,只是开发期间的快速检查。它同样基于upstream/dev的 merge-base 找出改动文件,要求改动已提交(否则提示No changed files found. Please ensure you have added your changes with git add & git commit),然后依次执行:
- 对改动的
.py文件跑 pylint 与 ruff,有错误时输出Please fix your lint issues before continuing并停止; - 若改动了
homeassistant/components/下的文件,额外校验gen_requirements_all是否通过,不通过时提示Please run script/gen_requirements.py; - 按文件名映射规则找出对应的
tests/测试文件并运行 pytest。
python3 script/lint_and_test.py判断标准看结尾输出:全部通过时打印Yay! This will most likely pass CI(文档原文如此,表示“很可能”通过 CI,不是保证);测试失败则打印Tests not passing。带--skiplint参数可跳过 lint 步骤(输出中会标注LINT DISABLED),仅适合确认 lint 已通过后快速复跑测试。
提交与发起 PR
检查全部通过后,按仓库规范提交并发起 PR:
- 分支限制:pre-commit 配置中的
no-commit-to-branch钩子禁止直接向dev、master、rc分支提交,改动必须走 PR; - 提交历史:AGENTS.md 要求不要在 PR 分支已经推送的提交上做
amend、squash 或 rebase,因为评审者需要按提交历史跟踪每次审查后的变化; - PR 流程:CONTRIBUTING.md 说明 PR 要针对
dev分支发起,并确保测试通过;AGENTS.md 要求使用仓库的 PR 模板,不得删除模板中任何内容,未勾选的复选框也要保留原样。
限制说明
script/lint与script/lint_and_test.py都依赖upstream/dev作为对比基线,若你的分支不是从upstream/dev切出,取到的改动文件列表会不符合预期;script/lint_and_test.py只是快速自检,AGENTS.md 中提到的钩子检查(如prek run --all-files)与完整 CI 的检查范围不同,本地全绿不等于 CI 必然通过;- 格式检查(
script/check_format)与 ruff-format 钩子都只作用于homeassistant、tests、script、*.py等 Python 文件,非 Python 文件的格式由 yamllint、prettier 等钩子在 pre-commit 阶段处理。
【免费下载链接】core:house_with_garden: Open source home automation that puts local control and privacy first.项目地址: https://gitcode.com/GitHub_Trending/co/core
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考