docs: 记录工程化改造(uv + ruff + pyright)的决策与踩过的坑
日志补记下半场:三件套的落地细节、行宽为何定 100、PTH 为何不开、pyright 两个关键开关;新增三条可复用环境坑(write_text 会把 LF 变 CRLF、同文件多次 Edit 互相覆盖、git status 与 git diff 不一致的判别)。 项目长期约定同步更新:运行方式改为 uv 单一可信来源,新增代码风格约定与质量门禁命令。
This commit is contained in:
1 parent
c414db4217
commit
52004571c8
2 files changed
+83
-6
No files matched your search
@@ -4,13 +4,17 @@
|
||||
终端农场经营游戏 + 小型多人游戏服务器(v2.0)。游戏跑在服务端进程里,
|
||||
TUI 是纯客户端,同时开放 HTTP + WebSocket 接口给 AI/脚本调用(服务端不内置 AI)。
|
||||
|
||||
## 运行方式
|
||||
- 依赖放隔离 venv:`C:/Users/Administrator/.workbuddy/binaries/python/envs/default/Scripts/python.exe`
|
||||
(服务端需要 fastapi + uvicorn[standard] + websockets;客户端与 TUI 只用标准库)
|
||||
- 服务端:`python main.py serve --daemon`,网页 <http://127.0.0.1:8765/>,文档 /docs
|
||||
- 玩:`python main.py play --farm 名字`;单机:`python main.py solo`
|
||||
## 运行方式(v2.0 起由 uv 统一管理)
|
||||
- **单一可信来源是 `pyproject.toml`**,`.venv/` 由 uv 创建;`uv.lock` **要提交**(可复现构建依据)。
|
||||
加/删依赖走 `uv add` / `uv remove`,不要手工编辑依赖表,也不要再列 `pip install`。
|
||||
- 所有命令带 `uv run ` 前缀:`uv run main.py serve --daemon`,网页 <http://127.0.0.1:8765/>,文档 /docs
|
||||
- 玩:`uv run main.py play --farm 名字`;单机:`uv run main.py solo`
|
||||
- AI/脚本入口:`main.py actions | do <动作> '<JSON>' | batch | state --json | watch | bot`
|
||||
- 测试:`python -m unittest discover -s tests`(97 项;不需要 FastAPI 时只跑 test_engine.py)
|
||||
- 测试:`uv run python -m unittest discover -s tests`(97 项)
|
||||
- 质量门禁(改动后都应跑一遍):
|
||||
`uv run ruff check .` / `uv run ruff format .` / `uv run pyright`
|
||||
- 不用 uv 的人:`requirements.txt` 是 `uv export` 的产物,只读、不要手工改。
|
||||
README 与 main.py 顶部保留了一段"没装 uv?把 `uv run ` 去掉即可"的兜底说明,**别删**。
|
||||
|
||||
## 架构约定(改动时必须遵守)
|
||||
- **分层**:`farm.engine` 只管规则,不认识网络/终端;`farm.tui` 不认识 socket;
|
||||
@@ -32,6 +36,23 @@ TUI 是纯客户端,同时开放 HTTP + WebSocket 接口给 AI/脚本调用(
|
||||
`open_url()`(回环直连),否则会拿到 502 并误判为"服务器没起来"。
|
||||
- Windows 下守护进程的 pid 必须由**服务进程自己**写(见 `farm/server/__main__.py`),
|
||||
父进程的 `Popen().pid` 不可信。
|
||||
- **写文件必须指定行尾**:Windows 上 `pathlib.write_text()` 会把 `\n` 转成 `\r\n`,
|
||||
破坏本仓库"统一 LF"的约定(`.gitattributes` 已声明 `eol=lf`)。
|
||||
用脚本改文件时一律 `read_bytes()/write_bytes()`,或 `write_text(..., newline="\n")`。
|
||||
- **同一文件在一条消息里多次 Edit 会被静默覆盖**(只落地一部分,随后报出"幽灵"错误)。
|
||||
批量改同一文件时改用**幂等 Python 补丁脚本**:整文件读入 → 精确匹配替换 →
|
||||
逐条打印 `ALREADY/APPLIED/MISS`,跑完即删。判断"已应用"要 `if new in text`,
|
||||
不要比对两行文本(会出现 new 是 old 子串的假阳性)。
|
||||
- `git status` 报 M 但 `git diff` 为空,是索引 stat 缓存过期,不是真差异;
|
||||
`git add -A`(内容相同时等于无操作)即恢复干净。
|
||||
|
||||
## 代码风格约定(ruff / pyright 已固化在 pyproject.toml)
|
||||
- 行宽 **100**;字符串统一双引号;`isort` 把 `farm` 视为第一方。
|
||||
- 类型标注用 PEP 585/604 写法(`dict[str, int]` / `X | None`),不要 `Dict` / `Optional`。
|
||||
- 吞异常要显式:`contextlib.suppress(...)` 优先于 `try/except/pass`。
|
||||
- 异常链:转换后重抛用 `raise ... from exc`;有意隐藏原始上下文用 `from None`(**不要省略**,会触发 B904)。
|
||||
- 路径保持 `str`(不要为了 lint 而转 `Path`);`farm/__init__.py` 的惰性 `__all__` 导出是刻意设计。
|
||||
- 改完代码的标准动作:`uv run ruff format . && uv run ruff check . && uv run pyright && uv run python -m unittest discover -s tests`
|
||||
|
||||
## 相关文档
|
||||
- 项目入口文档:`README.md`(接口表、WS 协议、边界处理、设计取舍全在里面)
|
||||
|
||||
Reference in new issue
Block a user