diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 667fb8f6952498c710f7aefbb586ab35d3d87274..4b2ba24d114f9be8e37f46aa159fad822b018e94 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,19 +1,21 @@ +exclude: ^swh/deposit/tests/data/atom/.*$ + repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.3.0 hooks: - id: trailing-whitespace - id: check-json - id: check-yaml - - repo: https://gitlab.com/pycqa/flake8 - rev: 4.0.1 + - repo: https://github.com/pycqa/flake8 + rev: 5.0.4 hooks: - id: flake8 - additional_dependencies: [flake8-bugbear==22.3.23] + additional_dependencies: [flake8-bugbear==22.9.23] - repo: https://github.com/codespell-project/codespell - rev: v2.1.0 + rev: v2.2.2 hooks: - id: codespell name: Check source code spelling @@ -31,11 +33,11 @@ repos: types: [python] - repo: https://github.com/PyCQA/isort - rev: 5.10.1 + rev: 5.11.5 hooks: - id: isort - repo: https://github.com/python/black - rev: 22.3.0 + rev: 22.10.0 hooks: - id: black diff --git a/PKG-INFO b/PKG-INFO index f3b69f5f4f89d14147d05ee47febeeb2b5fb5467..1c8b6bc3a5739957182900caa8002d213f833257 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: swh.deposit -Version: 1.2.0 +Version: 1.2.1 Summary: Software Heritage Deposit Server Home-page: https://forge.softwareheritage.org/source/swh-deposit/ Author: Software Heritage developers @@ -37,7 +37,7 @@ Description ----------- Most of the software source code artifacts present in the SWH Archive are gathered by -the mean of :term:`loader <loader>` workers run by the SWH project from sourve code +the mean of :term:`loader <loader>` workers run by the SWH project from source code origins identified by :term:`lister <lister>` workers. This is a pull mechanism: it's the responsibility of the SWH project to gather and collect source code artifacts that way. diff --git a/README.rst b/README.rst index 669519c560bd266f3060d3c93acd50405e758503..c9dc6efaca0b2a1abaa8b154dd9cbed1489c95a2 100644 --- a/README.rst +++ b/README.rst @@ -14,7 +14,7 @@ Description ----------- Most of the software source code artifacts present in the SWH Archive are gathered by -the mean of :term:`loader <loader>` workers run by the SWH project from sourve code +the mean of :term:`loader <loader>` workers run by the SWH project from source code origins identified by :term:`lister <lister>` workers. This is a pull mechanism: it's the responsibility of the SWH project to gather and collect source code artifacts that way. diff --git a/docs/README.rst b/docs/README.rst index 669519c560bd266f3060d3c93acd50405e758503..c9dc6efaca0b2a1abaa8b154dd9cbed1489c95a2 100644 --- a/docs/README.rst +++ b/docs/README.rst @@ -14,7 +14,7 @@ Description ----------- Most of the software source code artifacts present in the SWH Archive are gathered by -the mean of :term:`loader <loader>` workers run by the SWH project from sourve code +the mean of :term:`loader <loader>` workers run by the SWH project from source code origins identified by :term:`lister <lister>` workers. This is a pull mechanism: it's the responsibility of the SWH project to gather and collect source code artifacts that way. diff --git a/docs/api/metadata.rst b/docs/api/metadata.rst index 6319c7b7cdd48bc6a572660a83a1da28217d8b41..2e94b70025d6905f8d59e60b42db953eeb596eac 100644 --- a/docs/api/metadata.rst +++ b/docs/api/metadata.rst @@ -104,7 +104,7 @@ Using Atom with CodeMeta <codemeta:identifier> article id </codemeta:identifier> </codemeta:referencePublication> <codemeta:isPartOf> - <codemeta:type> Collaboration/Projet </codemeta:type> + <codemeta:type> Collaboration/Project </codemeta:type> <codemeta:name> project name</codemeta:name> <codemeta:identifier> id </codemeta:identifier> </codemeta:isPartOf> diff --git a/docs/api/register-account.rst b/docs/api/register-account.rst index 5d7f2258eeebe501670ee1bed1f55660c4ca753f..f37cece2af9e10b38fd855eac80c318afc81bafd 100644 --- a/docs/api/register-account.rst +++ b/docs/api/register-account.rst @@ -15,9 +15,9 @@ As a deposit client ------------------- For this, as a client, you need to register an account on the swh keycloak `production -<https://archive.softwareheritage.org/oidc/login/?next_path=https://archive.softwareheritage.org/>`_ +<https://archive.softwareheritage.org/oidc/login/>`_ or `staging -<https://webapp.staging.swh.network/oidc/login/?next_path=https://webapp.staging.swh.network/>`_ +<https://webapp.staging.swh.network/oidc/login/>`_ instance. .. _swh-deposit-register-account-as-sysadm: diff --git a/docs/index.rst b/docs/index.rst index bc7e90039461b51d3ea6111e24894fe48d7c90e3..551263a7ac2bad7ebfdf1d9f3211183f0571eea3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -18,4 +18,12 @@ Reference Documentation :maxdepth: 2 cli - /apidoc/swh.deposit + +.. only:: standalone_package_doc + + Indices and tables + ------------------ + + * :ref:`genindex` + * :ref:`modindex` + * :ref:`search` diff --git a/docs/specs/protocol-reference.rst b/docs/specs/protocol-reference.rst index f02ea0fa5270177ebfc0cf2054e0a59bbd9abc3c..98986ec2144ec9f848711722c4006f637d90bcbf 100644 --- a/docs/specs/protocol-reference.rst +++ b/docs/specs/protocol-reference.rst @@ -144,11 +144,30 @@ of Software Heritage. While CodeMeta is designed for use in JSON-LD, it is easy to reuse its vocabulary and embed it in an XML document, in three steps: -1. use the JSON-LD compact representation of the CodeMeta document -2. replace ``@context`` declarations with XML namespaces -3. unfold JSON lists to sibling XML subtrees - -For example, this CodeMeta document: +1. use the `JSON-LD compact representation`_ of the CodeMeta document with + ``@context: "https://doi.org/10.5063/SCHEMA/CODEMETA-2.0"`` and no other context; + which implies that: + + 1. Codemeta properties (whether in the ``https://codemeta.github.io/terms/`` + or ``http://schema.org/`` namespaces) are unprefixed terms + 2. other properties in the ``http://schema.org/`` namespace use `compact IRIs`_ + with the ``schema`` prefix + 3. other properties are absolute +2. replace ``@context`` declarations with a XMLNS declaration with + ``https://doi.org/10.5063/SCHEMA/CODEMETA-2.0`` as namespace + (eg. ``xmlns="https://doi.org/10.5063/SCHEMA/CODEMETA-2.0"`` + or ``xmlns:codemeta="https://doi.org/10.5063/SCHEMA/CODEMETA-2.0"``) +3. if using a non-default namespace, apply its prefix to any unprefixed term + (ie. any term defined in https://doi.org/10.5063/SCHEMA/CODEMETA-2.0 ) +4. add XMLNS declarations for any other prefix (eg. ``xmlns:schema="http://schema.org/"`` + if any property in that namespace is used) +5. unfold JSON lists to sibling XML subtrees + +.. _JSON-LD compact representation: https://www.w3.org/TR/json-ld11/#compacted-document-form +.. _compact IRIs: https://www.w3.org/TR/json-ld11/#compact-iris + +Example Codemeta document +""""""""""""""""""""""""" .. code:: json @@ -201,6 +220,56 @@ Or, equivalently: </entry> +Note that in both these examples, ``codemeta:name`` is used even though +the property is actually ``http://schema.org/name``. + +Example generic JSON-LD document +"""""""""""""""""""""""""""""""" + +Another example using properties not part of Codemeta: + +.. code:: json + + { + "@context": "https://doi.org/10.5063/SCHEMA/CODEMETA-2.0", + "name": "My Software", + "schema:sameAs": "http://example.org/my-software" + } + +which is equivalent to: + +.. code:: json + + { + "@context": "https://doi.org/10.5063/SCHEMA/CODEMETA-2.0", + "name": "My Software", + "http://schema.org/sameAs": "http://example.org/my-software" + } + +becomes this XML document: + +.. code:: xml + + <?xml version="1.0"?> + <atom:entry xmlns:atom="http://www.w3.org/2005/Atom" + xmlns="https://doi.org/10.5063/SCHEMA/CODEMETA-2.0" + xmlns:schema="http://schema.org/"> + <name>My Software</name> + <schema:sameAs>http://example.org/my-software</schema:sameAs> + </atom:entry> + +Or, equivalently: + +.. code:: xml + + <?xml version="1.0"?> + <entry xmlns="http://www.w3.org/2005/Atom" + xmlns:codemeta="https://doi.org/10.5063/SCHEMA/CODEMETA-2.0" + xmlns:schema="http://schema.org/"> + <codemeta:name>My Software</codemeta:name> + <schema:sameAs>http://example.org/my-software</schema:sameAs> + </entry> + .. _mandatory-attributes: Mandatory attributes diff --git a/docs/specs/spec-loading.rst b/docs/specs/spec-loading.rst index 29b29ab0d0bbd0b371ad5dc434c9069348e1e528..c1420b4c091c48a949a769a25318e9b2ad655c33 100644 --- a/docs/specs/spec-loading.rst +++ b/docs/specs/spec-loading.rst @@ -63,15 +63,16 @@ For examples: .. code-block:: bash - $ http -pb https://archive.softwareheritage.org/api/1/origin/https://hal.archives-ouvertes.fr/hal-02560320/get/ + $ http -pb https://archive.softwareheritage.org/api/1/origin/https://hal.archives-ouvertes.fr/hal-01883795/get/ would result in: .. code-block:: json { - "origin_visits_url": "https://archive.softwareheritage.org/api/1/origin/https://hal.archives-ouvertes.fr/hal-02560320/visits/", - "url": "https://hal.archives-ouvertes.fr/hal-02560320" + "url": "https://hal.archives-ouvertes.fr/hal-01883795", + "origin_visits_url": "https://archive.softwareheritage.org/api/1/origin/https://hal.archives-ouvertes.fr/hal-01883795/visits/", + "metadata_authorities_url": "https://archive.softwareheritage.org/api/1/raw-extrinsic-metadata/swhid/swh:1:ori:0094225e66277f3b2de66155b3cb30ca25f12565/authorities/" } @@ -85,7 +86,7 @@ For examples: .. code-block:: bash - $ http -pb https://archive.softwareheritage.org/api/1/origin/https://hal.archives-ouvertes.fr/hal-02560320/visits/ + $ http -pb https://archive.softwareheritage.org/api/1/origin/https://hal.archives-ouvertes.fr/hal-01883795/visits/ would result in: @@ -93,30 +94,29 @@ would result in: [ { - "date": "2020-05-14T11:59:55.942964+00:00", + "date": "2023-03-29T12:12:08.960810+00:00", "metadata": {}, - "origin": "https://hal.archives-ouvertes.fr/hal-02560320", - "origin_visit_url": "https://archive.softwareheritage.org/api/1/origin/https://hal.archives-ouvertes.fr/hal-02560320/visit/2/", - "snapshot": "e5e82d064a9c3df7464223042e0c55d72ccff7f0", - "snapshot_url": "https://archive.softwareheritage.org/api/1/snapshot/e5e82d064a9c3df7464223042e0c55d72ccff7f0/", + "origin": "https://hal.archives-ouvertes.fr/hal-01883795", + "origin_visit_url": "https://archive.softwareheritage.org/api/1/origin/https://hal.archives-ouvertes.fr/hal-01883795/visit/2/", + "snapshot": "e59379a4f88c297066e964703893c23b08264ec8", + "snapshot_url": "https://archive.softwareheritage.org/api/1/snapshot/e59379a4f88c297066e964703893c23b08264ec8/", "status": "full", "type": "deposit", "visit": 2 }, { - "date": "2020-05-14T11:59:41.094260+00:00", + "date": "2019-01-10T12:30:26.326411+00:00", "metadata": {}, - "origin": "https://hal.archives-ouvertes.fr/hal-02560320", - "origin_visit_url": "https://archive.softwareheritage.org/api/1/origin/https://hal.archives-ouvertes.fr/hal-02560320/visit/1/", - "snapshot": "3e95ef6e04c381a34cc2f314576bc5644f2c797f", - "snapshot_url": "https://archive.softwareheritage.org/api/1/snapshot/3e95ef6e04c381a34cc2f314576bc5644f2c797f/", + "origin": "https://hal.archives-ouvertes.fr/hal-01883795", + "origin_visit_url": "https://archive.softwareheritage.org/api/1/origin/https://hal.archives-ouvertes.fr/hal-01883795/visit/1/", + "snapshot": "fd1b8fc1bdd3ebeac913eb6dd377a646a3149747", + "snapshot_url": "https://archive.softwareheritage.org/api/1/snapshot/fd1b8fc1bdd3ebeac913eb6dd377a646a3149747/", "status": "full", "type": "deposit", "visit": 1 } ] - Snapshot artifact ~~~~~~~~~~~~~~~~~ @@ -127,7 +127,7 @@ For example: .. code-block:: bash - $ http -pb https://archive.softwareheritage.org/api/1/snapshot/3e95ef6e04c381a34cc2f314576bc5644f2c797f/ + $ http -pb https://archive.softwareheritage.org/api/1/snapshot/e59379a4f88c297066e964703893c23b08264ec8/ would result in: @@ -136,26 +136,45 @@ would result in: { "branches": { "HEAD": { - "target": "2122424b547a8eca9282ba3131ec61ff1d8df7d4", - "target_type": "revision", - "target_url": "https://archive.softwareheritage.org/api/1/revision/2122424b547a8eca9282ba3131ec61ff1d8df7d4/" + "target": "fc8e44c5bb3fabe81e5ebe46ac013a2510271616", + "target_type": "release", + "target_url": "https://archive.softwareheritage.org/api/1/release/fc8e44c5bb3fabe81e5ebe46ac013a2510271616/" } }, - "id": "3e95ef6e04c381a34cc2f314576bc5644f2c797f", + "id": "e59379a4f88c297066e964703893c23b08264ec8", "next_branch": null } -Note that previous versions of the deposit-loader named the branch ``master`` -instead, and created release branches under certain conditions. +Note that previous versions of the deposit-loader created a release instead of a revision. +For example: -Release artifact -~~~~~~~~~~~~~~~~ -.. warning:: +.. code-block:: bash + + http -pb https://archive.softwareheritage.org/api/1/snapshot/fd1b8fc1bdd3ebeac913eb6dd377a646a3149747/ + +resulted in: + +.. code-block:: json + + { + "branches": { + "master": { + "target": "66ff08f00acc06131fe610be0f9878a6c78bfe44", + "target_type": "revision", + "target_url": "https://archive.softwareheritage.org/api/1/revision/66ff08f00acc06131fe610be0f9878a6c78bfe44/" + } + }, + "id": "fd1b8fc1bdd3ebeac913eb6dd377a646a3149747", + "next_branch": null + } + +Even older versions named the branch ``master`` instead of ``HEAD``, and created +release branches (pointing to revisions) under certain conditions. - This part of the specification is not implemented yet, only revisions are - currently being created. +Release artifact +~~~~~~~~~~~~~~~~ The content is deposited with a set of descriptive metadata in the CodeMeta vocabulary. The following CodeMeta terms implies that the @@ -169,9 +188,9 @@ If present, a release artifact will be created with the mapping below: +-------------------+-----------------------------------+-----------------+----------------+ | SWH release field | Description | CodeMeta term | Fallback value | +===================+===================================+=================+================+ -| target | revision containing all metadata | X |X | +| target | directory containing all metadata | X |X | +-------------------+-----------------------------------+-----------------+----------------+ -| target_type | revision | X |X | +| target_type | directory | X |X | +-------------------+-----------------------------------+-----------------+----------------+ | name | release or tag name (mandatory) | softwareVersion | X | +-------------------+-----------------------------------+-----------------+----------------+ @@ -183,31 +202,36 @@ If present, a release artifact will be created with the mapping below: +-------------------+-----------------------------------+-----------------+----------------+ +.. code-block:: bash + + http -pb https://archive.softwareheritage.org/api/1/release/fc8e44c5bb3fabe81e5ebe46ac013a2510271616/ + .. code-block:: json { - "release": { - "author": { - "email": "hal@ccsd.cnrs.fr", - "fullname": "HAL <phal@ccsd.cnrs.fr>", - "name": "HAL" - }, - "author_url": "/api/1/person/x/", - "date": "2019-05-27T16:28:33+02:00", - "id": "a9f3396f372ed4a51d75e15ca16c1c2df1fc5c97", - "message": "AffectationRO Version 1.1 - added new feature\n", - "name": "1.1", - "synthetic": true, - "target": "396b1ff29f7c75a0a3cc36f30e24ff7bae70bb52", - "target_type": "revision", - "target_url": "/api/1/revision/396b1ff29f7c75a0a3cc36f30e24ff7bae70bb52/" - } + "author": { + "email": "robot@softwareheritage.org", + "fullname": "Software Heritage", + "name": "Software Heritage" + }, + "date": "2021-01-01T00:00:00+00:00", + "id": "fc8e44c5bb3fabe81e5ebe46ac013a2510271616", + "message": "hal: Deposit 2753 in collection hal\n\n- Replace qmake with CMake.- Fix bugs.- Move repository.\n", + "name": "HEAD", + "synthetic": true, + "target": "7057a716afab8ca80728aa7c6c2cc4bd03b0f45b", + "target_type": "directory", + "target_url": "https://archive.softwareheritage.org/api/1/directory/7057a716afab8ca80728aa7c6c2cc4bd03b0f45b/" } Revision artifact ~~~~~~~~~~~~~~~~~ +.. note:: + + Revision artifacts are no longer created by the deposit. + The metadata sent with the deposit is stored outside the revision, and does not affect the hash computation. It contains the same fields as any revision object; in particular: @@ -229,6 +253,81 @@ It contains the same fields as any revision object; in particular: | committer_date | see below | +-------------------+-----------------------------------------+ +.. code-block:: bash + + http -pb https://archive.softwareheritage.org/api/1/revision/66ff08f00acc06131fe610be0f9878a6c78bfe44/ + +.. code-block:: json + + { + "author": { + "email": "robot@softwareheritage.org", + "fullname": "Software Heritage", + "name": "Software Heritage" + }, + "committer": { + "email": "robot@softwareheritage.org", + "fullname": "Software Heritage", + "name": "Software Heritage" + }, + "committer_date": "2019-01-10T12:27:59.639536+00:00", + "date": "2019-01-10T12:27:59.639536+00:00", + "directory": "70c73de7d406938315d6cf30bf87bb9eb480017e", + "directory_url": "https://archive.softwareheritage.org/api/1/directory/70c73de7d406938315d6cf30bf87bb9eb480017e/", + "extra_headers": [], + "history_url": "https://archive.softwareheritage.org/api/1/revision/66ff08f00acc06131fe610be0f9878a6c78bfe44/log/", + "id": "66ff08f00acc06131fe610be0f9878a6c78bfe44", + "merge": false, + "message": "hal: Deposit 225 in collection hal", + "metadata": { + "@xmlns": "http://www.w3.org/2005/Atom", + "@xmlns:codemeta": "https://doi.org/10.5063/SCHEMA/CODEMETA-2.0", + "author": { + "email": "hal@ccsd.cnrs.fr", + "name": "HAL" + }, + "client": "hal", + "codemeta:applicationCategory": "sdu.ocean", + "codemeta:author": { + "codemeta:affiliation": "LaMP", + "codemeta:name": "D. Picard" + }, + "codemeta:codeRepository": "https://forge.clermont-universite.fr/git/libszdist", + "codemeta:dateCreated": "2018-09-28T16:58:05+02:00", + "codemeta:description": "libszdist is a C++ library and command line tools that implement the algorithm used to process the data of instruments called SMPS/DMPS. These instruments measure the size distribution of aerosol particles. The algorithm is known as ''inversion''.", + "codemeta:developmentStatus": "Actif", + "codemeta:keywords": "SMPS,DMPS,Aerosol Size Distribution", + "codemeta:license": { + "codemeta:name": "GNU GPLv3" + }, + "codemeta:name": "libszdist", + "codemeta:operatingSystem": [ + "Linux", + "Windows", + "Mac OS X", + "ARM" + ], + "codemeta:programmingLanguage": "C++", + "codemeta:runtimePlatform": [ + "qmake", + "gcc" + ], + "codemeta:softwareVersion": "v.0.10.4", + "codemeta:url": "https://hal.archives-ouvertes.fr/hal-01883795", + "codemeta:version": "1", + "committer": "David Picard", + "external_identifier": "hal-01883795", + "id": "hal-01883795" + }, + "parents": [], + "synthetic": true, + "type": "tar", + "url": "https://archive.softwareheritage.org/api/1/revision/66ff08f00acc06131fe610be0f9878a6c78bfe44/" + } + +Note that the metadata field is deprecated. The "extrinsic metadata" endpoints described +below should be used instead. + The date mapping ^^^^^^^^^^^^^^^^ @@ -276,117 +375,49 @@ A release contains one date: | date |release date = publication date | datePublished | reception_date | +-------------------+----------------------------------+----------------+-----------------+ - -.. code-block:: json - - { - "revision": { - "author": { - "email": "robot@softwareheritage.org", - "fullname": "Software Heritage", - "id": 18233048, - "name": "Software Heritage" - }, - "author_url": "/api/1/person/18233048/", - "committer": { - "email": "robot@softwareheritage.org", - "fullname": "Software Heritage", - "id": 18233048, - "name": "Software Heritage" - }, - "committer_date": "2019-05-27T16:28:33+02:00", - "committer_url": "/api/1/person/18233048/", - "date": "2012-01-01T00:00:00+00:00", - "directory": "fb13b51abbcfd13de85d9ba8d070a23679576cd7", - "directory_url": "/api/1/directory/fb13b51abbcfd13de85d9ba8d070a23679576cd7/", - "history_url": "/api/1/revision/396b1ff29f7c75a0a3cc36f30e24ff7bae70bb52/log/", - "id": "396b1ff29f7c75a0a3cc36f30e24ff7bae70bb52", - "merge": false, - "message": "hal: Deposit 282 in collection hal", - "metadata": { - "@xmlns": "http://www.w3.org/2005/Atom", - "@xmlns:codemeta": "https://doi.org/10.5063/SCHEMA/CODEMETA-2.0", - "author": { - "email": "hal@ccsd.cnrs.fr", - "name": "HAL" - }, - "codemeta:applicationCategory": "info", - "codemeta:author": { - "codemeta:name": "Morane Gruenpeter" - }, - "codemeta:codeRepository": "www.code-repository.com", - "codemeta:contributor": { - "codemeta:name": "Morane Gruenpeter", - }, - "codemeta:dateCreated": "2012", - "codemeta:datePublished": "2019-05-27T16:28:33+02:00", - "codemeta:description": "description\\_en test v2", - "codemeta:developmentStatus": "Inactif", - "codemeta:keywords": "mot_cle_en,mot_cle_2_en,mot_cle_fr", - "codemeta:license": [ - { - "codemeta:name": "MIT License" - }, - { - "codemeta:name": "CeCILL Free Software License Agreement v1.1" - } - ], - "codemeta:name": "Test\\_20190527\\_01", - "codemeta:operatingSystem": "OS", - "codemeta:programmingLanguage": "Java", - "codemeta:referencePublication": null, - "codemeta:relatedLink": null, - "codemeta:releaseNotes": "releaseNote", - "codemeta:runtimePlatform": "outil", - "codemeta:softwareVersion": "1.0.1", - "codemeta:url": "https://hal.archives-ouvertes.fr/hal-02140606", - "codemeta:version": "2", - "id": "hal-02140606", - "original_artifact": [ - { - "archive_type": "zip", - "blake2s256": "96be3ddedfcee9669ad9c42b0bb3a706daf23824d04311c63505a4d8db02df00", - "length": 193072, - "name": "archive.zip", - "sha1": "5b6ecc9d5bb113ff69fc275dcc9b0d993a8194f1", - "sha1_git": "bd10e4d3ede17162692d7e211e08e87e67994488", - "sha256": "3e2ce93384251ce6d6da7b8f2a061a8ebdaf8a28b8d8513223ca79ded8a10948" - } - ] - }, - "parents": [ - { - "id": "a9fdc3937d2b704b915852a64de2ab1b4b481003", - "url": "/api/1/revision/a9fdc3937d2b704b915852a64de2ab1b4b481003/" - } - ], - "synthetic": true, - "type": "tar", - "url": "/api/1/revision/396b1ff29f7c75a0a3cc36f30e24ff7bae70bb52/" - } - } - Directory artifact ~~~~~~~~~~~~~~~~~~ The directory artifact is the archive(s)' raw content deposited. -.. code-block:: json +.. code-block:: bash - { - "directory": [ - { - "dir_id": "fb13b51abbcfd13de85d9ba8d070a23679576cd7", - "length": null, - "name": "AffectationRO", - "perms": 16384, - "target": "fbc418f9ac2c39e8566b04da5dc24b14e65b23b1", - "target_url": "/api/1/directory/fbc418f9ac2c39e8566b04da5dc24b14e65b23b1/", - "type": "dir" - } - ] - } + http -pb https://archive.softwareheritage.org/api/1/directory/7057a716afab8ca80728aa7c6c2cc4bd03b0f45b/ + +.. code-block:: json + [ + { + "checksums": { + "sha1": "cadfc0e77c0119a025a5ed45d07f71df4071f645", + "sha1_git": "b89214f14acaca84efb65ff6542cb5d790b6ac5c", + "sha256": "47c165ad20425a13f65ebd9db61447363bb9cf3ce0b0fa4418d9cfc951f157e3" + }, + "dir_id": "7057a716afab8ca80728aa7c6c2cc4bd03b0f45b", + "length": 150, + "name": ".gitignore", + "perms": 33188, + "status": "visible", + "target": "b89214f14acaca84efb65ff6542cb5d790b6ac5c", + "target_url": "https://archive.softwareheritage.org/api/1/content/sha1_git:b89214f14acaca84efb65ff6542cb5d790b6ac5c/", + "type": "file" + }, + { + "checksums": { + "sha1": "816fde05704e5b7c8a744044949b9f7944702993", + "sha1_git": "de6f1f373a44be2b16232b2ff9744f31fe7e3715", + "sha256": "09585c721573beadc56a98754745f9381c15626f6471b7da18475366e4e8f2cb" + }, + "dir_id": "7057a716afab8ca80728aa7c6c2cc4bd03b0f45b", + "length": 51, + "name": "AUTHORS", + "perms": 33188, + "status": "visible", + "target": "de6f1f373a44be2b16232b2ff9744f31fe7e3715", + "target_url": "https://archive.softwareheritage.org/api/1/content/sha1_git:de6f1f373a44be2b16232b2ff9744f31fe7e3715/", + "type": "file" + } + ] Questions raised concerning loading ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -472,3 +503,120 @@ Metadata loading - ``authority`` is computed from the deposit client information, and ``fetcher`` is the deposit loader. + +They can be queried using the directory SWHID. + +First, we need to get the list of authorities which published metadata on this directory: + +.. code-block:: bash + + http -pb https://archive.softwareheritage.org/api/1/raw-extrinsic-metadata/swhid/swh:1:dir:7057a716afab8ca80728aa7c6c2cc4bd03b0f45b/authorities/ + +.. code-block:: json + + [ + { + "metadata_list_url": "https://archive.softwareheritage.org/api/1/raw-extrinsic-metadata/swhid/swh:1:dir:7057a716afab8ca80728aa7c6c2cc4bd03b0f45b/?authority=deposit_client%20https://hal.archives-ouvertes.fr/", + "type": "deposit_client", + "url": "https://hal.archives-ouvertes.fr/" + }, + { + "metadata_list_url": "https://archive.softwareheritage.org/api/1/raw-extrinsic-metadata/swhid/swh:1:dir:7057a716afab8ca80728aa7c6c2cc4bd03b0f45b/?authority=registry%20https://softwareheritage.org/", + "type": "registry", + "url": "https://softwareheritage.org/" + } + ] + +The former is HAL, the latter is Software Heritage itself (to provide attestation of tarball checksums). +We can get the list of metadata provided by HAL: + + +.. code-block:: bash + + http -pb https://archive.softwareheritage.org/api/1/raw-extrinsic-metadata/swhid/swh:1:dir:7057a716afab8ca80728aa7c6c2cc4bd03b0f45b/\?authority\=deposit_client%20https://hal.archives-ouvertes.fr/ + +.. code-block:: json + + [ + { + "authority": { + "type": "deposit_client", + "url": "https://hal.archives-ouvertes.fr/" + }, + "discovery_date": "2023-03-29T12:11:53+00:00", + "fetcher": { + "name": "swh-deposit", + "version": "1.1.0" + }, + "format": "sword-v2-atom-codemeta-v2", + "metadata_url": "https://archive.softwareheritage.org/api/1/raw-extrinsic-metadata/get/c65992f8f3efe416ccf2666f8ff09753ea94377d/?filename=swh:1:dir:7057a716afab8ca80728aa7c6c2cc4bd03b0f45b_metadata", + "origin": "https://hal.archives-ouvertes.fr/hal-01883795", + "release": "swh:1:rel:fc8e44c5bb3fabe81e5ebe46ac013a2510271616", + "target": "swh:1:dir:7057a716afab8ca80728aa7c6c2cc4bd03b0f45b" + } + ] + +and finally, we got the URL to the metadata blob itself: + +.. code-block:: bash + + http -pb https://archive.softwareheritage.org/api/1/raw-extrinsic-metadata/get/c65992f8f3efe416ccf2666f8ff09753ea94377d/\?filename\=swh:1:dir:7057a716afab8ca80728aa7c6c2cc4bd03b0f45b_metadata + +.. code-block:: xml + + <?xml version="1.0" encoding="utf-8"?> + <entry xmlns="http://www.w3.org/2005/Atom" xmlns:codemeta="https://doi.org/10.5063/SCHEMA/CODEMETA-2.0" xmlns:schema="http://schema.org/" xmlns:swh="https://www.softwareheritage.org/schema/2018/deposit"> + <id>hal-01883795</id> + <swh:deposit> + <swh:create_origin> + <swh:origin url="https://hal.archives-ouvertes.fr/hal-01883795"/> + </swh:create_origin> + <swh:metadata-provenance> + <schema:url>https://hal.archives-ouvertes.fr/hal-01883795</schema:url> + </swh:metadata-provenance> + </swh:deposit> + <author> + <name>HAL</name> + <email>hal@ccsd.cnrs.fr</email> + </author> + <codemeta:name>libszdist</codemeta:name> + <codemeta:description>libszdist is a C++ library and command line tools that implement the algorithm used to process the data of instruments called SMPS/DMPS. These instruments measure the size distribution of aerosol particles. The algorithm is known as ''inversion''.</codemeta:description> + <codemeta:dateCreated>2021-01-01</codemeta:dateCreated> + <codemeta:datePublished>2023-03-16</codemeta:datePublished> + <codemeta:license> + <codemeta:name>GNU GPLv3</codemeta:name> + </codemeta:license> + <schema:identifier> + <codemeta:type>schema:PropertyValue</codemeta:type> + <schema:propertyID>HAL-ID</schema:propertyID> + <schema:value>hal-01883795</schema:value> + </schema:identifier> + <codemeta:applicationCategory>sdu.ocean</codemeta:applicationCategory> + <codemeta:keywords>SMPS,DMPS,Aerosol Size Distribution,MPSS</codemeta:keywords> + <codemeta:institution>CNRS</codemeta:institution> + <codemeta:codeRepository>https://forge.clermont-universite.fr/git/libszdist</codemeta:codeRepository> + <codemeta:relatedLink>https://gitlab.in2p3.fr/david.picard/libszdist</codemeta:relatedLink> + <codemeta:programmingLanguage>C++</codemeta:programmingLanguage> + <codemeta:runtimePlatform>gcc</codemeta:runtimePlatform> + <codemeta:runtimePlatform>CMake</codemeta:runtimePlatform> + <codemeta:operatingSystem>Linux</codemeta:operatingSystem> + <codemeta:operatingSystem>Windows</codemeta:operatingSystem> + <codemeta:operatingSystem>Mac OS X</codemeta:operatingSystem> + <codemeta:operatingSystem>ARM</codemeta:operatingSystem> + <codemeta:operatingSystem>PC</codemeta:operatingSystem> + <codemeta:version>2</codemeta:version> + <codemeta:softwareVersion>v.0.11.1</codemeta:softwareVersion> + <codemeta:dateModified>2023-03-24</codemeta:dateModified> + <codemeta:releaseNotes>- Replace qmake with CMake.- Fix bugs.- Move repository.</codemeta:releaseNotes> + <codemeta:developmentStatus>Actif</codemeta:developmentStatus> + <codemeta:author> + <codemeta:name>D. Picard</codemeta:name> + <codemeta:affiliation>LPC</codemeta:affiliation> + <codemeta:affiliation>LaMP</codemeta:affiliation> + </codemeta:author> + <codemeta:contributor> + <codemeta:name>David PICARD</codemeta:name> + </codemeta:contributor> + </entry> + +which is the exact document provided by HAL when uploading the deposit. diff --git a/requirements-server.txt b/requirements-server.txt index 1da85404ac731d6e7ab3c40d5dc274ae7fec7f44..f433b444ac81f0f8f5d5e85a06b47cc5aab81773 100644 --- a/requirements-server.txt +++ b/requirements-server.txt @@ -1,5 +1,5 @@ -django >= 2, < 4 +django djangorestframework -psycopg2 < 2.9 +psycopg2 setuptools xmlschema diff --git a/requirements-swh.txt b/requirements-swh.txt index 07448bc2819fa332d7472d367eb06660cc68a3a9..1d5432fb2d8b4fbb7484e3912f89d87ba4532253 100644 --- a/requirements-swh.txt +++ b/requirements-swh.txt @@ -1,2 +1,3 @@ swh.core[http] >= 0.4 swh.model >= 4.4.0 +swh.scheduler diff --git a/swh.deposit.egg-info/PKG-INFO b/swh.deposit.egg-info/PKG-INFO index f3b69f5f4f89d14147d05ee47febeeb2b5fb5467..1c8b6bc3a5739957182900caa8002d213f833257 100644 --- a/swh.deposit.egg-info/PKG-INFO +++ b/swh.deposit.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: swh.deposit -Version: 1.2.0 +Version: 1.2.1 Summary: Software Heritage Deposit Server Home-page: https://forge.softwareheritage.org/source/swh-deposit/ Author: Software Heritage developers @@ -37,7 +37,7 @@ Description ----------- Most of the software source code artifacts present in the SWH Archive are gathered by -the mean of :term:`loader <loader>` workers run by the SWH project from sourve code +the mean of :term:`loader <loader>` workers run by the SWH project from source code origins identified by :term:`lister <lister>` workers. This is a pull mechanism: it's the responsibility of the SWH project to gather and collect source code artifacts that way. diff --git a/swh.deposit.egg-info/SOURCES.txt b/swh.deposit.egg-info/SOURCES.txt index 23dc3e4b84d7aa6dd9c0ae397096bd7e191f7eb9..de372a3f91c03c1b1b6a27f5122ca9f4cc0312b4 100644 --- a/swh.deposit.egg-info/SOURCES.txt +++ b/swh.deposit.egg-info/SOURCES.txt @@ -185,6 +185,7 @@ swh/deposit/tests/conftest.py swh/deposit/tests/test_backend.py swh/deposit/tests/test_client_module.py swh/deposit/tests/test_common.py +swh/deposit/tests/test_config.py swh/deposit/tests/test_gunicorn_config.py swh/deposit/tests/test_init.py swh/deposit/tests/test_migrations.py diff --git a/swh.deposit.egg-info/requires.txt b/swh.deposit.egg-info/requires.txt index cd826cb66a0d81146908e7a7e03a8af66df655d8..04dcd9c52c624a33d832b6059fae5cf388c8a3f9 100644 --- a/swh.deposit.egg-info/requires.txt +++ b/swh.deposit.egg-info/requires.txt @@ -4,11 +4,12 @@ requests sentry-sdk swh.core[http]>=0.4 swh.model>=4.4.0 +swh.scheduler [server] -django<4,>=2 +django djangorestframework -psycopg2<2.9 +psycopg2 setuptools xmlschema swh.core[http]>=0.4 @@ -31,9 +32,9 @@ djangorestframework-stubs>=1.4 django-test-migrations types-requests types-pyyaml -django<4,>=2 +django djangorestframework -psycopg2<2.9 +psycopg2 setuptools xmlschema swh.core[http]>=0.4 diff --git a/swh/deposit/api/common.py b/swh/deposit/api/common.py index b2a24959c0f72d0a77e922c7e81592070dcf1efb..7e970d0517d396c41c368d847203905de49a3038 100644 --- a/swh/deposit/api/common.py +++ b/swh/deposit/api/common.py @@ -584,15 +584,24 @@ class APIBase(APIConfig, APIView, metaclass=ABCMeta): "in the multipart deposit", ) - filehandler = data["application/zip"] - if not filehandler: - filehandler = data["application/x-tar"] + filehandler = data["application/zip"] or data["application/x-tar"] + if filehandler is None: + raise DepositError( + BAD_REQUEST, + "You must provide an archive, either as application/zip or " + "application/x-tar", + ) assert isinstance(filehandler, UploadedFile), filehandler self._check_file_length(filehandler) self._check_file_md5sum(filehandler, headers.content_md5sum) + if data["application/atom+xml"] is None: + raise DepositError( + BAD_REQUEST, "You must provide an application/atom+xml entry." + ) + try: raw_metadata, metadata_tree = self._read_metadata( data["application/atom+xml"] @@ -620,7 +629,6 @@ class APIBase(APIConfig, APIView, metaclass=ABCMeta): deposit, deposit_request_data, replace_metadata, replace_archives ) - assert filehandler is not None return Receipt( deposit_id=deposit.id, deposit_date=deposit.reception_date, @@ -1010,9 +1018,7 @@ class APIBase(APIConfig, APIView, metaclass=ABCMeta): if self._client is None: try: - self._client = DepositClient.objects.get( # type: ignore - username=username - ) + self._client = DepositClient.objects.get(username=username) except DepositClient.DoesNotExist: raise DepositError(NOT_FOUND, f"Unknown client name {username}") diff --git a/swh/deposit/api/private/urls.py b/swh/deposit/api/private/urls.py index f9f8357a2a081e541314836204937a77a0453415..a5d29b0ed166216c7d2f71b5cfdfb552aa2e3624 100644 --- a/swh/deposit/api/private/urls.py +++ b/swh/deposit/api/private/urls.py @@ -1,9 +1,9 @@ -# Copyright (C) 2017-2022 The Software Heritage developers +# Copyright (C) 2017-2023 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information -from django.conf.urls import url +from django.urls import re_path as url from ...config import ( PRIVATE_CHECK_DEPOSIT, diff --git a/swh/deposit/api/urls.py b/swh/deposit/api/urls.py index a8b7146baf3bd3943e953b71845a889a541c2ef6..c204c04d2f4869127665069d1c6d18b692ee3bd1 100644 --- a/swh/deposit/api/urls.py +++ b/swh/deposit/api/urls.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017-2021 The Software Heritage developers +# Copyright (C) 2017-2023 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information @@ -7,8 +7,8 @@ """ -from django.conf.urls import url from django.shortcuts import render +from django.urls import re_path as url from ..config import COL_IRI, CONT_FILE_IRI, EDIT_IRI, EM_IRI, SD_IRI, SE_IRI, STATE_IRI from .collection import CollectionAPI diff --git a/swh/deposit/cli/admin.py b/swh/deposit/cli/admin.py index 594ca17723a6859b9ce5ec6c2d4a972685f1f73f..7e0735b500191017d8a5dc62bb01d930f5963b94 100644 --- a/swh/deposit/cli/admin.py +++ b/swh/deposit/cli/admin.py @@ -114,7 +114,7 @@ def user_create( # user create/update try: - user = DepositClient.objects.get(username=username) # type: ignore + user = DepositClient.objects.get(username=username) click.echo(f"Update user '{username}'.") action_done = "updated" except DepositClient.DoesNotExist: @@ -166,7 +166,7 @@ def user_exists(ctx, username: str): from swh.deposit.models import DepositClient try: - DepositClient.objects.get(username=username) # type: ignore + DepositClient.objects.get(username=username) click.echo(f"User {username} exists.") ctx.exit(0) except DepositClient.DoesNotExist: diff --git a/swh/deposit/config.py b/swh/deposit/config.py index 585b3be4c717aae1604412769a1fbe0fc5403aae..aaf2ebd99c7aa95d212f526554c8990f7c0b9ab7 100644 --- a/swh/deposit/config.py +++ b/swh/deposit/config.py @@ -4,7 +4,7 @@ # See top-level LICENSE file for more information import os -from typing import Any, Dict +from typing import Any, Dict, Optional from swh.core import config from swh.deposit import __version__ @@ -58,36 +58,37 @@ DEFAULT_CONFIG = { } -def setup_django_for(platform=None, config_file=None): - """Setup function for command line tools (swh.deposit.create_user) to - initialize the needed db access. +def setup_django_for(platform: Optional[str] = None, config_file: Optional[str] = None): + """Setup function for command line tools (e.g. swh.deposit.create_user) to + initialize the needed db access. Note: Do not import any django related module prior to this function - call. Otherwise, this will raise an - django.core.exceptions.ImproperlyConfigured error message. + call. Otherwise, this will raise a django.core.exceptions.ImproperlyConfigured + error message. Args: - platform (str): the platform the scheduling is running - config_file (str): Extra configuration file (typically for the - production platform) + platform: the platform to use when running program (e.g. cli, ...) + config_file: Extra configuration file (typically for the production platform) Raises: - ValueError in case of wrong platform inputs. + ValueError in case of wrong platform inputs """ if platform is not None: if platform not in AUTHORIZED_PLATFORMS: - raise ValueError("Platform should be one of %s" % AUTHORIZED_PLATFORMS) + raise ValueError(f"Platform should be one of {AUTHORIZED_PLATFORMS}") if "DJANGO_SETTINGS_MODULE" not in os.environ: - os.environ["DJANGO_SETTINGS_MODULE"] = "swh.deposit.settings.%s" % platform + os.environ["DJANGO_SETTINGS_MODULE"] = f"swh.deposit.settings.{platform}" if config_file: + # Hack to set the environment variable which in some cases is required (e.g. + # production) os.environ.setdefault("SWH_CONFIG_FILENAME", config_file) - import django + from django import setup - django.setup() + setup() class APIConfig: diff --git a/swh/deposit/tests/api/test_collection_post_multipart.py b/swh/deposit/tests/api/test_collection_post_multipart.py index 20f1bdb4c60215427d44639860b3711b2fa75f6b..812263e9c3af6dcb28811cb973465b1eed494179 100644 --- a/swh/deposit/tests/api/test_collection_post_multipart.py +++ b/swh/deposit/tests/api/test_collection_post_multipart.py @@ -271,7 +271,7 @@ def test_post_deposit_multipart_put_to_replace_metadata( # FAILURE scenarios -def test_post_deposit_multipart_only_archive_and_atom_entry( +def test_post_deposit_multipart_only_one_archive_and_atom_entry( authenticated_client, deposit_collection ): """Multipart deposit only accepts one archive and one atom+xml""" @@ -391,3 +391,81 @@ def test_post_deposit_multipart_if_upload_size_limit_exceeded( with pytest.raises(Deposit.DoesNotExist): Deposit.objects.get(external_id=external_id) + + +def test_post_deposit_atom_400_multipart_no_atom( + authenticated_client, deposit_collection, atom_dataset, deposit_user, sample_archive +): + """Posting without an atom body should return a 400 response""" + origin_url = "http://example.org/foo" + + archive = InMemoryUploadedFile( + BytesIO(sample_archive["data"]), + field_name=sample_archive["name"], + name=sample_archive["name"], + content_type="application/x-tar", + size=sample_archive["length"], + charset=None, + ) + + atom_data = atom_dataset["entry-data0"] % origin_url + + atom_entry = InMemoryUploadedFile( + BytesIO(atom_data.encode("utf-8")), + field_name="atom0", + name="atom0", + content_type="application/x-foobar", # should be application/atom+xml + size=len(atom_data), + charset="utf-8", + ) + + response = authenticated_client.post( + reverse(COL_IRI, args=[deposit_collection.name]), + format="multipart", + data={ + "archive": archive, + "atom_entry": atom_entry, + }, + ) + + assert response.status_code == status.HTTP_400_BAD_REQUEST + assert "provide an application/atom+xml entry" in response.content.decode() + + +def test_post_deposit_atom_400_multipart_no_archive( + authenticated_client, deposit_collection, atom_dataset, deposit_user, sample_archive +): + """Posting without an atom body should return a 400 response""" + origin_url = "http://example.org/foo" + + archive = InMemoryUploadedFile( + BytesIO(sample_archive["data"]), + field_name=sample_archive["name"], + name=sample_archive["name"], + content_type="application/x-foobar", # should be application/x-tar + size=sample_archive["length"], + charset=None, + ) + + atom_data = atom_dataset["entry-data0"] % origin_url + + atom_entry = InMemoryUploadedFile( + BytesIO(atom_data.encode("utf-8")), + field_name="atom0", + name="atom0", + content_type="application/atom+xml", + size=len(atom_data), + charset="utf-8", + ) + + response = authenticated_client.post( + reverse(COL_IRI, args=[deposit_collection.name]), + format="multipart", + data={ + "archive": archive, + "atom_entry": atom_entry, + }, + ) + + assert response.status_code == status.HTTP_400_BAD_REQUEST + assert "provide an archive" in response.content.decode() diff --git a/swh/deposit/tests/conftest.py b/swh/deposit/tests/conftest.py index e858a1214cc1967e3e34f78e8e71bccba1e22a83..5f13a6c64a8098dc864682ebb3ca36e8b45ce71d 100644 --- a/swh/deposit/tests/conftest.py +++ b/swh/deposit/tests/conftest.py @@ -264,7 +264,7 @@ def _create_deposit_user( user_data_d = deepcopy(user_data) user_data_d.pop("collection", None) passwd = user_data_d.pop("password", None) - user, _ = DepositClient.objects.get_or_create( # type: ignore + user, _ = DepositClient.objects.get_or_create( username=user_data_d["username"], defaults={**user_data_d, "collections": [collection.id]}, ) diff --git a/swh/deposit/tests/test_config.py b/swh/deposit/tests/test_config.py new file mode 100644 index 0000000000000000000000000000000000000000..82fd404aa5ef6c2ae3b36600dd190f38fba761a3 --- /dev/null +++ b/swh/deposit/tests/test_config.py @@ -0,0 +1,38 @@ +# Copyright (C) 2022 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information + +import os + +import pytest + +from swh.deposit.config import setup_django_for + + +def test_setup_django_for_raise_unknown_platform(): + """Unknown platform should make the function setup raise""" + with pytest.raises(ValueError, match="Platform should be"): + setup_django_for(platform="unknown") + + +def test_setup_django__for_set_django_settings_module(monkeypatch, deposit_config_path): + monkeypatch.delenv("DJANGO_SETTINGS_MODULE") + platform = "testing" + setup_django_for(platform) + + assert os.environ["DJANGO_SETTINGS_MODULE"] == f"swh.deposit.settings.{platform}" + + +def test_setup_django_for_ok_set_django_settings_module( + monkeypatch, deposit_config_path +): + monkeypatch.delenv("SWH_CONFIG_FILENAME") + setup_django_for("testing", deposit_config_path) + + assert os.environ["SWH_CONFIG_FILENAME"] == deposit_config_path + + +def test_setup_django_for_ok(deposit_config_path): + """Everything is fine, moving along (fixture sets environment appropriately)""" + setup_django_for() diff --git a/swh/deposit/urls.py b/swh/deposit/urls.py index 64aee5607ade9280c2867b96648c9e11056607ae..36eb3a1dff696282133624642c6656f45b5c759c 100644 --- a/swh/deposit/urls.py +++ b/swh/deposit/urls.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017-2021 The Software Heritage developers +# Copyright (C) 2017-2023 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information @@ -10,8 +10,9 @@ from __future__ import annotations from typing import Sequence, Union -from django.conf.urls import include, url +from django.conf.urls import include from django.shortcuts import render +from django.urls import re_path as url from django.views.generic.base import RedirectView from rest_framework.urlpatterns import format_suffix_patterns diff --git a/tox.ini b/tox.ini index dcdc31082f7ba851ebb6e763d37454664af8e860..52e042f0b4e6ec3893d2b31aa0176ad70fc9fe53 100644 --- a/tox.ini +++ b/tox.ini @@ -1,4 +1,6 @@ [tox] +requires = + tox>4 envlist=flake8,mypy,py3-django2,py3-django3 [testenv] @@ -22,15 +24,16 @@ commands = [testenv:black] skip_install = true deps = - black==22.3.0 + black==22.10.0 commands = {envpython} -m black --check swh [testenv:flake8] skip_install = true deps = - flake8==4.0.1 - flake8-bugbear==22.3.23 + flake8==5.0.4 + flake8-bugbear==22.9.23 + pycodestyle==2.9.1 commands = {envpython} -m flake8 \ --exclude=.tox,.git,__pycache__,.tox,.eggs,*.egg,swh/deposit/migrations @@ -40,7 +43,7 @@ setenv = DJANGO_SETTINGS_MODULE=swh.deposit.settings.testing extras = testing deps = - mypy==0.942 + mypy==1.0.1 commands = mypy swh @@ -48,14 +51,13 @@ commands = # git HEAD of swh-docs, is executed on CI for each diff to prevent # breaking doc build [testenv:sphinx] -whitelist_externals = make +allowlist_externals = make usedevelop = true extras = testing deps = # fetch and install swh-docs in develop mode - -e git+https://forge.softwareheritage.org/source/swh-docs#egg=swh.docs - + -e git+https://gitlab.softwareheritage.org/swh/devel/swh-docs.git\#egg=swh.docs setenv = SWH_PACKAGE_DOC_TOX_BUILD = 1 # turn warnings into errors @@ -63,18 +65,16 @@ setenv = commands = make -I ../.tox/sphinx/src/swh-docs/swh/ -C docs - # build documentation only inside swh-environment using local state # of swh-docs package [testenv:sphinx-dev] -whitelist_externals = make +allowlist_externals = make usedevelop = true extras = testing deps = # install swh-docs in develop mode -e ../swh-docs - setenv = SWH_PACKAGE_DOC_TOX_BUILD = 1 # turn warnings into errors