Files
AnyImage/openspec/changes/separate-node-sources-and-tools/design.md
nan 9debab5c0c Add comprehensive tests for image processing nodes and refactor node imports
- Introduced new test files for image layer, image plane, normal scale, object normal rotation, shadeless, and temporary attributes.
- Implemented tests to validate the behavior of alpha curves, depth layers, and normal scales in various rendering engines.
- Refactored import paths for node groups to align with the new directory structure.
- Added checks for temporary attribute lifetimes and ensured proper cleanup without warnings.
- Enhanced CLI commands to require the Blender group and validate the presence of generated node assets before packaging.
- Updated packaging scripts to enforce the existence of necessary assets, preventing build failures.
2026-09-19 21:23:19 +08:00

113 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Context
节点组的可维护源码位于 `tools/nodes/groups` 和 `tools/nodes/common`,构建入口、布局、校验与预览也位于同一包中。生成后的 `src/anyimage/assets/O_AnyImage.blend` 被扩展运行时读取并进入发布包,但它同时作为 Git LFS 文件提交,历史中已累积多个 1–10 MB 的版本。
项目通过 `blender` dependency group 安装 `bpy==4.5.3`,现有测试也使用该 wheel 创建节点、求值几何及写入 `.blend`。因此本地和 CI 都不需要额外安装或定位完整 Blender 应用程序。
## Goals / Non-Goals
**Goals:**
- 根目录 `nodes/` 只表达节点组及共用节点构建定义。
- `tools/nodes/` 只表达构建、布局、校验和预览工具。
- 干净 CI 从源码生成、验证并打包节点资产。
- 本地与 CI 使用同一个 `node-group` 执行路径,不需要 `.env` 或 `BLENDER_BIN`。
- Git 当前树不再包含生成的 `.blend` 或对应 LFS pointer。
- 节点组的接口、默认值、求值和最终发布包保持不变。
**Non-Goals:**
- 不在本变更中重写 Git 历史或清理远程 LFS 对象。
- 不改变节点组业务名称和实现逻辑。
- 不把节点资产改为扩展运行时动态创建。
- 不提供选择其他 Blender 可执行程序或版本的兼容路径。
## Decisions
### 节点定义成为独立顶层包
建立 `nodes/` Python package:
```text
nodes/
├── common/
└── groups/
tools/nodes/
├── arrangement/
├── preview/
├── build.py
├── check.py
└── cli.py
```
`nodes/groups` 保存各命名节点组定义,`nodes/common` 保存这些定义共享的节点图构建逻辑。布局属于产物呈现和构建工具,继续位于 `tools/nodes/arrangement`。旧 `tools.nodes.groups` 与 `tools.nodes.common` 路径直接删除,不提供转发模块。
Hatch 的工具 wheel同时包含 `tools` 和 `nodes`,确保安装后的 `node-group` 入口能导入节点定义。相应测试按同一职责拆分:节点行为测试进入 `tests/nodes`,工具入口、布局、保存资产和校验测试保留在 `tests/tools/nodes`。
### `.blend` 是构建产物而不是源码
`src/anyimage/assets/O_AnyImage.blend` 加入 `.gitignore` 并从 Git 索引移除。源码检出不承诺该文件存在;开发者使用 `node-group build` 生成它。扩展运行时仍只通过 `load_node_group` 加载生成资产,不在用户运行时创建节点组。
保留 `.gitattributes` 的通用 Blender LFS 规则,因为它可能服务其他手工资产;忽略规则确保本生成物不再加入 Git。删除当前文件只影响未来提交,历史容量将在后续仓库历史整理时处理。
### node-group 统一使用 bpy wheel
`node-group build`、`check` 和 `preview` 都在 `uv run --group blender` 提供的 Python 环境中工作。CLI 不再解析 `--blender`,也不再读取 `BLENDER_BIN`、项目 `.env` 或系统 `PATH`。
为保持构建与保存后检查的进程隔离,CLI 使用 `sys.executable -m` 顺序启动模块:
```text
node-group build
├── python -m tools.nodes.build
├── python -m tools.nodes.check
└── python -m pytest tests/nodes tests/tools/nodes
```
`check` 只运行后两步,`preview` 使用同一 Python 运行预览导出模块。节点命令只运行与节点定义和工具直接相关的测试;项目常规与 AI 测试由各自命令负责。缺少 `bpy` 时命令明确提示使用 `uv run --group blender node-group ...`,不回退到外部 Blender。
相比保留完整 Blender 启动器,这一方案删除了路径发现、`.env` 解析、wheel 解压和 `--python-expr` bootstrap,且让本地与 CI 覆盖同一入口。
### CI 通过 node-group 构建
测试工作流在 pytest 前执行:
```bash
uv run --group blender node-group build --skip-tests
```
该命令使用 CI 已安装的 `bpy==4.5.3`,顺序生成并检查资产。随后运行常规测试目录,节点资产测试读取刚生成的文件。
发布工作流采用同样顺序,在测试成功后执行 `uv run pack`。生成文件留在 job 工作区,由打包器收入扩展压缩包,不作为工作流 artifact 单独传递。
备选方案是在本地或 CI 查找完整 Blender。它下载更大、存在第二套 Python 和依赖 bootstrap,且现有 bpy wheel 已覆盖所需 API,因此删除而不是保留兼容路径。
### 缺失资产时打包明确失败
打包器在创建任何平台包前检查生成资产存在且为普通文件;缺失时给出先构建节点资产的错误。打包测试既验证缺失失败,也验证每个平台归档包含 `assets/O_AnyImage.blend`。
这避免生成步骤遗漏后发布一个运行时才报错的不完整扩展。
## Risks / Trade-offs
- [bpy wheel 的资产兼容性发生变化] → 固定 `bpy==4.5.3`,构建后在独立 Python 进程运行资产检查和现有求值测试。
- [开发者从源码直接启用扩展时缺少资产] → `node-group build` 成为源码使用和打包前置步骤,缺失资产由工具给出明确错误。
- [测试路径重组造成覆盖遗漏] → 沿真实导入路径迁移测试并运行节点构建、常规测试和全量测试。
- [生成文件被误提交] → `.gitignore` 固定忽略具体资产路径,并增加版本控制边界测试。
- [从 Git 删除文件不会立即释放现有远程 LFS 容量] → 本变更只阻止继续增长;后续创建精简根历史时排除旧 LFS 对象。
## Migration Plan
1. 移动节点定义及对应测试,更新全部导入与 wheel 包清单。
2. 将 `node-group` 改为通过当前 Python 的独立子进程运行构建、检查和预览,删除完整 Blender 定位与 bootstrap。
3. 在保留现有资产的情况下构建并验证,确认重组没有改变节点行为。
4. 为测试和发布工作流加入统一的 `node-group` 生成步骤,补充缺失资产打包测试。
5. 将生成资产加入 `.gitignore` 并从 Git 索引移除。
6. 从无节点资产的干净状态执行 CI 等价流程,确认最终发布包包含重新生成的资产。
回滚时恢复节点定义路径、工作流和已提交资产即可;Git 历史清理不属于本变更,因此回滚不需要恢复远程历史。
## Open Questions
无。