diff --git a/requirements.txt b/requirements.txt --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ pyld xmltodict typing-extensions +python-debian diff --git a/swh/indexer/metadata_dictionary/R.py b/swh/indexer/metadata_dictionary/R.py new file mode 100644 --- /dev/null +++ b/swh/indexer/metadata_dictionary/R.py @@ -0,0 +1,48 @@ +from debian.deb822 import Deb822 + +from swh.indexer.codemeta import CROSSWALK_TABLE + +from .base import DictMapping, SingleFileMapping + + +def parse_debian_control(s): + metadata = {} + for paragraph in Deb822.iter_paragraphs(s): + metadata.update(**paragraph) + + return metadata + + +class RDescriptionMapping(DictMapping, SingleFileMapping): + """Dedicated class for ...""" + + name = "description" + filename = b"DESCRIPTION" + mapping = CROSSWALK_TABLE["R Package Description"] + + string_fields = [ + "URL", + "SystemRequirements", + "Date", + "License", + "Description", + "Package", + "Title", + "givenName", + "familyName", + "Suggests", + "Maintainer", + "BugReports", + ] + + def translate(self, raw_content): + raw_content = raw_content.decode() + content_dict = parse_debian_control(raw_content) + content_dict["Suggests"] = content_dict["Suggests"].replace(",", "").split() + content_dict["Imports"] = content_dict["Imports"].replace(",", "").split() + content_dict["Collate"] = ( + content_dict["Collate"].replace(",", "").replace("'", "").split() + ) + + # print (content_dict) + return self._translate_dict(content_dict) diff --git a/swh/indexer/metadata_dictionary/__init__.py b/swh/indexer/metadata_dictionary/__init__.py --- a/swh/indexer/metadata_dictionary/__init__.py +++ b/swh/indexer/metadata_dictionary/__init__.py @@ -2,7 +2,7 @@ import click -from . import cff, codemeta, maven, npm, python, ruby +from . import R, cff, codemeta, maven, npm, python, ruby MAPPINGS = { "CodemetaMapping": codemeta.CodemetaMapping, @@ -11,6 +11,7 @@ "PythonPkginfoMapping": python.PythonPkginfoMapping, "GemspecMapping": ruby.GemspecMapping, "CffMapping": cff.CffMapping, + "RDescriptionMapping": R.RDescriptionMapping, } diff --git a/swh/indexer/storage/__init__.py b/swh/indexer/storage/__init__.py --- a/swh/indexer/storage/__init__.py +++ b/swh/indexer/storage/__init__.py @@ -38,7 +38,15 @@ INDEXER_CFG_KEY = "indexer_storage" -MAPPING_NAMES = ["cff", "codemeta", "gemspec", "maven", "npm", "pkg-info"] +MAPPING_NAMES = [ + "cff", + "codemeta", + "description", + "gemspec", + "maven", + "npm", + "pkg-info", +] SERVER_IMPLEMENTATIONS: Dict[str, str] = { diff --git a/swh/indexer/tests/storage/test_storage.py b/swh/indexer/tests/storage/test_storage.py --- a/swh/indexer/tests/storage/test_storage.py +++ b/swh/indexer/tests/storage/test_storage.py @@ -1584,7 +1584,7 @@ assert result == { "per_mapping": { "cff": 0, - "gemspec": 1, + "description" "gemspec": 1, "npm": 2, "pkg-info": 1, "codemeta": 0, diff --git a/swh/indexer/tests/test_cli.py b/swh/indexer/tests/test_cli.py --- a/swh/indexer/tests/test_cli.py +++ b/swh/indexer/tests/test_cli.py @@ -89,6 +89,7 @@ [ "cff", "codemeta", + "description", "gemspec", "maven", "npm", diff --git a/swh/indexer/tests/test_metadata.py b/swh/indexer/tests/test_metadata.py --- a/swh/indexer/tests/test_metadata.py +++ b/swh/indexer/tests/test_metadata.py @@ -67,6 +67,7 @@ self.pkginfo_mapping = MAPPINGS["PythonPkginfoMapping"]() self.gemspec_mapping = MAPPINGS["GemspecMapping"]() self.cff_mapping = MAPPINGS["CffMapping"]() + self.description_mapping = MAPPINGS["RDescriptionMapping"]() def test_compute_metadata_none(self): """ @@ -162,6 +163,97 @@ # then self.assertEqual(expected, result) + def test_compute_metadata_description(self): + """ + testing DESCRIPTION translation + """ + # given + content = """Package: desc +Title: Manipulate DESCRIPTION Files +Version: 1.3.0.9000 +Authors@R: + c(person(given = "Gábor", + family = "Csárdi", + role = c("aut", "cre"), + email = "csardi.gabor@gmail.com"), + person(given = "Kirill", + family = "Müller", + role = "aut"), + person(given = "Jim", + family = "Hester", + role = "aut", + email = "james.f.hester@gmail.com"), + person(given = "Maëlle", + family = "Salmon", + role = "ctb", + comment = c(ORCID = "0000-0002-2815-0399"))) +Maintainer: Gábor Csárdi +Description: Tools to read, write, create, and manipulate DESCRIPTION files. + It is intended for packages that create or manipulate other packages. +License: MIT + file LICENSE +LazyData: true +URL: https://github.com/r-lib/desc#readme +BugReports: https://github.com/r-lib/desc/issues +Depends: + R (>= 3.1.0) +Suggests: + covr, + testthat, + whoami, + withr, + spelling, + gh +Imports: + utils, + R6, + crayon, + rprojroot +Encoding: UTF-8 +RoxygenNote: 7.1.1.9000 +Roxygen: list(r6 = FALSE, load = "installed") +Collate: + 'assertions.R' + 'authors-at-r.R' + 'built.R' + 'classes.R' + 'collate.R' + 'constants.R' + 'deps.R' + 'description.R' + 'encoding.R' + 'latex.R' + 'non-oo-api.R' + 'package-archives.R' + 'read.R' + 'remotes.R' + 'str.R' + 'syntax_checks.R' + 'urls.R' + 'utils.R' + 'validate.R' + 'version.R' +Language: en-US""".encode( + "utf-8" + ) + + expected = { + "@context": "https://doi.org/10.5063/schema/codemeta-2.0", + "type": "SoftwareSourceCode", + "description": """Tools to read, write, create, and manipulate DESCRIPTION files.\n \ +It is intended for packages that create or manipulate other packages.""", + "schema:identifier": "desc", + "schema:license": "MIT + file LICENSE", + "name": "Manipulate DESCRIPTION Files", + "schema:url": "https://github.com/r-lib/desc#readme", + "codemeta:issueTracker": "https://github.com/r-lib/desc/issues", + "maintainer": "G\u00e1bor Cs\u00e1rdi ", + } + + # when + result = self.description_mapping.translate(content) + # then + self.assertEqual(expected, result) + def test_compute_metadata_npm(self): """ testing only computation of metadata with hard_mapping_npm