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  import os 
 57   
 58  from mercurial.node import bin, hex, nullid  
 59  from mercurial.context import workingctx  
 60   
 61   
 62   
 63   
 64  try: 
 65      from mercurial import demandimport 
 66      demandimport.disable() 
 67  except ImportError: 
 68      pass 
 69   
 70   
 71   
 72   
 73  try: 
 74      from mercurial.encoding import fromlocal 
 75      _hush_pyflakes = [fromlocal] 
 76      del _hush_pyflakes 
 77  except ImportError: 
 80   
 81 -def hook(ui, repo, hooktype, node=None, source=None, **kwargs): 
  82       
 83      master = ui.config('hgbuildbot', 'master') 
 84      if master: 
 85          branchtype = ui.config('hgbuildbot', 'branchtype') 
 86          branch = ui.config('hgbuildbot', 'branch') 
 87          fork = ui.configbool('hgbuildbot', 'fork', False) 
 88           
 89          stripcount = int(ui.config('notify','strip') or ui.config('hgbuildbot','strip',3)) 
 90          category = ui.config('hgbuildbot', 'category', None) 
 91          project = ui.config('hgbuildbot', 'project', '') 
 92          auth = ui.config('hgbuildbot', 'auth', None) 
 93      else: 
 94          ui.write("* You must add a [hgbuildbot] section to .hg/hgrc in " 
 95                   "order to use buildbot hook\n") 
 96          return 
 97   
 98      if hooktype != "changegroup": 
 99          ui.status("hgbuildbot: hooktype %s not supported.\n" % hooktype) 
100          return 
101   
102      if fork: 
103          child_pid = os.fork() 
104          if child_pid == 0: 
105               
106              pass 
107          else: 
108               
109              ui.status("Notifying buildbot...\n") 
110              return 
111   
112       
113      from buildbot.clients import sendchange 
114      from twisted.internet import defer, reactor 
115   
116      if branch is None: 
117          if branchtype is not None: 
118              if branchtype == 'dirname': 
119                  branch = os.path.basename(repo.root) 
120              if branchtype == 'inrepo': 
121                  branch = workingctx(repo).branch() 
122   
123      if not auth: 
124          auth = 'change:changepw' 
125      auth = auth.split(':', 1) 
126   
127      s = sendchange.Sender(master, auth=auth) 
128      d = defer.Deferred() 
129      reactor.callLater(0, d.callback, None) 
130       
131      def _send(res, c): 
132          if not fork: 
133              ui.status("rev %s sent\n" % c['revision']) 
134          return s.send(c['branch'], c['revision'], c['comments'], 
135                        c['files'], c['username'], category=category, 
136                        repository=repository, project=project) 
 137   
138      try:     
139          start = repo[node].rev() 
140          end = len(repo) 
141      except TypeError:    
142          start = repo.changelog.rev(bin(node)) 
143          end = repo.changelog.count() 
144   
145      repository = strip(repo.root, stripcount) 
146   
147      for rev in xrange(start, end): 
148           
149          node = repo.changelog.node(rev) 
150          manifest, user, (time, timezone), files, desc, extra = repo.changelog.read(node) 
151          parents = filter(lambda p: not p == nullid, repo.changelog.parents(node)) 
152          if branchtype == 'inrepo': 
153              branch = extra['branch'] 
154           
155          if len(parents) > 1 and not files: 
156              files = ["merge"] 
157          if branch: 
158              branch = fromlocal(branch) 
159          change = { 
160              'master': master, 
161              'username': fromlocal(user), 
162              'revision': hex(node), 
163              'comments': fromlocal(desc), 
164              'files': files, 
165              'branch': branch 
166          } 
167          d.addCallback(_send, change) 
168   
169      def _printSuccess(res): 
170          ui.status(s.getSuccessString(res) + '\n') 
171   
172      def _printFailure(why): 
173          ui.warn(s.getFailureString(why) + '\n') 
174   
175      d.addCallbacks(_printSuccess, _printFailure) 
176      d.addBoth(lambda _ : reactor.stop()) 
177      reactor.run() 
178   
179      if fork: 
180          os._exit(os.EX_OK) 
181      else: 
182          return 
183   
184   
186      '''Strip the count first slash of the path''' 
187   
188       
189      path = '/'.join(path.split(os.sep)) 
190       
191      while count > 0: 
192          c = path.find('/') 
193          if c == -1: 
194              break 
195          path = path[c + 1:] 
196          count -= 1 
197      return path 
 198