周六晚上本来只想查个 MCP 依赖的用法,结果顺着 readme 里的作者主页一路摸过去,捞到了这个:lovestaco/gh-search-dsl。副标题一行字写得很勾人——把 GitHub 搜索框的语法抽出来,编成 SQL 直接查数据库。再往下一看:200 行。
语法解析这种东西,我平时是能躲就躲的。手写 parser 是什么体验,用过 yacc 的同行都懂。所以看到作者挑了 participle 这个路子,我的第一反应是:哦?还能这么走。
具体说就是:用 Go 结构体定义语法,字段上的标签写清楚怎么捕获输入,不用单独的语法文件,也不用代码生成。一个 Query 表示整个查询,一个 Term 表示搜索单元,一个 Qualifier 表示 key:value。三个结构体,AST 齐活。怎么才让我蹲到。
其实真正让我服气的还不是这 200 行,是那些只有被 GitHub 搜索语法真坑过的人才写得出来的细节。
词法分析器里有一个细节我停了挺久:破折号在搜索语法里其实有三种身份——行首是否定符号,标识符中间是连字符,日期里是分隔符。他没搞那种想当然的一刀切,而是排了一组正则规则,让每个破折号都往自己该去的地方走;还留了 2 个 token 的 lookahead,专门用来区分自由文本和限定符,因为这俩都是以标识符开头的。
还有一个坑,以 - 开头的搜索词,比如 -author:bot,到了命令行会被 Go 的 flag 包半路劫走,得在前面补一个双破折号 -- 隔开。这种边缘问题,README 里竟然写到了——光靠翻文档翻不出来,得真跟这套语法较过劲才写得出来。
安全他也做了个实在动作:所有用户输入一律走绑定参数,绝不拼 SQL 字符串。这本身不算稀奇,稀奇的是他还给了个 --sql 标志,能把你正要发出去的那条 SQL 原样打印出来。嘴上说防注入谁都会,拉出来看看才算数。
上手门槛不高,make demo 一条命令,自带三张表加 20 条样本问题,跑起来哗哗的。数据库用的是 modernc.org/sqlite,纯 Go 驱动,不用 CGO——这个我是在意的,一说要装 CGO 我就想关窗户。
适合谁:手头数据已经躺在 SQLite 里、缺一个"像 GitHub 那样"的搜索入口的,这能直接省掉一层自建服务。不适合谁:想要 OR、括号这种完整布尔逻辑的,现在这版还接不住,别硬上。
刷着刷着跑题一句:作者主页上还挂着个叫 git-lrc 的项目,commit 的时候跑 AI code review,免费、源码开放、跟踪一百多种失败模式。已经扔进候选池了,下期再讲。
这玩意儿能不能打,自己拉下来跑一圈最准。我先给作者点个 star 去。
