Package buildbot :: Package changes :: Module hgbuildbot
[frames] | no frames]

Source Code for Module buildbot.changes.hgbuildbot

  1  # hgbuildbot.py - mercurial hooks for buildbot 
  2  # 
  3  # Copyright 2007 Frederic Leroy <fredo@starox.org> 
  4  # 
  5  # This software may be used and distributed according to the terms 
  6  # of the GNU General Public License, incorporated herein by reference. 
  7   
  8  # hook extension to send change notifications to buildbot when a changeset is 
  9  # brought into the repository from elsewhere. 
 10  # 
 11  # default mode is to use mercurial branch 
 12  # 
 13  # to use, configure hgbuildbot in .hg/hgrc like this: 
 14  # 
 15  #   [hooks] 
 16  #   changegroup = python:buildbot.changes.hgbuildbot.hook 
 17  # 
 18  #   [hgbuildbot] 
 19  #   # config items go in here 
 20  # 
 21  # config items: 
 22  # 
 23  # REQUIRED: 
 24  #   master = host:port                   # host to send buildbot changes 
 25  # 
 26  # OPTIONAL: 
 27  #   branchtype = inrepo|dirname          # dirname: branch = name of directory 
 28  #                                        #          containing the repository 
 29  #                                        # 
 30  #                                        # inrepo:  branch = mercurial branch 
 31  # 
 32  #   branch = branchname                  # if set, branch is always branchname 
 33  # 
 34  #   fork = True|False                    # if mercurial should fork before  
 35  #                                        # notifying the master 
 36  # 
 37  #   strip = 3                            # number of path to strip for local  
 38  #                                        # repo path to form 'repository' 
 39  # 
 40  #   category = None                      # category property 
 41  #   project = ''                         # project this repository belong to 
 42   
 43  import os 
 44   
 45  from mercurial.node import bin, hex, nullid #@UnresolvedImport 
 46  from mercurial.context import workingctx #@UnresolvedImport 
 47   
 48  # mercurial's on-demand-importing hacks interfere with the: 
 49  #from zope.interface import Interface 
 50  # that Twisted needs to do, so disable it. 
 51  try: 
 52      from mercurial import demandimport 
 53      demandimport.disable() 
 54  except ImportError: 
 55      pass 
 56   
57 -def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
58 # read config parameters 59 master = ui.config('hgbuildbot', 'master') 60 if master: 61 branchtype = ui.config('hgbuildbot', 'branchtype') 62 branch = ui.config('hgbuildbot', 'branch') 63 fork = ui.configbool('hgbuildbot', 'fork', False) 64 # notify also has this setting 65 stripcount = int(ui.config('notify','strip') or ui.config('hgbuildbot','strip',3)) 66 category = ui.config('hgbuildbot', 'category', None) 67 project = ui.config('hgbuildbot', 'project', '') 68 else: 69 ui.write("* You must add a [hgbuildbot] section to .hg/hgrc in " 70 "order to use buildbot hook\n") 71 return 72 73 if hooktype != "changegroup": 74 ui.status("hgbuildbot: hooktype %s not supported.\n" % hooktype) 75 return 76 77 if fork: 78 child_pid = os.fork() 79 if child_pid == 0: 80 #child 81 pass 82 else: 83 #parent 84 ui.status("Notifying buildbot...\n") 85 return 86 87 # only import inside the fork if forked 88 from buildbot.clients import sendchange 89 from twisted.internet import defer, reactor 90 91 if branch is None: 92 if branchtype is not None: 93 if branchtype == 'dirname': 94 branch = os.path.basename(repo.root) 95 if branchtype == 'inrepo': 96 branch = workingctx(repo).branch() 97 98 s = sendchange.Sender(master, None) 99 d = defer.Deferred() 100 reactor.callLater(0, d.callback, None) 101 # process changesets 102 def _send(res, c): 103 if not fork: 104 ui.status("rev %s sent\n" % c['revision']) 105 return s.send(c['branch'], c['revision'], c['comments'], 106 c['files'], c['username'], category=category, 107 repository=repository, project=project)
108 109 try: # first try Mercurial 1.1+ api 110 start = repo[node].rev() 111 end = len(repo) 112 except TypeError: # else fall back to old api 113 start = repo.changelog.rev(bin(node)) 114 end = repo.changelog.count() 115 116 repository = strip(repo.root, stripcount) 117 118 for rev in xrange(start, end): 119 # send changeset 120 node = repo.changelog.node(rev) 121 manifest, user, (time, timezone), files, desc, extra = repo.changelog.read(node) 122 parents = filter(lambda p: not p == nullid, repo.changelog.parents(node)) 123 if branchtype == 'inrepo': 124 branch = extra['branch'] 125 # merges don't always contain files, but at least one file is required by buildbot 126 if len(parents) > 1 and not files: 127 files = ["merge"] 128 change = { 129 'master': master, 130 'username': user, 131 'revision': hex(node), 132 'comments': desc, 133 'files': files, 134 'branch': branch 135 } 136 d.addCallback(_send, change) 137 138 d.addCallbacks(s.printSuccess, s.printFailure) 139 d.addBoth(s.stop) 140 s.run() 141 142 if fork: 143 os._exit(os.EX_OK) 144 else: 145 return 146 147 # taken from the mercurial notify extension
148 -def strip(path, count):
149 '''Strip the count first slash of the path''' 150 151 # First normalize it 152 path = '/'.join(path.split(os.sep)) 153 # and strip it part after part 154 while count > 0: 155 c = path.find('/') 156 if c == -1: 157 break 158 path = path[c + 1:] 159 count -= 1 160 return path
161