Skip to content

Commit b3faffb

Browse files
committed
Added support for parsing citation.cff files
Parses citation files containing information about citing software/dataset. Added tests to validate the parser. Added documentation for citation.cff in list of supported package parsers. fixes #3580 Check comments for mapping of keys between citation.cff and models.py Signed-off-by: Zumitify <sumitpagar123@gmail.com>
1 parent 8de1e90 commit b3faffb

6 files changed

Lines changed: 306 additions & 0 deletions

File tree

docs/source/reference/available_package_parsers.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ parsers in scancode-toolkit during documentation builds.
141141
- ``chrome_crx``
142142
- JavaScript
143143
- https://chrome.google.com/extensions
144+
* - Citation File Format
145+
- ``*.cff``
146+
- ``citation``
147+
- ``citation_cff``
148+
- None
149+
- https://citation-file-format.github.io/
144150
* - Cocoapods Podfile
145151
- ``*Podfile``
146152
- ``cocoapods``

src/packagedcode/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from packagedcode import debian
2121
from packagedcode import debian_copyright
2222
from packagedcode import distro
23+
from packagedcode import citation
2324
from packagedcode import conda
2425
from packagedcode import cocoapods
2526
from packagedcode import cran
@@ -74,6 +75,8 @@
7475
cocoapods.PodfileLockHandler,
7576
cocoapods.PodfileHandler,
7677

78+
citation.CitationHandler,
79+
7780
conda.CondaYamlHandler,
7881
conda.CondaMetaYamlHandler,
7982

src/packagedcode/citation.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#
2+
# Copyright (c) nexB Inc. and others. All rights reserved.
3+
# ScanCode is a trademark of nexB Inc.
4+
# SPDX-License-Identifier: Apache-2.0
5+
# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
6+
# See https://github.com/nexB/scancode-toolkit for support or download.
7+
# See https://aboutcode.org for more information about nexB OSS projects.
8+
#
9+
10+
import io
11+
import saneyaml
12+
from packagedcode import models
13+
14+
"""
15+
Handle CITATION.cff files, see https://citation-file-format.github.io/
16+
https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md
17+
18+
See https://github.com/citation-file-format/citation-file-format/tree/main/examples/1.2.0/pass for examples.
19+
"""
20+
21+
class CitationHandler(models.DatafileHandler):
22+
datasource_id = 'citation_cff'
23+
default_package_type = 'citation'
24+
path_patterns = ('*/CITATION.cff',)
25+
description = 'Citation file format'
26+
documentation_url = 'https://citation-file-format.github.io/'
27+
28+
@classmethod
29+
def parse(cls, location):
30+
metayaml = get_cff_data(location)
31+
title = metayaml.get('title')
32+
abstract = metayaml.get('abstract')
33+
keywords = metayaml.get('keywords')
34+
release_date = metayaml.get('date-released')
35+
# This is the version of the software/item and not cff-version
36+
version = metayaml.get('version')
37+
parties = []
38+
authors = metayaml.get('authors')
39+
if authors:
40+
for author in authors:
41+
name = author.get('family-names') or author.get('name')
42+
email = author.get('email')
43+
url = author.get('orcid')
44+
parties.append(models.Party(
45+
name=name,
46+
email=email,
47+
url=url
48+
))
49+
repository_homepage_url = metayaml.get('repository')
50+
repository_download_url = metayaml.get('repository-code')
51+
extracted_license_statement = metayaml.get('license')
52+
homepage_url = metayaml.get('url')
53+
54+
yield models.PackageData(
55+
datasource_id=cls.datasource_id,
56+
type=cls.default_package_type,
57+
name=title,
58+
description=abstract,
59+
keywords=keywords,
60+
release_date=release_date,
61+
parties=parties,
62+
version=version,
63+
repository_homepage_url=repository_homepage_url,
64+
repository_download_url=repository_download_url,
65+
extracted_license_statement=extracted_license_statement,
66+
homepage_url=homepage_url
67+
)
68+
69+
70+
def get_cff_data(location):
71+
"""
72+
Return a mapping of yaml/cff data loaded from a CITATION.cff files.
73+
"""
74+
75+
# TODO: Should this be Jinja-based?
76+
yaml_lines = []
77+
with io.open(location, encoding='utf-8') as citationcff:
78+
for line in citationcff:
79+
if not line:
80+
continue
81+
yaml_lines.append(line)
82+
83+
return saneyaml.load('\n'.join(yaml_lines))
84+
85+
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# This CITATION.cff file was created by ruby-cff (v 1.1.0).
2+
# Added few changes to help with testing.
3+
# Gem: https://rubygems.org/gems/cff
4+
# CFF: https://citation-file-format.github.io/
5+
# Link: https://github.com/citation-file-format/ruby-cff/blob/main/CITATION.cff
6+
7+
cff-version: 1.2.0
8+
message: If you use ruby-cff in your work, please cite it using the following metadata
9+
title: Ruby CFF Library
10+
type: software
11+
abstract: This library provides a Ruby interface to manipulate Citation File Format files
12+
authors:
13+
- family-names: Haines
14+
given-names: Robert
15+
orcid: https://orcid.org/0000-0002-9538-7919
16+
affiliation: The University of Manchester, UK
17+
- name: The Ruby Citation File Format Developers
18+
email: abc@developer.com
19+
keywords:
20+
- ruby
21+
- credit
22+
- software citation
23+
- research software
24+
- software sustainability
25+
- metadata
26+
- citation file format
27+
- CFF
28+
version: 1.1.0
29+
doi: 10.5281/zenodo.1184077
30+
date-released: 2023-04-10
31+
license: Apache-2.0
32+
url: https://rubygems.org/
33+
repository: https://github.com/citation-file-format/
34+
repository-artifact: https://rubygems.org/gems/cff
35+
repository-code: https://github.com/citation-file-format/ruby-cff
36+
references:
37+
- type: software
38+
title: Citation File Format
39+
authors:
40+
- family-names: Druskat
41+
given-names: Stephan
42+
orcid: https://orcid.org/0000-0003-4925-7248
43+
- family-names: Spaaks
44+
given-names: Jurriaan H.
45+
orcid: https://orcid.org/0000-0002-7064-4069
46+
- family-names: Chue Hong
47+
given-names: Neil
48+
orcid: https://orcid.org/0000-0002-8876-7606
49+
- family-names: Haines
50+
given-names: Robert
51+
orcid: https://orcid.org/0000-0002-9538-7919
52+
- family-names: Baker
53+
given-names: James
54+
orcid: https://orcid.org/0000-0002-2682-6922
55+
- family-names: Bliven
56+
given-names: Spencer
57+
orcid: https://orcid.org/0000-0002-1200-1698
58+
email: spencer.bliven@gmail.com
59+
- family-names: Willighagen
60+
given-names: Egon
61+
orcid: https://orcid.org/0000-0001-7542-0286
62+
- family-names: Pérez-Suárez
63+
given-names: David
64+
orcid: https://orcid.org/0000-0003-0784-6909
65+
website: https://dpshelio.github.io
66+
- family-names: Konovalov
67+
given-names: Alexander
68+
orcid: https://orcid.org/0000-0001-5299-3292
69+
identifiers:
70+
- type: doi
71+
value: 10.5281/zenodo.1003149
72+
description: The concept DOI for the collection containing all versions of the Citation File Format.
73+
- type: doi
74+
value: 10.5281/zenodo.5171937
75+
description: The versioned DOI for the version 1.2.0 of the Citation File Format.
76+
keywords:
77+
- citation file format
78+
- CFF
79+
- citation files
80+
- software citation
81+
- file format
82+
- YAML
83+
- software sustainability
84+
- research software
85+
- credit
86+
abstract: CITATION.cff files are plain text files with human- and machine-readable citation information for software. Code developers can include them in their repositories to let others know how to correctly cite their software. This is the specification for the Citation File Format.
87+
date-released: 2021-08-09
88+
license: CC-BY-4.0
89+
version: 1.2.0
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
[
2+
{
3+
"type": "citation",
4+
"namespace": null,
5+
"name": "Ruby CFF Library",
6+
"version": "1.1.0",
7+
"qualifiers": {},
8+
"subpath": null,
9+
"primary_language": null,
10+
"description": "This library provides a Ruby interface to manipulate Citation File Format files",
11+
"release_date": "2023-04-10",
12+
"parties": [
13+
{
14+
"type": null,
15+
"role": null,
16+
"name": "Haines",
17+
"email": null,
18+
"url": "https://orcid.org/0000-0002-9538-7919"
19+
},
20+
{
21+
"type": null,
22+
"role": null,
23+
"name": "The Ruby Citation File Format Developers",
24+
"email": "abc@developer.com",
25+
"url": null
26+
}
27+
],
28+
"keywords": [
29+
"ruby",
30+
"credit",
31+
"software citation",
32+
"research software",
33+
"software sustainability",
34+
"metadata",
35+
"citation file format",
36+
"CFF"
37+
],
38+
"homepage_url": "https://rubygems.org/",
39+
"download_url": null,
40+
"size": null,
41+
"sha1": null,
42+
"md5": null,
43+
"sha256": null,
44+
"sha512": null,
45+
"bug_tracking_url": null,
46+
"code_view_url": null,
47+
"vcs_url": null,
48+
"copyright": null,
49+
"holder": null,
50+
"declared_license_expression": "apache-2.0",
51+
"declared_license_expression_spdx": "Apache-2.0",
52+
"license_detections": [
53+
{
54+
"license_expression": "apache-2.0",
55+
"matches": [
56+
{
57+
"score": 100.0,
58+
"start_line": 1,
59+
"end_line": 1,
60+
"matched_length": 3,
61+
"match_coverage": 100.0,
62+
"matcher": "1-hash",
63+
"license_expression": "apache-2.0",
64+
"rule_identifier": "spdx_license_id_apache-2.0_for_apache-2.0.RULE",
65+
"rule_relevance": 100,
66+
"rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/spdx_license_id_apache-2.0_for_apache-2.0.RULE",
67+
"matched_text": "Apache-2.0"
68+
}
69+
],
70+
"identifier": "apache_2_0-d66ab77d-a5cc-7104-e702-dc7df61fe9e8"
71+
}
72+
],
73+
"other_license_expression": null,
74+
"other_license_expression_spdx": null,
75+
"other_license_detections": [],
76+
"extracted_license_statement": "Apache-2.0",
77+
"notice_text": null,
78+
"source_packages": [],
79+
"file_references": [],
80+
"extra_data": {},
81+
"dependencies": [],
82+
"repository_homepage_url": "https://github.com/citation-file-format/",
83+
"repository_download_url": "https://github.com/citation-file-format/ruby-cff",
84+
"api_data_url": null,
85+
"datasource_id": "citation_cff",
86+
"purl": "pkg:citation/Ruby%20CFF%20Library@1.1.0"
87+
}
88+
]
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#
2+
# Copyright (c) nexB Inc. and others. All rights reserved.
3+
# ScanCode is a trademark of nexB Inc.
4+
# SPDX-License-Identifier: Apache-2.0
5+
# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
6+
# See https://github.com/nexB/scancode-toolkit for support or download.
7+
# See https://aboutcode.org for more information about nexB OSS projects.
8+
#
9+
10+
import os
11+
12+
from packages_test_utils import PackageTester
13+
from packagedcode import citation
14+
from scancode_config import REGEN_TEST_FIXTURES
15+
16+
17+
class TestCitation(PackageTester):
18+
#test_data_dir = os.path.join(os.path.dirname(__file__), 'data')
19+
20+
def test_get_cff_data(self):
21+
test_file = self.get_test_loc('citation/CITATION.cff')
22+
results = citation.get_cff_data(test_file)
23+
assert list(results.items())[0] == ((u'cff-version', u'1.2.0')) \
24+
and (list(results.items())[8]) == (u'doi',
25+
u'10.5281/zenodo.1184077')
26+
27+
def test_citationcff_is_package_data_file(self):
28+
test_file = self.get_test_loc('citation/CITATION.cff')
29+
assert citation.CitationHandler.is_datafile(test_file)
30+
31+
def test_parse(self):
32+
test_file = self.get_test_loc('citation/CITATION.cff')
33+
package = citation.CitationHandler.parse(test_file)
34+
expected_loc = self.get_test_loc('citation/citation.cff.expected.json')
35+
self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES)

0 commit comments

Comments
 (0)