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

Source Code for Module buildbot.changes.hgbuildbot

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