首页
/ diagrams 开发环境配置指南:基于 Docker 与 macOS 的本地构建、测试与代码自动生成流程

diagrams 开发环境配置指南:基于 Docker 与 macOS 的本地构建、测试与代码自动生成流程

2026-09-05 16:43:43作者:郜逊炳

diagrams 是一个用 Python 代码绘制云系统架构图的开源项目(Diagram as Code),其贡献流程高度依赖一套“二进制工具 + 单元测试 + 自动代码生成”的本地开发环境。本文基于仓库中的开发指南(DEVELOPMENT.md)展开,完整覆盖 Docker 容器化开发与 macOS 原生开发两条路线的全部命令,并结合 Dockerfileautogen.shconfig.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 处理 onpremazure 提供商的图标
convert(ImageMagick) 图像裁剪与缩放 svg2png2 方式处理 ociibm 提供商
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.pytests/test_c4.py。从 test_diagram.py 的测试用例可以看到,这套单元测试覆盖了 Diagram 的方向参数校验(TB/BT/LR/RL 合法,BR/TL/UnknownValueError)、曲线样式(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 个提供商(onpremawsazuredigitaloceangcpibmfirebasek8salibabacloudociprogrammingsaaselasticgenericopenstackoutscale),分三个阶段执行。

阶段一:图标资源预处理

对每个提供商,脚本按以下规则调用 scripts/resource.py

  • onprem、azurepython -m scripts.resource svg2png <pvd>——用 Inkscape 将 SVG 图标转为 PNG。config.py 中对应参数为 CMD_SVG2PNG = "inkscape",选项 -w 256 -h 256 --export-type png,即统一输出 256x256 的 PNG;
  • oci、ibmpython -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 字典中;
  • 仅 awspython -m scripts.resource round <pvd>——调用 round(config.py 中 CMD_ROUND_OPTS = ("-w",))把方形图标圆角化,这正是 AWS 图标风格与其他提供商不同的原因。

阶段二:模块类与 API 文档生成

对每个提供商执行 python -m scripts.generate <pvd>,随后再对 custom 模块单独执行一次文档生成。从 scripts/generate.pygenerate() 实现看,其流程为:

  1. os.walk 遍历 resources/<pvd>/ 下的每个子目录(每个子目录对应一个类型,如 computenetwork),收集其中除 rounded 之外的 .png 图标路径;
  2. templates/module.tmpl 渲染类代码,写出到 diagrams/<pvd>/<typ>.py。模板首行即标注 # This module is automatically generated by autogen.sh. DO NOT EDIT.,这正是你在 diagrams/generic/compute.py 等生成文件中看到的声明——这些模块文件不是手写的,而是由图标资源派生出来的;
  3. 类名由图标文件名派生:文件名按连字符拆分后逐段做大小写变换,再受 config.py 中 UPPER_WORDS(强制全大写,如 ebs -> EBS)、TITLE_WORDS(定制拼写,如 cloudfront -> CloudFront)与 ALIASES(如 AWS 的 SimpleStorageServiceS3 -> S3、K8s 的 PV -> PersistentVolume)三层规则约束,从而保证生成类名符合各厂商的惯用缩写;
  4. 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 都正确执行,开发系统才算就绪

  • 单元测试验证的是库本身的行为正确性——图方向/曲线/输出格式的参数校验、DiagramCluster 的全局上下文管理、Node 之间的连接运算符语义(见 tests/test_diagram.py);
  • autogen.sh 验证的是工具链与生成流水线的完整性——它会在每次运行后重写 diagrams/<pvd>/*.py 模块文件与 docs/nodes/ 文档,如果这些自动产物被 git 检出为变更,通常意味着 resources/ 下的图标资源发生了变化,需要一并检查后再提交。

掌握以上内容后,你可以按官方路线在 Docker 或 macOS 环境中把 diagrams 的开发环境搭建起来,并理解其中每一个命令、每一个被检查的二进制工具在代码生成流水线中的确切位置。

登录后查看全文
热门项目推荐
相关项目推荐