Merge Hooke and BE branches of update-copyright.
[update-copyright.git] / update_copyright.py
index ca7417d7c0037c72839367457d5c5ff36715cfb3..4ca5e647c881c99038dacb507c16cb09626c74f3 100755 (executable)
@@ -1,28 +1,32 @@
 #!/usr/bin/python
 #
-# Copyright (C) 2010 W. Trevor King <wking@drexel.edu>
+# Copyright (C) 2009-2012 W. Trevor King <wking@drexel.edu>
 #
-# This file is part of Hooke.
+# This file is part of update-copyright.
 #
-# Hooke is free software: you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation, either
-# version 3 of the License, or (at your option) any later version.
+# update-copyright is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
 #
-# Hooke is distributed in the hope that it will be useful,
+# update-copyright is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
 #
-# You should have received a copy of the GNU Lesser General Public
-# License along with Hooke.  If not, see
+# You should have received a copy of the GNU General Public License
+# along with update-copyright.  If not, see
 # <http://www.gnu.org/licenses/>.
 
 """Automatically update copyright boilerplate.
 
-This script is adapted from one written for `Bugs Everywhere`_.
+This script is adapted from one written for `Bugs Everywhere`_. and
+later modified for `Hooke`_ before returning to `Bugs Everywhere`_.  I
+finally gave up on maintaining separate versions, so here it is as a
+stand-alone module.
 
 .. _Bugs Everywhere: http://bugseverywhere.org/
+.. _Hooke: http://code.google.com/p/hooke/
 """
 
 import difflib
@@ -35,7 +39,7 @@ import time
 
 
 PROJECT_INFO = {
-    'project': 'Hooke',
+    'project': 'update-copyright',
     'vcs': 'Git',
     }
 
@@ -43,13 +47,13 @@ PROJECT_INFO = {
 # REGEXP if we decide to go back to regexps.
 COPY_RIGHT_TEXT = [
     'This file is part of %(project)s.',
-    '%(project)s is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.',
-    '%(project)s is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.',
-    'You should have received a copy of the GNU Lesser General Public License along with %(project)s.  If not, see <http://www.gnu.org/licenses/>.'
+    '%(project)s is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.',
+    '%(project)s is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.',
+    'You should have received a copy of the GNU General Public License along with %(project)s.  If not, see <http://www.gnu.org/licenses/>.'
     ]
 
 SHORT_COPY_RIGHT_TEXT = [
-    '%(project)s comes with ABSOLUTELY NO WARRANTY and is licensed under the GNU Lesser General Public License.  For details, %(get-details)s.'
+    '%(project)s comes with ABSOLUTELY NO WARRANTY and is licensed under the GNU General Public License.  For details, %(get-details)s.'
     ]
 
 COPY_RIGHT_TAG='-xyz-COPY' + '-RIGHT-zyx-' # unlikely to occur in the wild :p
@@ -63,35 +67,14 @@ COPY_RIGHT_TAG='-xyz-COPY' + '-RIGHT-zyx-' # unlikely to occur in the wild :p
 #     }
 # Git-based projects are encouraged to use .mailmap instead of
 # ALIASES.  See git-shortlog(1) for details.
-ALIASES = {
-    'A. Seeholzer':
-        ['A. Seeholzer'],
-    'Alberto Gomez-Casado':
-        ['albertogomcas'],
-    'Massimo Sandal <devicerandom@gmail.com>':
-        ['Massimo Sandal',
-         'devicerandom',
-         'unknown'],
-    'Fabrizio Benedetti':
-        ['fabrizio.benedetti.82'],
-    'Richard Naud <richard.naud@epfl.ch>':
-        ['Richard Naud'],
-    'Rolf Schmidt <rschmidt@alcor.concordia.ca>':
-        ['Rolf Schmidt',
-         'illysam'],
-    'Marco Brucale':
-        ['marcobrucale'],
-    'Pancaldi Paolo':
-        ['pancaldi.paolo'],
-    }
+ALIASES = {}
 
 # List of paths that should not be scanned for copyright updates.
 # IGNORED_PATHS = ['./.git/']
-IGNORED_PATHS = ['./.hg/', './doc/img/', './test/data/',
-                 './build/', './doc/build/']
+IGNORED_PATHS = ['./.git']
 # List of files that should not be scanned for copyright updates.
 # IGNORED_FILES = ['COPYING']
-IGNORED_FILES = ['COPYING', 'COPYING.LESSER']
+IGNORED_FILES = ['COPYING']
 
 # Work around missing author holes in the VCS history.
 # AUTHOR_HACKS[<path tuple>] = [<missing authors]
@@ -100,16 +83,7 @@ IGNORED_FILES = ['COPYING', 'COPYING.LESSER']
 # AUTHOR_HACKS = {
 #     ('path', 'to', 'module.py'):['John Doe'],
 #     }
-AUTHOR_HACKS = {
-    ('hooke','driver','hdf5.py'):['Massimo Sandal'],
-    ('hooke','driver','mcs.py'):['Allen Chen'],
-    ('hooke','driver','mfp3d.py'):['A. Seeholzer','Richard Naud','Rolf Schmidt',
-                                   'Alberto Gomez-Casado'],
-    ('hooke','util','peak.py'):['Fabrizio Benedetti'],
-    ('hooke','plugin','showconvoluted.py'):['Rolf Schmidt'],
-    ('hooke','ui','gui','formatter.py'):['Francesco Musiani','Massimo Sandal'],
-    ('hooke','ui','gui','prettyformat.py'):['Rolf Schmidt'],
-    }
+AUTHOR_HACKS = {}
 
 # Work around missing year holes in the VCS history.
 # YEAR_HACKS[<path tuple>] = <original year>
@@ -118,17 +92,7 @@ AUTHOR_HACKS = {
 # YEAR_HACKS = {
 #     ('path', 'to', 'module.py'):2008,
 #     }
-YEAR_HACKS = {
-    ('hooke','driver','hdf5.py'):2009,
-    ('hooke','driver','mfp3d.py'):2008,
-    ('hooke','driver','picoforce.py'):2006,
-    ('hooke','driver','picoforcealt.py'):2006,
-    ('hooke','util','peak.py'):2007,
-    ('hooke','plugin','showconvoluted.py'):2009,
-    ('hooke','plugin','tutorial.py'):2007,
-    ('hooke','ui','gui','formatter.py'):2006,
-    ('hooke','ui','gui','prettyformat.py'):2009,
-    }
+YEAR_HACKS = {}
 
 # Helpers for VCS-specific commands
 
@@ -187,32 +151,40 @@ if PROJECT_INFO['vcs'] == 'Git':
         status,stdout,stderr = invoke(['git'] + list(args))
         return stdout.rstrip('\n')
 
-    def original_year(filename=None, year_hacks=YEAR_HACKS):
-        args = [
-            '--format=format:%ad',  # Author date
-            '--date=short',         # YYYY-MM-DD
-            ]
-        if filename != None:
-            args.extend(['--follow', filename])
-        output = git_cmd('log', *args)
+    version = git_cmd('--version').split(' ')[-1]
+    if version.startswith('1.5.'):
+        # Author name <author email>
+        author_format = '--pretty=format:%an <%ae>'
+        year_format = ['--pretty=format:%ai']  # Author date
+        # YYYY-MM-DD HH:MM:SS Z
+        # Earlier versions of Git don't seem to recognize --date=short
+    else:
+        author_format = '--pretty=format:%aN <%aE>'
+        year_format = ['--pretty=format:%ad',  # Author date
+                       '--date=short']         # YYYY-MM-DD
+
+    def original_year(filename, year_hacks=YEAR_HACKS):
+        output = git_cmd(*(['log', '--follow']
+                           + year_format
+                           + [filename]))
+        if version.startswith('1.5.'):
+            output = '\n'.join([x.split()[0] for x in output.splitlines()])
         years = [int(line.split('-', 1)[0]) for line in output.splitlines()]
-        if filename == None:
-            years.extend(year_hacks.values())
-        elif splitpath(filename) in year_hacks:
+        if splitpath(filename) in year_hacks:
             years.append(year_hacks[splitpath(filename)])
         years.sort()
         return years[0]
 
     def authors(filename, author_hacks=AUTHOR_HACKS):
-        output = git_cmd('log', '--follow', '--format=format:%aN <%aE>',
-                         filename)   # Author name <author email>
+        output = git_cmd('log', '--follow', author_format,
+                         filename)
         ret = list(set(output.splitlines()))
         if splitpath(filename) in author_hacks:
             ret.extend(author_hacks[splitpath(filename)])
         return ret
 
     def authors_list(author_hacks=AUTHOR_HACKS):
-        output = git_cmd('log', '--format=format:%aN <%aE>')
+        output = git_cmd('log', author_format)
         ret = list(set(output.splitlines()))
         for path,authors in author_hacks.items():
             ret.extend(authors)
@@ -318,7 +290,7 @@ elif PROJECT_INFO['vcs'] == 'Bazaar':
         cmd.outf = StringIO.StringIO()
         kwargs = {'log_format':YearLogFormatter, 'levels':0}
         if filename != None:
-            kwargs['file_list'] = [filenme]
+            kwargs['file_list'] = [filename]
         cmd.run(**kwargs)
         years = [int(year) for year in set(cmd.outf.getvalue().splitlines())]
         if filename == None:
@@ -500,9 +472,10 @@ def _copyright_string(original_year, final_year, authors,
     ...                        )
     Copyright (C) 2005 A <a@a.com>, B <b@b.edu>
     <BLANKLINE>
-    Hooke comes with ABSOLUTELY NO WARRANTY and is
-    licensed under the GNU Lesser General Public
+    update-copyright comes with ABSOLUTELY NO WARRANTY
+    and is licensed under the GNU General Public
     License.  For details, %(get-details)s.
+
     >>> print _copyright_string(original_year=2005,
     ...                         final_year=2005,
     ...                         authors=['A <a@a.com>', 'B <b@b.edu>'],
@@ -514,7 +487,7 @@ def _copyright_string(original_year, final_year, authors,
     ...                        )
     Copyright (C) 2005 A <a@a.com>, B <b@b.edu>
     <BLANKLINE>
-    Hooke comes with ABSOLUTELY NO WARRANTY and is licensed under the GNU Lesser General Public License.  For details, %(get-details)s.
+    update-copyright comes with ABSOLUTELY NO WARRANTY and is licensed under the GNU General Public License.  For details, %(get-details)s.
     """
     for key in ['initial_indent', 'subsequent_indent']:
         if key not in wrap_kwargs: