目录

Lxxbv/glob

Lxxbv/glob 是一个面向 MoonBit 的跨平台 Glob 路径匹配与文件检索库。它把模式解析为 AST,再进行可复用匹配;同时提供文件系统遍历、批量查询、忽略规则、内存路径索引、解释诊断、编译缓存和确定性基准工作负载。

项目定位是构建工具、静态站点生成器、CLI 文件检索器和后台扫描任务的基础库。它不是对任意 Shell 语法的完整模拟,也不会执行用户输入的命令。

当前能力

  • 词法分析、语法分析和 AST:支持 *?**、字符类、范围、否定字符类、花括号展开和反斜杠转义。
  • 可复用编译:CompiledPattern 保存 AST、复杂度统计、字面量前缀和递归通配符信息,适合循环匹配。
  • 文件系统搜索:glob / glob_with_options 支持文件、目录、隐藏项、最大深度和排序;I/O 失败通过 GlobError::FilesystemError 返回。
  • 组合查询:GlobQueryGlobPipeline 支持 include/exclude、深度、隐藏项、排序、去重、限制返回数量和截断报告。
  • 索引查询:GlobQuery::execute_index 支持在已构建的 PathIndex 上重复查询,并保留文件/目录类型过滤;QueryReport 提供分页、摘要和截断状态。
  • 忽略规则:GlobRules 使用类似 .gitignore 的注释、否定规则、锚定规则、目录规则和 last-match-wins 语义。
  • 路径索引:PathIndex 保存规范化路径、文件/目录类型、深度、扩展名和隐藏属性,支持前缀、子项、模式和规则查询。
  • 诊断与性能:explain_pattern 输出 token、AST、复杂度和风险分类;PatternCache 统计命中、未命中和淘汰;GlobWorkload 提供 284/1404 条候选路径规模的可重复基准数据。

“高性能”在本项目中有明确边界:减少重复解析、利用静态目录前缀缩小初始遍历、复用编译缓存;实际速度取决于目标平台、文件系统和工作负载,必须以 moon bench 的本机结果为准。

Glob 语义

语法 语义 示例
* 匹配单个路径组件内的零个或多个字符,不跨 / src/*.mbt
? 匹配单个非 / 字符 test_?.mbt
** 递归匹配目录层级,可匹配零层目录 src/**/*.mbt
[abc] 匹配字符类中的一个字符 file[abc].txt
[a-z] 匹配字符范围中的一个字符 file[0-9].txt
[!abc] / [^abc] 匹配不在字符类中的一个字符 file[!0-9].txt
{a,b} 展开为多个候选分支 *.{mbt,json}
\ 转义下一个字符,使通配符按普通字符处理 file\*.txt

顶层逗号不是独立的 Glob 通配符;只有花括号内部的逗号才表示分支。未闭合花括号、未闭合字符类、反向范围、空模式和文件系统 I/O 失败都会返回 GlobError,不会静默吞错。

实现参考了 Go 的 path/filepath.Match 和 JavaScript 生态的 minimatch,但本项目的 AST、错误类型、** 递归边界和文件系统 API 是独立实现,不能把不同项目的边界行为直接等同。

参考项目与许可证范围

本项目是独立的 MoonBit 实现,未复制 justjavac/glob、Go 标准库或 minimatch 的源代码;上述项目仅用于比较 Glob 语义和 API 设计。若下游继续复用这些项目的代码或测试数据,应分别遵守其仓库中声明的许可证和版权要求。本仓库自身的实现、测试和文档按根目录 Apache License 2.0 发布,MoonBit 依赖通过 moon.mod 显式声明。

安装与运行

安装 MoonBit 工具链

组委会验收环境使用 MoonBit 0.10.3。建议先安装并检查版本:

# Windows PowerShell
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
irm https://cli.moonbitlang.com/install/powershell.ps1 | iex
moon version --all  # CI uses the current official release; local acceptance passes on moonc v0.10.3

Linux/macOS:

bash -c "\$(curl -fsSL https://cli.moonbitlang.com/install/unix.sh)"
echo "$HOME/.moon/bin" >> "$GITHUB_PATH"  # CI 环境;本地请按 Shell 配置 PATH
moon version --all

作为依赖使用

在消费者模块目录运行:

moon add Lxxbv/glob
moon install

如果需要使用仓库中的 CLI 包,构建系统支持将可执行包作为 binary 依赖:

moon add Lxxbv/glob --bin
moon install

依赖版本以消费者的 moon.mod 和锁定/缓存状态为准;本仓库不在源码中隐藏额外运行时依赖。

直接运行仓库 CLI

moon run cmd/main "**/*.mbt"
moon run cmd/main "src/**/*.mbt" "src"

CLI 输出相对于指定目录的匹配路径;没有匹配项时输出提示,模式解析或 I/O 失败时输出错误信息。

API 示例

一次性匹配:

match @glob.match_pattern("src/**/*.mbt", "src/core/parser.mbt") {
  Ok(true) => println("matched")
  Ok(false) => println("not matched")
  Err(err) => println("pattern error: \{err}")
}

高频循环应编译一次:

let compiled = @glob.compile_pattern("src/**/*.mbt")?
let candidates = ["src/main.mbt", "src/core/parser.mbt", "docs/readme.md"]
let result = @glob.filter_compiled_patterns([compiled], candidates)

带文件系统选项的检索:

let options = @glob.GlobOptions::default()
  .files_only()
  .without_hidden()
  .sorted()
  .with_max_depth(4)?
let files = @glob.glob_with_options(".", "**/*.mbt", options)?

组合 include/exclude 查询:

let query = @glob.GlobQuery::new()
  .include_pattern("src/**/*.mbt")?
  .exclude_pattern("**/generated/**")?
  .without_hidden()
  .sorted()
let report = query.execute_paths(["src/main.mbt", "src/generated/api.mbt"])

// 对已经建立的索引重复查询,避免每次重新访问文件系统。
let indexed_report = query.execute_index(index)
let first_page = indexed_report.page(0, 20)

规则、索引和诊断:

let rules = @glob.GlobRules::from_text("*.tmp\n!important.tmp\n")?
let index = @glob.PathIndex::from_entries([
  @glob.PathRecord::file("src/main.mbt"),
  @glob.PathRecord::directory("src"),
])
let matched = index.query_with_rules("src/**/*.mbt", rules)?
let explanation = @glob.explain_pattern("src/{lib,test}/**/*.mbt")?
println(explanation.summary())

重复模式查询可以显式携带缓存,读取命中率:

let cache = @glob.PatternCache::new(32)?
let (cache, files) = cache.filter("src/**/*.mbt", candidates)?
println(cache.summary())

测试、边界和基准

本地验收建议在仓库根目录执行:

moon fmt
moon clean
moon info
moon check --deny-warn --target all
moon build --target all
moon test --deny-warn --target all
moon bench
git diff --check

当前测试覆盖解析错误、逗号/花括号、字符范围、转义、Windows 分隔符、隐藏路径、最大深度、空匹配、I/O 错误、规则否定、索引去重、缓存淘汰、工作负载统计和限制截断。确定性工作负载可直接运行:

let workload = @glob.build_default_workload()
let result = @glob.evaluate_workload(workload)
println(result.summary())

build_default_workload() 包含源代码、测试、文档、JSON、生成文件、隐藏缓存和嵌套资源,默认约 284 条候选路径;build_large_workload() 约 1404 条候选路径,适合比较编译复用、缓存和遍历策略。基准输出不写入仓库,也不宣称跨机器固定的纳秒数。

工程结构

  • lexer.mbt / parser.mbt / types.mbt:词法、语法和 AST。
  • matcher.mbt / glob.mbt:匹配器与文件系统搜索。
  • compiled.mbt / cache.mbt / traversal.mbt:编译复用、缓存和静态前缀剪枝。
  • query.mbt / pipeline.mbt / rules.mbt:组合查询、批处理和忽略规则。
  • index.mbt / explain.mbt / workload.mbt:路径索引、诊断和可重复工作负载。
  • cmd/main:可直接运行的 CLI。
  • .github/workflows/check.yml:Linux、macOS、Windows 的 check/build/test/fmt/info CI,Windows native 使用 MSYS2 UCRT64 GCC。

项目当前以 20 个生产 .mbt 文件、3780 行生产实现和 75 个自动化测试为本地验收基线;测试代码与生成的 .mbti 接口文件不计入生产代码规模。规模统计来自当前工作树,后续扩展只增加真实功能,不以注释或重复代码填充规模。

开源合规

本项目使用 Apache License 2.0。版权和许可声明保留在仓库根目录;依赖通过 moon.mod 显式声明,不复制第三方源码。提交前请检查新增文件是否带有兼容许可证、是否误提交构建产物、个人密钥或本机路径。

项目仓库

贡献与版本

问题反馈请附上 MoonBit 版本、目标后端、操作系统、最小模式、候选路径以及可复现的 moon test 输出。版本号遵循 SemVer;破坏性 API 变化应记录在 CHANGELOG.md

关于

glob-mbt 是一个专门为 MoonBit 语言设计的高性能、零外部依赖的路径通配符(Glob)匹配与文件检索库。类似于 Go 语言的 path/filepath.Match 和 JavaScript 生态的 minimatch/picomatch。它提供了对标准通配符模式(如 *、?、**、[char-class] 以及 {group1,group2})的解析、编译与高速路径匹配功能,并能够

261.0 KB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号