mod_hg.py

Mon, 19 Jan 2015 16:42:36 -0500

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Mon, 19 Jan 2015 16:42:36 -0500
changeset 120
9880bb697149
parent 117
6c0609395889
child 121
ac07779f788d
permissions
-rw-r--r--

- added doomseeker support, fixed up mod_bridge, now shortens new commit links with bit.ly

from hgapi import hgapi, Repo
from datetime import datetime
import hgpoll as HgPoll
import re
import bt as Bt
from configfile import Config
from modulecore import command_error

ModuleData = {
	'commands':
	[
		{
			'name': 'checkhg',
			'description': 'Polls the zandronum repositories for updates',
			'args': None,
			'level': 'admin',
		},

		{
			'name': 'cset',
			'description': 'Yields changeset information (use a hash or date as key)',
			'args': '<key>',
			'level': 'normal',
		},

		{
			'name': 'hg',
			'description': 'Executes a hg command',
			'args': '<repo> <command...>',
			'level': 'admin',
		},

		{
			'name': 'resolves',
			'description': 'Manually cause a ticket to be resolved by a changeset',
			'args': '<ticket> <changeset>',
			'level': 'admin', # TODO
		},

		{
			'name': 'compress',
			'description': 'Compresses a head on the sandbox repositories.',
			'args': '<changeset>',
			'level': 'admin', # TODO
		}
	]
}

def plural (a):
	return '' if a == 1 else 's'

def cmd_checkhg (bot, **rest):
	HgPoll.force_poll()

def cmd_cset (bot, args, reply, **rest):
	repo = Repo ('zandronum-everything')
	data = ""
	node = args['key']

	# Possibly we're passed a date version instead. Try find the node for this.
	try:
		datetime.strptime (args['key'], '%y%m%d-%H%M')
		HgPoll.make_commits_txt()
		commits_txt = open ('commits.txt', 'r')

		for line in commits_txt:
			data = line.replace ('\n', '').split (' ')
			if data[1] == args['key']:
				node = data[0]
				break
		else:
			command_error ('couldn\'t find changeset for date %s' % args['key'])
			return
	except ValueError:
		pass

	# zandronum-everything contains all zandronum changesets, so look for changesets in that.
	try:
		data = repo.hg_command ("log", "-l1", "-r", node, "--template",
			"{node|short}@@@@@@@" +
			"{desc}@@@@@@@" +
			"{author}@@@@@@@" +
			"{diffstat}@@@@@@@" +
			"{date|hgdate}@@@@@@@" +
			"{bookmarks}@@@@@@@" +
			"{latesttagdistance}@@@@@@@" +
			"{latesttag}")
	except hgapi.HgException:
		command_error ('couldn\'t find changeset %s' % (node))
		return

	try:
		data = data.split ('@@@@@@@')
		node = data[0]
		message = data[1]
		author = data[2]
		diffstat = data[3]
		date = datetime.utcfromtimestamp (int (data[4].split (' ')[0]))
		bookmarks = data[5]
		latesttagdistance = int (data[6])
		latesttag = data[7]
		delta = datetime.utcnow() - date
		datestring = ''

		if bookmarks:
			bookmarks = HgPoll.prettify_bookmarks (bookmarks)

		# Find out the Zandronum version of this changeset
		repo.hg_command ('revert', '-r', node, 'src/version.h')
		zanversion = '<unknown zandronum version>'

		with open ('zandronum-everything/src/version.h') as version_file:
			regexps = [ \
				re.compile (r'#define\s+GAMEVER_STRING\s+"([^"]+)"'), \
				re.compile (r'#define\s+DOTVERSIONSTR_NOREV\s+"([^"]+)"'), \
				re.compile (r'#define\s+DOTVERSIONSTR\s+"([^"]+)"')]

			for line in version_file:
				for rex in regexps:
					match = rex.match (line)
					if match != None:
						zanversion = match.group (1)
						break

				if match != None:
					break


		repo.hg_command ('revert', '--all')

		# Remove the email address from the author if possible
		match = re.compile (r'^(.+) <([^>]+)>$.*').match (author)
		if match:
			author = match.group (1)
			email = match.group (2)

		username = Config.find_developer_by_email (email)

		if username != '':
			author = username

		# Try prettify the diffstat
		rex = re.compile (r'^([0-9]+): \+([0-9]+)/-([0-9]+)$')
		match = rex.match (diffstat)

		if match:
			diffstat = "%s\003:\0033 +%s\003/\0034-%s\003" % (match.group (1), match.group (2), match.group (3))

		if delta.days < 4:
			if delta.days == 0:
				if delta.seconds < 60:
					datestring = 'just now'
				elif delta.seconds < 3600:
					minutes = delta.seconds / 60
					datestring = '%d minute%s ago' % (minutes, plural (minutes))
				else:
					hours = delta.seconds / 3600
					datestring = '%d hour%s ago' % (hours, plural (hours))
			else:
				datestring = '%d day%s ago' % (delta.days, plural (delta.days))
		else:
			datestring = 'on %s' % (str (date))

		versionstring = ""
		if latesttagdistance != 0:
			versionstring = '%s %s, %d hops from %s' % (zanversion, date.strftime ('%y%m%d-%H%M'), latesttagdistance, latesttag)
		else:
			versionstring = latesttag

		reply ('changeset\0035 %s%s\003 (%s)\003: committed by\0032 %s\003 %s,\0032 %s' % \
			(node, bookmarks, versionstring, author, datestring, diffstat))

		for line in message.split ('\n'):
			reply ('    ' + line)
	except hgapi.HgException as e:
		result = HgPoll.decipher_hgapi_error (e)

		if result[0]:
			command_error (result[1])
		else:
			command_error (`e`)

def cmd_hg (bot, args, reply, **rest):
	try:
		repo = hgapi.Repo (args['repo'])
		result = repo.hg_command (*args['command'])
		reply (result)
	except hgapi.hgapi.HgException as e:
		result = HgPoll.decipher_hgapi_error (e)

		if result[0]:
			command_error (result[1])
		else:
			command_error (`e`)

def cmd_resolves (bot, args, **rest):
	try:
		HgPoll.announce_ticket_resolved (args['ticket'], args['changeset'])
	except Exception as e:
		command_error (str (e))

mercurial