changeset 0:939b2b9901f3

Initial import
author Louis Opter <kalessin@kalessin.fr>
date Thu, 25 Mar 2010 18:26:42 +0100
parents
children b6cf3e38343e
files doxyhook.py
diffstat 1 files changed, 131 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doxyhook.py	Thu Mar 25 18:26:42 2010 +0100
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+
+# The MIT License
+#
+# Copyright (c) 2010 Louis Opter <kalessin@kalessin.fr>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+import os
+import re
+import shutil
+import subprocess
+import sys
+import tempfile
+
+from mercurial import ui, hg, commands
+
+OUTPUT = '/var/www/doc/api'
+
+class DoxyfileNotFound(Exception):
+    def __str__(self):
+        return ('can\'t find a doxyfile to generate the documentation')
+
+class TempDir(object):
+    """Wrap tempfile.mkdtemp to use the with statement"""
+
+    def __init__(self):
+        pass
+
+    def __enter__(self):
+        self.__path = tempfile.mkdtemp()
+        return self.__path
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        pass
+#shutil.rmtree(self.__path)
+
+def clone_repo(ui, source, dest):
+    """Clone repo at directory source to directory dest"""
+
+    commands.clone(ui, source, dest, opts={'uncompressed': True})
+    ui.status('doxyhook: working copy created.\n')
+
+def gen_doc(clone):
+    """
+    Generate the documentation with the first doxyfile found under clone
+    directory.
+
+    Return the output directory of the doc or None if no doc was generated.
+    """
+
+    # Regular expression for a doxygen configuration file:
+    doxyre = re.compile('.*[dD]oxyfile$')
+    # Regular expression used on a line of the doxygen configuration file to
+    # find the output directory:
+    outputre = re.compile('OUTPUT_DIRECTORY\\s*=\\s*(.*)$')
+
+    files = os.listdir(clone)
+    try:
+        doxyfile = (f for f in files if not os.path.isdir(f) and doxyre.match(f)).next()
+    except StopIteration:
+        raise DoxyfileNotFound
+
+    with open(os.path.join(clone, doxyfile)) as doxyconf:
+        for line in doxyconf:
+            output = outputre.match(line)
+            if output:
+                output = output.group(1)
+                break
+
+    if output:
+        with open(os.devnull, 'w') as ignore:
+            oldpwd = os.getcwd()
+            # We have to change our directory so the doc is generated at the
+            # right place.
+            os.chdir(clone)
+            subprocess.call(['doxygen', doxyfile], stdout=ignore, stderr=ignore)
+            os.chdir(oldpwd)
+        # clone will be ignored if output is an absolute path
+        html = os.path.join(clone, output, 'html')
+        if os.path.isdir(html):
+            return html
+
+    return None
+
+def move_doc(source, dest):
+    """Move the doc from source to dest"""
+
+    shutil.move(source, dest)
+
+def hook(ui, repo, hooktype, **kwargs):
+    if hooktype == 'changegroup':
+        with TempDir() as clone:
+            clone_repo(ui, repo.root, clone)
+            try:
+                output = gen_doc(clone)
+                if output:
+                    ui.status('doxyhook: doc generated.\n')
+                    move_doc(output, OUTPUT)
+                else:
+                    ui.status('doxyhook: no doc generated.\n')
+            except (OSError, DoxyfileNotFound), ex:
+                ui.status('doxyhook: %s.\n' % str(ex))
+    else:
+        ui.status('doxyhook: is a changegroup hook only.\n')
+
+if __name__ == '__main__':
+    if len(sys.argv) != 2:
+        print 'Usage: %s mercurial-repo' % os.path.basename(sys.argv[0])
+        sys.exit(1)
+
+    ui = ui.ui()
+    repo = hg.repository(ui, sys.argv[1])
+    hook(ui, repo, 'changegroup')
+    sys.exit(0)