swift-glob

一个 Swift 原生实现的 glob 模式库,用于匹配和过滤文件。

项目目标

换句话说,该项目旨在成为 Swift 的 *最佳* glob 库,可用于底层工具和高层应用程序。

通过创建具有严格兼容现有(例如 POSIX)的 Swift 原生 glob 匹配实现,可以使工具迁移到 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

贡献

非常鼓励大家做出贡献。以下是一些您可以贡献的方式

编写代码: 如果您发现缺少某些功能或存在错误,欢迎提交 pull request。最好先打开一个 issue,以确保您不会浪费任何精力,以防您正在构建的内容已经在开发中或朝着不同的方向发展。即使您不打算编写实现,创建一个包含失败测试的 PR 也可以大大有助于启动某些东西。

已经有很多失败的测试(包含在 XCTExpectFailure 中)。这些将是一个好的开始。

改进文档: 如果您发现某些内容不清楚,那么其他人也可能觉得不清楚。

提交 issue: 如果您发现模式匹配方式中存在错误或不一致,请提交 issue。

如果您有任何疑问,请在 Github 上打开一个 issue 或在 Mastodon 上联系。

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