ダイレクト URL データ構造 <Direct URL Data Structure>#

この説明文書では、python プロジェクトや VCS 上のソースツリーやローカルのソースツリーやソースコード配布物や wheel ファイルのような配布物アーティファクトに対してURLを表現することを可能とする、 JSON のシリアル化抽象データ構造の仕様を定義します。

本稿執筆時点では、ツール群に渡せるようにこのデータ構造の各部分を単一の URL にまとめる方法については公式には指定されていません。よく見られる表現形式は pip URL フォーマット (VCS サポート) で、他の例が バージョン指定子仕様 の中で提供されています。

仕様#

直接 URL データ構造は辞書でなければならず、 RFC 8259 に従って JSON にシリアライズできなければなりません。

少なくとも二つのフィールドが含まれていなければなりません。一つ目は string 型の url です。その内容は、 WHATWG URL 標準 に従う正当な URL でなければなりません。

url が何を参照しているかによって、二つ目のフィールドは vcs_info (url が VCS 参照である場合)・ archive_info (url がソースコードアーカイブか wheel である場合)・ dir_info (url がローカルディレクトリである場合) のうちのいずれか一つでなければなりません。これらの info フィールドは、(空である場合もありますが) 以下に定義するキー群を持つことができるサブディレクトリを値として持ちます。

固持する場合には、url は、セキュリティ上の理由から、機微に関わる認証情報をすべて削除しておかなければなりません。

URLの user:password の部分は、しかしながら、次に述べる正規表現に合致する形で、環境変数から構成しても構いません:

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

さらに、 URL の user:password 部分は、広く知られたセキュリティ的に問題のない文字列であっても構いません。典型的な例としては、 ssh://git@gitlab.com/user/repo のような URL における git を挙げることができます。

VCS URL群#

url が VCS リポジトリを参照している場合、 以下のキー群を伴った vcs_info キーが辞書に存在していなければなりません:

  • (githgbzrsvn のいずれかのような) VCS の名前を含んだ vcs キー (string 型) が存在していなければなりません。その他の VCS については、この仕様を修正するための PEP を書くことによって登録されるべきです。当該 VCS の checkout/download コマンドへの翻訳をしなくてもインストーラが 手を離してしまえるようにするために、 url の値は対応する VCS と齟齬のないものでなければなりません。

  • requested_revision キー (string 型) は、 (VCS と互換性のあるフォーマットであれば) どのブランチ・タグ・リファレンス・コミット・リビジョンその他を指定するために存在していても構いません。このフィールドは、ユーザが要求するリビジョンに合致しなければなりませんし、ユーザが特定のリビジョンを選択していない場合には存在してはなりません。

  • commit_id キー (string 型) は、正確にどのコミットまたはリビジョンがインストールされた/されるかを示すもので、必須のキーです。 VCS がリビジョン識別子に基づくコミットハッシュをサポートしているなら、インストールされたもののソースコードの不変のバージョンを指し示す目的で、そのようなコミットハッシュを commit_id として使わなければなりません。

アーカイブ URL 群#

url がソースコードのアーカイブや wheel ファイルを指し示す場合には、 archive_info キーが次のようなキーを持つ辞書の形で存在しなければなりません:

  • hashes キーは、ハッシュ名から16進数表記のファイルハッシュ値への対応を保持する辞書として存在するべきです。

    複数のハッシュ値を含めることが可能で、そのような複数のハッシュ値を使って何をするか (すべてのハッシュ値を検証しても一部だけを検証しても構いませんし、何もしなくても構いません) については利用する側次第です。

    これらのハッシュの名前は、常に小文字に正規化されているべきです。

    hash lib 経由で利用可能なハッシュアルゴリズム (とりわけ、 hashlib.new() に渡すことができて、かつ、それ以上のパラメータを必要としないもの) はどれでも、ハッシュ値を格納する辞書のキーとして用いることができます。 hashlib.algorithms_garanteed から安全なアルゴリズムを少なくともひとつ選択して含めるべきです。執筆時点では、 sha256 が特に推奨されています。

  • 非推奨となった hash キー (string 型) は、後方互換性を保つ目的でなら <hash-algorithm>=<expected-hash> を値に取る形で存在していても構いません。

データ構造を生成する側では、ひとつまたは複数のハッシュが利用できるなら hashes キーを生成するべきです。以前からそうしていたので既存のクライアントのために後方互換性を保つためなら、生成側は hash キーの生成を継続するべきです。

hashhashes の両方のキーが存在する時は、 hash キーの中に現れるハッシュは、 hashes の辞書の中にも存在しなければならず、そうすることで利用する側では hashes キーがあればそれだけを考慮し、なければ hash にフォールバックすることが可能になります。

ローカルディレクトリ#

url がローカルのディレクトリを参照している場合には、以下のキーを含む辞書として dir_info キーが存在していなければなりません。

  • 配布物が編集可能モードでインストールされた/される場合には editable (boolean 型): true 、そうでなければ false 。存在していない場合のデフォルトは false です。

url がローカルのディレクトリを参照している場合、 :rfc:8089` に適合する ``file スキームが存在していなければなりません。特にパス部分は絶対パスでなければなりません。相対パスを絶対パスに変換する際には、シンボリックリンクはそのまま保存されているべきです。

サブディレクトリ内のプロジェクト群#

トップレベルの subdirectory フィールドは、 pyproject.toml または setup.py が存在する場所を指定するために、 VCS リポジトリやソースコードのアーカイブやローカルのディレクトリのルートディレクトリに対する相対パスとして示したディレクトリパスを値とするものとして存在することが許されています。

登録済みの VCS#

この節では登録済み VCS; vcsrequested_revision やその他の vcs_info 内のフィールドや、さらにある場合には特定の VCS に特有のフィールドなどの使い方のような拡張された VCS 特有の情報 の一覧を示します。 PEP を書くことでこの仕様を修正する形で別の VCS を登録することが推奨されていますが、ツールの側で他の VCS を (訳注、VCS 登録作業抜きで) サポートしても構いません。 vcs フィールドの値は、 (小文字の) コマンド名であるべきです。当該 VCS をサポートするのに必要であると思われるその他のフィールドについては、当該 VCS のコマンド名で始まる名前にするべきです。

Git#

ホームページ

https://git-scm.com/

vcs コマンド

git

vcs フィールド

git

requested_revision フィールド

タグ名・ブランチ名・Git 参照・コミットハッシュ・短縮型コミットハッシュ・その他のコミットハッシュ的なもの。

commit_id フィールド

コミットハッシュ (16進数で40文字のSHA1)。

注釈

ツールは、 requested_revision が Git 参照に対応しているか否かを判断するために git show-refgit symbolic-ref コマンドを使うことができます。さらに、 refs/tags/ で始まる参照はタグに対応し、クローンした後に refs/remotes/origin/ で始まる参照はブランチに対応します。

Mercurial#

ホームページ

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

vcs コマンド

hg

vcs フィールド

hg

requested_revision フィールド

タグ名・ブランチ名・チェンジセット ID ・短縮型チェンジセット ID。

commit_id フィールド

チェンジセット ID (16 進数で 40 文字)。

Bazaar#

ホームページ

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

vcs コマンド

bzr

vcs フィールド

bzr

requested_revision フィールド

タグ名・ブランチ名・リビジョン id 。

commit_id フィールド

リビジョン id 。

Subversion#

ホームページ

https://subversion.apache.org/

vcs コマンド

svn

vcs フィールド

svn

requested_revision フィールド

requested_revision は、 svn checkout --revision オプションと互換でなければなりません。 Subversion では、ブランチまたはタグは url の一部です。

commit_id フィールド

Subversion は大域的にユニークな識別子をサポートしていないので、このフィールドは当該リポジトリにおける Subversion のリビジョン番号です。

JSON スキーマ#

以下に述べる JSON スキーマを direct_url.json の内容を検証するために使うことができます:

{
  "$schema": "https://json-schema.org/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月: direct_url.json メタデータファイルを定義するこの仕様は、 PEP 610 を通じて承認されました。

  • 2023年1月: archive_info.hashes キーを追加しました (議論) 。