新闻详情

新闻详情

首页 / 资讯中心 / 详情

semgrep 的 OCaml 化之路:osemgrep 迁移笔记中的架构决策、进度清单与测试策略

发布时间:2026/10/2 17:56:07来源:尧图网络
semgrep 的 OCaml 化之路:osemgrep 迁移笔记中的架构决策、进度清单与测试策略
SAST应用安全静态分析开发工具代码质量【免费下载链接】semgrepLightweight static analysis for many languages. Find bug variants with patterns that look like source code.项目地址https://gitcode.com/GitHub_Trending/se/semgrep点击查看免费下载导读Semgrep 是一个用看起来像源代码的匹配模式来查找多语言 bug 变体的轻量级静态分析工具。其传统形态由 Python 编写的 CLI 包装层semgrep与 OCaml 编写的扫描引擎semgrep-core构成。为消除 Python 依赖、提升性能与可维护性社区启动了把 Python CLI 包装层整体移植为 OCaml 的长期工程临时命名为osemgrep。本文以仓库中的历史进度文档 src/osemgrep/TODO.md 为骨架结合当前仓库源码梳理 osemgrep 迁移的阶段性目标、核心架构决策配置对象、config manager、目标管理、HTTP 并发选型Cohttp/Lwt以及端到端测试策略帮助你理解 semgrep 这一大型迁移工程的演进脉络与实现现状。背景为什么要把 Python CLI 重写为 OCaml根据 src/osemgrep/README.md 的说明src/osemgrep是 OCaml CLI 的临时驻地目标是取代 Python CLI 包装层。它隶属于 semgrep 仓库的 OCaml 代码体系是与semgrep-core不同的独立可执行文件之所以暂时放在src/osemgrep目录而不是直接改名是为了避免大规模重命名引发的 git 冲突——这类重命名可以放到一个只处理改名问题的短期分支中集中完成。迁移被规划为清晰的三个阶段Phase 1Python 关键代码的字面翻译——把所有调用semgrep命令的 pytest 测试改为同时调用osemgreposemgrep以库调用的方式调用 semgrep-core 的 OCaml 代码。此阶段结束时osemgrep应具备semgrep的基本扫描功能使测试达到非零通过率形成概念验证proof-of-concept。Phase 2把通过的 pytest 测试翻译为 OCaml——复刻 Python CLI 的测试体系再把通过的测试翻译成纯 OCaml证明新实现可以在完全不依赖 Python 的情况下完成测试。Phase 3功能补全——翻译剩余 Python 实现使osemgrep与semgrep达到功能对等feature parity随后进入密集 QA 阶段并交付给用户选用。最终交付Delivery意味着osemgrep正式成为semgrep停止维护 Python 实现所有改进只针对 OCaml 实现随后进入简化Simplifications阶段逐步消除包装层代码与 legacy semgrep-core 代码之间的重复功能。TODO.md 正是这份迁移工程早期的进度与思路备忘由作者 Martin 于2022 年 10 月 10 日写下记录了当时迁移起步阶段的实现状态、待办事项与长期设想。进度快照scan 是当时唯一部分实现的子命令TODO.md 开篇即给出当时的实现基线osemgrep scan是唯一一个部分实现的子命令其余子命令尚未开始。对照今天仓库的结构可以清晰看到这一工程的演进——如今 src/osemgrep 下已经分化出大量子命令目录cli_scansemgrep scan相关Scan_CLI.ml、Scan_subcommand.ml、Diff_scan.ml、Ls_subcommand.ml等cli_ciCI 模式Ci_subcommand.ml、Git_metadata.ml、Github_metadata.mlcli_login、cli_logout登录/登出cli_lsp、cli_mcp、cli_test、cli_validate、cli_show、cli_install_semgrep_pro支撑性目录configuring环境变量与设置、networking规则获取与 Semgrep App/Registry 交互、reporting多格式输出、core认证、退出码、规则配置等。TODO.md 同时提醒当前osemgrep/下的大量代码是临时性的随着迁移推进会被删除或改名。这一点在今天的代码注释中仍有体现例如 Scan_CLI.ml 注明其主要由 scan.py 翻译而来部分翻译自 semgrep_main.py 和 core_runner.py属于迁移期的直接映射。输出格式JSON 化与关闭文本输出TODO.md 记录的首要待办是semgrep scan的输出需要格式化为 JSON并且需要关闭文本输出。这是让osemgrep能与既有测试体系对接的第一步——pytest 测试大量依赖机器可读的 JSON 输出做断言。从当前仓库看这一模块已经成长为独立的 reporting 子系统包含多种输出格式的实现Cli_json_output.mlCLI 兼容的 JSON 输出Text_output.ml 与 Text_reports.ml人类可读文本输出Sarif_output.ml、Gitlab_output.ml、Junit_xml_output.mlSARIF、GitLab、JUnit 等生态格式。在命令行层Scan_CLI.ml 中的o_output与o_json选项分别对应--output输出到文件或 URLNone表示输出到 stdout和--jsonJSON 输出开关。conf记录中的output : string option与output_conf : Output.conf字段见 Scan_CLI.ml共同决定了扫描结果的呈现方式。目标管理Target Managementinclude/exclude 与 glob 过滤TODO.md 指出两个待办一是目标管理需要补全与测试二是include/exclude 过滤尚未实现。作者明确表达了对旧命名include/exclude的不认可我从来没觉得它们直观并在 OCaml 实现中尽可能重命名。核心难点在于需要基于与 Python 兼容的 glob 模式过滤文件路径列表。TODO.md 给出了两条候选路线复用ocaml-re库的Glob模块或自行编写解析器以保证与 Python 实现完全向后兼容。今天的仓库显示这一功能已由targeting模块承接见 src/targeting含 Find_targets.ml 与 .semgrepignore 解析等而 Scan_CLI.ml 中的o_exclude与o_include选项保留了向后兼容的语义--excludePATTERN跳过路径匹配该模式的任何文件或目录。例如--exclude*.py会忽略foo.py、src/foo.py、foo.py/bar.sh--excludetests会忽略tests/foo.py以及a/b/tests/c/foo.py。可多次指定。模式为 glob 风格语法与 gitignore / semgrepignore 一致。--includePATTERN只扫描匹配该模式的文件或目录应用于--exclude、git/SCM 过滤与.semgrepignore过滤之后可多次指定命中任一 include 模式即被选中。此外与目标选择相关的选项还包括--max-target-bytes超过该大小的文件被忽略默认值取自targeting_conf.max_target_bytes、--use-git-ignore/--no-git-ignore默认调用 git 并遵守.gitignore--no-git-ignore则不调用 gitgitignored 文件与子模块也会被扫描除非被.semgrepignore/--exclude等方式排除、以及--scan-unknown-extensions/--skip-unknown-extensions命令行直接指定的目标文件是否绕过语言检测见 Scan_CLI.ml。配置管理器Config Manager与 HTTP 客户端选型TODO.md 明确记录config manager负责解释--config参数、决定如何获取 Semgrep 规则的模块当时尚未实现——当时只是假设参数是一个纯规则文件需要挑选合适的 OCaml HTTP 客户端库。作者给出的选型建议非常具体值得展开Cohttp 客户端依赖 Lwt。Lwt 提供了与 JavaScript Promise 相同的功能适合安全地并发发起多个请求与 JS 不同的是它要求显式启动管理事件驱动任务的循环event loop。这允许你启动 Lwt 循环并发执行一批 HTTP 调用完成后退出循环。Cohttp 可靠作者可提供起步代码并对 Lwt Promise 做辅导。同步封装兜底如果学习 Lwt 成本过高、且只需要带超时的一次性 HTTP 调用可以轻易提供同步客户端函数把 Lwt 完全藏在底层。作者对近年其他 OCaml HTTP 库不熟悉不确定是否有值得使用的可靠替代品。从当前仓库看config manager 已落地为 networking 子系统Rule_fetching.ml负责按配置获取规则内部多处调用Semgrep_Registry.url_of_registry_config_kind来解析 registry 配置Semgrep_Registry.mlSemgrep Registry 的 URL 解析Fetch_file.ml文件/URL 抓取Semgrep_App.ml、Semgrep_login.ml与 Semgrep App 的交互与登录。而--config参数的解释在 Scan_CLI.ml 中其值可以是 YAML 配置文件、目录含.yml/.yaml结尾的 YAML 文件集合、配置文件的 URL或 Semgrep registry 条目名--config auto会自动获取适配当前项目的规则可用多个--config同时加载多套规则例如semgrep --config p/python --config myrules/myrule.yaml。该选项还支持SEMGREP_RULES环境变量。规则来源在类型层面被建模为 Rules_source.ml 中的变体type t | Pattern of string * Analyzer.t option * string option (* replacement *) | Configs of Rules_config.config_string list即-e/--pattern命令行模式对应Pattern分支与--config规则配置对应Configs分支是互斥的规则来源这与 TODO.md 提到的mix of --pattern/--lang/--replacement, --config结构一致。架构设计原则小功能直译、大功能从零设计TODO.md 记录了一条重要的迁移方法论小的功能可以直接从 Python 直译过来但对于更大的特性比如整个目标管理器最好不看 Python 实现、从零设计。在这些情况下Python 类和方法的外部接口interface才是最要紧的。这意味着迁移并非机械的逐行翻译Python 侧的关键是稳定对外接口OCaml 侧则可以按 OCaml 惯用法重新设计内部结构。这解释了为什么 osemgrep 代码在结构上与 Python 的scan.py等文件有对应关系如 Scan_subcommand.ml 的注释Translated mainly from scan.py, with parts translated also from semgrep_main.py and core_runner.py但内部组织却是 OCaml 风格的模块化。配置对象设计Scan_CLI.conf、default 与 Runner_configTODO.md 详细描述了当时的配置对象设计这也是整份笔记中最具可迁移到任何 CLI 重构价值的架构经验Scan_CLI 的 conf 记录semgrep-scan目录存放与semgrep scan子命令相关的代码。定义配置类型和命令行界面Scan_CLI的模块与拿配置去执行动作的代码即Semgrep_Scan.main函数相互独立semgrep-scan/下所有模块都可以依赖Scan_CLI.conf类型该类型被设计为到处传递的对象Scan_CLI.default是持有默认配置的记录可通过 OCaml 的with语法继承派生例如{ default with foo 123 }——这为测试和局部定制提供了极大的便利。今天的 Scan_CLI.ml 完整实现了这一设计conf记录聚合了规则来源rules_source、目标根target_roots、规则过滤rule_filtering_conf、目标选择targeting_conf、引擎类型engine_type默认OSS、autofix、性能配置core_runner_conf、输出output/output_conf、网络metrics/version_check、公共 CLI 配置common等字段并提供了完整的default记录。值得注意的默认值包括rules_source Configs [ auto ]、target_roots [ Scanning_root.of_string . ]、error_on_findings false、metrics Metrics_.Auto、version_check true。semgrep-core 的 Runner_configTODO.md 提到semgrep-core的命令行配置Runner_config.t当时也新增了单个Runner_config.default默认对象便于不经命令行解析就修改参数进行测试。但同时指出Runner_config.t尚不完整有些选项仍以全局变量形式存放在Flag模块中作者更希望把它们收进配置记录里如果不愿到处传递配置记录则建议把Flag模块的各条目合并为单一记录 单一全局如val conf : t option ref并提供临时设置与锁定配置的函数否则将无法判断Flag.filter_irrelevant_rules这类标志当前是开还是关也无法排除它被前一次调用错误设置的可能。这条建议在今天仍有普遍参考价值——显式传入配置记录优于隐式读写可变全局。从当前仓库看src/osemgrep各子模块已普遍采用配置记录传入 default派生的风格例如 CLI_common.ml、Core_runner.ml正是这一设计的延续。测试策略osemgrep-e2e 与 osemgrep-qaTODO.md 给出了当时的测试入口端到端/QA 测试在/cli/semgrep下通过make osemgrep-e2e或osemgrep-qa运行后者耗时更长建议初期先聚焦前者。对照 cli/Makefile 中的实际目标定义make osemgrep-e2e设置PYTEST_USE_OSEMGREPtrue运行pytest -m not osemfail tests/default/e2e——即用 osemgrep 替换默认 CLI 执行 e2e 测试集并跳过标记为osemfail当前尚无法通过的用例make osemgrep-qa设置PYTEST_USE_OSEMGREPtrue后执行make qa即pytest tests/qa覆盖范围更大、耗时更长。这套机制的核心思想是同一套 pytest 用例通过环境变量PYTEST_USE_OSEMGREP切换被测的 CLI 实现Python 版还是 OCaml 版用未通过标记osemfail/pysemfail来表达迁移缺口从而让两套实现始终在统一测试基准下竞争与收敛。相关测试基础设施见 cli/tests/conftest.py 与 cli/tests/semgrep_runner.py。长期愿景osemgrep 成为新的 semgrepTODO.md 结尾记录了迁移工程的北极星考虑让osemgrep成为新的semgrep命令并让它回退调用semgrep-py旧的semgrep。也就是说过渡期可能采取新命令默认生效、旧命令兜底的策略osemgrep升格为semgrep旧的 Python 实现改名为semgrep-py作为回退路径。这与 README.md 中Deliveryosemgrep 成为 semgrep停止维护 Python 实现的目标相互印证构成完整的迁移终局设计。当前仓库中 Pysemgrep.ml 的存在正对应着必要时回调 Python 实现的兼容层职责可参考其 Pysemgrep.mli。小结一份迁移笔记的参考价值src/osemgrep/TODO.md 虽然是一份 2022 年的历史进度记录但它浓缩了大型 CLI 重写工程中最有价值的方法论渐进式替换从唯一子命令部分实现起步用统一 pytest 基准 失败标记驱动收敛而非一次性重写接口优先小功能直译、大功能从零设计Python 侧只保留稳定的外部接口语义配置显式化用default记录 with派生代替散落的全局Flag让配置可测试、可推断并发选型用 Lwt 承载 Cohttp 以支持并发规则获取必要时以同步封装降低学习成本。对照今天的源码目录这份笔记中的每一项待办几乎都找到了落地的模块scan之外的子命令、JSON/SARIF 等多格式输出、include/exclude 过滤、config managerRule_fetching Semgrep_Registry、可派生的Scan_CLI.conf以及osemgrep-e2e/osemgrep-qa测试目标。对希望理解 semgrep 内部结构或规划类似重写既有 CLI工程的读者而言这份笔记连同其后续代码是一份难得的完整案例。赞分享SAST应用安全静态分析开发工具代码质量【免费下载链接】semgrepLightweight static analysis for many languages. Find bug variants with patterns that look like source code.项目地址https://gitcode.com/GitHub_Trending/se/semgrep点击查看免费下载相关推荐semgrep 的 OCaml CLI 迁移之路深入解析 osemgrep 的项目结构与实现原理semgrep 的 OCaml CLI 迁移之路深入解析 osemgrep 的项目结构与实现原理 导读 本文基于 src/osemgrep/README.mSAST应用安全静态分析开发工具代码质量终极指南Vimium从Manifest V2到V3的无缝迁移策略终极指南Vimium从Manifest V2到V3的无缝迁移策略 Vimium作为一款深受开发者喜爱的浏览器扩展被誉为The hackers brows开发工具迁移粒度跟随合并粒度Open Notebook 数据库迁移策略的架构决策ADR-006解读迁移粒度跟随合并粒度Open Notebook 数据库迁移策略的架构决策ADR 006解读 数据库迁移migration的分包粒度是一个感觉上很小、人工智能AI 应用RAG后端前端上一篇体验Web版Ubuntu在浏览器中感受开源系统的魅力下一篇如何3步搞定电脑风扇噪音FanControl 风扇调速完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

基于ASR与LLM的视频课程知识点提取流水线设计与实践 2026/10/2 18:43:21

基于ASR与LLM的视频课程知识点提取流水线设计与实践

去年我接手了一个挺头疼的活儿:公司在线培训平台上积压了上百小时的录播课程,内容质量很高,但学员检索困难、课程大纲缺失、学习笔记基本靠人工抄写。销售团队反馈说,新人想找某个知识点,得整段整段拖进度条。于是我搭…

阅读更多 →
SPSS实现Quade非参数协方差分析:秩变换与残差比较步骤 2026/10/2 18:43:08

SPSS实现Quade非参数协方差分析:秩变换与残差比较步骤

手里攒了一批数据,想做组间比较,但Shapiro-Wilk检验p值小得可怜;想控制协变量,又不敢用参数ANCOVA,因为正态性和方差齐性根本过不了关。这时候你大概率会在SPSS里翻半天菜单,然后发现一个很尴尬的事实——S…

阅读更多 →
Zabbix 7.0钉钉Webhook告警配置与排错实战 2026/10/2 18:43:02

Zabbix 7.0钉钉Webhook告警配置与排错实战

1. 为什么Zabbix 7.0告警必须走钉钉Webhook——不是“能用就行”,而是“必须稳、必须快、必须可追溯”Zabbix 7.0发布后,我接手的三个中型监控项目里,有两家在上线前夜推翻了原有邮件告警方案,全部切换为钉钉Webhook机器人推送。这…

阅读更多 →
自建rustDesk私有远程桌面:hbbs/hbbr部署与安全实践 2026/10/2 18:42:43

自建rustDesk私有远程桌面:hbbs/hbbr部署与安全实践

1. 为什么我要把远程桌面换成 rustDesk 自建方案先说结论:如果你手里同时管理着三五台以上跨系统的设备,或者经常需要在不同网络环境下远程办公、给家人朋友维护电脑,那么一套自建的 rustDesk 私有远程桌面服务,是性价比极高的选择…

阅读更多 →
华为交换机VLANIF配置IP原理与实操指南 2026/10/2 18:42:43

华为交换机VLANIF配置IP原理与实操指南

1. 项目概述:为什么在eNSP里给交换机配IP不是“多此一举”很多人第一次打开eNSP,拖出一台S5700或S3700交换机,双击进入CLI界面,敲下system-view,再输入interface vlanif 1,准备配IP时突然卡住——“交换机又…

阅读更多 →
Codex 接入 Jev 模型与 Skill 机制实战配置指南 2026/10/2 18:42:43

Codex 接入 Jev 模型与 Skill 机制实战配置指南

1. 这套组合到底在解决什么问题先把话说在前头:Codex 本身是个能力很强的代码智能体,但它的默认配置和默认模型路由,对国内大部分开发者来说并不算友好。你要么忍受网络层面的各种不确定性,要么在模型选择上被锁死在一个固定的供应…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉