chore: add ruff checks

This commit is contained in:
chengma
2026-07-07 15:11:40 +08:00
parent 862f791fde
commit 6e2347e1c8
13 changed files with 81 additions and 16 deletions
+7 -1
View File
@@ -24,6 +24,7 @@
| 运行日志 | SQLite `run_logs` / `run_log_events` | 已定 | ③ dry-run 与真实更新都留痕;结构化内容走脱敏 |
| 图片处理 | `requests`(下载)+ `Pillow`(按分辨率/jpg质量存盘) | 部分待定 | 下载旧封面;新封面按 resolution 生成、jpg_quality 存盘 |
| 测试 | `python -m compileall app main.py` + `unittest` + 手动 CDP/AI 验证 | 已定(分层) | 配置/DB/Excel/prompts 用单测;CDP/Shopee 与真实 AI 属集成验证或 mock |
| 代码质量 | `ruff`(lint + format 可用) | 已定 | T-525 引入开发检查依赖;CI 先强制安全类 lint,不做全仓格式化重排 |
| 打包分发 | PyInstaller onedir(`cmshopee.spec`) | 已定 | 产出 Windows 免安装文件夹;不内置配置、DB、图片、日志、Chrome 登录态或提示词等本地数据;运行时统一写入程序同级 `data/` |
## 二、决策记录与演进
@@ -48,7 +49,10 @@
| 用途 | 命令 |
| --- | --- |
| 安装依赖 | `py -3.10 -m pip install -r requirements.txt` |
| 安装开发检查依赖 | `py -3.10 -m pip install -r requirements-dev.txt` |
| 检查 PySide6 | `python -c "import PySide6; print(PySide6.__version__)"` |
| ruff 安全检查 | `py -3.10 -m ruff check app tests main.py` |
| ruff 格式化(按需) | `py -3.10 -m ruff format app tests main.py` |
| 语法检查 | `py -3.10 -m compileall app main.py` |
| 启动 GUI | `py -3.10 main.py` / `py -3.10 -m app` |
| 单元测试(T-006 后) | `py -3.10 -m unittest discover -s tests` |
@@ -75,6 +79,7 @@ set AUTO=1 && python prototypes/demo.py
## 四、依赖纪律
- 运行时第三方依赖统一写入根目录 `requirements.txt` 并锁定版本;换机或 CI 使用 `python -m pip install -r requirements.txt` 安装。
- 开发检查依赖写入 `requirements-dev.txt`;当前只包含 ruff,不属于运行时或打包依赖。
- 打包依赖只写入 `requirements-build.txt`;PyInstaller 不属于运行时依赖,不写进 `requirements.txt`。
- 当前直接依赖锁定:PySide6 6.5.3、openpyxl 3.1.3、requests 2.31.0、websocket-client 1.6.1、Pillow 9.5.0。
- 新增第三方依赖前,先在本文说明用途、替代方案和维护成本,并同步更新 `requirements.txt`。
@@ -87,8 +92,9 @@ set AUTO=1 && python prototypes/demo.py
| 层级 | 覆盖对象 | 验证方式 |
| --- | --- | --- |
| 语法 | 正式代码包与入口 | `python -m compileall app main.py` |
| lint | 正式代码、测试与入口 | `python -m ruff check app tests main.py`;当前只开启安全类规则,格式化命令可用但不强制全仓重排 |
| 单元 | `appconfig/db/excel/prompts/config/chrome` 的纯逻辑 | T-006 建立 `tests/` 后运行 `python -m unittest discover -s tests`,使用临时目录/临时 SQLite/样例 Excel |
| GUI 轻测 | PySide6 主窗口可创建、Tab 数量、worker signal 基本行为 | 可用 unittest 构造 `QApplication`,不连真实 Shopee |
| CI | push / pull_request 自动跑语法 + 全量 unittest | `.github/workflows/tests.yml` 安装 `requirements.txt`,运行 `python -m compileall app main.py` 与 `python -m unittest discover -s tests`;不连真实 Shopee/AI |
| CI | push / pull_request 自动跑 ruff + 语法 + 全量 unittest | `.github/workflows/tests.yml` 安装 `requirements.txt` 与 `requirements-dev.txt`,运行 `python -m ruff check app tests main.py`、`python -m compileall app main.py` 与 `python -m unittest discover -s tests`;不连真实 Shopee/AI |
| 集成 | CDP/editor 操作 Shopee 测试商品 | 手动跑 `prototypes/demo.py` 或后续专用集成脚本 |
| 外部 AI | 模型连接、文本/图像生成 | 默认 mock;真实调用只在手动验证时跑,避免成本和限流 |
+3
View File
@@ -53,6 +53,7 @@
完成前至少检查:
- [ ] `python -m compileall app main.py` 通过(T-000 前仅文档改动不要求)。
- [ ] `python -m ruff check app tests main.py` 通过(T-525 后;当前只开启安全类规则)。
- [ ] T-006 完成后,纯逻辑改动有对应 `unittest`,至少覆盖正常路径和一个失败路径。
- [ ] 涉及 CDP 的改动,在测试商品(ITEM_ID 51100639510)上实跑验证。
- [ ] 涉及更新封面删除线上第一张图时,必须先验证该任务 `old_cover_path` 本地备份存在;备份缺失不得删除线上图片。
@@ -64,6 +65,7 @@
- [ ] 回复里如实说明跑了什么命令、结果如何。
```bash
python -m ruff check app tests main.py
python -m compileall app main.py
python -m unittest discover -s tests # T-006 完成且 tests/ 存在后
python prototypes/demo.py # 单账号闭环验证(不提交)
@@ -72,6 +74,7 @@ python prototypes/demo.py # 单账号闭环验证(不提交)
测试命令时机:
- T-006 前:`tests/` 尚未建立时,只要求运行与当前任务匹配的可用验证;不要因为 `python -m unittest discover -s tests` 缺目录而判失败。
- T-525 后:`python -m ruff check app tests main.py` 成为代码改动的必跑项;当前只启用安全类 lint,不要求全仓格式化。
- T-006 后:`python -m unittest discover -s tests` 成为纯逻辑改动的必跑项;新增/修改 appconfig、db、excel、prompts、config、chrome 纯逻辑时同步补测。
## 7. 绝不
+1 -1
View File
@@ -143,7 +143,7 @@
| --- | --- | --- | --- | --- |
| T-541 | 打包版主窗口初始位置与小屏适配 | T-523, T-537, T-540 | Bug:在 Windows 10 虚拟机/小分辨率环境运行打包后的 `dist/cmshopee/cmshopee.exe` 或 release 包时,主窗口可能贴到屏幕左上角且左边/标题栏显示不全,看不到「蝦皮圈優化助手 v<APP_VERSION>」标题,用户无法拖动窗口到中间。根因:`MainWindow.__init__()` 只调用 `self.resize(1180, 760)`,没有根据 `QApplication.primaryScreen().availableGeometry()` 限制初始尺寸、没有居中、没有保证窗口 frame/title bar 在可用屏幕范围内;PyInstaller 本身不是根因,小屏、高 DPI、任务栏占用、多显示器或 VM 分辨率更容易触发。方案:① 抽一个主窗口初始布局 helper(如 `_fit_and_center_window(window, preferred_size=(1180,760), margin=40)`),读取当前屏幕 `availableGeometry()`;② 初始宽高不超过可用区域减安全边距,保留合理最小值(如 960x640,若屏幕更小则继续适配);③ `resize()` 后按可用区域中心 `move()`,确保 `frameGeometry()` 左上角不小于可用区域左上角,标题栏完整可见;④ offscreen/headless 测试环境不依赖真实屏幕时可跳过或用 mock geometry;⑤ 不保存/恢复历史窗口位置,避免把坏坐标持久化。同步 `docs/packaging.md` 打包验收:在目标 VM/小分辨率环境启动 release exe,窗口标题栏必须完整可见且可拖动。GUI 单测覆盖小屏 mock 下尺寸被限制、窗口被居中/夹进可用区域;不改业务流程、DB、AI、Excel、CDP/Shopee、打包产物结构 | DONE |
| T-542 | GUI 用户可见 `shopee/Shopee` 文案统一改为「蝦皮」 | T-523, T-537 | 需求:运行程序后,GUI 上用户能看到的 `shopee` / `Shopee` 字符统一改成中文「蝦皮」,例如主 Tab「③ 更新shopee」改为「③ 更新蝦皮」,设置分区「Shopee 更新安全 / 执行模式」改为「蝦皮更新安全 / 执行模式」,引导、弹窗、状态栏、运行日志、空状态、右键/确认文案里的“更新 Shopee / 未打开 Shopee / 不回滚 Shopee”等也改为「蝦皮」。范围:只改**用户可见文案与 GUI 测试断言**,包括 `app/gui/widgets.py` 的 `TAB_TITLES`、`MainWindow` 里依赖 Tab 文案的判断、`tabs/apply.py`、`tabs/settings.py`、`tabs/collect.py`、`tabs/generate.py`、`gui/workers.py` 中的可见提示和相关 `tests/test_gui.py`;同时修正 `app/editor.py` 里会冒到 GUI 的自定义错误文案。边界:不得改内部标识符、配置键、DB 字段、文件名、URL、域名、CDP 选择器和第三方原始错误,例如 `shopee_update`、`cmshopee`、`shopee待处理任务模板.xlsx`、`seller.shopee.tw`、`.shopee-image-manager`、`window.__cmshopee_*`、`cmshopee.db` 必须保持原样;代码注释/技术文档中指平台事实可继续写 `Shopee`。验收:`rg -n "更新shopee|Shopee 更新安全|更新 Shopee|未打开 Shopee|不回滚 Shopee" app tests` 不命中;`python -m compileall app main.py` 与 `python -m unittest discover -s tests` 通过;不涉及 CDP 流程实跑 | DONE |
| T-525 | 引入 ruff(lint + format)+ 可选 pre-commit | T-006 | 依据 `docs/engineering-review.md` P1。加 `ruff` 配置(lint + format),先以现状为基线不做大规模风格重排,只开启安全规则(未用 import/变量、明显错误);可选 `.pre-commit-config.yaml`;不改业务逻辑;CI(T-522)可串入 ruff 检查。数据模型渐进上 mypy 作为后续可选。当前因业务优先级调整顺延到 T-526~T-528 之后 | TODO |
| T-525 | 引入 ruff(lint + format)+ 可选 pre-commit | T-006 | 依据 `docs/engineering-review.md` P1。加 `ruff` 配置(lint + format),先以现状为基线不做大规模风格重排,只开启安全规则(未用 import/变量、明显错误);可选 `.pre-commit-config.yaml`;不改业务逻辑;CI(T-522)可串入 ruff 检查。数据模型渐进上 mypy 作为后续可选。当前因业务优先级调整顺延到 T-526~T-528 之后 | DONE |
| T-537 | 品牌名「蝦皮圈優化助手」(显示层中文品牌,cmshopee 保留为代号/标识符) | T-523 | 需求:项目/软件正式定名「蝦皮圈優化助手」。**原则**:产品**显示/品牌名** = 「蝦皮圈優化助手」;`cmshopee` 保留为**代码库/仓库/技术代号**,一切**标识符不改**——遵项目「文档与 UI 文案用中文、标识符用英文」规则,且避免非 ASCII 文件名破坏现有用户数据。**改(显示/品牌层)**:① `app/gui/main_window.py` 窗口标题 `setWindowTitle("cmshopee")` → `"蝦皮圈優化助手"`(任务栏/标题栏显示中文品牌);② 文档产品名散文 `docs/00-ai-start-here.md`、`docs/README.md`、`AGENTS.md`(及 vision/brief 若有)把「cmshopee 是一个…」改为「蝦皮圈優化助手(代号 cmshopee)是一个…」,明确品牌名并保留代号;③ 空的 `README.md` 补品牌标题行;④ 可选:`app/gui/__init__.py` PySide6 缺失启动失败提示带上品牌名。**不改(技术标识符,保留 cmshopee)**:`app` 包名、`cmshopee.exe` 打包产物名、`cmshopee.db`(+`-wal/-shm`)/`db_path` 默认值、`cmshopee.spec`、`cmshopee.log`、`config.json`/`config/*.json` 文件名、slug/`chrome_user_data_dir`、仓库目录;`app/editor.py` 注入页面的 JS 全局 `window.__cmshopee_*`(JS 标识符须 ASCII)、`app/ai.py` multipart boundary `----cmshopee-*`、`app/workers.py` `thread._cmshopee_worker`、`app/chrome.py` 快捷方式内部前缀 `cmshopee-`。**决策点**:`app/excel.py` 回写文件名后缀 `_cmshopee回写` 为用户可见产物名——本任务**默认保留**(改动会影响已生成副本命名习惯),如需改「_優化助手回写」另行确认。**影响**:不改 db/exe/spec/包名 → 打包、更新流程、现有用户数据零影响。验收:窗口标题栏/任务栏/README/相关文档显示「蝦皮圈優化助手」;`cmshopee.db`/exe/包名不变;GUI 单测若断言窗口标题须同步更新;`python -m compileall app main.py` + `python -m unittest discover -s tests` 全绿。边界:纯显示/文档层,不改任何文件名、schema、流程、CDP/Shopee 逻辑 | DONE |
| T-538 | 打包产物用户数据收进 `data/` 子文件夹(便携方案 1) | T-524 | 问题:当前 onedir 产物把用户数据(`config.json`、`config/ai_models.json`、`config/cmhub.json`、`cmshopee.db(+-wal/-shm)`、`chrome_user_data_dir/`、`images/`、`logs/`、`prompts/`、`title_prompt.txt`)生成在 exe 顶层,和程序文件/依赖文件混放:更新易误删数据、放进 Program Files 只读目录会写失败/被 VirtualStore 重定向、程序与数据关注点混杂。方案(保持便携):① **统一数据根**——所有用户数据落到 exe 同级的单个 `data/` 子文件夹;`app/appconfig.py` 用显式 `data_dir`(默认 `<exe目录>/data`,源码运行时可为项目根/`data`)解析并返回绝对路径,**替代现在 `main.py` 的 chdir**(chdir 影响全进程相对路径/文件对话框默认目录,脆弱);文件名保持不变(仍是 `cmshopee.db` 等),只是移入 `data/`。② **旧布局迁移**——新版首次运行若在 exe 顶层发现旧的 `config.json`/`cmshopee.db` 等,自动迁移进 `data/`(或明确提示手动迁移),不得对老用户生成空 `data/` 丢失原数据。③ **可写性检测**——启动时若 `data_dir` 不可写(如放在 Program Files),弹清晰错误「请把程序放到可写目录,勿放 Program Files」并优雅退出,不静默失败。④ **发布只含程序**——`cmshopee.spec`/`scripts/build_exe.ps1` 构建检查确保不打包 `data/` 或任何用户数据;发布 zip 不含 `data/`,从而「整包解压覆盖」也安全(覆盖程序文件、不碰 `data/`);T-540 后当前打包脚本固定 PyInstaller 6.11.1,产物为 `cmshopee.exe` + `_internal/` onedir,具体版本和 release 命名由 T-540 维护。⑤ **更新流程前提**——原地更新=换程序留 `data/`,依赖:DB 迁移幂等且只向前(现 `init_db`+`ALTER TABLE ADD COLUMN`)、`config` 向前兼容(`load_config` 补默认值)。同步更新 `docs/packaging.md`(目录结构、首次运行数据位置、§5 更新步骤简化为「覆盖新版程序文件和依赖文件,`data/` 不动」)。测试:`test_appconfig` 断言各路径解析进 `data_dir`、可写性检测行为、旧布局迁移;`test_packaging` 断言产物不含 `data/`/用户数据。边界:只改路径解析层(`appconfig` 路径 + `main.py` 数据根 + 迁移/可写检测)、spec/构建脚本、打包文档;不改文件名、DB schema、业务逻辑、AI/Excel、CDP/Shopee 流程 | DONE |
| T-539 | ⑤ 隐藏数据路径设置(设置简化,非防逆向) | T-538, T-517 | 背景:T-538 后用户数据固定收进 exe 同级 `data/`,⑤「路径与端口」里的 DB 路径(`dbPathEdit`)、图片目录(`imageDirEdit`)、账号数据根目录(`userDataRootEdit`)已不该由用户改动——改了会指向 `data/` 之外导致数据分裂/丢失。**定性说明**:本任务是**设置简化**,与 T-517/T-529 隐藏 `test_item_id`/`dry_run` 同一思路;**不是防逆向手段**——`cmshopee.db` 在磁盘上任何 SQLite 浏览器可直接打开,隐藏 UI 字段对逆向无意义,防逆向由另行任务(发布包加固/价值上移 cmhub)承担。方案:① ⑤普通设置页**隐藏** `db_path`/`image_dir`/账号数据根三个输入框(不再占表单位置),`config.json` 对应字段保留为内部兼容——手工编辑配置仍生效(内部回滚路径),加载/保存不丢字段;② **保留可见**:Chrome 路径(每台机器安装位置不同,真实配置需求)与默认端口/端口区间/CDP 就绪超时(端口冲突需可调);③ 首次运行/迁移后各路径默认解析到 `data/` 下(沿用 T-538 的 `data_dir` 规则),无需用户感知。同步 `docs/routes.md` ⑤ 说明与 GUI 设置单测(隐藏字段不再可见、config 字段仍读写、手工配置值仍被尊重)。边界:只改⑤设置页展示层与文档;不改 `config.json` schema、路径解析逻辑(T-538 范围)、DB、业务流程、CDP/Shopee | TODO |
+4 -2
View File
@@ -32,15 +32,17 @@
```powershell
python -m pip install -r requirements.txt
python -m pip install -r requirements-dev.txt
python -m ruff check app tests main.py
python -m compileall app main.py
python -m unittest discover -s tests
python -m pip install -r requirements-build.txt
powershell -ExecutionPolicy Bypass -File scripts\build_exe.ps1
```
`requirements.txt` 只锁定运行所需第三方依赖;打包环境使用 `requirements-build.txt` 安装 PyInstaller;T-538 后 `data/` 统一保存配置、SQLite、图片、登录态、日志、提示词和密钥,运营 Excel 仍是本地数据,不提交版本库。
`requirements.txt` 只锁定运行所需第三方依赖;`requirements-dev.txt` 锁定 ruff 等开发检查依赖;打包环境使用 `requirements-build.txt` 安装 PyInstaller;T-538 后 `data/` 统一保存配置、SQLite、图片、登录态、日志、提示词和密钥,运营 Excel 仍是本地数据,不提交版本库。
GitHub Actions 工作流见 `.github/workflows/tests.yml`,在 push / pull_request 上使用 Windows + Python 3.11 安装 `requirements.txt`,并自动运行语法检查和全量单元/GUI 测试。
GitHub Actions 工作流见 `.github/workflows/tests.yml`,在 push / pull_request 上使用 Windows + Python 3.11 安装 `requirements.txt` 与 `requirements-dev.txt`,并自动运行 ruff、语法检查和全量单元/GUI 测试。
## 任务 / 进度 / 当前状态
+1 -1
View File
@@ -187,4 +187,4 @@ cmhub 返回结构化 `{error:{code}}`。映射层**按 `code` 优先分支**(
- **第五步(T-530)**:Base URL 规整到网关根,404 给出明确中文提示。
- 文档随每步同步。
> 当前已在 `docs/06-tasks.md` 落成 T-526~T-530;下一步回到 T-525 工程基础设施,仍遵守 `docs/05-coding-rules.md` 验证清单。
> 当前已在 `docs/06-tasks.md` 落成 T-526~T-535,且 T-525 工程基础设施已完成;下一步按看板进入 T-539 设置简化,仍遵守 `docs/05-coding-rules.md` 验证清单。
+14 -7
View File
File diff suppressed because one or more lines are too long
+2
View File
@@ -44,6 +44,8 @@
### 5. 没有 lint/format/type 配置(→ T-525)
> 落地状态:T-525 已完成。当前已加入 `pyproject.toml`、`requirements-dev.txt` 和 CI ruff 检查;先只强制安全类 lint,不做全仓格式化重排,mypy 仍作为后续可选。
- **现状**:无 ruff/black/mypy/pre-commit;类型注解部分覆盖。
- **影响**:大代码库 + AI agent 持续改,缺一致性门禁会慢慢腐化(未用 import、风格漂移)。
- **方案**:引入 ruff(lint+format 一把梭)+ 可选 pre-commit hook;数据模型可渐进上 mypy。