后端Web框架【免费下载链接】fountain一个用于服务器应用开发的综合工具库。 - 零配置文件 - 环境变量和命令行参数配置 - 约定优于配置 - 深刻利用仓颉语言特性 - 只需要开发动态链接库fboot负责加载、初始化并运行 - 覆盖服务器应用开发的各种场景项目地址https://gitcode.com/Cangjie-SIG/fountain点击查看免费下载本文介绍 fountain 仓库中docs/模块依赖图/下的三套生成脚本它们为根 README.md 的「模块依赖关系」章节产出两张图分层连线图module-dependencies.svg与依赖矩阵module-dependency-matrix.svg并给出依赖抽取、API 引用量统计等排查手段。读完你将掌握什么才算一条真实依赖cjpm.toml声明 源码 import 双层判定、如何一键重画两张图、连线图的布局与避让路由算法、矩阵图的读图方式以及重跑产物一致、自检全绿的工程约定。这套工具的定位README 里那两张图是怎么来的fountain 根 README.md 的「模块依赖关系」章节里有两张图分层连线图.assets/README/module-dependencies.svg箭头A → B表示 A 依赖 B按依赖层级分层排布适合一眼看懂谁在底层、谁在上层依赖矩阵.assets/README/module-dependency-matrix.svg行 依赖方、列 被依赖方适合按模块精确查询它依赖了谁 / 谁依赖了它。这两张图并非手工维护而是由 docs/模块依赖图/ 下的三个 Python 脚本自动生成。三个脚本分工如下见 docs/模块依赖图/README.md 的产物表格产物生成脚本.assets/README/module-dependencies.svg分层连线图gen_layered_svg.py.assets/README/module-dependency-matrix.svg依赖矩阵gen_matrix_svg.py依赖表 / 统计排查用extract_deps.py另有--usage每条边的 API 引用次数、--declared连未引用的声明一起列、--json其中extract_deps.py是数据源与口径的唯一权威它的 docstring 明确写着改『什么算依赖』只改这里两个绘图脚本都以模块方式import extract_deps复用其graph()、api_usage()、top_edges()、summary()等函数。核心口径什么才算一条真实依赖双层判定这是整套工具的基石。仓颉语言里要用某个模块的 API 必须把它声明成直接依赖间接依赖的符号不可见因此「cjpm.toml的[dependencies]里声明了fountain::X」 且 「该模块src/下的非测试源码里真的import了fountain::X…」——两条同时成立才算一条边。从源码看这两层在 extract_deps.py 的scan()中分别实现声明层读取各模块cjpm.toml用正则切出[dependencies]段匹配fountain::([A-Za-z0-9_])形式条目#注释行跳过引用层imports_dep()遍历该模块src/下所有.cj文件src_files()会剔除*_test.cj用IMPORT_FMT正则匹配import fountain::dep…。该正则在 extract_deps.py 中支持带可见性修饰的 importIMPORT_FMT (r^\s*(?:(?:public|protected|internal|private)\s)?import\s rfountain::{}(?![A-Za-z0-9_]))即public import/protected import/internal import/private import都算引用普通import自然也算。声明了但源码未引用的边不进图——它们只是多余的声明比如f_orm/cjpm.toml里声明了一批模块但某条没在源码中出现不代表真实依赖关系间接可达关系也不画比如 A 依赖 B、B 依赖 CA 与 C 之间没有直接边即使 A 能通过 B 间接用到 C 的能力也不画。两条图只画 used 边这保证了图上的每一条边都能在源码里找到对应的 import 证据。以根 README 对图的说明为旁证README.md只画『cjpm.toml声明了、且源码里真的 import 了对方 API』的依赖与脚本实现完全一致。一键重画三条命令与产物路径模块依赖变化后只需两条命令即可重画两张图。原文档给出的流程为docs/模块依赖图/README.mdcd docs/模块依赖图 python3 extract_deps.py # 先看抽取结果modules… declared… used… unused… python3 gen_layered_svg.py # → ../../.assets/README/module-dependencies.svg python3 gen_matrix_svg.py # → ../../.assets/README/module-dependency-matrix.svg环境要求极低只要 Python 3无任何第三方依赖两个绘图脚本只用标准库math/os/random/sys/xml.etree.ElementTree。在笔者的验证环境Python 3仓库当前状态上实际运行python3 extract_deps.py得到modules44 declared238 used219 unused19即当前仓库抽取到44 个模块含fboot、fleet[dependencies]中声明了 238 条fountain::*依赖其中219 条被源码真正引用进图19 条属于声明了但未引用不进图可用--declared列出以便清理。两个绘图脚本都支持可选输出路径参数python3 gen_layered_svg.py [输出路径]默认分别写docs/模块依赖图/../../.assets/README/module-dependencies.svgdocs/模块依赖图/../../.assets/README/module-dependency-matrix.svg排查利器extract_deps.py 的命令行参数extract_deps.py既是绘图脚本的数据源也是一个独立的依赖排查工具支持四个参数python3 extract_deps.py # 依赖表 统计默认只列已引用的边 python3 extract_deps.py --declared # 连「声明了但未引用」的边一起列标 UNUSED便于清理 cjpm.toml python3 extract_deps.py --usage # 每条边的 API 引用次数连线图靠它决定颜色深浅 python3 extract_deps.py --json # 输出 JSON含 declared / used / usage python3 extract_deps.py --usage | head # 看引用量最大的边--declared对每个模块额外输出[UNUSED: …]列表标出那些声明了却没引用的依赖是清理cjpm.toml冗余声明的直接依据--usage按 API 引用次数降序列出每条边--json则输出结构化数据供其它脚本消费。实测引用量最大的边节选493.2 f_orm - f_base 412.7 f_data - f_concurrent 347.5 f_orm - f_data 344.3 f_llm - f_data注意--usage输出的次数可能带小数如 493.2这是 API 引用量口径里同名符号均摊的结果见下节。API 引用量的精确口径api_usage()extract_deps.py统计A 的非测试源码里出现 B 的公开符号名的次数有四处严格的过滤规则import 行本身不计——只看真正的使用处正则ANY_IMPORT匹配到import开头的行直接跳过注释与字符串字面量不计——_clean()先用正则剥掉块注释/*…*/、行注释//…和字符串…避免把文档、文案里的名字误算成 API 引用同名符号按候选数均摊——若某个符号同时属于 A 依赖的多个模块如Exception可能同时是f_exception和标准库的名字出现一次就按 1/N 分给每个候选模块不重复计给每一个A 自己也声明了同名符号则不计——symbols()用PUBLIC_DECL正则public … (class|interface|struct|enum|func|macro|let|var|const|type|prop|operator)收集各模块对外公开的符号名若nm in syms[a]说明该符号归属不明直接跳过。symbols()有缓存_SYM_CACHE、_PAT_CACHE多脚本重复调用时不重复扫描源码。均摊后可能出现.5这类一位小数最终round(v, 1)保留。每模块前三top_edgestop_edges(k3)extract_deps.py按 API 引用量给每个模块的依赖排序取前三名次数相同时按依赖名字典序定序保证结果可复现。两张图共用同一条规则连线图中前三名画彩色实线、其余画灰色虚线矩阵图中前三名画彩色格、其余画浅灰格。实测main_edges数量会随仓库演进变化重画时脚本会在输出中打印。连线图gen_layered_svg.py的布局与避让路由gen_layered_svg.py产出的分层连线图在可读性上做了大量设计原文档归纳了其中的要点源码里可以一一对应分层布局level 到汇点无依赖的模块的最长路径递归lvl()越底层 level 越小行从上到下排布节点宽度NW按最长模块名自适应中文字符按 1.04 倍、ASCII 按 0.55 倍估宽而不是固定宽度省掉大片空白行内布局节点少的行把省下的横向空间摊到行内间隙HGAP96下限、MAX_HGAP210上限并叠加行级横向错位optimize_shifts对每行试探 9 个偏移比例取交叉数最小者把所有长边挤成一条竖直走廊的问题错开行内排序多起点启发式搜索——先按 3 个确定性起点原始顺序 / 入度降序 / 出度降序加 12 个固定种子随机打乱共 15 个候选每个候选跑多轮「重心法 相邻交换」barycenter10 轮 transpose预算 150 次目标函数是沿真实路径统计的几何交叉数crossings沿避让折线每 32px 采样一次 x统计相邻采样间顺序翻转的对数——折线 y 单调翻转一次即相交一次只对交叉数最好的 3 个起点做相邻交换跨层长边避让路由这是连线图最精巧的部分。channel_x()对每条span 1的跨层长边在中间每一层挑选一条通道 x——通道只能落在该层节点之间的空隙或行两端外侧free_slots扣掉与节点框的净距CLR7同一空隙内的多条边按自然插值 x 均匀铺开因此线永远不会压到任何节点框路径中竖直段用L行间过渡用控制点在竖直中点的三次贝塞尔path_d曲线不会超出两端 x 范围出/入边锚点分散anchors_at让一个节点的多条出边沿底边、多条入边沿顶边均匀分散避免一点引出一束线交互每个节点带title含被依赖数、自身依赖数、API 引用合计CSS 悬停节点时高亮其直连边svg:has(#nd-{n}:hover) g.e[data-src…]剥离 CSS 也不影响静态观感。配色黄金角散布 引用量分档配色规则原文档约定 源码实现每个模块一个不重复的色相hues()用黄金角137.508°按顺序散布(i * GOLDEN) % 36044 个模块互不撞色边的深浅 引用量shade_of(u)先把引用量做log1p归一化再分6 档LEVELS 61 档最浅、6 档最深pair_hex在模块色相上按档位调明度light0.80 → dark0.34引用越多越深两张图共用这套色连线图与矩阵图都调用extract_deps.hues()且矩阵图按(level, name)同序分配保证同一模块在两张图里同色。节点样式还承担语义被依赖数 ≥ 10HUB的模块画蓝框hub无依赖的基础层画绿框foundation其余为浅色框。自检与可复现脚本运行结束时会打印自检报告源码 gen_layered_svg.pyheader overflow页眉文字是否横向超出画布 / 纵向压进节点区——必须nonenode crossings逐条采样复核线压节点——必须none实测会打印none没有线压到节点框overlaps节点框是否互相重叠——必须nonecolors unique色相互不重复——打印yes及模块数/色相数。产物可复现random.Random(20261008)固定随机种子同一脚本连跑两次两张图md5应一致。这保证 CI 或协作场景下重画不会产生随机漂移。矩阵图gen_matrix_svg.py的读图方式与布局gen_matrix_svg.py产出依赖矩阵它与连线图是同一份数据extract_deps.graph()、同一条配色规则的另一种读法两轴同一顺序按(level, name)升序基础层在左上排列因此依赖只落在对角线右上侧左下三角铺一层浅底结构上不可能有依赖查询场景更快看某模块依赖了谁 → 看该行看谁依赖了某模块 → 看该列格子颜色该行 API 引用量前三的依赖画彩色格色相 依赖方、深浅 引用量与连线图一致其余画浅灰格#e2e8f0每个格子带title含引用次数与前三/未进前三标注悬停可看列名下边的数字 该模块被依赖次数in-degree原文档特别说明这个数字原先放在网格底行已上移到列名正下方紧贴列名视觉上直接回答谁是被依赖最多的模块被依赖 ≥ 10 的模块列名加粗网格每 5 格加深分隔线便于数格子定位自检项较少header overflow与colors unique两项必须干净。矩阵图的行/列标签都是模块短名加上行列数字后非常适合在评审依赖关系时逐模块核对。约定速览改脚本时保持一致原文档把改脚本时必须遵守的约定集中列了出来这里汇总为一张速查表约定内容不写死路径仓库根按脚本位置推断脚本在docs/模块依赖图/下产物写../../.assets/README/见ROOT abspath(…/../..)什么算依赖cjpm.toml声明了fountain::X且src/非_test.cj里import了fountain::X…声明了但未引用、间接可达都不画API 引用量A 源码里出现 B 公开符号名的次数import 行、注释、字符串不计同名符号按候选数均摊A 自己声明的同名符号不计每模块前三按引用量排序并列按依赖名定序保证可复现前三画彩色实线 / 彩色格其余灰色虚线 / 浅灰格——两张图同一规则配色每模块一个不重复色相黄金角散布边/格深浅 引用量log 归一 6 档越多越深两张图同色连线图布局节点宽度按最长模块名自适应行内摊开 行级错位行内排序用多起点重心法 相邻交换目标 几何交叉数跨层长边只在节点间隙 / 行外侧路由矩阵图数字列名下边紧贴一个数字 该模块被依赖次数原在网格底行已上移产物可复现固定随机种子同一脚本连跑两次两张图 md5 一致自检全绿连线图header overflow / node crossings / overlaps / colors unique矩阵图header overflow / colors unique示例应用不进图fdemo、fcoder、frpcdemo列在EXCLUDE里见 extract_deps.py根 README 的模块清单只含库模块与fleet其中EXCLUDE的实现值得一提scan()里glob所有*/cjpm.toml后按目录名过滤掉三个示例应用目录因此它们的依赖包括未纳入中心仓的私有模块不会污染图。与技能 fountain-tag 同源原文档最后一条约定是fountain-tag/scripts/deps/是同一套脚本的技能副本差别只有两点——仓库根按FOUNTAIN_ROOT git 仓库根 当前目录的顺序推断以及产物路径不同。改完docs/模块依赖图/下的脚本后需要运行python3 技能目录/scripts/deps/sync_from_repo.py # 同步同源脚本 check_sync.py --run # 校验同源与产物一致需要说明的是当前仓库的 skills/ 目录下只包含cangjie-doc-lookup与fountain-developer两个技能fountain-tag技能副本并不在本仓库内同步操作应在安装该技能的本地环境执行。这条约定保证了同一套口径、同一份产物在仓库与技能侧保持一致避免两份脚本各改各的导致依赖图口径漂移。小结docs/模块依赖图/下的三套脚本构成了 fountain 仓库一套自洽、可复现、可自检的模块依赖可视化体系口径统一一切依赖边都经过「cjpm.toml声明 源码 import」双层判定声明了没用的边和间接可达关系一律不进图图上的每一条边都能在源码里找到证据一数据两视图extract_deps.py产出统一数据连线图看整体分层、矩阵图查单模块明细配色与每模块前三规则跨图一致工程化程度高无第三方依赖、固定随机种子保证产物可复现、内置 4 项自检、示例应用隔离、与技能侧脚本保持同源同步。对 fountain 开发者来说这套工具的实际价值在于新增或调整模块依赖后跑一遍三条命令就能得到两张最新、准确且干净的依赖图用--declared能顺手清理cjpm.toml里的冗余声明用--usage能识别谁在重度依赖谁为模块拆分与架构演进提供量化依据。赞分享后端Web框架【免费下载链接】fountain一个用于服务器应用开发的综合工具库。 - 零配置文件 - 环境变量和命令行参数配置 - 约定优于配置 - 深刻利用仓颉语言特性 - 只需要开发动态链接库fboot负责加载、初始化并运行 - 覆盖服务器应用开发的各种场景项目地址https://gitcode.com/Cangjie-SIG/fountain点击查看免费下载相关推荐NetExec模块依赖管理工具解析与解决依赖NetExec模块依赖管理工具解析与解决依赖 在网络执行工具NetExec的日常使用中依赖管理是确保工具稳定性和功能完整性的关键环节。你是否曾遇到过模块网络安全渗透测试CLI应用安全PydepsPython模块依赖可视化工具PydepsPython模块依赖可视化工具 安装指南 Pydeps是一款强大的Python包专注于以图形方式展现Python模块间的依赖关系。要安装Pyde开发工具Pilot Shell auto_approve_plan详解模型切换流程中的ExitPlanMode授权Pilot Shell auto_approve_plan详解模型切换流程中的ExitPlanMode授权 如果你在用 Pilot Shell 搭配 Clau创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?