Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • anlambert/swh-model
  • lunar/swh-model
  • franckbret/swh-model
  • douardda/swh-model
  • olasd/swh-model
  • swh/devel/swh-model
  • Alphare/swh-model
  • samplet/swh-model
  • marmoute/swh-model
  • rboyer/swh-model
10 results
Show changes
Commits on Source (271)
# Changes here will be overwritten by Copier
_commit: v0.3.3
_src_path: https://gitlab.softwareheritage.org/swh/devel/swh-py-template.git
description: Software Heritage data model
distribution_name: swh-model
have_cli: true
have_workers: false
package_root: swh/model
project_name: swh.model
python_minimal_version: '3.7'
readme_format: rst
# python: Reformat code with black
bf3f1cec8685c8f480ddd95027852f8caa10b8e3
4c39334b2aa9f782950aaee72781dc1df9d37550
5ff7c5b592ce1d76f5696a7f089680807ad557a6
*~
build
/.coverage
/.coverage.*
dist
*.egg-info/ *.egg-info/
*.pyc
.coverage
.eggs/ .eggs/
.hypothesis .hypothesis
*.pyc .mypy_cache
__pycache__
.pytest_cache
*.sw?
.tox .tox
version.txt __pycache__
.mypy_cache/ build/
dist/
# these are symlinks created by a hook in swh-docs' main sphinx conf.py
docs/README.rst
docs/README.md
# this should be a symlink for people who want to build the sphinx doc
# without using tox, generally created by the swh-env/bin/update script
docs/Makefile.sphinx
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.4.0 rev: v5.0.0
hooks: hooks:
- id: trailing-whitespace - id: trailing-whitespace
- id: flake8 - id: check-json
- id: check-json - id: check-yaml
- id: check-yaml
- repo: https://github.com/codespell-project/codespell - repo: https://github.com/python/black
rev: v1.16.0 rev: 25.1.0
hooks: hooks:
- id: codespell - id: black
- repo: local - repo: https://github.com/PyCQA/isort
hooks: rev: 6.0.0
- id: mypy hooks:
name: mypy - id: isort
entry: mypy
args: [swh]
pass_filenames: false
language: system
types: [python]
- repo: https://github.com/python/black - repo: https://github.com/pycqa/flake8
rev: 19.10b0 rev: 7.1.1
hooks: hooks:
- id: black - id: flake8
additional_dependencies: [flake8-bugbear==24.12.12, flake8-pyproject]
# unfortunately, we are far from being able to enable this... - repo: https://github.com/codespell-project/codespell
# - repo: https://github.com/PyCQA/pydocstyle.git rev: v2.4.1
# rev: 4.0.0 hooks:
# hooks: - id: codespell
# - id: pydocstyle name: Check source code spelling
# name: pydocstyle stages: [pre-commit]
# description: pydocstyle is a static analysis tool for checking compliance with Python docstring conventions. args: [-L assertIn, -L anc]
# entry: pydocstyle --convention=google - id: codespell
# language: python name: Check commit message spelling
# types: [python] stages: [commit-msg]
- repo: local
hooks:
- id: mypy
name: mypy
entry: mypy
args: [swh]
pass_filenames: false
language: system
types: [python]
- id: twine-check
name: twine check
description: call twine check when pushing an annotated release tag
entry: bash -c "ref=$(git describe) &&
[[ $ref =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] &&
(python3 -m build --sdist && twine check $(ls -t dist/* | head -1)) || true"
pass_filenames: false
stages: [pre-push]
language: python
additional_dependencies: [twine, build]
...@@ -6,7 +6,7 @@ In the interest of fostering an open and welcoming environment, we as Software ...@@ -6,7 +6,7 @@ In the interest of fostering an open and welcoming environment, we as Software
Heritage contributors and maintainers pledge to making participation in our Heritage contributors and maintainers pledge to making participation in our
project and our community a harassment-free experience for everyone, regardless project and our community a harassment-free experience for everyone, regardless
of age, body size, disability, ethnicity, sex characteristics, gender identity of age, body size, disability, ethnicity, sex characteristics, gender identity
and expression, level of experience, education, socio-economic status, and expression, level of experience, education, socioeconomic status,
nationality, personal appearance, race, religion, or sexual identity and nationality, personal appearance, race, religion, or sexual identity and
orientation. orientation.
......
Daniele Serafini Daniele Serafini
Ishan Bhanuka Ishan Bhanuka
Antoine Cezar
Pierre-Yves David
include README.md
include Makefile
include requirements*.txt
include version.txt
recursive-include swh/model/tests/data *.tgz
recursive-include swh py.typed
swh-model Software Heritage - Data model
========= ==============================
Implementation of the Data model of the Software Heritage project, used to Implementation of the Data model of the Software Heritage project, used to
archive source code artifacts. archive source code artifacts.
This module defines the notion of SoftWare Heritage persistent IDentifiers This module defines the notion of SoftWare Hash persistent IDentifiers
(SWHIDs) and provides tools to compute them: (SWHIDs) and provides tools to compute them:
```sh .. code-block:: shell
$ swh-identify fork.c kmod.c sched/deadline.c $ swh-identify fork.c kmod.c sched/deadline.c
swh:1:cnt:2e391c754ae730bd2d8520c2ab497c403220c6e3 fork.c swh:1:cnt:2e391c754ae730bd2d8520c2ab497c403220c6e3 fork.c
swh:1:cnt:0277d1216f80ae1adeed84a686ed34c9b2931fc2 kmod.c swh:1:cnt:0277d1216f80ae1adeed84a686ed34c9b2931fc2 kmod.c
...@@ -15,4 +16,4 @@ This module defines the notion of SoftWare Heritage persistent IDentifiers ...@@ -15,4 +16,4 @@ This module defines the notion of SoftWare Heritage persistent IDentifiers
$ swh-identify --no-filename /usr/src/linux/kernel/ $ swh-identify --no-filename /usr/src/linux/kernel/
swh:1:dir:f9f858a48d663b3809c9e2f336412717496202ab swh:1:dir:f9f858a48d663b3809c9e2f336412717496202ab
```
...@@ -5,16 +5,17 @@ ...@@ -5,16 +5,17 @@
# --ignore-empty-folders # --ignore-empty-folders
# 38f8d2c3a951f6b94007896d0981077e48bbd702 # 38f8d2c3a951f6b94007896d0981077e48bbd702
import click
import os import os
import click
from swh.model import from_disk, hashutil from swh.model import from_disk, hashutil
def combine_filters(*filters): def combine_filters(*filters):
"""Combine several ignore filters""" """Combine several ignore filters"""
if len(filters) == 0: if len(filters) == 0:
return from_disk.accept_all_directories return from_disk.accept_all_paths
elif len(filters) == 1: elif len(filters) == 1:
return filters[0] return filters[0]
...@@ -31,7 +32,6 @@ def combine_filters(*filters): ...@@ -31,7 +32,6 @@ def combine_filters(*filters):
) )
@click.option("--ignore", multiple=True, help="Ignore pattern.") @click.option("--ignore", multiple=True, help="Ignore pattern.")
def main(path, ignore_empty_folder=False, ignore=None): def main(path, ignore_empty_folder=False, ignore=None):
filters = [] filters = []
if ignore_empty_folder: if ignore_empty_folder:
filters.append(from_disk.ignore_empty_directories) filters.append(from_disk.ignore_empty_directories)
...@@ -42,7 +42,7 @@ def main(path, ignore_empty_folder=False, ignore=None): ...@@ -42,7 +42,7 @@ def main(path, ignore_empty_folder=False, ignore=None):
try: try:
d = from_disk.Directory.from_disk( d = from_disk.Directory.from_disk(
path=os.fsencode(path), dir_filter=combine_filters(*filters) path=os.fsencode(path), path_filter=combine_filters(*filters)
) )
hash = d.hash hash = d.hash
except Exception as e: except Exception as e:
......
...@@ -11,13 +11,11 @@ ...@@ -11,13 +11,11 @@
import sys import sys
from swh.model import identifiers, hashutil from swh.model import hashutil, identifiers
def revhash(revision_raw): def revhash(revision_raw):
"""Compute the revision hash. """Compute the revision hash."""
"""
# HACK: string have somehow their \n expanded to \\n # HACK: string have somehow their \n expanded to \\n
if b"\\n" in revision_raw: if b"\\n" in revision_raw:
revision_raw = revision_raw.replace(b"\\n", b"\n") revision_raw = revision_raw.replace(b"\\n", b"\n")
......
include ../../swh-docs/Makefile.sphinx include Makefile.sphinx
-include Makefile.local -include Makefile.local
...@@ -3,4 +3,4 @@ Command-line interface ...@@ -3,4 +3,4 @@ Command-line interface
.. click:: swh.model.cli:identify .. click:: swh.model.cli:identify
:prog: swh identify :prog: swh identify
:show-nested: :nested: full
...@@ -74,8 +74,7 @@ synonyms. ...@@ -74,8 +74,7 @@ synonyms.
**directories** **directories**
a list of named directory entries, each of which pointing to other artifacts, a list of named directory entries, each of which pointing to other artifacts,
usually file contents or sub-directories. Directory entries are also usually file contents or sub-directories. Directory entries are also
associated to arbitrary metadata, which vary with technologies, but usually associated to some metadata stored as permission bits.
includes permission bits, modification timestamps, etc.
**revisions** (AKA "commits") **revisions** (AKA "commits")
software development within a specific project is essentially a time-indexed software development within a specific project is essentially a time-indexed
...@@ -92,8 +91,8 @@ synonyms. ...@@ -92,8 +91,8 @@ synonyms.
some revisions are more equals than others and get selected by developers as some revisions are more equals than others and get selected by developers as
denoting important project milestones known as "releases". Each release denoting important project milestones known as "releases". Each release
points to the last commit in project history corresponding to the release and points to the last commit in project history corresponding to the release and
might carry arbitrary metadata—e.g., release name and version, release carries metadata: release name and version, release message, cryptographic
message, cryptographic signatures, etc. signatures, etc.
Additionally, the following crawling-related information are stored as Additionally, the following crawling-related information are stored as
...@@ -260,3 +259,39 @@ making emergent structures such as code reuse across different projects or ...@@ -260,3 +259,39 @@ making emergent structures such as code reuse across different projects or
software origins, readily available. Further reinforcing the Software Heritage software origins, readily available. Further reinforcing the Software Heritage
use cases, this object could become a veritable "map of the stars" of our use cases, this object could become a veritable "map of the stars" of our
entire software commons. entire software commons.
Extended data model
-------------------
In addition to the artifacts detailed above used to represent original software
artifacts, the Software Heritage archive stores information about these
artifacts.
**extid**
a relationship between an original identifier of an artifact, in its
native/upstream environment, and a `core SWHID <persistent-identifiers>`,
which is specific to Software Heritage. As such, it includes:
* the external identifier, stored as bytes whose format is opaque to the
data model
* a type (a simple name and a version), to identify the type of relationship
* the "target", which is a core SWHID
An extid may also include a "payload", which is arbitrary data about the
relationship. For example, an extid might link a directory to the
cryptographic hash of the tarball that originally contained it. In this
case, the payload could include data useful for reconstructing the
original tarball from the directory. The payload data is stored
separately. An extid refers to it by its ``sha1_git`` hash.
**raw extrinsic metadata**
an opaque bytestring, along with its format (a simple name), an identifier
of the object the metadata is about and in which context (similar to a
`qualified SWHID <persistent-identifiers>`), and provenance information
(the authority who provided it, the fetcher tool used to get it, and the
data it was discovered at).
It provides both a way to store information about an artifact contributed by
external entities, after the artifact was created, and an escape hatch to
store metadata that would not otherwise fit in the data model.
.. _swh-model: .. _swh-model:
Software Heritage - Data model .. include:: README.rst
==============================
Implementation of the :ref:`data-model` to archive source code artifacts.
.. toctree:: .. toctree::
:caption: Overview: :caption: Overview:
...@@ -12,4 +9,12 @@ Implementation of the :ref:`data-model` to archive source code artifacts. ...@@ -12,4 +9,12 @@ Implementation of the :ref:`data-model` to archive source code artifacts.
data-model data-model
persistent-identifiers persistent-identifiers
cli cli
/apidoc/swh.model
.. only:: standalone_package_doc
Indices and tables
------------------
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
.. _persistent-identifiers: .. _persistent-identifiers:
.. _swhids:
================================================= =================================================
SoftWare Heritage persistent IDentifiers (SWHIDs) SoftWare Heritage persistent IDentifiers (SWHIDs)
================================================= =================================================
**version 1.5, last modified 2020-05-14** **version 1.6, last modified 2021-04-30**
.. contents:: .. contents::
:local: :local:
...@@ -45,7 +46,7 @@ properties. Together, these identifiers form a `Merkle structure ...@@ -45,7 +46,7 @@ properties. Together, these identifiers form a `Merkle structure
See the :ref:`Software Heritage data model <data-model>` for an overview of See the :ref:`Software Heritage data model <data-model>` for an overview of
object types and how they are linked together. See object types and how they are linked together. See
:py:mod:`swh.model.identifiers` for details on how the intrinsic identifiers :py:mod:`swh.model.git_objects` for details on how the intrinsic identifiers
embedded in SWHIDs are computed. embedded in SWHIDs are computed.
The optional qualifiers are of two kinds: The optional qualifiers are of two kinds:
...@@ -57,6 +58,7 @@ The optional qualifiers are of two kinds: ...@@ -57,6 +58,7 @@ The optional qualifiers are of two kinds:
from different *origins*, that may evolve between different *visits* from different *origins*, that may evolve between different *visits*
* **fragment qualifiers:** allow to pinpoint specific subparts of an object * **fragment qualifiers:** allow to pinpoint specific subparts of an object
.. _swhids-syntax:
Syntax Syntax
====== ======
...@@ -113,10 +115,12 @@ embeddability of SWHID in other contexts. ...@@ -113,10 +115,12 @@ embeddability of SWHID in other contexts.
.. _RFC 3987: https://tools.ietf.org/html/rfc3987 .. _RFC 3987: https://tools.ietf.org/html/rfc3987
.. _swhids-semantics:
Semantics Semantics
========= =========
.. _swhids-core:
Core identifiers Core identifiers
---------------- ----------------
...@@ -141,27 +145,28 @@ The actual object pointed to is identified by the intrinsic identifier ...@@ -141,27 +145,28 @@ The actual object pointed to is identified by the intrinsic identifier
``<object_id>``, which is a hex-encoded (using lowercase ASCII characters) SHA1 ``<object_id>``, which is a hex-encoded (using lowercase ASCII characters) SHA1
computed on the content and metadata of the object itself, as follows: computed on the content and metadata of the object itself, as follows:
* for **snapshots**, intrinsic identifiers are computed as per * for **snapshots**, intrinsic identifiers are SHA1 hashes of manifests computed as per
:py:func:`swh.model.identifiers.snapshot_identifier` :py:func:`swh.model.git_objects.snapshot_git_object`
* for **releases**, as per * for **releases**, as per
:py:func:`swh.model.identifiers.release_identifier` :py:func:`swh.model.git_objects.release_git_object`
that produces the same result as a git release hash that produces the same result as a git release hash
* for **revisions**, as per * for **revisions**, as per
:py:func:`swh.model.identifiers.revision_identifier` :py:func:`swh.model.git_objects.revision_git_object`
that produces the same result as a git commit hash that produces the same result as a git commit hash
* for **directories**, per * for **directories**, per
:py:func:`swh.model.identifiers.directory_identifier` :py:func:`swh.model.git_objects.directory_git_object`
that produces the same result as a git tree hash that produces the same result as a git tree hash
* for **contents**, the intrinsic identifier is the ``sha1_git`` hash returned by * for **contents**, the intrinsic identifier is the ``sha1_git`` hash returned by
:py:func:`swh.model.identifiers.content_identifier`, i.e., the SHA1 of a byte :py:meth:`swh.hashutil.MultiHash.digest`, i.e., the SHA1 of a byte
sequence obtained by juxtaposing the ASCII string ``"blob"`` (without sequence obtained by juxtaposing the ASCII string ``"blob"`` (without
quotes), a space, the length of the content as decimal digits, a NULL byte, quotes), a space, the length of the content as decimal digits, a NULL byte,
and the actual content of the file. and the actual content of the file.
.. _swhids-qualifiers:
Qualifiers Qualifiers
---------- ----------
...@@ -228,6 +233,24 @@ Note that Git compatibility is incidental and is not guaranteed to be ...@@ -228,6 +233,24 @@ Note that Git compatibility is incidental and is not guaranteed to be
maintained in future versions of this scheme (or Git). maintained in future versions of this scheme (or Git).
Automatically fixing invalid SWHIDs
-----------------------------------
User interfaces may fix invalid SWHIDs, by lower-casing the
``<identifier_core>`` part of a SWHID, if it contains upper-case letters
because of user errors or limitations in software displaying SWHIDs.
However, implementations displaying or generating SWHIDs should not rely
on this behavior, and must display or generate only valid SWHIDs when
technically possible.
User interfaces should show an error when such an automatic fix occurs,
so users have a chance to fix their SWHID before pasting it to an other interface
that does not perform the same corrections.
This also makes it easier to understand issues when a case-sensitive
qualifier has its casing altered.
Examples Examples
======== ========
...@@ -256,35 +279,31 @@ Core identifiers ...@@ -256,35 +279,31 @@ Core identifiers
Identifiers with qualifiers Identifiers with qualifiers
--------------------------- ---------------------------
* The following `SWHID * The following :swh_web:`SWHID
<https://archive.softwareheritage.org/swh:1:cnt:4d99d2d18326621ccdd70f5ea66c2e2ac236ad8b;origin=https://gitorious.org/ocamlp3l/ocamlp3l_cvs.git;visit=swh:1:snp:d7f1b9eb7ccb596c2622c4780febaa02549830f9;anchor=swh:1:rev:2db189928c94d62a3b4757b3eec68f0a4d4113f0;path=/Examples/SimpleFarm/simplefarm.ml;lines=9-15>`_ <swh:1:cnt:4d99d2d18326621ccdd70f5ea66c2e2ac236ad8b;origin=https://gitorious.org/ocamlp3l/ocamlp3l_cvs.git;visit=swh:1:snp:d7f1b9eb7ccb596c2622c4780febaa02549830f9;anchor=swh:1:rev:2db189928c94d62a3b4757b3eec68f0a4d4113f0;path=/Examples/SimpleFarm/simplefarm.ml;lines=9-15>`
denotes the lines 9 to 15 of a file content that can be found at absolute denotes the lines 9 to 15 of a file content that can be found at absolute
path ``/Examples/SimpleFarm/simplefarm.ml`` from the root directory of the path ``/Examples/SimpleFarm/simplefarm.ml`` from the root directory of the
revision ``swh:1:rev:2db189928c94d62a3b4757b3eec68f0a4d4113f0`` that is revision ``swh:1:rev:2db189928c94d62a3b4757b3eec68f0a4d4113f0`` that is
contained in the snapshot contained in the snapshot
``swh:1:snp:d7f1b9eb7ccb596c2622c4780febaa02549830f9`` taken from the origin ``swh:1:snp:d7f1b9eb7ccb596c2622c4780febaa02549830f9`` taken from the origin
``https://gitorious.org/ocamlp3l/ocamlp3l_cvs.git``: ``https://gitorious.org/ocamlp3l/ocamlp3l_cvs.git``::
.. code-block:: url
swh:1:cnt:4d99d2d18326621ccdd70f5ea66c2e2ac236ad8b;
origin=https://gitorious.org/ocamlp3l/ocamlp3l_cvs.git;
visit=swh:1:snp:d7f1b9eb7ccb596c2622c4780febaa02549830f9;
anchor=swh:1:rev:2db189928c94d62a3b4757b3eec68f0a4d4113f0;
path=/Examples/SimpleFarm/simplefarm.ml;
lines=9-15
* Here is an example of a `SWHID swh:1:cnt:4d99d2d18326621ccdd70f5ea66c2e2ac236ad8b;
<https://archive.softwareheritage.org/swh:1:cnt:f10371aa7b8ccabca8479196d6cd640676fd4a04;origin=https://github.com/web-platform-tests/wpt;visit=swh:1:snp:b37d435721bbd450624165f334724e3585346499;anchor=swh:1:rev:259d0612af038d14f2cd889a14a3adb6c9e96d96;path=/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/x%3Burl=foo/>`_ origin=https://gitorious.org/ocamlp3l/ocamlp3l_cvs.git;
with a file path that requires percent-escaping: visit=swh:1:snp:d7f1b9eb7ccb596c2622c4780febaa02549830f9;
anchor=swh:1:rev:2db189928c94d62a3b4757b3eec68f0a4d4113f0;
path=/Examples/SimpleFarm/simplefarm.ml;
lines=9-15
.. code-block:: url * Here is an example of a :swh_web:`SWHID
<swh:1:cnt:f10371aa7b8ccabca8479196d6cd640676fd4a04;origin=https://github.com/web-platform-tests/wpt;visit=swh:1:snp:b37d435721bbd450624165f334724e3585346499;anchor=swh:1:rev:259d0612af038d14f2cd889a14a3adb6c9e96d96;path=/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/x%253Burl=foo/>`
with a file path that requires percent-escaping::
swh:1:cnt:f10371aa7b8ccabca8479196d6cd640676fd4a04; swh:1:cnt:f10371aa7b8ccabca8479196d6cd640676fd4a04;
origin=https://github.com/web-platform-tests/wpt; origin=https://github.com/web-platform-tests/wpt;
visit=swh:1:snp:b37d435721bbd450624165f334724e3585346499; visit=swh:1:snp:b37d435721bbd450624165f334724e3585346499;
anchor=swh:1:rev:259d0612af038d14f2cd889a14a3adb6c9e96d96; anchor=swh:1:rev:259d0612af038d14f2cd889a14a3adb6c9e96d96;
path=/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/x%3Burl=foo/ path=/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/x%3Burl=foo/
Implementation Implementation
...@@ -299,11 +318,14 @@ it can be *computed from the object itself*, without having to rely on any ...@@ -299,11 +318,14 @@ it can be *computed from the object itself*, without having to rely on any
third party. An implementation of SWHID that allows to do so locally is the third party. An implementation of SWHID that allows to do so locally is the
`swh identify <https://docs.softwareheritage.org/devel/swh-model/cli.html>`_ `swh identify <https://docs.softwareheritage.org/devel/swh-model/cli.html>`_
tool, available from the `swh.model <https://pypi.org/project/swh.model/>`_ tool, available from the `swh.model <https://pypi.org/project/swh.model/>`_
Python package under the GPL license. Python package under the GPL license. This package can be installed via the ``pip``
package manager with the one liner ``pip3 install swh.model[cli]`` on any machine with
Python (at least version 3.7) and ``pip`` installed (on a Debian or Ubuntu system a simple ``apt install python3 python3-pip``
will suffice, see `the general instructions <https://packaging.python.org/tutorials/installing-packages/>`_ for other platforms).
SWHIDs are also automatically computed by Software Heritage for all archived SWHIDs are also automatically computed by Software Heritage for all archived
objects as part of its archival activity, and can be looked up via the project objects as part of its archival activity, and can be looked up via the project
`Web interface <https://archive.softwareheritage.org>`_. :swh_web:`Web interface <>`.
This has various practical implications: This has various practical implications:
...@@ -316,6 +338,25 @@ This has various practical implications: ...@@ -316,6 +338,25 @@ This has various practical implications:
archival on Software Heritage archival on Software Heritage
Choosing what type of SWHID to use
----------------------------------
``swh:1:dir:`` SWHIDs are the most robust SWHIDs, as they can be recomputed from
the simplest objects (a directory structure on a filesystem), even when all
metadata is lost, without relying on the Software Heritage archive.
Therefore, we advise implementers and users to prefer this type of SWHIDs
over ``swh:1:rev:`` and ``swh:1:rel:`` to reference a source code artifacts.
However, since keeping the metadata is also important, you should add an anchor
qualifier to ``swh:1:dir:`` SWHIDs whenever possible, so the metadata stored
in the Software Heritage archive can be retrieved when needed.
This means, for example, that you should prefer
``swh:1:dir:a8eded6a2d062c998ba2dcc3dcb0ce68a4e15a58;anchor=swh:1:rel:22ece559cc7cc2364edc5e5593d63ae8bd229f9f``
over ``swh:1:rel:22ece559cc7cc2364edc5e5593d63ae8bd229f9f``.
Resolvers Resolvers
--------- ---------
...@@ -323,25 +364,25 @@ Resolvers ...@@ -323,25 +364,25 @@ Resolvers
Software Heritage resolver Software Heritage resolver
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~
SWHIDs can be resolved using the Software Heritage `Web interface SWHIDs can be resolved using the Software Heritage :swh_web:`Web interface <>`.
<https://archive.softwareheritage.org>`_. In particular, the **root endpoint** In particular, the **root endpoint**
``/`` can be given a SWHID and will lead to the browsing page of the ``/`` can be given a SWHID and will lead to the browsing page of the
corresponding object, like this: corresponding object, like this:
``https://archive.softwareheritage.org/<identifier>``. ``https://archive.softwareheritage.org/<identifier>``.
A **dedicated** ``/resolve`` **endpoint** of the Software Heritage `Web API A **dedicated** ``/resolve`` **endpoint** of the Software Heritage :swh_web:`Web API
<https://archive.softwareheritage.org/api/>`_ is also available to <api/>` is also available to
programmatically resolve SWHIDs; see: :http:get:`/api/1/resolve/(swhid)/`. programmatically resolve SWHIDs; see: :http:get:`/api/1/resolve/(swhid)/`.
Examples: Examples:
* `<https://archive.softwareheritage.org/swh:1:cnt:94a9ed024d3859793618152ea559a168bbcbb5e2>`_ * :swh_web:`swh:1:cnt:94a9ed024d3859793618152ea559a168bbcbb5e2`
* `<https://archive.softwareheritage.org/swh:1:dir:d198bc9d7a6bcf6db04f476d29314f157507d505>`_ * :swh_web:`swh:1:dir:d198bc9d7a6bcf6db04f476d29314f157507d505`
* `<https://archive.softwareheritage.org/api/1/resolve/swh:1:rev:309cf2674ee7a0749978cf8265ab91a60aea0f7d>`_ * :swh_web:`api/1/resolve/swh:1:rev:309cf2674ee7a0749978cf8265ab91a60aea0f7d`
* `<https://archive.softwareheritage.org/api/1/resolve/swh:1:rel:22ece559cc7cc2364edc5e5593d63ae8bd229f9f>`_ * :swh_web:`api/1/resolve/swh:1:rel:22ece559cc7cc2364edc5e5593d63ae8bd229f9f`
* `<https://archive.softwareheritage.org/api/1/resolve/swh:1:snp:c7c108084bc0bf3d81436bf980b46e98bd338453>`_ * :swh_web:`api/1/resolve/swh:1:snp:c7c108084bc0bf3d81436bf980b46e98bd338453`
* `<https://archive.softwareheritage.org/swh:1:cnt:4d99d2d18326621ccdd70f5ea66c2e2ac236ad8b;origin=https://gitorious.org/ocamlp3l/ocamlp3l_cvs.git;visit=swh:1:snp:d7f1b9eb7ccb596c2622c4780febaa02549830f9;anchor=swh:1:rev:2db189928c94d62a3b4757b3eec68f0a4d4113f0;path=/Examples/SimpleFarm/simplefarm.ml;lines=9-15>`_ * :swh_web:`swh:1:cnt:4d99d2d18326621ccdd70f5ea66c2e2ac236ad8b;origin=https://gitorious.org/ocamlp3l/ocamlp3l_cvs.git;visit=swh:1:snp:d7f1b9eb7ccb596c2622c4780febaa02549830f9;anchor=swh:1:rev:2db189928c94d62a3b4757b3eec68f0a4d4113f0;path=/Examples/SimpleFarm/simplefarm.ml;lines=9-15`
* `<https://archive.softwareheritage.org/swh:1:cnt:f10371aa7b8ccabca8479196d6cd640676fd4a04;origin=https://github.com/web-platform-tests/wpt;visit=swh:1:snp:b37d435721bbd450624165f334724e3585346499;anchor=swh:1:rev:259d0612af038d14f2cd889a14a3adb6c9e96d96;path=/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/x%3Burl=foo/>`_ * :swh_web:`swh:1:cnt:f10371aa7b8ccabca8479196d6cd640676fd4a04;origin=https://github.com/web-platform-tests/wpt;visit=swh:1:snp:b37d435721bbd450624165f334724e3585346499;anchor=swh:1:rev:259d0612af038d14f2cd889a14a3adb6c9e96d96;path=/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/x%253Burl=foo/`
Third-party resolvers Third-party resolvers
...@@ -367,7 +408,7 @@ Examples: ...@@ -367,7 +408,7 @@ Examples:
* `<https://n2t.net/swh:1:rel:22ece559cc7cc2364edc5e5593d63ae8bd229f9f>`_ * `<https://n2t.net/swh:1:rel:22ece559cc7cc2364edc5e5593d63ae8bd229f9f>`_
* `<https://n2t.net/swh:1:snp:c7c108084bc0bf3d81436bf980b46e98bd338453>`_ * `<https://n2t.net/swh:1:snp:c7c108084bc0bf3d81436bf980b46e98bd338453>`_
* `<https://n2t.net/swh:1:cnt:4d99d2d18326621ccdd70f5ea66c2e2ac236ad8b;origin=https://gitorious.org/ocamlp3l/ocamlp3l_cvs.git;visit=swh:1:snp:d7f1b9eb7ccb596c2622c4780febaa02549830f9;anchor=swh:1:rev:2db189928c94d62a3b4757b3eec68f0a4d4113f0;path=/Examples/SimpleFarm/simplefarm.ml;lines=9-15>`_ * `<https://n2t.net/swh:1:cnt:4d99d2d18326621ccdd70f5ea66c2e2ac236ad8b;origin=https://gitorious.org/ocamlp3l/ocamlp3l_cvs.git;visit=swh:1:snp:d7f1b9eb7ccb596c2622c4780febaa02549830f9;anchor=swh:1:rev:2db189928c94d62a3b4757b3eec68f0a4d4113f0;path=/Examples/SimpleFarm/simplefarm.ml;lines=9-15>`_
* `<https://n2t.net/swh:1:cnt:f10371aa7b8ccabca8479196d6cd640676fd4a04;origin=https://github.com/web-platform-tests/wpt;visit=swh:1:snp:b37d435721bbd450624165f334724e3585346499;anchor=swh:1:rev:259d0612af038d14f2cd889a14a3adb6c9e96d96;path=/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/x%3Burl=foo/>`_ * `<https://n2t.net/swh:1:cnt:f10371aa7b8ccabca8479196d6cd640676fd4a04;origin=https://github.com/web-platform-tests/wpt;visit=swh:1:snp:b37d435721bbd450624165f334724e3585346499;anchor=swh:1:rev:259d0612af038d14f2cd889a14a3adb6c9e96d96;path=/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/x%25253Burl=foo/>`_
References References
......
[mypy]
namespace_packages = True
warn_unused_ignores = True
# 3rd party libraries without stubs (yet)
[mypy-attrs_strict.*] # a bit sad, but...
ignore_missing_imports = True
[mypy-deprecated.*]
ignore_missing_imports = True
[mypy-django.*] # false positive, only used my hypotesis' extras
ignore_missing_imports = True
[mypy-dulwich.*]
ignore_missing_imports = True
[mypy-iso8601.*]
ignore_missing_imports = True
[mypy-pkg_resources.*]
ignore_missing_imports = True
[mypy-pyblake2.*]
ignore_missing_imports = True
[mypy-pytest.*]
ignore_missing_imports = True
[project]
name = "swh.model"
authors = [
{name="Software Heritage developers", email="swh-devel@inria.fr"},
]
description = "Software Heritage data model"
readme = {file = "README.rst", content-type = "text/x-rst"}
requires-python = ">=3.7"
classifiers = [
"Programming Language :: Python :: 3",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Operating System :: OS Independent",
"Development Status :: 5 - Production/Stable",
]
dynamic = ["version", "dependencies", "optional-dependencies"]
[tool.setuptools.packages.find]
include = ["swh.*"]
[tool.setuptools.dynamic]
dependencies = {file = ["requirements.txt"]}
[tool.setuptools.dynamic.optional-dependencies]
cli = {file = "requirements-cli.txt"}
testing = {file = ["requirements-cli.txt", "requirements-test.txt"]}
testing_minimal = {file = "requirements-test.txt"}
[project.entry-points.console_scripts]
"swh.identify" = "swh.model.cli:identify"
[project.entry-points."swh.cli.subcommands"]
"swh.model" = "swh.model.cli"
[project.urls]
"Homepage" = "https://gitlab.softwareheritage.org/swh/devel/swh-model"
"Bug Reports" = "https://gitlab.softwareheritage.org/swh/devel/swh-model/-/issues"
"Funding" = "https://www.softwareheritage.org/donate"
"Documentation" = "https://docs.softwareheritage.org/devel/swh-model/"
"Source" = "https://gitlab.softwareheritage.org/swh/devel/swh-model.git"
[build-system]
requires = ["setuptools", "setuptools-scm"]
build-backend = "setuptools.build_meta"
[tool.setuptools_scm]
fallback_version = "0.0.1"
[tool.black] [tool.black]
target-version = ['py37'] target-version = ['py39', 'py310', 'py311', 'py312']
[tool.isort]
multi_line_output = 3
include_trailing_comma = true
force_grid_wrap = 0
use_parentheses = true
ensure_newline_before_comments = true
line_length = 88
force_sort_within_sections = true
known_first_party = ['swh']
[tool.mypy]
namespace_packages = true
warn_unused_ignores = true
explicit_package_bases = true
# ^ Needed for mypy to detect py.typed from swh packages installed
# in editable mode
plugins = []
# 3rd party libraries without stubs (yet)
# [[tool.mypy.overrides]]
# module = [
# "package1.*",
# "package2.*",
# ]
# ignore_missing_imports = true
[tool.flake8]
select = ["C", "E", "F", "W", "B950"]
ignore = [
"E203", # whitespaces before ':' <https://github.com/psf/black/issues/315>
"E231", # missing whitespace after ','
"E501", # line too long, use B950 warning from flake8-bugbear instead
"W503" # line break before binary operator <https://github.com/psf/black/issues/52>
]
max-line-length = 88
[tool.pytest.ini_options]
addopts = "--doctest-modules -p no:pytest_swh_core"
norecursedirs = "build docs .*"
asyncio_mode = "strict"
consider_namespace_packages = true
markers = [
"requires_optional_deps: tests in test_cli.py that should not run if optional dependencies are not installed",
]
[pytest]
addopts = --doctest-modules
norecursedirs = docs
markers =
fs: tests that involve filesystem ios
swh.core swh.core >= 0.3
Click Click
dulwich dulwich
Click aiohttp
dulwich click
pytest pytest >= 8.1
pytz pytz
types-click
types-python-dateutil
types-pytz
types-deprecated