diff --git a/.gitignore b/.gitignore index d7945c6a70d..488e359bfc6 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,5 @@ doc/html/ *.sw[a-z] # Ignore MDAnalysis log files MDAnalysis.log +# Ignore the authors.py files as they are generated files +authors.py diff --git a/package/AUTHORS b/package/AUTHORS index e06a47e3b24..30c82135170 100644 --- a/package/AUTHORS +++ b/package/AUTHORS @@ -49,6 +49,7 @@ Chronological list of authors - Robert McGibbon - Richard J. Gowers - Alejandro Bernardin + - Lennard van der Feltz 2014 - Matthieu Chavent - Joe Jordan diff --git a/package/CHANGELOG b/package/CHANGELOG index a4d1fad1e69..a6db1d2d279 100644 --- a/package/CHANGELOG +++ b/package/CHANGELOG @@ -13,7 +13,7 @@ The rules for this file: * release numbers follow "Semantic Versioning" http://semver.org ------------------------------------------------------------------------------ -??/??/16 jandom, abhinavgupta94, orbeckst, kain88-de, hainm, jdetle +??/??/16 jandom, abhinavgupta94, orbeckst, kain88-de, hainm, jdetle, jbarnoud * 0.15.0 @@ -21,6 +21,8 @@ Metadata * link download_url to GitHub releases so that Depsy recognizes contributors (issue #749) + * a __version__ variable is now exposed; it is built by setup.py from the + AUTHORS file (Issue #784) API Changes diff --git a/package/MDAnalysis/__init__.py b/package/MDAnalysis/__init__.py index f7db3601edd..648fd8b845d 100644 --- a/package/MDAnalysis/__init__.py +++ b/package/MDAnalysis/__init__.py @@ -139,7 +139,14 @@ import logging import warnings +logger = logging.getLogger("MDAnalysis.__init__") + from .version import __version__ +try: + from .authors import __authors__ +except ImportError: + logger.info('Could not find authors.py, __authors__ will be empty.') + __authors__ = [] # custom exceptions and warnings from .exceptions import ( diff --git a/package/doc/sphinx/source/conf.py b/package/doc/sphinx/source/conf.py index bfb6a470edc..6d022370323 100644 --- a/package/doc/sphinx/source/conf.py +++ b/package/doc/sphinx/source/conf.py @@ -78,17 +78,8 @@ def __getattr__(cls, name): # (take the list from AUTHORS) # Ordering: (1) Naveen (2) Elizabeth, then all contributors in alphabetical order # (last) Oliver -authors = u"""Naveen Michaud-Agrawal, Elizabeth J. Denning, Joshua - Adelman, Balasubramanian, Jonathan Barnoud, Christian Beckstein (logo), Alejandro - Bernardin, Sébastien Buchoux, David Caplan, Matthieu Chavent, - Xavier Deupi, Jan Domański, David L. Dotson, Lennard van der - Feltz, Philip Fowler, Joseph Goose, Richard J. Gowers, Lukas - Grossar, Benjamin Hall, Joe Jordan, Max Linke, Jinju Lu, Robert - McGibbon, Alex Nesterenko, Manuel Nuno Melo, Hai Nguyen, - Caio S. Souza, Mattia F. Palermo, Danny Parton, Joshua L. Phillips, Tyler Reddy, - Paul Rigor, Sean L. Seyler, Andy Somogyi, Lukas Stelzl, - Gorman Stock, Isaac Virshup, Zhuyi Xue, Carlos Yáñez S., - and Oliver Beckstein""" +author_list = __import__('MDAnalysis').__authors__ +authors = u', '.join(author_list[:-1]) + u', and ' + author_list[-1] project = u'MDAnalysis' copyright = u'2005-2015, ' + authors diff --git a/package/setup.py b/package/setup.py index d1c990823c4..49a74d59b65 100755 --- a/package/setup.py +++ b/package/setup.py @@ -351,7 +351,78 @@ def extensions(config): "failed/disabled Cython build.".format(source)) return extensions, cython_generated + +def dynamic_author_list(): + """Generate __authors__ from AUTHORS + + This function generates authors.py that contains the list of the + authors from the AUTHORS file. This avoids having that list maintained in + several places. Note that AUTHORS is sorted chronologically while we want + __authors__ in authors.py to be sorted alphabetically. + + The authors are written in AUTHORS as bullet points under the + "Chronological list of authors" title. + """ + authors = [] + with open('AUTHORS') as infile: + # An author is a bullet point under the title "Chronological list of + # authors". We first want move the cursor down to the title of + # interest. + for line_no, line in enumerate(infile, start=1): + if line[:-1] == "Chronological list of authors": + break + else: + # If we did not break, it means we did not find the authors. + raise IOError('EOF before the list of authors') + # Skip the next line as it is the title underlining + line = next(infile) + line_no += 1 + if line[:4] != '----': + raise IOError('Unexpected content on line {0}, ' + 'should be a string of "-".'.format(line_no)) + # Add each bullet point as an author until the next title underlining + for line in infile: + if line[:4] in ('----', '====', '~~~~'): + # The previous line was a title, hopefully it did not start as + # a bullet point so it got ignored. Since we hit a title, we + # are done reading the list of authors. + break + elif line.strip()[:2] == '- ': + # This is a bullet point, so it should be an author name. + name = line.strip()[2:].strip().decode('utf-8') + authors.append(name) + + # So far, the list of authors is sorted chronologically. We want it + # sorted alphabetically of the last name. + authors.sort(key=lambda name: name.split()[-1]) + # Move Naveen and Elizabeth first, and Oliver last. + authors.remove('Naveen Michaud-Agrawal') + authors.remove('Elizabeth J. Denning') + authors.remove('Oliver Beckstein') + authors = (['Naveen Michaud-Agrawal', 'Elizabeth J. Denning'] + + authors + ['Oliver Beckstein']) + + # Write the authors.py file. + with open('MDAnalysis/authors.py', 'w') as outfile: + # Write the header + header = '''\ +#-*- coding:utf-8 -*- + +# This file is generated from the AUTHORS file during the installation process. +# Do not edit it as your changes will be overwritten. +''' + print(header, file=outfile) + + # Write the list of authors as a python list + template = u'__authors__ = [\n{}\n]' + author_string = u',\n'.join(u' u"{}"'.format(name) + for name in authors) + print(template.format(author_string).encode('utf-8'), file=outfile) + + if __name__ == '__main__': + dynamic_author_list() + with open("SUMMARY.txt") as summary: LONG_DESCRIPTION = summary.read() CLASSIFIERS = [ diff --git a/testsuite/CHANGELOG b/testsuite/CHANGELOG index 2823c337e4b..ac7b0f9f343 100644 --- a/testsuite/CHANGELOG +++ b/testsuite/CHANGELOG @@ -13,13 +13,15 @@ Also see https://github.com/MDAnalysis/mdanalysis/wiki/MDAnalysisTests and https://github.com/MDAnalysis/mdanalysis/wiki/UnitTests ------------------------------------------------------------------------------ -??/??/16 orbeckst +??/??/16 orbeckst, jbarnoud * 0.15.0 - metadata update: link download_url to GitHub releases so that Depsy recognizes contributors (issue #749) and added @richardjgowers as maintainer + - a __version__ variable is now exposed; it is built by setup.py from the + AUTHORS file (Issue #784) 02/28/16 manuel.nuno.melo diff --git a/testsuite/MDAnalysisTests/__init__.py b/testsuite/MDAnalysisTests/__init__.py index dd74518c911..633c0e949ce 100644 --- a/testsuite/MDAnalysisTests/__init__.py +++ b/testsuite/MDAnalysisTests/__init__.py @@ -106,8 +106,16 @@ .. _Gromacs: http://www.gromacs.org """ +import logging +logger = logging.getLogger("MDAnalysisTests.__init__") __version__ = "0.14.1-dev0" # keep in sync with RELEASE in setup.py +try: + from .authors import __authors__ +except ImportError: + logger.info('Could not find authors.py, __authors__ will be empty.') + __authors__ = [] + # Do NOT import MDAnalysis at this level. Tests should do it themselves. # If MDAnalysis is imported here coverage accounting might fail because all the import diff --git a/testsuite/MDAnalysisTests/test_authors.py b/testsuite/MDAnalysisTests/test_authors.py new file mode 100644 index 00000000000..ab5cb0aadef --- /dev/null +++ b/testsuite/MDAnalysisTests/test_authors.py @@ -0,0 +1,28 @@ +# -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*- +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 fileencoding=utf-8 +# +# MDAnalysis --- http://www.MDAnalysis.org +# Copyright (c) 2006-2015 Naveen Michaud-Agrawal, Elizabeth J. Denning, Oliver +# Beckstein and contributors (see AUTHORS for the full list) +# +# Released under the GNU Public Licence, v2 or any higher version +# +# Please cite your use of MDAnalysis in published work: +# +# N. Michaud-Agrawal, E. J. Denning, T. B. Woolf, and O. Beckstein. +# MDAnalysis: A Toolkit for the Analysis of Molecular Dynamics Simulations. +# J. Comput. Chem. 32 (2011), 2319--2327, doi:10.1002/jcc.21787 +# +from numpy.testing import assert_ + +import MDAnalysis + +def test_package_authors(): + assert_(len(MDAnalysis.__authors__) > 0, + 'Could not find the list of authors') + + +def test_testsuite_authors(): + from . import __authors__ + assert_(len(__authors__) > 0, + 'Could not find the list of authors') diff --git a/testsuite/setup.py b/testsuite/setup.py index b0d9e59aec2..d4ea5d612b3 100755 --- a/testsuite/setup.py +++ b/testsuite/setup.py @@ -42,6 +42,75 @@ import os import glob + +def dynamic_author_list(): + """Generate __authors__ from AUTHORS + + This function generates authors.py that contains the list of the + authors from the AUTHORS file. This avoids having that list maintained in + several places. Note that AUTHORS is sorted chronologically while we want + __authors__ in authors.py to be sorted alphabetically. + + The authors are written in AUTHORS as bullet points under the + "Chronological list of authors" title. + """ + authors = [] + with open('AUTHORS') as infile: + # An author is a bullet point under the title "Chronological list of + # authors". We first want move the cursor down to the title of + # interest. + for line_no, line in enumerate(infile, start=1): + if line[:-1] == "Chronological list of authors": + break + else: + # If we did not break, it means we did not find the authors. + raise IOError('EOF before the list of authors') + # Skip the next line as it is the title underlining + line = next(infile) + line_no += 1 + if line[:4] != '----': + raise IOError('Unexpected content on line {0}, ' + 'should be a string of "-".'.format(line_no)) + # Add each bullet point as an author until the next title underlining + for line in infile: + if line[:4] in ('----', '====', '~~~~'): + # The previous line was a title, hopefully it did not start as + # a bullet point so it got ignored. Since we hit a title, we + # are done reading the list of authors. + break + elif line.strip()[:2] == '- ': + # This is a bullet point, so it should be an author name. + name = line.strip()[2:].strip().decode('utf-8') + authors.append(name) + + # So far, the list of authors is sorted chronologically. We want it + # sorted alphabetically of the last name. + authors.sort(key=lambda name: name.split()[-1]) + # Move Naveen and Elizabeth first, and Oliver last. + authors.remove('Naveen Michaud-Agrawal') + authors.remove('Elizabeth J. Denning') + authors.remove('Oliver Beckstein') + authors = (['Naveen Michaud-Agrawal', 'Elizabeth J. Denning'] + + authors + ['Oliver Beckstein']) + + # Write the authors.py file. + with open('MDAnalysisTests/authors.py', 'w') as outfile: + # Write the header + header = '''\ +#-*- coding:utf-8 -*- + +# This file is generated from the AUTHORS file during the installation process. +# Do not edit it as your changes will be overwritten. +''' + print(header, file=outfile) + + # Write the list of authors as a python list + template = u'__authors__ = [\n{}\n]' + author_string = u',\n'.join(u' u"{}"'.format(name) + for name in authors) + print(template.format(author_string).encode('utf-8'), file=outfile) + + # Make sure I have the right Python version. if sys.version_info[:2] < (2, 7): print("MDAnalysis requires Python 2.7 or better. Python {0:d}.{1:d} detected".format(* @@ -51,6 +120,8 @@ if __name__ == '__main__': + dynamic_author_list() + RELEASE = "0.14.1-dev0" # this must be in-sync with MDAnalysis LONG_DESCRIPTION = \ """MDAnalysis is a tool for analyzing molecular dynamics trajectories.