-import os
-import sys
-import select
-from subprocess import Popen, PIPE, mswindows
-from threading import Thread
-
-COPYRIGHT_TEXT="""#
-# This program 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 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA."""
-
-COPYRIGHT_TAG='-xyz-COPYRIGHT-zyx-' # unlikely to occur in the wild :p
-
-ALIASES = [
- ['Ben Finney <benf@cybersource.com.au>',
- 'Ben Finney <ben+python@benfinney.id.au>',
- 'John Doe <jdoe@example.com>'],
- ['Chris Ball <cjb@laptop.org>',
- 'Chris Ball <cjb@thunk.printf.net>'],
- ['Gianluca Montecchi <gian@grys.it>',
- 'gian <gian@li82-39>',
- 'gianluca <gian@galactica>'],
- ['W. Trevor King <wking@drexel.edu>',
- 'wking <wking@mjolnir>'],
- [None,
- 'j^ <j@oil21.org>'],
- ]
-COPYRIGHT_ALIASES = [
- ['Aaron Bentley and Panometrics, Inc.',
- 'Aaron Bentley <abentley@panoramicfeedback.com>'],
- ]
-EXCLUDES = [
- ['Aaron Bentley and Panometrics, Inc.',
- 'Aaron Bentley <aaron.bentley@utoronto.ca>',]
- ]
-
-
-IGNORED_PATHS = ['./.be/', './.bzr/', './build/']
-IGNORED_FILES = ['COPYING', 'update_copyright.py', 'catmutt']
-
-class Pipe (object):
- """
- Simple interface for executing POSIX-style pipes based on the
- subprocess module. The only complication is the adaptation of
- subprocess.Popen._comminucate to listen to the stderrs of all
- processes involved in the pipe, as well as the terminal process'
- stdout. There are two implementations of Pipe._communicate, one
- for MS Windows, and one for POSIX systems. The MS Windows
- implementation is currently untested.
-
- >>> p = Pipe([['find', '/etc/'], ['grep', '^/etc/ssh$']])
- >>> p.stdout
- '/etc/ssh\\n'
- >>> p.status
- 1
- >>> p.statuses
- [1, 0]
- >>> p.stderrs # doctest: +ELLIPSIS
- ["find: `...': Permission denied\\n...", '']
- """
- def __init__(self, cmds, stdin=None):
- # spawn processes
- self._procs = []
- for cmd in cmds:
- if len(self._procs) != 0:
- stdin = self._procs[-1].stdout
- self._procs.append(Popen(cmd, stdin=stdin, stdout=PIPE, stderr=PIPE))
-
- self.stdout,self.stderrs = self._communicate(input=None)
-
- # collect process statuses
- self.statuses = []
- self.status = 0
- for proc in self._procs:
- self.statuses.append(proc.wait())
- if self.statuses[-1] != 0:
- self.status = self.statuses[-1]
-
- # Code excerpted from subprocess.Popen._communicate()
- if mswindows == True:
- def _communicate(self, input=None):
- assert input == None, "stdin != None not yet supported"
- # listen to each process' stderr
- threads = []
- std_X_arrays = []
- for proc in self._procs:
- stderr_array = []
- thread = Thread(target=proc._readerthread,
- args=(proc.stderr, stderr_array))
- thread.setDaemon(True)
- thread.start()
- threads.append(thread)
- std_X_arrays.append(stderr_array)
-
- # also listen to the last processes stdout
- stdout_array = []
- thread = Thread(target=proc._readerthread,
- args=(proc.stdout, stdout_array))
- thread.setDaemon(True)
- thread.start()
- threads.append(thread)
- std_X_arrays.append(stdout_array)
-
- # join threads as they die
- for thread in threads:
- thread.join()
-
- # read output from reader threads
- std_X_strings = []
- for std_X_array in std_X_arrays:
- std_X_strings.append(std_X_array[0])
-
- stdout = std_X_strings.pop(-1)
- stderrs = std_X_strings
- return (stdout, stderrs)
- else: # POSIX
- def _communicate(self, input=None):
- read_set = []
- write_set = []
- read_arrays = []
- stdout = None # Return
- stderr = None # Return
-
- if self._procs[0].stdin:
- # Flush stdio buffer. This might block, if the user has
- # been writing to .stdin in an uncontrolled fashion.
- self._procs[0].stdin.flush()
- if input:
- write_set.append(self._procs[0].stdin)
- else:
- self._procs[0].stdin.close()
- for proc in self._procs:
- read_set.append(proc.stderr)
- read_arrays.append([])
- read_set.append(self._procs[-1].stdout)
- read_arrays.append([])
-
- input_offset = 0
- while read_set or write_set:
- try:
- rlist, wlist, xlist = select.select(read_set, write_set, [])
- except select.error, e:
- if e.args[0] == errno.EINTR:
- continue
- raise
- if self._procs[0].stdin in wlist:
- # When select has indicated that the file is writable,
- # we can write up to PIPE_BUF bytes without risk
- # blocking. POSIX defines PIPE_BUF >= 512
- chunk = input[input_offset : input_offset + 512]
- bytes_written = os.write(self.stdin.fileno(), chunk)
- input_offset += bytes_written
- if input_offset >= len(input):
- self._procs[0].stdin.close()
- write_set.remove(self._procs[0].stdin)
- if self._procs[-1].stdout in rlist:
- data = os.read(self._procs[-1].stdout.fileno(), 1024)
- if data == "":
- self._procs[-1].stdout.close()
- read_set.remove(self._procs[-1].stdout)
- read_arrays[-1].append(data)
- for i,proc in enumerate(self._procs):
- if proc.stderr in rlist:
- data = os.read(proc.stderr.fileno(), 1024)
- if data == "":
- proc.stderr.close()
- read_set.remove(proc.stderr)
- read_arrays[i].append(data)
-
- # All data exchanged. Translate lists into strings.
- read_strings = []
- for read_array in read_arrays:
- read_strings.append(''.join(read_array))
-
- stdout = read_strings.pop(-1)
- stderrs = read_strings
- return (stdout, stderrs)
+import mercurial
+import mercurial.dispatch
+
+
+PROJECT_INFO = {
+ 'project': 'Hooke',
+ 'vcs': 'Mercurial',
+ }
+
+# Break "copyright" into "copy" and "right" to avoid matching the
+# REGEXP.
+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/>.
+""".strip()
+
+COPY_RIGHT_TAG='-xyz-COPY' + '-RIGHT-zyx-' # unlikely to occur in the wild :p
+
+ALIASES = {
+ 'Alberto Gomez-Casado':
+ ['albertogomcas'],
+ 'Massimo Sandal <devicerandom@gmail.com>':
+ ['devicerandom',
+ 'unknown'],
+ 'Fabrizio Benedetti':['fabrizio.benedetti'],
+ 'il':['illysam'],
+ 'Marco Brucale':['marcobrucale'],
+ 'pp':['pancaldi.paolo'],
+ }
+
+IGNORED_PATHS = ['./.hg/', './doc/img', './test/data/',
+ './build/', '/doc/build/']
+IGNORED_FILES = ['COPYING', 'COPYING.LESSER']
+
+
+# VCS-specific commands
+
+def mercurial_cmd(*args):
+ cwd = os.getcwd()
+ stdout = sys.stdout
+ stderr = sys.stderr
+ tmp_stdout = StringIO.StringIO()
+ tmp_stderr = StringIO.StringIO()
+ sys.stdout = tmp_stdout
+ sys.stderr = tmp_stderr
+ try:
+ mercurial.dispatch.dispatch(list(args))
+ finally:
+ os.chdir(cwd)
+ sys.stdout = stdout
+ sys.stderr = stderr
+ return (tmp_stdout.getvalue().rstrip('\n'),
+ tmp_stderr.getvalue().rstrip('\n'))
+
+def original_year(filename):
+ # shortdate filter: YEAR-MONTH-DAY
+ output,error = mercurial_cmd('log', '--follow',
+ '--template', '{date|shortdate}\n',
+ filename)
+ years = [int(line.split('-', 1)[0]) for line in output.splitlines()]
+ years.sort()
+ return years[0]
+
+def authors(filename):
+ output,error = mercurial_cmd('log', '--follow',
+ '--template', '{author}\n',
+ filename)
+ return list(set(output.splitlines()))
+
+def authors_list():
+ output,error = mercurial_cmd('log', '--follow',
+ '--template', '{author}\n')
+ return list(set(output.splitlines()))
+
+def is_versioned(filename):
+ output,error = mercurial_cmd('log', '--follow',
+ '--template', '{date|shortdate}\n',
+ filename)
+ if len(error) > 0:
+ return False
+ return True
+
+# General utility commands