diagrams 开发环境配置指南:基于 Docker 与 macOS 的本地构建、测试与代码自动生成流程
diagrams 是一个用 Python 代码绘制云系统架构图的开源项目(Diagram as Code),其贡献流程高度依赖一套“二进制工具 + 单元测试 + 自动代码生成”的本地开发环境。本文基于仓库中的开发指南(DEVELOPMENT.md)展开,完整覆盖 Docker 容器化开发与 macOS 原生开发两条路线的全部命令,并结合 Dockerfile、autogen.sh、config.py 等源码,深入解释每一步背后依赖的工具链与代码生成机制,帮助你在动手贡献节点、模块或文档之前,把开发环境一次性搭对。
开发环境的依赖构成
在开始任何一条安装路线之前,先理解 diagrams 开发环境到底需要哪些组件。从 pyproject.toml 可以确认项目的 Python 版本要求为 ^3.9(即 Python 3.9 及以上),核心运行时依赖是 graphviz(负责把图渲染为图片)和 jinja2(负责代码与文档模板渲染)。而开发侧(dev-dependencies)引入了 black(代码格式化工具),并约定了 line-length = 120 的格式规范。
除了 Python 生态的依赖,diagrams 还依赖四个关键的二进制命令行工具,这也是后续所有命令能跑通的前提。从 autogen.sh 开头的依赖检查逻辑可以确认:
| 工具 | 用途 | 在自动流程中的角色 |
|---|---|---|
round(Go 编写) |
将方形 PNG 图标生成为圆角图标 | 仅对 AWS 提供商执行 |
inkscape |
将 SVG 转成 PNG | 处理 onprem、azure 提供商的图标 |
convert(ImageMagick) |
图像裁剪与缩放 | 以 svg2png2 方式处理 oci、ibm 提供商 |
black |
Python 代码格式化 | 对生成的 diagrams/**/*.py 模块做 lint |
autogen.sh 会逐个用 command -v 检查这四个命令是否可执行,任何一个缺失都会直接 exit 1 终止。换句话说:“跑通单元测试 + 跑通 autogen.sh”之所以是开发环境就绪的判定标准,正是因为 autogen.sh 会把上述整套工具链都过一遍。
Docker 本地开发路线
这是官方开发指南推荐的主路线。整条路线共 6 步,全部在项目根目录执行。
1. 构建开发用 Docker 镜像
docker build --tag diagrams:1.0 -f ./docker/dev/Dockerfile .
该命令指定了仓库中的开发镜像定义文件 docker/dev/Dockerfile。从 Dockerfile 内容可以看到,这个镜像被刻意做成了一个“自带全部二进制依赖”的自包含环境:
- 基础镜像为
python:3.13.1-alpine3.20; - 通过
apk add一次性安装系统级依赖:gcc libc-dev g++ graphviz git bash go imagemagick inkscape ttf-opensans curl fontconfig xdg-utils; - 用
go install github.com/mingrammer/round@latest安装圆角图标工具round,并通过ENV PATH="$PATH:/root/go/bin"把 Go 二进制目录加入 PATH; - 下载并安装 NotoSansCJKjp 中文字体后执行
fc-cache -fv刷新字体缓存(保证图中中文标签能正常渲染); - 设置
WORKDIR /usr/src/diagrams,即后续容器内源码的挂载目标路径; - 最后用
pip install black graphviz jinja2安装 Python 侧依赖。
正因为镜像内已经预装了 autogen.sh 所需的全部二进制工具,Docker 路线才不需要在宿主机上单独安装 Go、Inkscape、ImageMagick。
2. 创建容器并挂载项目源码
docker run -d \
-it \
--name diagrams \
--mount type=bind,source="$(pwd)",target=/usr/src/diagrams \
diagrams:1.0
这条命令的关键在于 --mount type=bind,source="$(pwd)",target=/usr/src/diagrams:它以 bind mount 方式把宿主机上的项目根目录($(pwd))挂载到容器的 /usr/src/diagrams。这样做的意义是:你在宿主机上编辑的源码,容器内实时可见,测试和 autogen 的产物(生成的模块、文档、图标)也会直接写回宿主机的工作目录,无需额外拷贝。-d -it 表示容器在后台运行并保持 TTY,方便后续 docker exec 交互式执行命令。
3. 用容器运行单元测试验证环境
docker exec diagrams python -m unittest tests/*.py -v
这里通过 docker exec 在已启动的 diagrams 容器内运行标准库 unittest,对 tests/ 目录下的测试文件做详细(-v)模式执行。仓库当前包含 tests/test_diagram.py 与 tests/test_c4.py。从 test_diagram.py 的测试用例可以看到,这套单元测试覆盖了 Diagram 的方向参数校验(TB/BT/LR/RL 合法,BR/TL/Unknown 抛 ValueError)、曲线样式(ortho/curved)、输出格式(png/jpg/svg/pdf/dot)的合法值校验,以及全局图上下文(getdiagram/setdiagram)、Node 连接运算符(-、>>、<<)等核心行为。单元测试能通过,说明容器内的 Python 依赖与 graphviz 渲染链路是完整的。
4. 运行 autogen.sh 完成最终验证
docker exec diagrams ./autogen.sh
这一步等价于在宿主机执行 autogen.sh。它不只是“测试”,而是一次完整的资源预处理 + 代码生成 + 文档生成 + 格式化的流水线(下文详述)。当单元测试和 autogen.sh 都正确执行完毕,按照开发指南的判定标准,你的系统即已具备 diagrams 开发能力。
Docker 路线小结
| 步骤 | 命令 | 目的 |
|---|---|---|
| 构建镜像 | docker build --tag diagrams:1.0 -f ./docker/dev/Dockerfile . |
预装 Python 3.13、graphviz、go、inkscape、imagemagick、round、字体 |
| 启动容器 | docker run -d -it --name diagrams --mount type=bind,source="$(pwd)",target=/usr/src/diagrams diagrams:1.0 |
绑定挂载源码,宿主机与容器共享文件系统 |
| 单元测试 | docker exec diagrams python -m unittest tests/*.py -v |
验证 Python 依赖与渲染链路 |
| 生成验证 | docker exec diagrams ./autogen.sh |
验证二进制工具链与代码/文档生成流水线 |
macOS 本地开发路线
如果不使用 Docker,也可以直接在 Mac 上搭建开发环境。官方指南要求系统预先安装 Python、Go 和 Homebrew(brew),随后按以下步骤执行,均在项目根目录进行:
1. 安装 poetry 并安装项目依赖
pip install poetry
poetry install
diagrams 使用 poetry 作为 Python 项目与依赖管理工具(name = "diagrams",当前版本 0.24.1,要求 python = "^3.9",并注册了 diagrams CLI 入口 diagrams.cli:main)。poetry install 会根据 pyproject.toml 创建虚拟环境并安装运行时依赖(graphviz、jinja2)及开发依赖(pytest、pylint、rope、isort、black)。
2. 安装二进制依赖
brew install imagemagick inkscape black
go install github.com/mingrammer/round@latest
# ln -sf ~/go/bin/round ~/.local/bin/round
这组命令正好对应 autogen.sh 检查的四个工具:brew 安装 ImageMagick(提供 convert)、Inkscape 和 black;go install 从源码安装 Go 编写的 round 工具,注释中的软链接命令用于在 ~/.local/bin 不在 PATH 时把 round 暴露出来(原生 macOS 环境下 Go 默认安装到 ~/go/bin,若该目录不在 PATH 中就需要这一步,这也是 Docker 镜像里要显式设置 ENV PATH 的同一问题)。
3. 运行单元测试与 autogen.sh
python -m unittest tests/*.py -v
./autogen.sh
与 Docker 路线相同的两条验证命令,只是直接在本机执行。两条命令都通过后,macOS 环境即视为就绪。
两条路线的对照
| 环节 | Docker 路线 | macOS 路线 |
|---|---|---|
| Python 依赖 | 镜像内 pip install black graphviz jinja2 |
poetry install |
| graphviz | 镜像内 apk add graphviz |
建议另行安装(渲染图必需,见 README.md) |
| 二进制工具 | 镜像内 apk + go install round 预装 |
brew install imagemagick inkscape black + go install round |
| 执行方式 | docker exec diagrams ... |
宿主机直接执行 |
深入 autogen.sh:开发验证背后的代码生成流水线
理解 autogen.sh 的完整流程,能帮助你判断“测试通过”到底意味着什么,也是理解 diagrams 贡献工作流(参见 CONTRIBUTING.md)的关键。该脚本按 config.py 中定义的 PROVIDERS 列表顺序遍历 16 个提供商(onprem、aws、azure、digitalocean、gcp、ibm、firebase、k8s、alibabacloud、oci、programming、saas、elastic、generic、openstack、outscale),分三个阶段执行。
阶段一:图标资源预处理
对每个提供商,脚本按以下规则调用 scripts/resource.py:
- onprem、azure:
python -m scripts.resource svg2png <pvd>——用 Inkscape 将 SVG 图标转为 PNG。config.py 中对应参数为CMD_SVG2PNG = "inkscape",选项-w 256 -h 256 --export-type png,即统一输出 256x256 的 PNG; - oci、ibm:
python -m scripts.resource svg2png2 <pvd>——改用 ImageMagick 的convert命令(选项-shave 25%x25% -resize 256x256!),先裁掉四周各 25% 再缩放至 256x256,从源码注释可知这是因为这两家的 SVG 直接导出效果不佳; - 所有提供商:
python -m scripts.resource clean <pvd>——按各提供商的规则清洗、统一文件名(如去掉Amazon-/AWS-/Azure-等厂商前缀、下划线转连字符、整体小写化),前缀清单定义在 config.py 的FILE_PREFIXES字典中; - 仅 aws:
python -m scripts.resource round <pvd>——调用round(config.py 中CMD_ROUND_OPTS = ("-w",))把方形图标圆角化,这正是 AWS 图标风格与其他提供商不同的原因。
阶段二:模块类与 API 文档生成
对每个提供商执行 python -m scripts.generate <pvd>,随后再对 custom 模块单独执行一次文档生成。从 scripts/generate.py 的 generate() 实现看,其流程为:
os.walk遍历resources/<pvd>/下的每个子目录(每个子目录对应一个类型,如compute、network),收集其中除rounded之外的.png图标路径;- 用 templates/module.tmpl 渲染类代码,写出到
diagrams/<pvd>/<typ>.py。模板首行即标注# This module is automatically generated by autogen.sh. DO NOT EDIT.,这正是你在 diagrams/generic/compute.py 等生成文件中看到的声明——这些模块文件不是手写的,而是由图标资源派生出来的; - 类名由图标文件名派生:文件名按连字符拆分后逐段做大小写变换,再受 config.py 中
UPPER_WORDS(强制全大写,如ebs->EBS)、TITLE_WORDS(定制拼写,如cloudfront->CloudFront)与ALIASES(如 AWS 的SimpleStorageServiceS3->S3、K8s 的PV->PersistentVolume)三层规则约束,从而保证生成类名符合各厂商的惯用缩写; - 用
apidoc.tmpl(提供商存在专属模板如apidoc_custom.tmpl时优先使用)渲染节点清单文档,写出到 docs/nodes/ 下对应<pvd>.md文件。
阶段三:图标同步与代码格式化
生成完成后,脚本执行:
cp -r resources website/static/img/
black diagrams/**/*.py
前者把处理后的图标资源同步到文档站点的静态目录(website/static/),后者用 black 对所有生成的模块文件做统一格式化(遵循 pyproject.toml 中 line-length = 120 的配置)。
因此,当 autogen.sh 在容器或本机成功跑完时,你实际上同时验证了:四个二进制工具可用、全部提供商的图标能完成清洗与转换、模板渲染链路能产出模块代码与文档、black 能通过格式检查。
开发就绪的判定标准
两条路线最终收敛到同一个判定标准(来自开发指南的最后一步):单元测试与 autogen.sh 都正确执行,开发系统才算就绪。
- 单元测试验证的是库本身的行为正确性——图方向/曲线/输出格式的参数校验、
Diagram与Cluster的全局上下文管理、Node之间的连接运算符语义(见 tests/test_diagram.py); - autogen.sh 验证的是工具链与生成流水线的完整性——它会在每次运行后重写
diagrams/<pvd>/*.py模块文件与 docs/nodes/ 文档,如果这些自动产物被 git 检出为变更,通常意味着resources/下的图标资源发生了变化,需要一并检查后再提交。
掌握以上内容后,你可以按官方路线在 Docker 或 macOS 环境中把 diagrams 的开发环境搭建起来,并理解其中每一个命令、每一个被检查的二进制工具在代码生成流水线中的确切位置。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00