# HG changeset patch # User Teemu Piippo # Date 1416255298 -7200 # Node ID 9e757b6025867d5763c2bbb50625a72f60ad2065 # Parent 6337540fb44b769ae5548aa4d9162231ccbdeb37 - added .resolves diff -r 6337540fb44b -r 9e757b602586 hgpoll.py --- a/hgpoll.py Sat Nov 15 16:50:47 2014 +0200 +++ b/hgpoll.py Mon Nov 17 22:14:58 2014 +0200 @@ -10,10 +10,10 @@ def make_commits_txt(): global g_needCommitsTxtRebuild - + if g_needCommitsTxtRebuild == False: return - + print 'Building commits.txt...' # Update zandronum-everything repo = hgapi.Repo ('zandronum-everything') @@ -21,15 +21,16 @@ repo.hg_command ('pull', '../zandronum-sandbox-stable') data = repo.hg_command ('log', '--template', '{node} {date|hgdate}\n') f = open ('commits.txt', 'w') - + for line in data.split ('\n'): if line == '': continue - + words = line.split (' ') timestamp = int (words[1]) - f.write ('%s %s\n' % (words[0], datetime.utcfromtimestamp (timestamp).strftime ('%y%m%d-%H%M'))) - + f.write ('%s %s\n' % (words[0], datetime.utcfromtimestamp (timestamp).strftime +('%y%m%d-%H%M'))) + f.close() g_needCommitsTxtRebuild = False @@ -38,15 +39,16 @@ print 'Checking that %s exists...' % repo_name repo_url = 'https://bitbucket.org/%s/%s' % (repo_owner, repo_name) zanrepo = hgapi.Repo (repo_name) - + try: zanrepo.hg_command ('id', '.') except hgapi.hgapi.HgException: - # If the repo does not exist, clone it. zandronum-everything can be spawned off other repos though + # If the repo does not exist, clone it. zandronum-everything can be spawned + # off other repos though if repo_name == 'zandronum-everything': if not os.path.exists (repo_name): os.makedirs (repo_name) - + global g_needCommitsTxtRebuild g_needCommitsTxtRebuild = True print 'Init %s' % repo_name @@ -58,7 +60,7 @@ print 'Done' make_commits_txt() return - + try: print 'Cloning %s...' % repo_name zanrepo.hg_clone (repo_url, repo_name) @@ -67,6 +69,99 @@ print 'Unable to clone %s from %s: %s' % (repo_name, repo_url, str (`e`)) quit (1) +def announce_ticket_resolved (ticket_id, commit_node): + zanrepo = hgapi.Repo ('zandronum-everything') + + # Acquire additional data + moredata = get_commit_data (zanrepo, commit_node, + '{author|nonempty}\n{date(date, \'%A %d %B %Y %T\')}').split('\n') + + if len (moredata) != 2: + Irc.broadcast ('error while processing %s: malformed hg data' % commit_node) + continue + + commit_author = moredata[0] + commit_date = moredata[1] + commit_email = "" + + try: + ticket_data = Bt.get_issue (ticket_id) + except Exception as e: + Irc.broadcast ('error while processing %s: %s' % (commit_node, `e`)) + continue + + # Remove the email address from the author if possible + rex = re.compile (r'^(.+) <([^>]+)>$.*') + match = rex.match (commit_author) + if match: + commit_author = match.group (1) + commit_email = match.group (2) + + commit_diffstat = zanrepo.hg_command ('diff', '--change', commit_node, '--stat') + + if len(commit_diffstat) > 0: + # commit_diffstat = 'Changes in files:\n[code]\n' + commit_diffstat + '\n[/code]' + commit_diffstat = 'Changes in files:\n' + bbcodify(commit_diffstat) + else: + commit_diffstat = 'No changes in files.' + + # Compare the email addresses against known developer usernames + commit_trackeruser = Config.find_developer_by_email (commit_email) + + if commit_trackeruser != '': + commit_author += ' [%s]' % commit_trackeruser + + message = 'Issue addressed by commit %s: [b][url=%s/commits/%s]%s[/url][/b]' \ + % (commit_node, repo_url, commit_node, commit_message) + message += "\nCommitted by %s on %s\n\n%s" \ + % (commit_author, commit_date, commit_diffstat) + + need_update = False + + # If not already set, set handler + if not 'handler' in ticket_data: + ticket_data['handler'] = {'name': commit_trackeruser} + need_update = True + + # Find out the status level of the ticket + needs_testing_level = 70 + + if ticket_data['status']['id'] < needs_testing_level: + ticket_data.status['id'] = needs_testing_level + need_update = True + + # Set target version if not set + if not 'target_version' in ticket_data: + ticket_data['target_version'] = '1.4' if repo_name == 'zandronum-stable' else '2.0' + need_update = True + elif (ticket_data['target_version'] == '2.0' or ticket_data['target_version'] == '2.0-beta') \ + and repo_name == 'zandronum-stable': + # Target version was 2.0 but this was just committed to zandronum-stable, adjust + ticket_data['target_version'] = '1.4' + need_update = True + elif ticket_data['target_version'] == '2.0-beta': + # Fix target version from 2.0-beta to 2.0 + ticket_data['target_version'] = '2.0' + need_update = True + + # Announce on IRC + for irc_client in Irc.all_clients: + for channel in irc_client.channels: + if channel.get_value ('btannounce', default=True): + irc_client.privmsg (channel.get_value ('name'), + "%s: commit %s fixes issue %d: %s" + % (repo_name, commit_node, ticket_id, commit_message)) + irc_client.privmsg (channel.get_value ('name'), + "Read all about it here: " + Bt.get_ticket_url (ticket_id)) + + if need_update: + # We need to remove the note data, otherwise the ticket notes + # will get unnecessary updates. WTF, MantisBT? + ticket_data.notes = [] + Bt.update_issue (ticket_id, ticket_data) + + Bt.post_note (ticket_id, message) + def init(): check_repo_exists ('zandronum', 'Torr_Samaho') check_repo_exists ('zandronum-stable', 'Torr_Samaho') @@ -90,39 +185,40 @@ def bbcodify (commit_diffstat): result = '' - + for line in commit_diffstat.split('\n'): rex = re.compile (r'^(.*)\|(.*) (\+*)(-*)(.*)$') match = rex.match (line) if match: line = '%s|%s [color=#5F7]%s[/color][color=#F53]%s[/color]%s\n' \ - % (match.group (1), match.group (2), match.group (3), match.group (4), match.group (5)) - + % (match.group (1), match.group (2), match.group (3), match.group (4), match.group +(5)) + # Tracker doesn't seem to like empty color tags line = line.replace ('[color=#5F7][/color]', '').replace ('[color=#F53][/color]', '') - + result += line - + return result def poll(): global repocheck_timeout if time.time() < repocheck_timeout: return - + for n in ['zandronum-stable', 'zandronum', 'zandronum-sandbox', 'zandronum-sandbox-stable']: poll_one_repo (n) - + hgns = Config.get_node ('hg') repocheck_timeout = time.time() + hgns.get_value ('checkinterval', default=15) * 60 def poll_one_repo (repo_name): global repocheck_timeout hgns = Config.get_node ('hg') - + if not hgns.get_value ('track', default=True): return - + usestable = repo_name == 'zandronum-stable' usesandbox = repo_name == 'zandronum-sandbox' or repo_name == 'zandronum-sandbox-stable' repo_owner = 'Torr_Samaho' if not usesandbox else 'crimsondusk' @@ -132,25 +228,25 @@ commit_data = [] delimeter = '@@@@@@@@@@' print 'Checking %s for updates' % repo_name - + try: data = zanrepo.hg_command ('incoming', '--quiet', '--template', '{node|short} {desc}' + delimeter) except hgapi.hgapi.HgException as e: deciphered = decipher_hgapi_error (e) - + if deciphered[0] and len(deciphered[1]) > 0: Irc.broadcast ("error while using hg import on %s: %s" % (repo_name, deciphered[1])) - + return except Exception as e: Irc.broadcast ("%s" % `e`) return - + for line in data.split (delimeter): if line == '': continue - + rex = re.compile (r'([^ ]+) (.+)') match = rex.match (line) failed = False @@ -158,20 +254,20 @@ if not match: Irc.broadcast ('malformed hg data: %s' % line) continue - + commit_node = match.group (1) commit_message = match.group (2) commit_data.append ([commit_node, commit_message]) - + print '%d new commits on %s' % (len (commit_data), repo_name) - + if len (commit_data) > 0: pull_args = []; - + for commit in commit_data: pull_args.append ('-r'); pull_args.append (commit[0]); - + print 'Pulling new commits...' try: zanrepo.hg_command ('pull', *pull_args) @@ -180,7 +276,7 @@ if usestable: devrepo = hgapi.Repo ('zandronum') devrepo.hg_command ('pull', '../zandronum-stable', *pull_args) - + # Pull everything into sandboxes too if not usesandbox: devrepo = hgapi.Repo ('zandronum-sandbox') @@ -188,7 +284,7 @@ devrepo = hgapi.Repo ('zandronum-sandbox-stable') devrepo.hg_command ('pull', '../%s' % repo_name, *pull_args) - + devrepo = hgapi.Repo ('zandronum-everything') devrepo.hg_command ('pull', '../%s' % repo_name, *pull_args) @@ -197,138 +293,48 @@ except Exception as e: Irc.broadcast ('Warning: unable to pull: %s' % `e`) return - + for commit in commit_data: commit_node = commit[0] commit_message = commit[1] print 'Processing new commit %s...' % commit_node - + try: if usesandbox: commit_author = get_commit_data (zanrepo, commit_node, '{author}') commit_url = '%s/commits/%s' % (repo_url, commit_node) commit_email = '' - + # Remove the email address from the author if possible rex = re.compile (r'^(.+) <([^>]+)>$.*') match = rex.match (commit_author) if match: commit_author = match.group (1) commit_email = match.group (2) - + commit_trackeruser = Config.find_developer_by_email (commit_email) committer = commit_trackeruser if commit_trackeruser != '' else commit_author - + for irc_client in Irc.all_clients: for channel in irc_client.channels: if channel.get_value ('btprivate', False): irc_client.privmsg (channel.get_value ('name'), "%s: new commit %s by %s: %s" % (repo_name, commit_node, committer, commit_url)) - + for line in commit_message.split ('\n'): irc_client.privmsg (channel.get_value ('name'), line) - + num_commits += 1 continue - + rex = re.compile (r'^.*(fixes|resolves|addresses|should fix) ([0-9]+).*$') match = rex.match (commit_message) - + if not match: continue # no "fixes" message in the commit - - ticket_id = int (match.group (2)) - - # Acquire additional data - moredata = get_commit_data (zanrepo, commit_node, - '{author|nonempty}\n{date(date, \'%A %d %B %Y %T\')}').split('\n') - - if len (moredata) != 2: - Irc.broadcast ('error while processing %s: malformed hg data' % commit_node) - continue - - commit_author = moredata[0] - commit_date = moredata[1] - commit_email = "" - - try: - ticket_data = Bt.get_issue (ticket_id) - except Exception as e: - Irc.broadcast ('error while processing %s: %s' % (commit_node, `e`)) - continue - - # Remove the email address from the author if possible - rex = re.compile (r'^(.+) <([^>]+)>$.*') - match = rex.match (commit_author) - if match: - commit_author = match.group (1) - commit_email = match.group (2) - - commit_diffstat = zanrepo.hg_command ('diff', '--change', commit_node, '--stat') - - if len(commit_diffstat) > 0: - # commit_diffstat = 'Changes in files:\n[code]\n' + commit_diffstat + '\n[/code]' - commit_diffstat = 'Changes in files:\n' + bbcodify(commit_diffstat) - else: - commit_diffstat = 'No changes in files.' - - # Compare the email addresses against known developer usernames - commit_trackeruser = Config.find_developer_by_email (commit_email) - - if commit_trackeruser != '': - commit_author += ' [%s]' % commit_trackeruser - - message = 'Issue addressed by commit %s: [b][url=%s/commits/%s]%s[/url][/b]' \ - % (commit_node, repo_url, commit_node, commit_message) - message += "\nCommitted by %s on %s\n\n%s" \ - % (commit_author, commit_date, commit_diffstat) - - need_update = False - - # If not already set, set handler - if not 'handler' in ticket_data: - ticket_data['handler'] = {'name': commit_trackeruser} - need_update = True - - # Find out the status level of the ticket - needs_testing_level = 70 - if ticket_data['status']['id'] < needs_testing_level: - ticket_data.status['id'] = needs_testing_level - need_update = True - - # Set target version if not set - if not 'target_version' in ticket_data: - ticket_data['target_version'] = '1.4' if repo_name == 'zandronum-stable' else '2.0' - need_update = True - elif (ticket_data['target_version'] == '2.0' or ticket_data['target_version'] == '2.0-beta') \ - and repo_name == 'zandronum-stable': - # Target version was 2.0 but this was just committed to zandronum-stable, adjust - ticket_data['target_version'] = '1.4' - need_update = True - elif ticket_data['target_version'] == '2.0-beta': - # Fix target version from 2.0-beta to 2.0 - ticket_data['target_version'] = '2.0' - need_update = True - - # Announce on IRC - for irc_client in Irc.all_clients: - for channel in irc_client.channels: - if channel.get_value ('btannounce', default=True): - irc_client.privmsg (channel.get_value ('name'), - "%s: commit %s fixes issue %d: %s" - % (repo_name, commit_node, ticket_id, commit_message)) - irc_client.privmsg (channel.get_value ('name'), - "Read all about it here: " + Bt.get_ticket_url (ticket_id)) - - if need_update: - # We need to remove the note data, otherwise the ticket notes - # will get unnecessary updates. WTF, MantisBT? - ticket_data.notes = [] - Bt.update_issue (ticket_id, ticket_data) - - Bt.post_note (ticket_id, message) + announce_ticket_resolved (match.group (2), commit_node) num_commits += 1 except Exception as e: Irc.broadcast ('Error while processing %s: %s' % (commit_node, e)) diff -r 6337540fb44b -r 9e757b602586 mod_hgpoll.py --- a/mod_hgpoll.py Sat Nov 15 16:50:47 2014 +0200 +++ b/mod_hgpoll.py Mon Nov 17 22:14:58 2014 +0200 @@ -25,7 +25,13 @@ 'description': 'Executes a hg command', 'args': ' ', 'level': 'admin', - } + }, + { + 'name': 'resolves', + 'description': 'Manually cause a ticket to be resolved by a changeset', + 'args': ' ', + 'level': 'admin', + }, ] } @@ -149,4 +155,10 @@ if result[0]: self.privmsg (replyto, 'error: %s' % result[1]) else: - self.privmsg (replyto, 'error: %s' % `e`) \ No newline at end of file + self.privmsg (replyto, 'error: %s' % `e`) + +def cmd_resolves (bot, args, replyto, **rest): + try: + HgPoll.announce_ticket_resolved (args['ticket'], args['changeset']) + except Exception as e: + bot.privmsg (replyto, 'Error: %s' % e)