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  # See the Buildbot manual for configuration instructions. 
 21   
 22  import os 
 23   
 24  from mercurial.node import bin, hex, nullid #@UnresolvedImport 
 25   
 26  # mercurial's on-demand-importing hacks interfere with the: 
 27  #from zope.interface import Interface 
 28  # that Twisted needs to do, so disable it. 
 29  try: 
 30      from mercurial import demandimport 
 31      demandimport.disable() 
 32  except ImportError: 
 33      pass 
 34   
 35  # In Mercurial post-1.7, some strings might be stored as a 
 36  # encoding.localstr class. encoding.fromlocal will translate 
 37  # those back to UTF-8 strings. 
 38  try: 
 39      from mercurial.encoding import fromlocal 
 40      _hush_pyflakes = [fromlocal] 
 41      del _hush_pyflakes 
 42  except ImportError: 
43 - def fromlocal(s):
44 return s
45
46 -def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
47 # read config parameters 48 baseurl = ui.config('hgbuildbot', 'baseurl', 49 ui.config('web', 'baseurl', '')) 50 masters = ui.configlist('hgbuildbot', 'master') 51 if masters: 52 branchtype = ui.config('hgbuildbot', 'branchtype', 'inrepo') 53 branch = ui.config('hgbuildbot', 'branch') 54 fork = ui.configbool('hgbuildbot', 'fork', False) 55 # notify also has this setting 56 stripcount = int(ui.config('notify','strip') or ui.config('hgbuildbot','strip',3)) 57 category = ui.config('hgbuildbot', 'category', None) 58 project = ui.config('hgbuildbot', 'project', '') 59 auth = ui.config('hgbuildbot', 'auth', None) 60 else: 61 ui.write("* You must add a [hgbuildbot] section to .hg/hgrc in " 62 "order to use buildbot hook\n") 63 return 64 65 if hooktype != "changegroup": 66 ui.status("hgbuildbot: hooktype %s not supported.\n" % hooktype) 67 return 68 69 if fork: 70 child_pid = os.fork() 71 if child_pid == 0: 72 #child 73 pass 74 else: 75 #parent 76 ui.status("Notifying buildbot...\n") 77 return 78 79 # only import inside the fork if forked 80 from buildbot.clients import sendchange 81 from twisted.internet import defer, reactor 82 83 if branch is None: 84 if branchtype == 'dirname': 85 branch = os.path.basename(repo.root) 86 87 if not auth: 88 auth = 'change:changepw' 89 auth = auth.split(':', 1) 90 91 # process changesets 92 def _send(res, s, c): 93 if not fork: 94 ui.status("rev %s sent\n" % c['revision']) 95 return s.send(c['branch'], c['revision'], c['comments'], 96 c['files'], c['username'], category=category, 97 repository=repository, project=project, vc='hg', 98 properties=c['properties'])
99 100 try: # first try Mercurial 1.1+ api 101 start = repo[node].rev() 102 end = len(repo) 103 except TypeError: # else fall back to old api 104 start = repo.changelog.rev(bin(node)) 105 end = repo.changelog.count() 106 107 repository = strip(repo.root, stripcount) 108 repository = baseurl + repository 109 110 for master in masters: 111 s = sendchange.Sender(master, auth=auth) 112 d = defer.Deferred() 113 reactor.callLater(0, d.callback, None) 114 115 for rev in xrange(start, end): 116 # send changeset 117 node = repo.changelog.node(rev) 118 manifest, user, (time, timezone), files, desc, extra = repo.changelog.read(node) 119 parents = filter(lambda p: not p == nullid, repo.changelog.parents(node)) 120 if branchtype == 'inrepo': 121 branch = extra['branch'] 122 is_merge = len(parents) > 1 123 # merges don't always contain files, but at least one file is required by buildbot 124 if is_merge and not files: 125 files = ["merge"] 126 properties = {'is_merge': is_merge} 127 if branch: 128 branch = fromlocal(branch) 129 change = { 130 'master': master, 131 'username': fromlocal(user), 132 'revision': hex(node), 133 'comments': fromlocal(desc), 134 'files': files, 135 'branch': branch, 136 'properties':properties 137 } 138 d.addCallback(_send, s, change) 139 140 def _printSuccess(res): 141 ui.status(s.getSuccessString(res) + '\n') 142 143 def _printFailure(why): 144 ui.warn(s.getFailureString(why) + '\n') 145 146 d.addCallbacks(_printSuccess, _printFailure) 147 d.addBoth(lambda _ : reactor.stop()) 148 reactor.run() 149 150 if fork: 151 os._exit(os.EX_OK) 152 else: 153 return 154 155 # taken from the mercurial notify extension
156 -def strip(path, count):
157 '''Strip the count first slash of the path''' 158 159 # First normalize it 160 path = '/'.join(path.split(os.sep)) 161 # and strip it part after part 162 while count > 0: 163 c = path.find('/') 164 if c == -1: 165 break 166 path = path[c + 1:] 167 count -= 1 168 return path
169