直接 URL 数据结构#

本文件指定一个 JSON 可序列化抽象数据结构,它可以表示指向 Python 项目和发行版工件(例如 VCS 源树、本地源树、源发行版和轮子)的 URL。

在撰写本文时,尚未正式指定如何将此数据结构的部分合并到可以传递给工具的单个 URL 中。一种常见的表示形式是 pip URL 格式(VCS 支持),其他示例在 版本说明符规范 中提供。

规范#

直接 URL 数据结构必须是一个字典,可根据 RFC 8259 序列化为 JSON。

它必须至少包含两个字段。第一个是 url,类型为 string。其内容必须是根据 WHATWG URL 标准 的有效 URL。

根据 url 所引用的内容,第二个字段必须是 vcs_info(如果 url 是 VCS 引用)、archive_info(如果 url 是源存档或轮子)或 dir_info(如果 url 是本地目录)。这些信息字段的值为(可能为空的)子字典,其中可能的键在下面定义。

出于安全原因,持久化时必须删除 url 中的任何敏感身份验证信息。

但是,URL 的用户:密码部分可以由环境变量组成,符合以下正则表达式

\$\{[A-Za-z0-9-_]+\}(:\$\{[A-Za-z0-9-_]+\})?

此外,URL 的用户:密码部分可能是一个众所周知、对安全性不敏感的字符串。一个典型的例子是 git,例如在 ssh://git@gitlab.com/user/repo 这样的 URL 中。

VCS URL#

url 引用 VCS 存储库时,vcs_info 键必须作为字典存在,其中包含以下键

  • 必须存在 vcs 键(类型 string),其中包含 VCS 的名称(即 githgbzrsvn 之一)。其他 VCS 应该通过编写 PEP 来修改此规范进行注册。 url 值必须与相应的 VCS 兼容,以便安装程序可以将其传递给 VCS 的签出/下载命令,而无需进行转换。

  • 可能存在 requested_revision 键(类型 string),其中命名分支/标签/引用/提交/修订等(采用与 VCS 兼容的格式)。此字段必须与用户请求的修订匹配,并且当用户未选择特定修订时,此字段不得存在。

  • 必须存在 commit_id 键(类型 string),其中包含要安装的精确提交/修订号。如果 VCS 支持基于提交哈希的修订标识符,则必须将此类提交哈希用作 commit_id,以便引用源代码的不可变版本。

存档 URL#

url 引用源存档或轮子时, archive_info 键必须作为包含以下键的字典存在

  • hashes 键应作为将哈希名称映射到文件的十六进制编码摘要的字典存在。

    可以包含多个哈希,由使用者决定如何处理多个哈希(可以验证所有哈希或其中的一部分,也可以不验证)。

    这些哈希名称应始终标准化为小写。

    可以通过 hashlib(具体来说,可以传递给 hashlib.new() 且不需要其他参数的任何哈希)获得的任何哈希算法都可以用作哈希字典的键。至少应始终包含 hashlib.algorithms_guaranteed 中的安全算法。在撰写本文时,特别建议使用 sha256

  • 出于向后兼容性的目的,可能存在已弃用的 hash 键(类型 string),其值为 <hash-algorithm>=<expected-hash>

数据结构的生成者应发出 hashes 键,无论是否提供一个或多个哈希。在以前发出 hash 键的上下文中,生成者应继续发出 hash 键,以便保持现有客户端的向后兼容性。

hashhashes 键同时存在时, hash 键中表示的哈希也必须存在于 hashes 字典中,以便使用者仅在存在 hashes 键时考虑 hashes 键,否则回退到 hash

本地目录#

url 引用本地目录时, dir_info 键必须作为包含以下键的字典存在

  • editable(类型:boolean):如果以可编辑模式安装/要安装发行版,则为 true,否则为 false。如果不存在,则默认为 false

url 指向本地目录时,它必须具有 file 方案,并且符合 RFC 8089。特别是,路径组件必须是绝对路径。在将相对路径转换为绝对路径时,应保留符号链接。

子目录中的项目#

可能存在一个顶级 subdirectory 字段,其中包含一个目录路径(相对于 VCS 存储库、源存档或本地目录的根目录),以指定 pyproject.tomlsetup.py 的位置。

已注册的 VCS#

本节列出了已注册的 VCS;扩展的 VCS 特定信息,说明如何使用 vcsrequested_revision 以及 vcs_info 的其他字段;在某些情况下还包括其他 VCS 特定字段。工具可能支持其他 VCS,但建议通过编写 PEP 来修改此规范以注册它们。 vcs 字段应为命令名称(小写)。支持此类 VCS 所需的其他字段应以 VCS 命令名称为前缀。

Git#

主页

https://git-scm.cn/

vcs 命令

git

vcs 字段

git

requested_revision 字段

标签名称、分支名称、Git 引用、提交哈希、缩短的提交哈希或其他提交标识符。

commit_id 字段

提交哈希(40 个十六进制字符 sha1)。

注意

工具可以使用 git show-refgit symbolic-ref 命令来确定 requested_revision 是否对应于 Git 引用。反过来,以 refs/tags/ 开头的引用对应于标签,以 refs/remotes/origin/ 开头的引用在克隆后对应于分支。

Mercurial#

主页

https://www.mercurial-scm.org/

vcs 命令

hg

vcs 字段

hg

requested_revision 字段

标签名称、分支名称、变更集 ID、缩短的变更集 ID。

commit_id 字段

变更集 ID(40 个十六进制字符)。

Bazaar#

主页

https://www.breezy-vcs.org/

vcs 命令

bzr

vcs 字段

bzr

requested_revision 字段

标签名称、分支名称、修订 ID。

commit_id 字段

修订 ID。

Subversion#

主页

https://subversion.org.cn/

vcs 命令

svn

vcs 字段

svn

requested_revision 字段

requested_revision 必须与 svn checkout --revision 选项兼容。在 Subversion 中,分支或标签是 url 的一部分。

commit_id 字段

由于 Subversion 不支持全局唯一标识符,因此此字段是相应存储库中的 Subversion 修订号。

JSON Schema#

以下 JSON Schema 可用于验证 direct_url.json 的内容

{
  "$schema": "https://json-schema.fullstack.org.cn/draft/2019-09/schema",
  "title": "Direct URL Data",
  "description": "Data structure that can represent URLs to python projects and distribution artifacts such as VCS source trees, local source trees, source distributions and wheels.",
  "definitions": {
    "URL": {
      "type": "string",
      "format": "uri"
    },
    "DirInfo": {
      "type": "object",
      "properties": {
        "editable": {
          "type": ["boolean", "null"]
        }
      }
    },
    "VCSInfo": {
      "type": "object",
      "properties": {
        "vcs": {
          "type": "string",
          "enum": [
            "git",
            "hg",
            "bzr",
            "svn"
          ]
        },
        "requested_revision": {
          "type": "string"
        },
        "commit_id": {
          "type": "string"
        },
        "resolved_revision": {
          "type": "string"
        }
      },
      "required": [
        "vcs",
        "commit_id"
      ]
    },
    "ArchiveInfo": {
      "type": "object",
      "properties": {
        "hash": {
          "type": "string",
          "pattern": "^\\w+=[a-f0-9]+$",
          "deprecated": true
        },
        "hashes": {
          "type": "object",
          "patternProperties": {
            "^[a-f0-9]+$": {
              "type": "string"
            }
          }
        }
      }
    }
  },
  "allOf": [
    {
      "type": "object",
      "properties": {
        "url": {
          "$ref": "#/definitions/URL"
        }
      },
      "required": [
        "url"
      ]
    },
    {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "dir_info": {
              "$ref": "#/definitions/DirInfo"
            }
          },
          "required": [
            "dir_info"
          ]
        },
        {
          "type": "object",
          "properties": {
            "vcs_info": {
              "$ref": "#/definitions/VCSInfo"
            }
          },
          "required": [
            "vcs_info"
          ]
        },
        {
          "type": "object",
          "properties": {
            "archive_info": {
              "$ref": "#/definitions/ArchiveInfo"
            }
          },
          "required": [
            "archive_info"
          ]
        }
      ]
    }
  ]
}

示例#

源存档

{
    "url": "https://github.com/pypa/pip/archive/1.3.1.zip",
    "archive_info": {
        "hashes": {
            "sha256": "2dc6b5a470a1bde68946f263f1af1515a2574a150a30d6ce02c6ff742fcc0db8"
        }
    }
}

带有标签和提交哈希的 Git URL

{
    "url": "https://github.com/pypa/pip.git",
    "vcs_info": {
        "vcs": "git",
        "requested_revision": "1.3.1",
        "commit_id": "7921be1537eac1e97bc40179a57f0349c2aee67d"
    }
}

本地目录

{
    "url": "file:///home/user/project",
    "dir_info": {}
}

可编辑模式下的本地目录

{
    "url": "file:///home/user/project",
    "dir_info": {
        "editable": true
    }
}

历史记录#

  • 2020 年 3 月:此规范已通过 PEP 610 批准,定义 direct_url.json 元数据文件。

  • 2023 年 1 月:添加 archive_info.hashes 键(讨论)。