From 12408702eaf89ea338670ba808da9ef49e35c562 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 14 Nov 2011 12:19:17 -0600 Subject: Allow population of signoff specs with SVN commit messages This pulls them from the latest SVN commit on trunk. We don't have a failproof method of getting the exact right commit, but this should be close if it is run on a regular basis via cron (aka hourly). Note that running locally, I needed the development version of South to get the migration included here to apply because of information_schema changes in the current version of MySQL. Signed-off-by: Dan McGee --- packages/management/commands/populate_signoffs.py | 89 +++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 packages/management/commands/populate_signoffs.py (limited to 'packages/management/commands/populate_signoffs.py') diff --git a/packages/management/commands/populate_signoffs.py b/packages/management/commands/populate_signoffs.py new file mode 100644 index 00000000..5b5acbaf --- /dev/null +++ b/packages/management/commands/populate_signoffs.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +""" +populate_signoffs command + +Pull the latest commit message from SVN for a given package that is +signoff-eligible and does not have an existing comment attached. + +Usage: ./manage.py populate_signoffs +""" + +from datetime import datetime +import logging +import subprocess +import sys +from xml.etree.ElementTree import XML + +from django.conf import settings +from django.contrib.auth.models import User +from django.core.management.base import NoArgsCommand + +from ...models import SignoffSpecification +from ...utils import get_signoff_groups + +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s -> %(levelname)s: %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + stream=sys.stderr) +logger = logging.getLogger() + +class Command(NoArgsCommand): + help = "Pull the latest commit message from SVN for a given package that is signoff-eligible and does not have an existing comment attached" + + def handle_noargs(self, **options): + v = int(options.get('verbosity', None)) + if v == 0: + logger.level = logging.ERROR + elif v == 1: + logger.level = logging.INFO + elif v == 2: + logger.level = logging.DEBUG + + return add_signoff_comments() + +def svn_log(pkgbase, repo): + path = '%s%s/%s/trunk/' % (settings.SVN_BASE_URL, repo.svn_root, pkgbase) + cmd = ['svn', 'log', '--limit=1', '--xml', path] + log_data = subprocess.check_output(cmd) + # the XML format is very very simple, especially with only one revision + xml = XML(log_data) + revision = int(xml.find('logentry').get('revision')) + date = datetime.strptime(xml.findtext('logentry/date'), + '%Y-%m-%dT%H:%M:%S.%fZ') + return { + 'revision': revision, + 'date': date, + 'author': xml.findtext('logentry/author'), + 'message': xml.findtext('logentry/msg'), + } + +def create_specification(package, log): + trimmed_message = log['message'].strip() + spec = SignoffSpecification(pkgbase=package.pkgbase, + pkgver=package.pkgver, pkgrel=package.pkgrel, + epoch=package.epoch, arch=package.arch, repo=package.repo, + comments=trimmed_message) + try: + spec.user = User.objects.get(username=log['author']) + except User.DoesNotExist: + pass + + return spec + +def add_signoff_comments(): + logger.info("getting all signoff groups") + groups = get_signoff_groups() + logger.info("%d signoff groups found", len(groups)) + + for group in groups: + if not group.default_spec: + continue + + logger.debug("getting SVN log for %s (%s)", group.pkgbase, group.repo) + log = svn_log(group.pkgbase, group.repo) + logger.info("creating spec with SVN message for %s", group.pkgbase) + spec = create_specification(group.packages[0], log) + spec.save() + +# vim: set ts=4 sw=4 et: -- cgit v1.2.3-2-g168b From 0344f8ad564644c50203985255fab1d053aed463 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Tue, 15 Nov 2011 15:04:33 -0600 Subject: Add ability to cache users by username on the UserFinder This is very useful in the signoff message population script where we are very likely to encounter the same users over and over. Signed-off-by: Dan McGee --- packages/management/commands/populate_signoffs.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'packages/management/commands/populate_signoffs.py') diff --git a/packages/management/commands/populate_signoffs.py b/packages/management/commands/populate_signoffs.py index 5b5acbaf..ce5ec734 100644 --- a/packages/management/commands/populate_signoffs.py +++ b/packages/management/commands/populate_signoffs.py @@ -20,6 +20,7 @@ from django.core.management.base import NoArgsCommand from ...models import SignoffSpecification from ...utils import get_signoff_groups +from devel.utils import UserFinder logging.basicConfig( level=logging.INFO, @@ -58,17 +59,13 @@ def svn_log(pkgbase, repo): 'message': xml.findtext('logentry/msg'), } -def create_specification(package, log): +def create_specification(package, log, finder): trimmed_message = log['message'].strip() spec = SignoffSpecification(pkgbase=package.pkgbase, pkgver=package.pkgver, pkgrel=package.pkgrel, epoch=package.epoch, arch=package.arch, repo=package.repo, comments=trimmed_message) - try: - spec.user = User.objects.get(username=log['author']) - except User.DoesNotExist: - pass - + spec.user = finder.find_by_username(log['author']) return spec def add_signoff_comments(): @@ -76,6 +73,8 @@ def add_signoff_comments(): groups = get_signoff_groups() logger.info("%d signoff groups found", len(groups)) + finder = UserFinder() + for group in groups: if not group.default_spec: continue @@ -83,7 +82,7 @@ def add_signoff_comments(): logger.debug("getting SVN log for %s (%s)", group.pkgbase, group.repo) log = svn_log(group.pkgbase, group.repo) logger.info("creating spec with SVN message for %s", group.pkgbase) - spec = create_specification(group.packages[0], log) + spec = create_specification(group.packages[0], log, finder) spec.save() # vim: set ts=4 sw=4 et: -- cgit v1.2.3-2-g168b