一个使用 Swift 原生实现的 glob 模式库,用于匹配和过滤文件。
换句话说,该项目旨在成为 Swift 首选 的 glob 库,可在底层工具和高级应用程序中使用。
通过使用原生 Swift 创建 glob 匹配实现,并严格遵守诸如 POSIX 之类的现有规范,可以方便地将工具迁移到 Swift,自定义和扩展行为,并使实现更高效和并发。
基本模式匹配和目录搜索已经工作,在我的测试中,使用大约 10 个排除模式搜索大型文件和文件夹层级结构非常快。 但是,仍然缺少一些功能,例如 分组。 截至本文撰写时, 匹配 fnmatch
行为的测试有 588 个测试失败。
1.0.0 版本的发布取决于与 fnmatch
的兼容性测试是否通过。
search
对给定目录中的所有文件执行递归枚举,并根据包含和排除模式对其进行过滤。
let output = try await Glob.search(
directory: searchURL,
include: [
Glob.Pattern("**/*.swift"),
],
exclude: [
Glob.Pattern("**/*.generated.swift"),
],
skipHiddenFiles: true
)
// output is an async sequence
// you can iterate it as files are found:
for try await url in output {
// do something with the file
}
// or convert the results to an array and wait for the search to finish:
output.reduce(into: [URL]()) { $0.append($1) }
还有一个版本的 search 接受一个 matching
闭包,而不是包含和排除模式,如果你需要更多地控制文件的匹配方式。
你可以直接使用一个模式来匹配字符串。
let pattern = try Glob.Pattern("Hello *!")
pattern.match("Hello World!") // returns true
Glob.Pattern
接受一个 Options
参数,该参数可用于自定义模式的解析方式以及匹配的评估方式。 提供了多种配置,例如 Glob.Pattern.Options.posix()
,试图匹配其他 glob 算法的行为。
let pattern = try Glob.Pattern("**/*.swift", options: .posix())
pattern.match("a/b/c/d/file.swift") // returns false because posix glob patters don't support ** (path level wildcard) matching.
默认配置尝试使用大多数开发人员期望的合理的默认值,并尽可能多地启用功能。 你可以通过创建可变副本来定制默认配置或任何配置
var options = Glob.Pattern.Options.default
options.pathSeparator = #"\"# // use windows path separator
非常鼓励大家贡献。以下是一些可以贡献的方式
编写代码: 如果你看到缺少的功能或错误,我欢迎提交拉取请求。 最好先打开一个 issue,以确保你不会浪费任何精力,因为你正在构建的内容可能已经在进行中或朝着不同的方向发展。 即使你没有能力编写实现,创建一个包含失败测试的 PR 对于启动某些工作也大有帮助。
已经有很多失败的测试(包装在 XCTExpectFailure
中)。 这些将是一个很好的起点。
改进文档: 如果你发现有什么不清楚的地方,其他人可能也会觉得不清楚。
提交 issue: 如果你发现模式匹配方式存在错误或不一致,请提交 issue。
如果你有任何问题,请在 Github 上打开一个 issue 或通过 Mastodon 与我联系。
通过参与此项目,你同意遵守 贡献者行为准则。