资讯详情

Swift Package Registry 服务规范附录 B 深度解读:package release metadata JSON Schema 全解析

📅 2026/9/25 17:13:27 | 华诺云谱 👁 阅读
Swift Package Registry 服务规范附录 B 深度解读:package release metadata JSON Schema 全解析
开发工具构建工具【免费下载链接】swift-package-managerThe Package Manager for the Swift Programming Language项目地址https://gitcode.com/gh_mirrors/sw/swift-package-manager点击查看免费下载在 SwiftPM 的包注册服务Swift Package Registry规范中附录 BRegistryServerSpecificationAppendixB为创建包发布create package release请求中携带的metadata对象定义了唯一的 JSON Schema。本文以该附录为主体结合当前仓库中PackageModel、PackageLoading与PackageRegistryCommand的源码实现完整讲解PackageRelease、Author、Organization三类对象的全部字段、必填约束、格式要求以及这些元数据在获取发布信息4.2、按 URL 查询包标识符4.5与创建包发布4.6三个 API 中的实际作用帮助注册服务实现者与 SwiftPM 高级用户准确构造、校验和消费发布元数据。一、附录 B 在注册服务规范中的位置附录 B 全文围绕一个问题展开创建包发布请求中的metadata部分应该长什么样。其上级规范 RegistryServerSpecification.md 在第 4.6 节Create a package release中规定客户端向PUT /{scope}/{name}/{version}发送的请求体是 multipart form-data其中各部分的约束如下KeyContent-Type描述要求级别source-archiveapplication/zip包的源代码归档REQUIREDsource-archive-signatureapplication/octet-stream源代码归档的签名OPTIONALmetadataapplication/json关于该发布的附加信息OPTIONALmetadata-signatureapplication/octet-stream元数据的签名OPTIONAL其中metadata部分必须符合附录 B 定义的 JSON Schema即一个类型为PackageRelease的 JSON 对象。同时第 4.2.2 节Package release metadata standards明确指出服务器可以自行扩展该 Schema、允许或补充附加元数据而metadata键会原样出现在 4.2Fetch information about a package release的 API 响应中用于承载用户提供的元数据 服务器补充的元数据。二、完整 JSON Schema 原文附录 B 给出的 Schema 基于JSON Schema Draft 2020-12$schema字段声明顶层对象为PackageRelease。完整定义如下{ $schema: https://json-schema.org/draft/2020-12/schema, $id: https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md, title: Package Release Metadata, description: Metadata of a package release., type: object, properties: { author: { type: object, properties: { name: { type: string, description: Name of the author. }, email: { type: string, format: email, description: Email address of the author. }, description: { type: string, description: A description of the author. }, organization: { type: object, properties: { name: { type: string, description: Name of the organization. }, email: { type: string, format: email, description: Email address of the organization. }, description: { type: string, description: A description of the organization. }, url: { type: string, format: uri, description: URL of the organization. } }, required: [name] }, url: { type: string, format: uri, description: URL of the author. } }, required: [name] }, description: { type: string, description: A description of the package release. }, licenseURL: { type: string, format: uri, description: URL of the package releases license document. }, originalPublicationTime: { type: string, format: date-time, description: Original publication time of the package release in ISO 8601 format. }, readmeURL: { type: string, format: uri, description: URL of the README specifically for the package release or broadly for the package. }, repositoryURLs: { type: array, description: Code repository URL(s) of the package release., items: { type: string, description: Code repository URL. } } } }注意该 Schema 的要点顶层PackageRelease对象本身没有required约束——也就是说从 JSON Schema 层面看所有属性都是可选的真正的必填约束体现在author.name与author.organization.name上详见下文类型表格。此外附录 B 也提醒服务端实现者第 4.6.2 节允许服务器将 Schema 中的任意属性以及自定义的附加属性设为必填因此各注册服务的实际必填策略可能不同。三、PackageRelease顶层对象字段详解附录 B 用表格形式给出了PackageRelease类型的完整字段说明如下表所示PropertyTypeDescriptionRequiredauthorAuthor该包发布的作者。否descriptionString该包发布的描述。否licenseURLString该包发布许可证文档的 URL。否originalPublicationTimeString该包发布最初发布时间的 ISO 8601 格式字符串。若该发布此前曾在别处发布可设置此项。注册服务应独立记录发布时间并在包发布元数据响应中将其作为publishedAt返回。若originalPublicationTime与publishedAt同时存在应使用originalPublicationTime。否readmeURLString专门针对该发布或泛指该包的 README 的 URL。否repositoryURLsArray该包的代码仓库 URL 列表。建议包含同一仓库的全部 URL 变体如 SSH、HTTPS。若包没有源代码控制表示可为空数组。设置该属性是注册服务获取仓库 URL 到包标识符映射的方式之一用于支撑lookup package identifiers registered for a URLAPI注册服务也可选择其他机制让包作者指定此类映射。否下面对几个关键字段做纵深展开。3.1originalPublicationTime迁移发布时间的正确姿势这是全部字段中语义最微妙的一个。附录 B 给出了三层约定适用场景如果该包发布此前已经在其他平台发布过即搬家场景作者可以在此记录最初发布时间。服务端职责注册服务应独立记录自己收到发布的时间并在 4.2Fetch information about a package release的响应中把它作为顶层字段publishedAt返回。也就是说originalPublicationTime作者提供与publishedAt服务端记录是两个不同来源的时间戳。冲突裁决当两者同时存在时应以originalPublicationTime为准——因为它更能反映这个版本真正诞生的时刻。在 RegistryServerSpecification.md 的 4.2 响应示例中publishedAt是顶层响应键之一形如publishedAt: 2023-02-16T04:00:00.000Z而originalPublicationTime属于metadata对象两者层级不同、职责互补。3.2repositoryURLs连接按 URL 查包标识符API 的桥梁repositoryURLs是本 Schema 中与另一个 API 强耦合的字段。规范 4.5 节Lookup package identifiers registered for a URL定义了一个GET /identifiers?url{url}端点用于返回与某个 URL 关联的包标识符列表GET /identifiers?urlhttps://github.com/mona/LinkedList HTTP/1.1 Host: packages.example.com Accept: application/vnd.swift.registry.v1成功响应200 OK形如{ identifiers: [ mona.LinkedList ] }而 4.5.1 节明确指出repositoryURLs数组正是服务端获取URL → 包标识符映射的来源之一。附录 B 进一步给出实操建议建议把同一仓库的所有 URL 变体都填进去例如 SSH 形式与 HTTPS 形式这样无论客户端用哪种形式的 URL 查询都能命中若包没有源代码控制表示repositoryURLs可以是空数组注册服务也可以采用其他机制让作者指定映射repositoryURLs只是规范推荐的路径之一服务端应验证包作者对相应仓库的所有权声明4.5.1 节。3.3 格式约束email、uri、date-timeSchema 中多处使用了 JSON Schema 的format关键字实现方在构造或校验元数据时应特别注意format应用于含义emailauthor.email、author.organization.email必须是合法的电子邮件地址格式uriauthor.url、author.organization.url、licenseURL、readmeURL必须是合法的 URIdate-timeoriginalPublicationTime必须是 ISO 8601 日期时间格式如2023-02-16T04:00:00.000Z四、Author类型详解author对象描述包发布的作者其字段如下PropertyTypeDescriptionRequirednameString作者姓名。✓emailString作者电子邮件地址。否descriptionString作者描述。否organizationOrganization作者所属的组织。否urlString作者 URL。否author.name是整个 Schema 中仅有的两个必填字段之一。也就是说只要提交了author对象就必须带上name而email、description、url、organization均可省略。五、Organization类型详解organization对象描述作者所属的组织字段如下PropertyTypeDescriptionRequirednameString组织名称。✓emailString组织电子邮件地址。否descriptionString组织描述。否urlString组织 URL。否organization.name是另一个必填字段只要提供了organization对象name就不可缺。organization本身嵌套在author中属于可选层级。六、元数据在创建包发布请求中的真实形态第 4.6 节给出了完整的 multipart 请求示例其中metadata部分可以非常精简——规范中的最小示例甚至只有一行--boundary Content-Disposition: form-data; namemetadata Content-Type: application/json Content-Transfer-Encoding: quoted-printable Content-Length: 3 { repositoryURLs: [] } --boundary而在 4.6.2 节规范给出了一个信息更完整的示例几乎覆盖了PackageRelease的主要可选字段--boundary Content-Disposition: form-data; namemetadata Content-Type: application/json Content-Length: 226 Content-Transfer-Encoding: quoted-printable { description: One thing links to another., repositoryURLs: [https://github.com/mona/LinkedList], licenseURL: https://www.apache.org/licenses/LICENSE-2.0, author: { name: Mona Lisa Octocat } }可以看到作者只填了必填的author.name其余字段按需补充。这印证了附录 B 的设计哲学——Schema 给出完整能力面但把字段的必填策略留给各注册服务自行决定。同时第 4.6.2 节对服务端提出了两条约束可扩展性服务器可以允许并/或补充附加元数据即 schema 之外的自定义字段校验失败处理若客户端提交了无效的 JSON 文档服务端应返回422Unprocessable Entity或413Payload Too Large并可在响应体中附带校验错误详情HTTP/1.1 422 Unprocessable Entity Content-Version: 1 Content-Type: application/problemjson Content-Language: en { detail: invalid JSON provided for release metadata }七、源码级印证Schema 如何落地为 Swift 类型与存储格式附录 B 定义的这三类对象在 SwiftPM 源码中有完整的一一对应实现可以从结构上印证字段语义。7.1 类型映射RegistryReleaseMetadata.Metadata在 RegistryReleaseMetadata.swift 中RegistryReleaseMetadata是注册发布元数据的核心模型其嵌套类型与 Schema 字段的对应关系如下JSON Schema 字段Swift 字段类型authormetadata.authorAuthor?descriptionmetadata.descriptionString?licenseURLmetadata.licenseURLURL?readmeURLmetadata.readmeURLURL?repositoryURLsmetadata.scmRepositoryURLs[SourceControlURL]?细节值得注意Swift 侧全部使用可选类型与 Schema 顶层无 required的宽松策略一致repositoryURLs在 Swift 模型中被命名为scmRepositoryURLs且元素类型是专门包装过的SourceControlURL来自Basics模块说明该字段在 SwiftPM 内部被当作源代码控制仓库 URL处理Author结构体包含name非可选、emailAddress、description、url、organization与附录 B 表格逐一对齐其中name是唯一非可选属性正是 Schema 中required: [name]的体现Organization结构体同样以name为唯一非可选属性呼应required: [name]。此外RegistryReleaseMetadata还携带source发布来源如某个 registry URL与signatureRegistrySignature记录签名者、签名格式与签名值说明 SwiftPM 客户端除了保存元数据本身还会记录这份元数据从哪个注册服务、以何种签名形式获得。7.2 持久化.registry-metadata文件RegistryReleaseMetadataSerialization.swift 负责元数据的磁盘持久化默认文件名固定为.registry-metadataRegistryReleaseMetadataStorage.fileNamesave(_:to:fileSystem:)通过JSONEncoder将RegistryReleaseMetadata编码后写入指定路径load(from:fileSystem:)通过JSONDecoder读回并还原为RegistryReleaseMetadata签名部分以 base64 编码字符串存储、读取时解码回字节数组。从实现看CodableRegistryReleaseMetadata同文件第 40 行起是面向磁盘的编码中间层它额外记录了registryURL 与signaturesignedBy、format、base64而元数据主体字段与附录 B Schema 保持同构。这意味着注册服务按附录 B 提交的元数据SwiftPM 客户端下载后会以.registry-metadata文件形式缓存在本地供后续构建与校验使用。7.3 发布命令package-metadata.json与--metadata-path在 PackageRegistryCommandPublish.swift 中swift package-registry publish子命令把元数据文件接入发布流程默认元数据文件名是package-metadata.jsonPublish.metadataFilename位于包目录根下若元数据文件不在默认位置可用--metadata-path path显式指定路径源码注释明确说明用于包目录中非package-metadata.json的包元数据 JSON 文件发布时会读取该文件并作为 multipart 的metadata段提交若启用了签名提供了--signing-identity、--private-key-path或--cert-chain-paths还会同时对元数据签名并提交metadata-signature段。这给包作者提供了一条可操作的落地路径在包目录里写好符合附录 B Schema 的package-metadata.json执行swift package-registry publish即可将元数据随发布一起提交对已发布到其他平台的版本可利用originalPublicationTime保留原始发布时间。八、服务端实现要点清单综合附录 B 与其上级规范的约束实现一个符合规范的注册服务时metadata处理环节至少应做到Schema 校验按 Draft 2020-12 规则校验metadataJSON 对象落实email、uri、date-time三种 format 检查必填策略自定Schema 层面仅author.name、author.organization.name必填服务端可自行将更多属性含自定义属性设为必填但应在文档中明示扩展与回显允许作者提交附加字段也允许服务端补充元数据如校验、评分信息并确保 4.2 响应中的metadata键同时包含用户提供与服务器补充的内容错误响应无效 JSON 返回422或413并使用 RFC 7807 的application/problemjson错误格式时间语义独立记录publishedAt但冲突时尊重originalPublicationTimeURL 映射从repositoryURLs提取 URL → 包标识符映射以支撑/identifiers查询并验证作者对仓库的所有权声明。九、总结附录 B 用一份 JSON Schema 三张类型表把包发布元数据的边界刻画得非常清晰顶层宽进全部可选、作者与组织窄出name 必填、格式严格email / uri / date-time。它同时承担了两个生态职能——在 4.6 创建发布时承载作者声明的描述、许可证、README、仓库地址与迁移时间在 4.5 按 URL 查询包标识符时充当URL → 包标识符映射的数据来源。而 SwiftPM 源码侧 RegistryReleaseMetadata.swift 的类型定义、RegistryReleaseMetadataSerialization.swift 的.registry-metadata持久化以及 PackageRegistryCommandPublish.swift 的package-metadata.json读取逻辑共同构成了这份规范在客户端侧的完整落地。无论是实现注册服务还是使用 SwiftPM 发布包到注册表这份附录都是必读的元数据契约。赞分享开发工具构建工具【免费下载链接】swift-package-managerThe Package Manager for the Swift Programming Language项目地址https://gitcode.com/gh_mirrors/sw/swift-package-manager点击查看免费下载相关推荐Swift Package Registry 服务规范深度解析从端点设计到 SwiftPM 客户端实现Swift Package Registry 服务规范深度解析从端点设计到 SwiftPM 客户端实现 本文基于 Swift Package Manager开发工具构建工具Swift Package Manager swift package dump-package 完全指南将解析后的 Package.swift 导出为 JSONSwift Package Manager swift package dump package 完全指南将解析后的 Package.swift 导出为 JS开发工具构建工具Swift Package Manager 注册表配置移除指南swift package-registry unset 命令全解析Swift Package Manager 注册表配置移除指南 swift package registry unset 命令全解析 swift packag开发工具构建工具上一篇ESLint prefer-spread 规则详解用展开运算符替代 Function.prototype.apply()下一篇Refine Ant Design useSelect 的 defaultValue 详解让默认值始终可靠地出现在下拉选项中创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑