|
| 1 | + |
| 2 | +.. _direct-url: |
| 3 | + |
| 4 | +========================================================== |
| 5 | +Recording the Direct URL Origin of installed distributions |
| 6 | +========================================================== |
| 7 | + |
| 8 | +This document specifies a :file:`direct_url.json` file in the |
| 9 | +:file:`*.dist-info` directory of an installed distribution, to record the |
| 10 | +Direct URL Origin of the distribution. The layout of this file was originally |
| 11 | +specified in :pep:`610` and is formally documented here. |
| 12 | + |
| 13 | +.. contents:: Contents |
| 14 | + :local: |
| 15 | + |
| 16 | +Specification |
| 17 | +============= |
| 18 | + |
| 19 | +The :file:`direct_url.json` file MUST be created in the :file:`*.dist-info` |
| 20 | +directory by installers when installing a distribution from a requirement |
| 21 | +specifying a direct URL reference (including a VCS URL). |
| 22 | + |
| 23 | +This file MUST NOT be created when installing a distribution from an other |
| 24 | +type of requirement (i.e. name plus version specifier). |
| 25 | + |
| 26 | +This JSON file MUST be a dictionary, compliant with `RFC 8259 |
| 27 | +<https://tools.ietf.org/html/rfc8259>`_ and UTF-8 encoded. |
| 28 | + |
| 29 | +If present, it MUST contain at least two fields. The first one is ``url``, with |
| 30 | +type ``string``. Depending on what ``url`` refers to, the second field MUST be |
| 31 | +one of ``vcs_info`` (if ``url`` is a VCS reference), ``archive_info`` (if |
| 32 | +``url`` is a source archives or a wheel), or ``dir_info`` (if ``url`` is a |
| 33 | +local directory). These info fields have a (possibly empty) subdictionary as |
| 34 | +value, with the possible keys defined below. |
| 35 | + |
| 36 | +``url`` MUST be stripped of any sensitive authentication information, |
| 37 | +for security reasons. |
| 38 | + |
| 39 | +The user:password section of the URL MAY however |
| 40 | +be composed of environment variables, matching the following regular |
| 41 | +expression:: |
| 42 | + |
| 43 | + \$\{[A-Za-z0-9-_]+\}(:\$\{[A-Za-z0-9-_]+\})? |
| 44 | + |
| 45 | +Additionally, the user:password section of the URL MAY be a |
| 46 | +well-known, non security sensitive string. A typical example is ``git`` |
| 47 | +in the case of an URL such as ``ssh://git@gitlab.com/user/repo``. |
| 48 | + |
| 49 | +When ``url`` refers to a VCS repository, the ``vcs_info`` key MUST be present |
| 50 | +as a dictionary with the following keys: |
| 51 | + |
| 52 | +- A ``vcs`` key (type ``string``) MUST be present, containing the name of the VCS |
| 53 | + (i.e. one of ``git``, ``hg``, ``bzr``, ``svn``). Other VCS's SHOULD be registered by |
| 54 | + writing a PEP to amend this specification. |
| 55 | + The ``url`` value MUST be compatible with the corresponding VCS, |
| 56 | + so an installer can hand it off without transformation to a |
| 57 | + checkout/download command of the VCS. |
| 58 | +- A ``requested_revision`` key (type ``string``) MAY be present naming a |
| 59 | + branch/tag/ref/commit/revision/etc (in a format compatible with the VCS) |
| 60 | + to install. |
| 61 | +- A ``commit_id`` key (type ``string``) MUST be present, containing the |
| 62 | + exact commit/revision number that was installed. |
| 63 | + If the VCS supports commit-hash |
| 64 | + based revision identifiers, such commit-hash MUST be used as |
| 65 | + ``commit_id`` in order to reference the immutable |
| 66 | + version of the source code that was installed. |
| 67 | + |
| 68 | +When ``url`` refers to a source archive or a wheel, the ``archive_info`` key |
| 69 | +MUST be present as a dictionary with the following key: |
| 70 | + |
| 71 | +- A ``hash`` key (type ``string``) SHOULD be present, with value |
| 72 | + ``<hash-algorithm>=<expected-hash>``. |
| 73 | + It is RECOMMENDED that only hashes which are unconditionally provided by |
| 74 | + the latest version of the standard library's ``hashlib`` module be used for |
| 75 | + source archive hashes. At time of writing, that list consists of 'md5', |
| 76 | + 'sha1', 'sha224', 'sha256', 'sha384', and 'sha512'. |
| 77 | + |
| 78 | +When ``url`` refers to a local directory, the ``dir_info`` key MUST be |
| 79 | +present as a dictionary with the following key: |
| 80 | + |
| 81 | +- ``editable`` (type: ``boolean``): ``true`` if the distribution was installed |
| 82 | + in editable mode, ``false`` otherwise. If absent, default to ``false``. |
| 83 | + |
| 84 | +When ``url`` refers to a local directory, it MUST have the ``file`` sheme and |
| 85 | +be compliant with `RFC 8089 <https://tools.ietf.org/html/rfc8089>`_. In |
| 86 | +particular, the path component must be absolute. Symbolic links SHOULD be |
| 87 | +preserved when making relative paths absolute. |
| 88 | + |
| 89 | +.. note:: |
| 90 | + |
| 91 | + When the requested URL has the file:// scheme and points to a local directory that happens to contain a |
| 92 | + VCS checkout, installers MUST NOT attempt to infer any VCS information and |
| 93 | + therefore MUST NOT output any VCS related information (such as ``vcs_info``) |
| 94 | + in :file:`direct_url.json`. |
| 95 | + |
| 96 | +A top-level ``subdirectory`` field MAY be present containing a directory path, |
| 97 | +relative to the root of the VCS repository, source archive or local directory, |
| 98 | +to specify where ``pyproject.toml`` or ``setup.py`` is located. |
| 99 | + |
| 100 | +.. note:: |
| 101 | + |
| 102 | + As a general rule, installers should as much as possible preserve the |
| 103 | + information that was provided in the requested URL when generating |
| 104 | + :file:`direct_url.json`. For example user:password environment variables |
| 105 | + should be preserved and ``requested_revision`` should reflect the revision that was |
| 106 | + provided in the requested URL as faithfully as possible. This information is |
| 107 | + however *enriched* with more precise data, such as ``commit_id``. |
| 108 | + |
| 109 | +Registered VCS |
| 110 | +============== |
| 111 | + |
| 112 | +This section lists the registered VCS's; expanded, VCS-specific information |
| 113 | +on how to use the ``vcs``, ``requested_revision``, and other fields of |
| 114 | +``vcs_info``; and in |
| 115 | +some cases additional VCS-specific fields. |
| 116 | +Tools MAY support other VCS's although it is RECOMMENDED to register |
| 117 | +them by writing a PEP to amend this specification. The ``vcs`` field SHOULD be the command name |
| 118 | +(lowercased). Additional fields that would be necessary to |
| 119 | +support such VCS SHOULD be prefixed with the VCS command name. |
| 120 | + |
| 121 | +Git |
| 122 | +--- |
| 123 | + |
| 124 | +Home page |
| 125 | + |
| 126 | + https://git-scm.com/ |
| 127 | + |
| 128 | +vcs command |
| 129 | + |
| 130 | + git |
| 131 | + |
| 132 | +``vcs`` field |
| 133 | + |
| 134 | + git |
| 135 | + |
| 136 | +``requested_revision`` field |
| 137 | + |
| 138 | + A tag name, branch name, Git ref, commit hash, shortened commit hash, |
| 139 | + or other commit-ish. |
| 140 | + |
| 141 | +``commit_id`` field |
| 142 | + |
| 143 | + A commit hash (40 hexadecimal characters sha1). |
| 144 | + |
| 145 | +.. note:: |
| 146 | + |
| 147 | + Installers can use the ``git show-ref`` and ``git symbolic-ref`` commands |
| 148 | + to determine if the ``requested_revision`` corresponds to a Git ref. |
| 149 | + In turn, a ref beginning with ``refs/tags/`` corresponds to a tag, and |
| 150 | + a ref beginning with ``refs/remotes/origin/`` after cloning corresponds |
| 151 | + to a branch. |
| 152 | + |
| 153 | +Mercurial |
| 154 | +--------- |
| 155 | + |
| 156 | +Home page |
| 157 | + |
| 158 | + https://www.mercurial-scm.org/ |
| 159 | + |
| 160 | +vcs command |
| 161 | + |
| 162 | + hg |
| 163 | + |
| 164 | +``vcs`` field |
| 165 | + |
| 166 | + hg |
| 167 | + |
| 168 | +``requested_revision`` field |
| 169 | + |
| 170 | + A tag name, branch name, changeset ID, shortened changeset ID. |
| 171 | + |
| 172 | +``commit_id`` field |
| 173 | + |
| 174 | + A changeset ID (40 hexadecimal characters). |
| 175 | + |
| 176 | +Bazaar |
| 177 | +------ |
| 178 | + |
| 179 | +Home page |
| 180 | + |
| 181 | + https://bazaar.canonical.com/ |
| 182 | + |
| 183 | +vcs command |
| 184 | + |
| 185 | + bzr |
| 186 | + |
| 187 | +``vcs`` field |
| 188 | + |
| 189 | + bzr |
| 190 | + |
| 191 | +``requested_revision`` field |
| 192 | + |
| 193 | + A tag name, branch name, revision id. |
| 194 | + |
| 195 | +``commit_id`` field |
| 196 | + |
| 197 | + A revision id. |
| 198 | + |
| 199 | +Subversion |
| 200 | +---------- |
| 201 | + |
| 202 | +Home page |
| 203 | + |
| 204 | + https://subversion.apache.org/ |
| 205 | + |
| 206 | +vcs command |
| 207 | + |
| 208 | + svn |
| 209 | + |
| 210 | +``vcs`` field |
| 211 | + |
| 212 | + svn |
| 213 | + |
| 214 | +``requested_revision`` field |
| 215 | + |
| 216 | + ``requested_revision`` must be compatible with ``svn checkout`` ``--revision`` option. |
| 217 | + In Subversion, branch or tag is part of ``url``. |
| 218 | + |
| 219 | +``commit_id`` field |
| 220 | + |
| 221 | + Since Subversion does not support globally unique identifiers, |
| 222 | + this field is the Subversion revision number in the corresponding |
| 223 | + repository. |
| 224 | + |
| 225 | +Examples |
| 226 | +======== |
| 227 | + |
| 228 | +Example direct_url.json |
| 229 | +----------------------- |
| 230 | + |
| 231 | +Source archive: |
| 232 | + |
| 233 | +.. code:: |
| 234 | +
|
| 235 | + { |
| 236 | + "url": "https://github.com/pypa/pip/archive/1.3.1.zip", |
| 237 | + "archive_info": { |
| 238 | + "hash": "sha256=2dc6b5a470a1bde68946f263f1af1515a2574a150a30d6ce02c6ff742fcc0db8" |
| 239 | + } |
| 240 | + } |
| 241 | +
|
| 242 | +Git URL with tag and commit-hash: |
| 243 | + |
| 244 | +.. code:: |
| 245 | +
|
| 246 | + { |
| 247 | + "url": "https://github.com/pypa/pip.git", |
| 248 | + "vcs_info": { |
| 249 | + "vcs": "git", |
| 250 | + "requested_revision": "1.3.1", |
| 251 | + "commit_id": "7921be1537eac1e97bc40179a57f0349c2aee67d" |
| 252 | + } |
| 253 | + } |
| 254 | +
|
| 255 | +Local directory: |
| 256 | + |
| 257 | +.. code:: |
| 258 | +
|
| 259 | + { |
| 260 | + "url": "file:///home/user/project", |
| 261 | + "dir_info": {} |
| 262 | + } |
| 263 | +
|
| 264 | +Local directory installed in editable mode: |
| 265 | + |
| 266 | +.. code:: |
| 267 | +
|
| 268 | + { |
| 269 | + "url": "file:///home/user/project", |
| 270 | + "dir_info": { |
| 271 | + "editable": true |
| 272 | + } |
| 273 | + } |
| 274 | +
|
| 275 | +
|
| 276 | +Example pip commands and their effect on direct_url.json |
| 277 | +-------------------------------------------------------- |
| 278 | + |
| 279 | +Commands that generate a ``direct_url.json``: |
| 280 | + |
| 281 | +* pip install https://example.com/app-1.0.tgz |
| 282 | +* pip install https://example.com/app-1.0.whl |
| 283 | +* pip install "git+https://example.com/repo/app.git#egg=app&subdirectory=setup" |
| 284 | +* pip install ./app |
| 285 | +* pip install file:///home/user/app |
| 286 | +* pip install --editable "git+https://example.com/repo/app.git#egg=app&subdirectory=setup" |
| 287 | + (in which case, ``url`` will be the local directory where the git repository has been |
| 288 | + cloned to, and ``dir_info`` will be present with ``"editable": true`` and no |
| 289 | + ``vcs_info`` will be set) |
| 290 | +* pip install -e ./app |
| 291 | + |
| 292 | +Commands that *do not* generate a ``direct_url.json`` |
| 293 | + |
| 294 | +* pip install app |
| 295 | +* pip install app --no-index --find-links https://example.com/ |
0 commit comments