Paste #19159

Welcome On LodgeIt

Welcome to the LodgeIt pastebin. In order to use the notification feature a 31 day cookie with an unique ID was created for you. The lodgeit database does not store any information about you, it's just used for an advanced pastebin experience :-). Read more on the about lodgeit page. Have fun :-)

hide this notification

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
Index: versioncontrol/api.py
===================================================================
--- versioncontrol/api.py       (revision 6374)
+++ versioncontrol/api.py       (working copy)
@@ -49,6 +49,18 @@
         """
 
 
+class IRepositoryListener(Interface):
+    """Extension point interface for components that require notification
+    when changesets are commited or pushed to the server.  This requires the
+    trac-post-commit-hook."""
+
+    def changeset_commited(chgset):
+        """Called after a changeset is commited."""
+
+    def changeset_synced(chgset):
+        """Called if a changeset is (re)synced."""
+
+
 class RepositoryManager(Component):
     """Component registering the supported version control systems,
 
Index: versioncontrol/hook.py
===================================================================
--- versioncontrol/hook.py      (revision 0)
+++ versioncontrol/hook.py      (revision 0)
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2005-2006 Edgewall Software
+# Copyright (C) 2008 Armin Ronacher <armin.ronacher@active-4.com>
+# All rights reserved.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://trac.edgewall.org/wiki/TracLicense.
+#
+# This software consists of voluntary contributions made by many
+# individuals. For the exact contribution history, see the revision
+# history and logs, available at http://trac.edgewall.org/log/.
+#
+# Author: Armin Ronacher <armin.ronacher@active-4.com>
+
+import sys
+from trac import __version__ as VERSION
+from trac.core import *
+from trac.versioncontrol import IRepositoryListener, NoSuchChangeset
+from trac.env import open_environment
+from optparse import OptionParser
+
+
+option_parser = OptionParser(version='trac-post-commit-hook ' + VERSION)
+opt = option_parser.add_option
+fail = option_parser.error
+opt('-e', '--env', dest='env',
+    help='The path to the trac environment folder.')
+opt('-r', '--rev', dest='rev',
+    help='The revision id for the changeset.')
+
+
+class CommitHook(Component):
+    repository_listeners = ExtensionPoint(IRepositoryListener)
+
+    def changeset_commited(self, chgset):
+        for listener in self.repository_listeners:
+            listener.changeset_commited(chgset)
+
+
+def post_commit_hook(args=None):
+    """Main entry point."""
+    if args is None:
+        args = sys.argv[1:]
+    options, args = option_parser.parse_args(args)
+    if not (options.rev and options.env):
+        fail('Environment and revision required.')
+
+    try:
+        env = open_environment(options.env)
+    except IOError, e:
+        if e.errno == 2:
+            fail('Not a valid trac environment')
+        raise
+
+    repo = env.get_repository()
+    repo.sync()
+    try:
+        chgset = repo.get_changeset(options.rev)
+    except NoSuchChangeset:
+        return
+    CommitHook(env).changeset_commited(chgset)
Index: versioncontrol/cache.py
===================================================================
--- versioncontrol/cache.py     (revision 6374)
+++ versioncontrol/cache.py     (working copy)
@@ -17,11 +17,11 @@
 import posixpath
 from datetime import datetime
 
-from trac.core import TracError
+from trac.core import TracError, ExtensionPoint
 from trac.util.datefmt import utc, to_timestamp
 from trac.util.translation import _
 from trac.versioncontrol import Changeset, Node, Repository, Authorizer, \
-                                NoSuchChangeset
+                                NoSuchChangeset, IRepositoryListener
 
 
 _kindmap = {'D': Node.DIRECTORY, 'F': Node.FILE}
@@ -36,6 +36,7 @@
 
 
 class CachedRepository(Repository):
+    repository_listeners = ExtensionPoint(IRepositoryListener)
 
     def __init__(self, db, repos, authz, log):
         Repository.__init__(self, repos.name, authz, log)
@@ -73,6 +74,8 @@
                                         cset.author, cset.message,
                                         (str(cset.rev))))
         self.db.commit()
+        for listener in self.repository_listeners:
+            listener.changeset_synced(cset)
         
     def sync(self, feedback=None):
         cursor = self.db.cursor()
@@ -203,7 +206,7 @@
                                         path, kind, action, bpath, brev))
 
                     # 1.3. iterate (1.1 should always succeed now)
-                    self.youngest = next_youngest                    
+                    self.youngest = next_youngest
                     next_youngest = self.repos.next_rev(next_youngest)
 
                     # 1.4. update 'youngest_rev' metadata (minimize failures at 0.)
@@ -211,6 +214,9 @@
                                    (str(self.youngest), CACHE_YOUNGEST_REV))
                     self.db.commit()
 
+                    for listener in self.repository_listeners:
+                        listener.changeset_synced(self.youngest)
+
                     # 1.5. provide some feedback
                     if feedback:
                         feedback(self.youngest)