AWS-PlantUML如何解决图标命名冲突:SHA1去重与递归命名空间生成机制全解析
【免费下载链接】AWS-PlantUMLPlantUML sprites, macros, and other includes for AWS components.项目地址: https://gitcode.com/gh_mirrors/aw/AWS-PlantUML
AWS-PlantUML 是一个为 PlantUML 提供 AWS 组件图标(sprite)、宏(macro)与构造型(stereotype)的开源工具包,让你几行代码就能画出带官方 AWS 图标的架构图。当上千个 AWS 图标涌入同一仓库,"同名图标撞车"几乎是必然的。本文带你完整拆解它如何用SHA1 去重与递归命名空间生成两大机制,彻底解决图标命名冲突问题。
图标命名冲突从何而来?
AWS 官方图标包遵循严格的文件命名规范(见 README.md):
<CATEGORY>_<SERVICE_NAME>[_<SERVICE_COMPONENT>][_LARGE]例如Storage_AmazonS3_bucket.png会被拆分为类别Storage / AmazonS3与组件名bucket(解析逻辑见 puml.py)。
问题就出在这里:"bucket"、"table"、"action" 这类子组件名,在不同服务下大量重名。如果直接拿组件名生成宏名,BUCKET、TABLE这些宏必然互相覆盖;此外,同一张图标图片还被 Amazon 放在多个分类目录下,会产生完全相同图形的重复文件。
AWS-PlantUML 的生成脚本 puml.py 用"先去重、再递归加命名空间"两步走解决了这两个问题。
第一道防线:SHA1 去重
在 filter_duplicate_images() 中,脚本对每张图标文件的原始字节计算 SHA1 摘要,再用groupby按摘要分组:
- 同一组内只有 1 个文件 → 正常保留;
- 同一组内有多个文件(即图片内容完全一致,只是文件名/路径不同)→只保留第一个。
这一步的妙处在于:它判断的不是"名字是否相同",而是"内容是否相同"。两个不同路径下像素级一致的图标,只会生成一份宏与 sprite,从源头消灭了重复定义带来的命名冲突。
# puml.py 中的去重核心思路 def shasum(puml): h = sha1() with open(puml.image_path, 'rb') as f: h.update(f.read()) return h.hexdigest()第二道防线:递归命名空间生成
去重之后,仍会剩下"名字相同、内容不同"的图标。这时轮到 set_unique_names() 登场——一个教科书级的递归消歧函数:
- 按 expand_name() 生成的候选名排序并分组;
- 某组里只有 1 个图标 → 候选名即最终唯一名(
unique_name); - 某组里有多个→ 只对这些冲突者递归调用自身,expand 加 1,候选名多拼一级父类别。
以Storage_AmazonS3_bucket.png为例,三轮候选名依次是:
| 轮次 | expand | 候选名 | 说明 |
|---|---|---|---|
| 第 1 轮 | 0 | bucket | 只用组件名,最简洁 |
| 第 2 轮 | 1 | AmazonS3_bucket | 加上父级服务名 |
| 第 3 轮 | 2 | Storage_AmazonS3_bucket | 加上顶层类别名,必然唯一 |
递归只在冲突子集内进行,且候选名最长也只是完整命名空间,因此必然收敛、必然终止——每个图标最终都拿到一个全局唯一的unique_name。
双重宏输出与点分命名空间
拿到唯一名后,macros 属性 会做一件贴心的事:当unique_name != name时,同时生成两份宏与两份 sprite(generate_sprite() 末尾追加了第二份定义)。
- 短名宏(如
BUCKET):画图时最常用,简洁好写; - 全名宏(如
AMAZONS3_BUCKET):当你同时需要多个不同来源的bucket时,用它精确引用。
此外,namespaced_name 还会把路径转成点分命名空间(如Storage.AmazonS3.bucket),它被用作 INI 配置文件的 section 名。InheritingConfigParser 在查不到当前节时会自动向上逐级回退(Storage.AmazonS3.bucket→Storage.AmazonS3→Storage),这就是 awspuml.ini 中[Analytics]、[Analytics.AWSGlue]、[Analytics.AWSGlue.AWSGlue_LARGE]这种层次化配置可以按粒度覆盖颜色与实体类型的原因。
; awspuml.ini 中的点分命名空间配置节 [Analytics] color: ${PUML.colors:orange} entity_type: node [Analytics.AWSGlue]最终效果:几行代码画出 AWS 架构图
以上机制全部发生在生成期,画图时你只需 common.puml 里的PUML_ENTITY宏。以 examples/component-customization.puml 为例:
!include path/to/common.puml !include path/to/Storage/AmazonS3/AmazonS3.puml AMAZONS3(s3_internal,"Default S3") AMAZONS3(s3_internal2,"S3 as node",node) AMAZONS3_LARGE(s3_partner,"Large S3")每个宏只需传"别名 + 可选标签",冲突消解、sprite 编码、构造型换行全部由生成机制在幕后完成。综合多个服务图标,就能得到如 examples/comments-architecture.puml 这样的完整架构:
机制速查表
| 机制 | 解决的问题 | 代码位置 |
|---|---|---|
| SHA1 去重 | 内容相同的重复图标文件 | puml.py |
| 递归命名空间生成 | 同名不同内容的图标 | puml.py |
| 双重宏 / 双 sprite 输出 | 短名易用与精确引用的兼得 | puml.py |
| 点分命名空间 + 配置继承 | 按分类粒度自定义样式 | puml.py |
💡 一句话总结:先用 SHA1 保证"相同内容只定义一次",再用递归命名空间保证"不同内容必有唯一名"——两道防线组合起来,就让上千个 AWS 图标宏可以和平共处,而画图的人完全无感。
【免费下载链接】AWS-PlantUMLPlantUML sprites, macros, and other includes for AWS components.项目地址: https://gitcode.com/gh_mirrors/aw/AWS-PlantUML
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考