swift-glob

一个使用 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 与我联系。

通过参与此项目,你同意遵守 贡献者行为准则