Skip to content

Commit ea62356

Browse files
orbeckstIAlibay
andcommitted
generate authors list from AUTHORS file
- reformatted AUTHORS - create MDAnalysisData/authors.py on installation (with a fall back) and make MDAnalysisData.__authors__ available; uses setup.dynamic_author_list() that was written by @jbarnoud with modifications by @tylerjereddy and @lilyminium and originally included in MDAnalysis setup.py under GPL v2+. All authors agreed to re-license their code under the BSD 3-clause license so that dynamic_author_list() could be included here. See #49 (comment) for the agreement to re-license. - add tests for __authors__ and __version__ - use __authors__ in doc generation (together with latest year via datetime) - update CHANGELOG Co-authored-by: Irfan Alibay <IAlibay@users.noreply.github.com>
1 parent 661270c commit ea62356

7 files changed

Lines changed: 152 additions & 22 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
MDAnalysisData/authors.py

AUTHORS

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,19 @@ Authors of MDAnalysisData
33

44
Contributors to MDAnalysisData are listed under the year of their
55
first contribution. Full names, GitHub handles (@name) or email
6-
addresses are all optional.
6+
addresses (all in parentheses) are all optional.
7+
8+
Chronological list of authors
9+
-----------------------------
710

811
2018
9-
- Oliver Beckstein @orbeckst
10-
- Shujie Fan @VOD555
11-
- Micaela Matta @micaela-matta
12-
- Richard J. Gowers @richardjgowers
12+
13+
- Oliver Beckstein (@orbeckst)
14+
- Shujie Fan (@VOD555)
15+
- Micaela Matta (@micaela-matta)
16+
- Richard J. Gowers (@richardjgowers)
1317

1418
2020
15-
- Lily Wang @lilyminium
19+
20+
- Lily Wang (@lilyminium)
21+

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99
### Added
1010
- docs for how to contribute a new dataset (#46)
11+
- new `MDAnalysis.__authors__` attribute with the list of AUTHORS
1112

1213
### Changes
1314
- update online docs theme (#43)

MDAnalysisData/__init__.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,15 @@
99

1010
from . import datasets
1111

12-
13-
14-
15-
1612
from ._version import get_versions
1713
__version__ = get_versions()['version']
1814
del get_versions
15+
16+
try:
17+
from .authors import __authors__
18+
except ImportError:
19+
import warnings
20+
warnings.warn('Could not find authors.py, __authors__ will be the '
21+
'generic MDAnalysis team.')
22+
__authors__ = ["The MDAnalysis Development Team"]
23+
del warnings
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import sys
4+
from six.moves import reload_module
5+
import pytest
6+
7+
import MDAnalysisData
8+
9+
10+
def test_authors():
11+
authors = MDAnalysisData.__authors__
12+
assert authors[:5] == ["Oliver Beckstein", "Shujie Fan",
13+
"Richard J. Gowers", "Micaela Matta",
14+
"Lily Wang"]
15+
16+
17+
def test_default_authors(monkeypatch):
18+
# authors.py did not exist and could not be imported
19+
monkeypatch.setitem(sys.modules, 'MDAnalysisData.authors', None)
20+
with pytest.warns(UserWarning,
21+
match="Could not find authors.py, __authors__ will "
22+
"be the generic MDAnalysis team."):
23+
reload_module(MDAnalysisData)
24+
authors = MDAnalysisData.__authors__
25+
assert authors == ["The MDAnalysis Development Team"]
26+
27+
28+
def test_version():
29+
# very generic because versioneer will provide different strings depending
30+
# on the repository status
31+
assert isinstance(MDAnalysisData.__version__, str)

docs/conf.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,19 @@
1212
# serve to show the default.
1313

1414
import sys, os
15+
import datetime
16+
17+
import sphinx_rtd_theme
1518

1619
# If extensions (or modules to document with autodoc) are in another directory,
1720
# add these directories to sys.path here. If the directory is relative to the
1821
# documentation root, use os.path.abspath to make it absolute, like shown here.
19-
#sys.path.insert(0, os.path.abspath('.'))
20-
22+
#
2123
# make sure sphinx always uses the current branch
2224
sys.path.insert(0, os.path.abspath('..'))
2325

24-
import sphinx_rtd_theme
26+
# to get authors and version
27+
import MDAnalysisData
2528

2629
# -- General configuration -----------------------------------------------------
2730

@@ -63,18 +66,19 @@
6366
master_doc = 'index'
6467

6568
# General information about the project.
69+
author_list = MDAnalysisData.__authors__
70+
authors = u', '.join(author_list[:-1]) + u', and ' + author_list[-1]
6671
project = u'MDAnalysisData'
67-
author = (u'Oliver Beckstein, Shujie Fan, Micaela Matta, '
68-
u'Richard J. Gowers, Lily Wang')
69-
copyright = u'2018-2020, ' + author
72+
now = datetime.datetime.now()
73+
copyright = u'2018-{}, '.format(now.year) + authors
7074

7175

7276
# The version info for the project you're documenting, acts as replacement for
7377
# |version| and |release|, also used in various other places throughout the
7478
# built documents.
7579
#
7680
# The full version, including alpha/beta/rc tags.
77-
release = __import__('MDAnalysisData').__version__
81+
release = MDAnalysisData.__version__
7882
# The short X.Y version.
7983
version = ".".join(release.split('.')[:2])
8084

@@ -240,7 +244,7 @@
240244
# author, documentclass [howto, manual, or own class]).
241245
latex_documents = [
242246
(master_doc, 'MDAnalysisData.tex', u'MDAnalysisData Documentation',
243-
author, 'manual'),
247+
authors, 'manual'),
244248
]
245249

246250
# The name of an image file (relative to this directory) to place at the top of
@@ -270,7 +274,7 @@
270274
# (source start file, name, description, authors, manual section).
271275
man_pages = [
272276
(master_doc, 'MDAnalysisData', u'MDAnalysisData Documentation',
273-
author.split(), 1)
277+
authors.split(), 1)
274278
]
275279

276280
# If true, show URL addresses after external links.
@@ -284,7 +288,7 @@
284288
# dir menu entry, description, category)
285289
texinfo_documents = [
286290
(master_doc, 'MDAnalysisData', u'MDAnalysisData Documentation',
287-
author, 'MDAnalysisData', 'Datasets for MDAnalysis',
291+
authors, 'MDAnalysisData', 'Datasets for MDAnalysis',
288292
'Miscellaneous'),
289293
]
290294

@@ -301,5 +305,5 @@
301305
# Configuration for intersphinx: refer to the Python standard library
302306
# and other packages used by MDAnalysis
303307
intersphinx_mapping = {'https://docs.python.org/': None,
304-
'https://www.mdanalysis.org/docs/': None,
308+
'https://docs.mdanalysis.org/stable': None,
305309
}

setup.py

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,94 @@
1919
from setuptools import setup, find_packages
2020
import versioneer
2121

22+
import os
23+
import warnings
2224
import codecs
2325

26+
27+
def abspath(file):
28+
return os.path.join(os.path.dirname(os.path.abspath(__file__)),
29+
file)
30+
31+
32+
def dynamic_author_list():
33+
"""Generate __authors__ from AUTHORS
34+
35+
This function generates authors.py that contains the list of the
36+
authors from the AUTHORS file. This avoids having that list maintained in
37+
several places. Note that AUTHORS is sorted chronologically while we want
38+
__authors__ in authors.py to be sorted alphabetically.
39+
40+
The authors are written in AUTHORS as bullet points under the
41+
"Chronological list of authors" title.
42+
"""
43+
44+
# The dynamic_author_list() function was taken from MDAnalysis's setup.py
45+
# file, which is licensed under GPL v2+. All original authors of the
46+
# function (@jbarnoud, @tylerjereddy, @lilyminium) agreed to re-license the
47+
# code under the BSD 3-clause license
48+
# (https://github.com/MDAnalysis/MDAnalysisData/pull/49#discussion_r672489685)
49+
# so that it can be included here with modifictions necessary for
50+
# MDAnalysisData.
51+
52+
authors = []
53+
with codecs.open(abspath('AUTHORS'), encoding='utf-8') as infile:
54+
# An author is a bullet point under the title "Chronological list of
55+
# authors". We first want move the cursor down to the title of
56+
# interest.
57+
for line_no, line in enumerate(infile, start=1):
58+
if line.rstrip() == "Chronological list of authors":
59+
break
60+
else:
61+
# If we did not break, it means we did not find the authors.
62+
raise IOError('EOF before the list of authors')
63+
# Skip the next line as it is the title underlining
64+
line = next(infile)
65+
line_no += 1
66+
if line[:4] != '----':
67+
raise IOError('Unexpected content on line {0}, '
68+
'should be a string of "-".'.format(line_no))
69+
# Add each bullet point as an author
70+
for line in infile:
71+
if line.strip()[:2] == '- ':
72+
# This is a bullet point, so it should be an author name.
73+
name = line.strip()[2:].strip()
74+
# Remove any @-handles in "A.U. Thor (@donnergott)"
75+
name = name.split("(")[0].strip()
76+
authors.append(name)
77+
78+
# So far, the list of authors is sorted chronologically. We want it
79+
# sorted alphabetically of the last name.
80+
authors.sort(key=lambda name: name.split()[-1])
81+
82+
# Write the authors.py file.
83+
out_path = abspath('MDAnalysisData/authors.py')
84+
with codecs.open(out_path, 'w', encoding='utf-8') as outfile:
85+
# Write the header
86+
header = '''\
87+
#-*- coding:utf-8 -*-
88+
89+
# This file is generated from the AUTHORS file during the installation process.
90+
# Do not edit it as your changes will be overwritten.
91+
'''
92+
print(header, file=outfile)
93+
94+
# Write the list of authors as a python list
95+
template = u'__authors__ = [\n{}\n]'
96+
author_string = u',\n'.join(u' u"{}"'.format(name)
97+
for name in authors)
98+
print(template.format(author_string), file=outfile)
99+
100+
24101
if __name__ == '__main__':
25102
with codecs.open("README.md", encoding="utf-8") as summary:
26103
LONG_DESCRIPTION = summary.read()
27104

105+
try:
106+
dynamic_author_list()
107+
except (OSError, IOError):
108+
warnings.warn('Cannot write the list of authors.')
109+
28110
CLASSIFIERS = [
29111
'Development Status :: 4 - Beta',
30112
'Environment :: Console',
@@ -74,6 +156,6 @@
74156
'setuptools',
75157
'tqdm',
76158
],
77-
tests_require=['pytest-mock', 'pytest'],
159+
tests_require=['pytest', 'pytest-mock'],
78160
zip_safe=True,
79161
)

0 commit comments

Comments
 (0)