5.2 包集合
8 分钟阅读
原文链接: https://docs.swift.org/latest/documentation/packagemanagerdocs/packagecollections/
5.2 包集合
学习创建、发布和使用 Swift 包集合。
概述
包集合由 SE-0291 引入,它是经过整理的包列表及配套元数据,你可以导入它们,让发现已有包变得更容易。
教育工作者和社区有影响力的人可以发布包集合,配合课程材料或博客文章一起使用,让读者更容易第一次使用这些包,或者为某个特定任务挑选合适的包。企业也可以用集合来提供一组受信任的包,或者一组团队一贯使用的包。你可以把包集合编写成一个静态 JSON 文档,发布到网上,或者在本地文件系统上分发。
使用 package-collection 命令行工具
借助 swift package-collection 命令行接口,SwiftPM 用户可以订阅包集合。已导入包集合的内容对 libSwiftPM 的任何客户端都可访问。
swift package-collection 有下列子命令:
add:添加一个新的集合describe:获取某个集合、或者已导入集合中某个包的元数据list:列出已配置的集合refresh:刷新已配置的集合remove:移除已配置的集合search:在已导入的集合中按关键字或模块名搜索包
创建包集合
包集合是一个 JSON 文档,其中包含一个包列表以及每个包的元数据。
任何人都可以创建和发布包集合。swift-package-collection-generator 项目提供了面向包集合发布者的工具:
package-collection-generate:给定一组包 URL,生成一个包集合package-collection-sign:对包集合签名package-collection-validate:对包集合执行基本校验package-collection-diff:比较两个包集合,看看内容是否有差异
所有包集合都必须遵循集合数据格式,SwiftPM 才能使用它们。创建包集合的推荐做法是使用 package-collection-generate。如果要自行实现,可以通过 PackageCollectionsModel 模块使用这些数据模型。
输入格式
首先,定义集合的顶层元数据:
name:包集合的名称,仅用于展示。overview:包集合的描述。可选。keywords:与该集合关联的关键字数组。可选。formatVersion:该集合遵循的格式版本。目前唯一允许的值是1.0。revision:该包集合的修订号。可选。generatedAt:该包集合生成时的 ISO 8601 格式日期时间字符串。generatedBy:该包集合的作者。可选。name:作者姓名。
packages:包的对象的非空数组。
把包添加到集合中
packages 数组中的每一项都是一个包对象,具有下列属性:
url:包的 URL。目前只支持 Git 仓库 URL。URL 应当使用 HTTPS,可以带.git后缀。identity:如果该包已发布到注册表,则是它的标识。可选。summary:包的描述。可选。keywords:与该包关联的关键字数组。可选。readmeURL:该包 README 的 URL。可选。license:该包当前的许可证信息。可选。url:许可证文件的 URL。name:许可证名称。推荐使用 SPDX 标识符(例如Apache-2.0、MIT等)。未知时可省略。可选。
versions:版本对象的数组,代表该包最近和/或相关的若干次发布。
为包添加版本
版本对象包含从 Package.swift 中提取的元数据,以及可选的、来自其他来源的额外元数据:
version:语义化版本字符串。summary:该包版本的描述。可选。manifests:按 Swift 工具版本组织的清单文件映射,非空。键是(语义化)工具版本(详见下文),值是:toolsVersion:清单文件中指定的 Swift 工具版本。packageName:包的名称。targets:该包版本的目标数组。name:目标名。moduleName:如果该目标可以作为模块导入,则是模块名。可选。
products:该包版本的产品数组。name:产品名。type:产品类型。它的 JSON 表示必须与 SwiftPM 的PackageModel.ProductType一致。target:该产品的目标数组。
minimumPlatformVersions:该包版本在Package.swift中声明支持的平台数组。可选。
| |
defaultToolsVersion:默认清单文件的 Swift 工具版本。manifests映射的键中必须包含它。verifiedCompatibility:已验证并测试过的兼容平台与 Swift 版本数组。有效的平台名包括macOS、iOS、tvOS、watchOS、Linux、Android和Windows。Swift 版本应当是语义化版本字符串,并且尽可能具体。可选。
| |
license:该包版本的许可证。可选。url:许可证文件的 URL。name:许可证名称。推荐使用 SPDX 标识符(例如Apache-2.0、MIT等)。未知时可省略。可选。
author:该包版本的作者。可选。name:该包版本的作者。
signer:该包版本的签名者。可选。 细节参见关于包签名的文档。type:签名者类型。目前唯一有效值是ADP(Apple Developer Program)。commonName:签名证书主体的通用名。organizationalUnitName:签名证书主体的组织单位名。organizationName:签名证书主体的组织名。
createdAt:该包版本创建时的 ISO 8601 格式日期时间字符串。可选。
带版本的清单文件
包集合生成工具应当同时包含「默认」清单文件 Package.swift 中的数据,以及带版本的清单文件中的数据
manifests 映射的键是 Swift 工具(语义化)版本:
- 对于
Package.swift,应当使用Package.swift中指定的工具版本。 - 对于带版本的清单文件,应当使用文件名中指定的工具版本。例如,对于
Package@swift-4.2.swift就是4.2。清单文件中的工具版本必须与文件名中的一致。
带版本的标签
包集合不支持带版本的标签。
配置文件
与包集合相关的配置保存在文件 ~/.swiftpm/config/collections.json 中。它记录用户已配置的集合列表,以及诸如 package-collection add 命令中 --trust-unsigned 和 --skip-signature-check 标志所设置的偏好。
注意:这个文件通过 Swift Package Manager 命令管理,用户不应手动编辑它。
示例
| |
保护包集合
对集合签名
对包集合签名可以确立其真实性并保护其完整性。这一步是可选的。在用户添加未签名的集合之前,系统会提示用户确认。你用来给包集合签名的证书必须满足一系列要求。如果不满足这些要求,包管理器会返回错误。
关于包管理器实现的安全特性的更多细节,参见包的安全性。
安全风险
虽然签名能为包集合提供一定程度的保护,降低其内容被恶意行为者篡改的风险,但它无法防止下列攻击手法:
- 剥离签名:攻击者从已签名的集合中移除签名,使其作为未签名的集合被下载,从而绕过签名检查。这种情况下,发布者应当明确声明该集合是已签名的,而 SwiftPM 用户在「未签名」警告出现在一个本应已签名的集合上时,应当中止
add操作。 - 替换签名:攻击者可能篡改集合后用另一个证书重新签名,伪装成同一个实体或另一个实体,只要签名有效,SwiftPM 就会接受它。
为了防御这些攻击,包管理器提供了证书固定(certificate-pinning)配置,让集合发布者可以:
- 要求对自己的集合进行签名检查——这可以防御「剥离签名」。
- 限制可以使用哪个证书签名——这可以防御「替换签名」。
集合发布者定义证书固定配置的流程如下:
- 编辑
PackageCollectionSourceCertificatePolicy,在defaultSourceCertPolicies字典中添加一个条目:
| |
- 发起一个拉取请求以供审核。请求者必须能够提供自己的身份以及对域名所有权的证明:
- 请求者必须提供实际的证书文件(DER 编码)。SwiftPM 团队会验证证书链有效,并且拉取请求中提供的取值正确。
- 请求者必须添加一条引用该拉取请求的 TXT 记录。SwiftPM 团队会运行
dig -t txt <DOMAIN>来验证。这可以作为域名所有权的证明。
- 变更被接受之后,会在下一个 SwiftPM 版本中生效。
由于证书固定配置与 Web 域名相关联,它只能应用于托管在 Web 上的已签名集合(即 URL 以 https:// 开头),不覆盖本地文件系统中的集合(即 URL 以 file:// 开头)。