ast-grep(sg)CLI 命令参考实战:sg run / scan / test / new / lsp 全解析
2026/9/21 15:53:55 网站建设 项目流程
  • 人工智能
  • AI Agent
  • 代码智能体
  • 多智能体
  • MCP Clients
  • Agent 编排

【免费下载链接】oh-my-openagent

OmO: Just type "mass ulw" keyword with your prompt. Now you are the master of graph engineering.

项目地址:https://gitcode.com/gh_mirrors/oh/oh-my-openagent
点击查看免费下载

本指南是 OmO 项目中 vendored ast-grep 技能(packages/shared-skills/skills/ast-grep/)所附带的 CLI 速查参考文档的展开讲解,完整覆盖sg runsg scansg testsg newsg lspsg completions六组命令的用法、参数表与实战示例。读完本文,你将能够绕过助手封装直接调用sg/ast-grep二进制完成结构化的代码搜索、批量重写与 YAML 规则扫描,并理解--update-all--json互斥陷阱、二进制解析链等在仓库源码中的底层实现。

Linux 二进制命名提示:在 Linux 上优先使用ast-grep全名而不是sg,因为sgutil-linux提供的setgroups命令同名冲突。仓库中的 install.md 明确记录了这一点,scripts/ast_grep_helper.py在 Linux 上检测到名为sg的可执行文件时会执行--version验证其是否为 ast-grep(见 ast_grep_helper.py)。


sg run— 一次性搜索 / 重写

sg run是默认子命令,sg -p 'foo'sg run -p 'foo'的简写形式。它把--pattern当作代码而不是正则字符串来解析,并在目标语言的语法树(AST)上进行结构匹配。

sg run [OPTIONS] --pattern <PATTERN> [PATHS...]

参数总表

Flag用途
-p, --pattern <P>AST 模式(pattern)。在 shell 中务必使用单引号,防止$VAR被展开。
-r, --rewrite <R>替换模式。与-U配合使用才会真正写入文件。
-l, --lang <LANG>目标语言。省略时根据文件扩展名推断。
--selector <KIND>当模式存在歧义时,只提取指定的 AST kind。
--strictness <S>cst|smart(默认)|ast|relaxed|signature
--debug-query[=<F>]打印解析后的模式。F 取值为pattern|ast|cst|sexp
--stdin从 stdin 读取代码而不是文件。必须显式设置--lang,因为此时无法从扩展名推断。
--globs <G>包含/排除 glob(可重复;前缀!表示排除)。
--follow跟随符号链接。
--no-ignore <T>禁用某一类忽略规则:hiddendotexcludeglobalparentvcs
-i, --interactive逐个确认匹配与重写。
-U, --update-all不确认直接应用所有重写。--json互斥(静默)
--json[=<S>]输出 JSON。S 取pretty|stream|compact(compact 最适合管道处理)。
--color <W>auto|always|ansi|never
--inspect <G>细节级别:nothing|summary|entity
-A, -B, -C <N>匹配后 / 前 / 上下文行数。
-j, --threads <N>线程数(默认启发式;0= 自动)。

关于--strictness的具体含义,patterns.md 有完整对照表:cst要求包括逗号、括号等未命名节点全部一致;smart(默认)忽略目标代码中模式未出现的未命名节点;ast只看命名节点;relaxed额外忽略注释;signature只按节点种类匹配,忽略文本与未命名节点,适合表达"匹配所有名为foo的函数,无论参数如何"。

--update-all+--json的陷阱

这是脚本化使用中最容易踩的坑:sg在设置--json时会静默忽略--update-all,即返回 JSON 但不修改任何文件。要同时做到"先预览再应用",必须跑两遍

# 第一遍:预览 sg run -p 'foo()' -r 'bar()' --json=compact src/ # 第二遍:应用 sg run -p 'foo()' -r 'bar()' --update-all src/

仓库中的ast_grep_helper.py replace --apply子命令会自动完成这个两遍流程。查看源码 ast_grep_helper.py:cmd_replace先以--json=compact跑 pass 1 收集匹配并展示 dry-run 预览(DRY-RUN: would rewrite N match(es) across M file(s)),只有传入--apply时才以--update-all跑 pass 2 真正写入文件(APPLIED: rewrote N match(es) across M file(s)),两遍之间没有任何--json标志混入。这与 SKILL.md 中"Always run dry-run first when rewriting"的硬性约定一致:绝不对未先预览过的重写执行--update-all

实战示例

# 基础搜索 sg run -p 'console.log($MSG)' --lang ts src/ # 带上下文行搜索 sg run -p 'eval($CODE)' --lang js -C 3 . # 重写,JSON dry-run 预览 sg run -p 'console.log($MSG)' -r 'logger.info($MSG)' --json=compact --lang ts src/ # 重写,直接应用 sg run -p 'console.log($MSG)' -r 'logger.info($MSG)' --update-all --lang ts src/ # 从 stdin 读入模式 echo 'console.log("x")' | sg run -p 'console.log($MSG)' --lang js --stdin # 限定具体文件集合 sg run -p 'foo()' --lang ts --globs 'src/**/*.ts' --globs '!**/*.test.ts' . # 调试返回 0 匹配的模式 sg run -p 'def $F($$$):' --lang py --debug-query=ast --stdin <<< 'def foo(): pass'

注意最后一条:def $F($$$):带尾随冒号在 Python 中无法作为完整的函数定义解析,--debug-query=ast会把解析器视角下的模式打印出来。关于"模式必须是可解析的完整代码"这一点,patterns.md 给出了一张坏模式对照表:function $NAME(缺参数与函数体)、class Foo:(Python 类无主体)、fn $NAME(Rust 缺签名)等都需要补齐为function $NAME($$$) { $$$ }class Foo($$$)fn $NAME($$$) -> $RET { $$$ }这样的完整形态。


sg scan— YAML 规则扫描器

sg scan在文件集合上运行一组 YAML 规则,适用于项目级 lint 与 codemod。配置由sgconfig.yml描述(ruleDirstestConfigsutilDirs等字段的完整说明见 sgconfig.md),sg会从当前目录向上查找最近的sgconfig.yml

sg scan [OPTIONS] [PATHS...]

参数总表

Flag用途
-c, --config <C>sgconfig.yml的路径(默认从 cwd 向上查找)。
-r, --rule <F>只运行单个规则文件。与--config互斥。
--inline-rules <Y>直接传入 YAML 规则文本。多个规则用---分隔。
--filter <RE>只运行id匹配该正则的规则。
--include-metadata在 JSON 输出中包含规则的metadata字段。
-U, --update-all自动应用fix:字段定义的修复。
--report-style <S>rich|medium|short
--format <F>github|sarif(面向 CI 的输出格式)。
--error[=ID]--warning[=ID]--info[=ID]--hint[=ID]--off[=ID]提升/降级规则的严重级别。
-i, --interactive交互式逐个确认修复。
--json[=<S>]JSON 输出。

实战示例

# 运行 sgconfig.yml 中 ruleDirs 发现的所有规则 sg scan src/ # 运行单个规则文件(无需 sgconfig.yml) sg scan -r rules/no-console.yml src/ # 内联规则(非常适合一次性任务和 CI) sg scan --inline-rules ' id: no-todo language: TypeScript severity: warning rule: { pattern: TODO }' src/ # 应用所有自动修复 sg scan -U src/ # CI 友好的 GitHub annotations sg scan --format github src/ # 面向安全扫描器的 SARIF sg scan --format sarif src/ > sarif.json

在仓库中,sg scan是项目级 lint 的主力入口。助手脚本的 cmd_scan 直接透传-c-r--inline-rules--report-style-U参数,即helper scan与裸sg scan的命令面一一对应。而 OmO 原生还注册了捆绑的 ast-grep MCP 服务器,其中mcp__ast_grep_scan({ paths })就是sg scan的 MCP 等价物(详见 SKILL.md 的 "OmO native" 一节)。规则文件的 YAML 模式(patternkindregexinsidehasallanynotmatchestransformfix)请查阅 yaml-rules.md。


sg test— 运行规则快照测试

规则进入 CI 之前,先用sg test验证它们的行为符合预期。测试机制是快照对比:每个测试文件提供valid:/invalid:代码片段,sg test运行规则、对比匹配位置与__snapshots__目录中的快照,不一致即失败。

sg test [OPTIONS]

参数总表

Flag用途
-c, --config <C>sgconfig.yml路径。
-t, --test-dir <D>测试目录。
--snapshot-dir <D>快照目录(默认__snapshots__)。
--skip-snapshot-tests只验证测试代码可解析,不对比快照。
-U, --update-all更新所有变更的快照。
-f, --filter <G>按规则 id 的 glob 过滤测试用例。
--include-off包含严重级别为off的规则。
-i, --interactive逐个确认变更的快照。

一个典型的测试目录布局:

test/ ├── no-console.yml # `valid:` 和 `invalid:` 代码片段 └── no-console-test.yml # 备选测试文件格式 __snapshots__/ └── no-console-snapshot.yml # 期望的匹配位置

测试文件的写法(字段说明见 sgconfig.md 的testConfigs一节):

id: no-console valid: - 'logger.info("hi")' invalid: - 'console.log("hi")'

sg test首次运行配合-U生成快照,此后任何改动都会在 diff 中暴露。助手脚本的cmd_test(ast_grep_helper.py)透传-c-t-U,因此helper test -U即可在 CI 中刷新快照。


sg new— 项目脚手架

sg new用于初始化 ast-grep 项目结构或生成新构件。

sg new <COMMAND> [NAME] [OPTIONS]
子命令创建内容
projectsgconfig.ymlrules/utils/__snapshots__/目录树
rule在第一个ruleDirs条目下创建新的 YAML 规则文件
testtestConfigs[0].testDir下创建新的测试文件
util在第一个utilDirs条目下创建新的工具规则
# 在当前目录初始化新项目 sg new project --yes # 新建规则 sg new rule no-console --lang typescript # 新建测试 sg new test no-console --yes

助手脚本的 cmd_new 把这组命令原样代理给sg newhelper new project/rule/test/util [NAME] [--lang LANG])。sg new project生成的sgconfig.yml骨架对应 sgconfig.md 中的最小布局:ruleDirs(必填)+testConfigs(可选,testDir/snapshotDir)+utilDirs(可选),其中utilDirs中的规则可以通过matches: <id>被项目内任意规则复用。


sg lsp— 语言服务器

sg lsp -c sgconfig.yml

sg lsp通过 stdin/stdout 说 LSP 协议。配置你的编辑器(VS Code 扩展、Neovim 的nvim-lspconfig、Helix 的languages.toml)启动该命令即可获得实时诊断。编辑器会在项目根目录自动检测sgconfig.yml——没有sgconfig.yml时 LSP 运行但不加载任何规则(见 sgconfig.md 的 "Editor integration" 一节)。

sg completions— shell 补全

sg completions bash >> ~/.bashrc sg completions zsh > "${fpath[1]}/_sg" sg completions fish > ~/.config/fish/completions/sg.fish sg completions powershell >> $PROFILE

实用一行命令

# 统计每个文件中的匹配数 sg run -p 'console.log($_)' --lang ts --json=compact . \ | jq -r '.[].file' | sort | uniq -c | sort -rn # 找出文件中所有唯一的 AST kind(用于确定 kind 名称) sg run -p '$_' --lang ts --debug-query=cst src/foo.ts \ | grep -oE 'kind: [a-z_]+' | sort -u # 只在文件子集中重写 sg run -p 'foo()' -r 'bar()' --update-all --globs 'src/**/*.ts' --globs '!src/legacy/**' . # 应用多条规则中 id 匹配特定模式的自动修复 sg scan --filter 'no-' -U src/ # 在 pre-commit 中把 ast-grep 当作 linter 使用 sg scan --format github src/ || exit 1

--json=compact的产物是匹配对象数组,形如{ file, range: {start, end}, text, replacement?, lines, language, ... }(输出契约详见 SKILL.md 的 "Output discipline" 一节),配合jq可以完成统计、聚合、二次处理等一切管道化操作。助手脚本的parse_compact_json(ast_grep_helper.py)甚至实现了对截断 JSON 输出的逐行"抢救"解析,说明生产环境管道中这类输出并不罕见。


在这份参考之上:何时用 helper、何时用裸sg

references/cli.md定位是"helper 不够用时直接调sg"的速查表。仓库实际给出的入口优先级是:

  1. OmO 原生 MCP 工具mcp__ast_grep_search/mcp__ast_grep_rewrite/mcp__ast_grep_scan):无需安装二进制、无需 PATH,首次调用时自动激活(见 SKILL.md),是单次查询的最快路径;
  2. scripts/ast_grep_helper.py:单文件 Python 3 stdlib 封装(749 行,无第三方依赖),在调用sg之前做离线模式校验(validate子命令,检测\w.*、字符类、字面|等正则误用,以及 Python 尾随冒号、JS/Go/Rust 缺函数体等语言特定错误),并沿OMO_AST_GREP_SG_PATH→ OmO runtime 目录 → skill 内缓存 → PATH → Homebrew 的优先级解析二进制(resolve_binary);
  3. sg:即本文的主体,当 helper 的"主观意见"不够用时获得完全控制权。

工具选择上可以参考 SKILL.md 的决策树:结构形态(函数形状、调用、类、import、控制流)→ ast-grep;文本形态(正则、字符类、文件名、注释内容)→rg/grep;语义问题(变量引用、是否会抛异常)→ LSP / 类型系统工具。判断标准只有一句:答案取决于语言的语法树,还是仅仅取决于文件的字节?

参见

  • references/yaml-rules.md — 规则模式(patternkindregexinsidehasallanynotmatchestransformfix
  • references/sgconfig.md — 项目配置(ruleDirstestConfigsutilDirslanguageGlobscustomLanguageslanguageInjections
  • references/patterns.md — 元变量($VAR$$$$$$VAR$_)与模式解析规则
  • references/pitfalls.md — 失败模式现场指南
  • references/install.md — 各操作系统安装方式与手动回退
  • SKILL.md — 面向 Agent 的完整技能说明与决策树
  • scripts/ast_grep_helper.py — 封装脚本(搜索 / 两遍重写 / 扫描 / 离线校验 / 二进制解析)
  • tests/smoke.sh 与 tests/smoke.ps1 — POSIX / PowerShell 自测脚本
  • 人工智能
  • AI Agent
  • 代码智能体
  • 多智能体
  • MCP Clients
  • Agent 编排

【免费下载链接】oh-my-openagent

OmO: Just type "mass ulw" keyword with your prompt. Now you are the master of graph engineering.

项目地址:https://gitcode.com/gh_mirrors/oh/oh-my-openagent
点击查看免费下载

相关推荐

上一篇:突破Android下载性能瓶颈:FileDownloadRandomAccessFile实现原理与优化实践
下一篇:突破300ms壁垒:EasyDarwin低延迟优化实战指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询