|
19 | 19 | from setuptools import setup, find_packages |
20 | 20 | import versioneer |
21 | 21 |
|
| 22 | +import os |
| 23 | +import warnings |
22 | 24 | import codecs |
23 | 25 |
|
| 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 | + |
24 | 101 | if __name__ == '__main__': |
25 | 102 | with codecs.open("README.md", encoding="utf-8") as summary: |
26 | 103 | LONG_DESCRIPTION = summary.read() |
27 | 104 |
|
| 105 | + try: |
| 106 | + dynamic_author_list() |
| 107 | + except (OSError, IOError): |
| 108 | + warnings.warn('Cannot write the list of authors.') |
| 109 | + |
28 | 110 | CLASSIFIERS = [ |
29 | 111 | 'Development Status :: 4 - Beta', |
30 | 112 | 'Environment :: Console', |
|
74 | 156 | 'setuptools', |
75 | 157 | 'tqdm', |
76 | 158 | ], |
77 | | - tests_require=['pytest-mock', 'pytest'], |
| 159 | + tests_require=['pytest', 'pytest-mock'], |
78 | 160 | zip_safe=True, |
79 | 161 | ) |
0 commit comments