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 master = ui.config('hgbuildbot', 'master') 51 if master: 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 s = sendchange.Sender(master, auth=auth) 92 d = defer.Deferred() 93 reactor.callLater(0, d.callback, None) 94 # process changesets 95 def _send(res, c): 96 if not fork: 97 ui.status("rev %s sent\n" % c['revision']) 98 return s.send(c['branch'], c['revision'], c['comments'], 99 c['files'], c['username'], category=category, 100 repository=repository, project=project, vc='hg', 101 properties=c['properties'])
102 103 try: # first try Mercurial 1.1+ api 104 start = repo[node].rev() 105 end = len(repo) 106 except TypeError: # else fall back to old api 107 start = repo.changelog.rev(bin(node)) 108 end = repo.changelog.count() 109 110 repository = strip(repo.root, stripcount) 111 repository = baseurl + repository 112 113 for rev in xrange(start, end): 114 # send changeset 115 node = repo.changelog.node(rev) 116 manifest, user, (time, timezone), files, desc, extra = repo.changelog.read(node) 117 parents = filter(lambda p: not p == nullid, repo.changelog.parents(node)) 118 if branchtype == 'inrepo': 119 branch = extra['branch'] 120 is_merge = len(parents) > 1 121 # merges don't always contain files, but at least one file is required by buildbot 122 if is_merge and not files: 123 files = ["merge"] 124 properties = {'is_merge': is_merge} 125 if branch: 126 branch = fromlocal(branch) 127 change = { 128 'master': master, 129 'username': fromlocal(user), 130 'revision': hex(node), 131 'comments': fromlocal(desc), 132 'files': files, 133 'branch': branch, 134 'properties':properties 135 } 136 d.addCallback(_send, change) 137 138 def _printSuccess(res): 139 ui.status(s.getSuccessString(res) + '\n') 140 141 def _printFailure(why): 142 ui.warn(s.getFailureString(why) + '\n') 143 144 d.addCallbacks(_printSuccess, _printFailure) 145 d.addBoth(lambda _ : reactor.stop()) 146 reactor.run() 147 148 if fork: 149 os._exit(os.EX_OK) 150 else: 151 return 152 153 # taken from the mercurial notify extension
154 -def strip(path, count):
155 '''Strip the count first slash of the path''' 156 157 # First normalize it 158 path = '/'.join(path.split(os.sep)) 159 # and strip it part after part 160 while count > 0: 161 c = path.find('/') 162 if c == -1: 163 break 164 path = path[c + 1:] 165 count -= 1 166 return path
167