From 6a332c5d8fa9ceb59be7f5e1c1db5dda11cd55ce Mon Sep 17 00:00:00 2001 From: Paul Eggleton Date: Tue, 3 Apr 2018 15:30:00 +1200 Subject: [PATCH] rrs: handle linking maintainership Provide a mechanism set the maintainer for things like gcc-cross- to the same as gcc. (We do have entries in the .inc file for these, however they aren't useful as they don't match the recipe name when we parse it, and due to the fact that RecipeMaintainer objects link directly to Recipe objects, we can't handle entries that don't map to a real recipe). Signed-off-by: Paul Eggleton --- rrs/admin.py | 7 +++- rrs/migrations/0010_recipemaintenancelink.py | 40 ++++++++++++++++++++ rrs/models.py | 20 ++++++++++ rrs/tools/rrs_maintainer_history.py | 26 ++++++++++--- 4 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 rrs/migrations/0010_recipemaintenancelink.py diff --git a/rrs/admin.py b/rrs/admin.py index fbebc65..d00785f 100644 --- a/rrs/admin.py +++ b/rrs/admin.py @@ -9,7 +9,8 @@ from django.contrib.admin import DateFieldListFilter from rrs.models import Release, Milestone, Maintainer, RecipeMaintainerHistory, \ RecipeMaintainer, RecipeDistro, RecipeUpgrade, RecipeUpstream, \ - RecipeUpstreamHistory, MaintenancePlan, MaintenancePlanLayerBranch + RecipeUpstreamHistory, MaintenancePlan, MaintenancePlanLayerBranch, \ + RecipeMaintenanceLink class MaintenancePlanLayerBranchInline(admin.StackedInline): model = MaintenancePlanLayerBranch @@ -70,6 +71,9 @@ class RecipeUpstreamAdmin(admin.ModelAdmin): 'type', ('date', DateFieldListFilter), 'history'] model = RecipeUpstream +class RecipeMaintenanceLinkAdmin(admin.ModelAdmin): + model = RecipeMaintenanceLink + admin.site.register(MaintenancePlan, MaintenancePlanAdmin) admin.site.register(Release, ReleaseAdmin) admin.site.register(Milestone, MilestoneAdmin) @@ -80,3 +84,4 @@ admin.site.register(RecipeDistro, RecipeDistroAdmin) admin.site.register(RecipeUpgrade, RecipeUpgradeAdmin) admin.site.register(RecipeUpstreamHistory, RecipeUpstreamHistoryAdmin) admin.site.register(RecipeUpstream, RecipeUpstreamAdmin) +admin.site.register(RecipeMaintenanceLink, RecipeMaintenanceLinkAdmin) diff --git a/rrs/migrations/0010_recipemaintenancelink.py b/rrs/migrations/0010_recipemaintenancelink.py new file mode 100644 index 0000000..2d94f44 --- /dev/null +++ b/rrs/migrations/0010_recipemaintenancelink.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +def insert_initial_link_data(apps, schema_editor): + RecipeMaintenanceLink = apps.get_model('rrs', 'RecipeMaintenanceLink') + + r = RecipeMaintenanceLink(pn_match='gcc-cross-*', pn_target='gcc') + r.save() + r = RecipeMaintenanceLink(pn_match='gcc-crosssdk-*', pn_target='gcc') + r.save() + r = RecipeMaintenanceLink(pn_match='gcc-source-*', pn_target='gcc') + r.save() + r = RecipeMaintenanceLink(pn_match='binutils-cross-*', pn_target='binutils') + r.save() + r = RecipeMaintenanceLink(pn_match='binutils-crosssdk-*', pn_target='binutils') + r.save() + r = RecipeMaintenanceLink(pn_match='gdb-cross-*', pn_target='gdb') + r.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('rrs', '0009_rmh_layerbranch'), + ] + + operations = [ + migrations.CreateModel( + name='RecipeMaintenanceLink', + fields=[ + ('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)), + ('pn_match', models.CharField(max_length=100, help_text='Expression to match against pn of recipes that should be linked (glob expression)')), + ('pn_target', models.CharField(max_length=100, help_text='Name of recipe to link to')), + ], + ), + migrations.RunPython(insert_initial_link_data, reverse_code=migrations.RunPython.noop), + ] diff --git a/rrs/models.py b/rrs/models.py index 536f3b1..c86dc93 100644 --- a/rrs/models.py +++ b/rrs/models.py @@ -408,3 +408,23 @@ class RecipeUpgrade(models.Model): return '%s: (%s, %s)' % (self.recipe.pn, self.version, self.commit_date) + +class RecipeMaintenanceLink(models.Model): + pn_match = models.CharField(max_length=100, help_text='Expression to match against pn of recipes that should be linked (glob expression)') + pn_target = models.CharField(max_length=100, help_text='Name of recipe to link to') + + @staticmethod + def link_maintainer(pn, rmh): + import fnmatch + for rml in RecipeMaintenanceLink.objects.all(): + if fnmatch.fnmatch(pn, rml.pn_match): + recipe_link_objs = rmh.layerbranch.recipe_set.filter(pn=rml.pn_target) + if recipe_link_objs: + lrm = RecipeMaintainer.objects.filter(recipe=recipe_link_objs[0], history=rmh) + if lrm: + return lrm[0] + return None + + + def __str__(self): + return '%s -> %s' % (self.pn_match, self.pn_target) diff --git a/rrs/tools/rrs_maintainer_history.py b/rrs/tools/rrs_maintainer_history.py index 6585f5b..8af658f 100755 --- a/rrs/tools/rrs_maintainer_history.py +++ b/rrs/tools/rrs_maintainer_history.py @@ -22,7 +22,7 @@ from django.db import transaction import settings from layerindex.models import Recipe, LayerBranch, LayerItem -from rrs.models import MaintenancePlan, Maintainer, RecipeMaintainerHistory, RecipeMaintainer +from rrs.models import MaintenancePlan, Maintainer, RecipeMaintainerHistory, RecipeMaintainer, RecipeMaintenanceLink from django.core.exceptions import ObjectDoesNotExist # FIXME we shouldn't be hardcoded to expect RECIPE_MAINTAINER to be set in this file, @@ -150,11 +150,18 @@ def maintainer_history(options, logger): if not RecipeMaintainer.objects.filter(recipe = recipe, history = rms): rm = RecipeMaintainer() rm.recipe = recipe - rm.maintainer = no_maintainer + link_maintainer = RecipeMaintenanceLink.link_maintainer(recipe.pn, rms) + if link_maintainer: + rm.maintainer = link_maintainer.maintainer + else: + rm.maintainer = no_maintainer rm.history = rms rm.save() - logger.debug("%s: Not found maintainer in commit %s set to 'No maintainer'." % \ - (recipe.pn, rms.sha1)) + if link_maintainer: + logger.debug("%s: linked to maintainer for %s" % (recipe.pn, link_maintainer.recipe.pn)) + else: + logger.debug("%s: Not found maintainer in commit %s set to 'No maintainer'." % \ + (recipe.pn, rms.sha1)) # set new recipes to no maintainer if don't have one rms = RecipeMaintainerHistory.get_last() @@ -162,10 +169,17 @@ def maintainer_history(options, logger): if not RecipeMaintainer.objects.filter(recipe = recipe, history = rms): rm = RecipeMaintainer() rm.recipe = recipe - rm.maintainer = no_maintainer + link_maintainer = RecipeMaintenanceLink.link_maintainer(recipe.pn, rms) + if link_maintainer: + rm.maintainer = link_maintainer.maintainer + else: + rm.maintainer = no_maintainer rm.history = rms rm.save() - logger.debug("%s: New recipe not found maintainer set to 'No maintainer'." % \ + if link_maintainer: + logger.debug("%s: New recipe linked to maintainer for %s" % (recipe.pn, link_maintainer.recipe.pn)) + else: + logger.debug("%s: New recipe not found maintainer set to 'No maintainer'." % \ (recipe.pn)) if options.dry_run: raise DryRunRollbackException