Commits

Fredrik Håård committed c63fb65

imported

  • Participants

Comments (0)

Files changed (5)

+pyo$
+pyc$
+~$
+\#$
+Copyright (C) 2011 by Fredrik Håård
+
+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.
+Automatic hook configuration for multiple Mercurial repositories

autohook/__init__.py

+"""
+not in any way done or working
+sample config
+[hooks]
+pretxnchangegroup = python:/path/to/autohook/autohook.py:hook
+
+[autohook]
+debug=True
+loadpath=/var/globalhooks /home/me/myhooks
+loadmodules=test
+repos = orig
+tests = adds_branch
+orig.path = C:\Users\fredrik\workspaces\test\orig
+orig.tests = has_multiple_heads test.hello
+
+""" 

autohook/autohook.py

+ # -*- coding: utf-8 -*-
+import mercurial.node
+import os.path, sys
+
+    
+def has_multiple_heads(ui, repo, user, start, end):
+    """Check if multiple heads are being added"""
+    heads = repo.heads()
+    count = 0
+    for rev in xrange(start, end):
+        if repo[rev] in heads:
+            count += 1
+    ui.debug("Found %d heads\n" % (count+1,))
+    return count > 1
+    
+
+def adds_branch(ui, repo, user, start, end):
+    """Check if a set of changes adds a new branch
+    Returns True if any revision in repo[start:end] does
+    not share branch with any parent"""
+    heads = repo.heads()
+    
+    for rev in xrange(start, end):
+        revbranch = repo[rev].branch()
+        one_parent_ok = False
+        for parent in repo[rev].parents():
+            if parent.branch() == revbranch:
+                one_parent_ok = True
+        if not one_parent_ok:
+            ui.warn("Rev %s adds a branch" % (repo[rev].hex()))
+            return True
+    return False
+
+def get_user(ui):
+    import os
+    if 'REMOTE_USER' in ui.environ: #remote
+        user = ui.environ['REMOTE_USER']
+    elif 'USER' in os.environ: #unixes
+        user = os.environ['USER']
+    elif 'USERNAME' in os.environ: #windows
+        user = os.environ['USERNAME']
+    return user
+
+
+def _get_reponame(ui, dest):
+    """Get configured name of this repository"""
+    for tmp in ui.configlist('autohook', 'repos'):
+        if os.path.abspath(ui.config('autohook', "%s.path" % tmp)) == dest:
+            return tmp
+    return None
+
+def _load_module(name, path):
+    """Find and load module"""
+    import imp
+    mod = imp.find_module(name, path)
+    globals()[name] = imp.load_module(name, *mod)
+
+
+def _load_modules(ui):
+    """Load modules configured in autohook.loadmodules"""
+    for module in ui.configlist("autohook", "loadmodules"):
+        ui.debug("Loading %s" % (module,))
+        _load_module(module, ui.configlist("autohook", "loadpath"))
+
+    
+def hook(ui, repo, url, node, hooktype, pending, **kwargs):
+        def debug(msg): 
+            if ui.configbool('autohook', 'debug') or ui.verbose: 
+                ui.write(msg + "\n")
+        def info(msg):
+            ui.write(msg + "\n")
+        def error(msg):
+            ui.write_err(msg + "\n")
+        
+        user = get_user(ui)
+        if user in ui.configlist('autohook', 'superuser'):
+            info("User %s bypassing hooks" % (user,))
+        _load_modules(ui)
+        failed_test = False
+        dest = os.path.abspath(pending())
+        reponame = _get_reponame(ui, dest)
+        if not reponame: 
+            info("Not configured for repo at %s" % (dest,))
+            return False
+
+        debug("Repo name " + reponame)
+
+        start = repo[node].rev()
+        end = len(repo)
+
+        debug("User is %s" % (user,))
+       
+        for test in (ui.configlist('autohook', 'tests') +
+                     ui.configlist('autohook', '%s.tests' % (reponame,))):
+            debug("Running " + test)
+            if "." in test:
+                names = test.split(".")
+                func = getattr(globals()[".".join(names[:-1])], names[-1])
+            else:
+                func = globals()[test]
+            if func(ui=ui, repo=repo, user=user, start=start, end=end):
+                error("Test '%s' failed" % (test,))
+                return True
+    
+        
+        return False