Skip to content

Commit 237fdfe

Browse files
authored
generate CITATION.cff alongside codemeta (mne-tools#10720)
1 parent a9b139d commit 237fdfe

1 file changed

Lines changed: 108 additions & 16 deletions

File tree

tools/generate_codemeta.py

Lines changed: 108 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,33 @@
11
import os
22
import subprocess
33
from datetime import date
4+
45
from mne import __version__ as release_version
56

6-
# NOTE: ../codemeta.json should not be continuously updated. Run this script
7-
# only at release time.
7+
# NOTE: ../codemeta.json and ../citation.cff should not be continuously
8+
# updated. Run this script only at release time.
9+
10+
package_name = 'MNE-Python'
11+
hard_dependencies = ('numpy', 'scipy')
12+
release_date = str(date.today())
13+
commit = subprocess.run(['git', 'log', '-1', '--pretty=%H'],
14+
capture_output=True, text=True).stdout.strip()
15+
16+
# KEYWORDS
17+
keywords = (
18+
'MEG',
19+
'magnetoencephalography',
20+
'EEG',
21+
'electroencephalography',
22+
'fNIRS',
23+
'functional near-infrared spectroscopy',
24+
'iEEG',
25+
'intracranial EEG',
26+
'eCoG',
27+
'electrocorticography',
28+
'DBS',
29+
'deep brain stimulation'
30+
)
831

932
# add to these as necessary
1033
compound_surnames = (
@@ -66,22 +89,21 @@ def parse_name(name):
6689

6790

6891
# CONSTRUCT JSON AUTHORS LIST
69-
authors = [f'''{{
92+
json_authors = [f'''{{
7093
"@type":"Person",
7194
"email":"{email}",
7295
"givenName":"{first}",
7396
"familyName": "{last}"
7497
}}''' for (first, last, email) in all_names]
7598

7699

77-
# GET OUR DEPENDENCIES
100+
# GET OUR DEPENDENCY VERSIONS
78101
with open(os.path.join('..', 'setup.py'), 'r') as fid:
79102
for line in fid:
80103
if line.strip().startswith('python_requires='):
81104
version = line.strip().split('=', maxsplit=1)[1].strip("'\",")
82105
dependencies = [f'python{version}']
83106
break
84-
hard_dependencies = ('numpy', 'scipy')
85107
with open(os.path.join('..', 'requirements.txt'), 'r') as fid:
86108
for line in fid:
87109
req = line.strip()
@@ -91,8 +113,9 @@ def parse_name(name):
91113

92114

93115
# these must be done outside the boilerplate (no \n allowed in f-strings):
94-
authors = ',\n '.join(authors)
116+
json_authors = ',\n '.join(json_authors)
95117
dependencies = '",\n "'.join(dependencies)
118+
json_keywords = '",\n "'.join(keywords)
96119

97120

98121
# ASSEMBLE COMPLETE JSON
@@ -103,22 +126,17 @@ def parse_name(name):
103126
"codeRepository": "git+https://github.com/mne-tools/mne-python.git",
104127
"dateCreated": "2010-12-26",
105128
"datePublished": "2014-08-04",
106-
"dateModified": "{str(date.today())}",
129+
"dateModified": "{release_date}",
107130
"downloadUrl": "https://github.com/mne-tools/mne-python/archive/v{release_version}.zip",
108131
"issueTracker": "https://github.com/mne-tools/mne-python/issues",
109-
"name": "MNE-Python",
132+
"name": "{package_name}",
110133
"version": "{release_version}",
111-
"description": "MNE-Python is an open-source Python package for exploring, visualizing, and analyzing human neurophysiological data. It provides methods for data input/output, preprocessing, visualization, source estimation, time-frequency analysis, connectivity analysis, machine learning, and statistics.",
134+
"description": "{package_name} is an open-source Python package for exploring, visualizing, and analyzing human neurophysiological data. It provides methods for data input/output, preprocessing, visualization, source estimation, time-frequency analysis, connectivity analysis, machine learning, and statistics.",
112135
"applicationCategory": "Neuroscience",
113136
"developmentStatus": "active",
114137
"referencePublication": "https://doi.org/10.3389/fnins.2013.00267",
115138
"keywords": [
116-
"MEG",
117-
"EEG",
118-
"fNIRS",
119-
"ECoG",
120-
"sEEG",
121-
"DBS"
139+
"{json_keywords}"
122140
],
123141
"programmingLanguage": [
124142
"Python"
@@ -132,7 +150,7 @@ def parse_name(name):
132150
"{dependencies}"
133151
],
134152
"author": [
135-
{authors}
153+
{json_authors}
136154
]
137155
}}
138156
''' # noqa E501
@@ -141,3 +159,77 @@ def parse_name(name):
141159
# WRITE TO FILE
142160
with open(os.path.join('..', 'codemeta.json'), 'w') as codemeta_file:
143161
codemeta_file.write(codemeta_boilerplate)
162+
163+
164+
# # # # # # # # # # # # # # #
165+
# GENERATE CITATION.CFF TOO #
166+
# # # # # # # # # # # # # # #
167+
message = ('If you use this software, please cite both the software itself, '
168+
'and the paper listed in the preferred-citation field.')
169+
170+
# in CFF, multi-word keywords need to be wrapped in quotes
171+
cff_keywords = (f'"{kw}"' if ' ' in kw else kw for kw in keywords)
172+
# make into a bulleted list
173+
cff_keywords = '\n'.join(f' - {kw}' for kw in cff_keywords)
174+
175+
# TODO: someday would be nice to include ORCiD identifiers too
176+
cff_authors = [f' - family-names: {last}\n given-names: {first}'
177+
if first else
178+
f' - name: {last}'
179+
for (first, last, _) in all_names]
180+
cff_authors = '\n'.join(cff_authors)
181+
182+
# this ↓↓↓ is the meta-DOI that always resolves to the latest release
183+
zenodo_doi = '10.5281/zenodo.592483'
184+
185+
# ASSEMBLE THE CFF STRING
186+
cff_boilerplate = f'''\
187+
cff-version: 1.2.0
188+
title: "{package_name}"
189+
message: "{message}"
190+
version: {release_version}
191+
date-released: "{release_date}"
192+
commit: {commit}
193+
doi: {zenodo_doi}
194+
keywords:
195+
{cff_keywords}
196+
authors:
197+
{cff_authors}
198+
preferred-citation:
199+
title: "MEG and EEG Data Analysis with MNE-Python"
200+
journal: "Frontiers in Neuroscience"
201+
type: article
202+
year: 2013
203+
volume: 7
204+
issue: 267
205+
start: 1
206+
end: 13
207+
doi: 10.3389/fnins.2013.00267
208+
authors:
209+
- family-names: Gramfort
210+
given-names: Alexandre
211+
- family-names: Luessi
212+
given-names: Martin
213+
- family-names: Larson
214+
given-names: Eric
215+
- family-names: Engemann
216+
given-names: Denis A.
217+
- family-names: Strohmeier
218+
given-names: Daniel
219+
- family-names: Brodbeck
220+
given-names: Christian
221+
- family-names: Goj
222+
given-names: Roman
223+
- family-names: Jas
224+
given-names: Mainak
225+
- family-names: Brooks
226+
given-names: Teon
227+
- family-names: Parkkonen
228+
given-names: Lauri
229+
- family-names: Hämäläinen
230+
given-names: Matti S.
231+
'''
232+
233+
# WRITE TO FILE
234+
with open(os.path.join('..', 'CITATION.cff'), 'w') as cff_file:
235+
cff_file.write(cff_boilerplate)

0 commit comments

Comments
 (0)