RRS: support grouping upgrades by version for multi-version recipes

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
This commit is contained in:
Paul Eggleton 2019-08-19 11:42:23 +12:00
parent ecb053472b
commit 51d7f139f8
7 changed files with 121 additions and 12 deletions

View File

@ -15,7 +15,8 @@ from django.core.exceptions import ValidationError
from rrs.models import Release, Milestone, Maintainer, RecipeMaintainerHistory, \
RecipeMaintainer, RecipeDistro, RecipeUpgrade, RecipeUpstream, \
RecipeUpstreamHistory, MaintenancePlan, MaintenancePlanLayerBranch, \
RecipeMaintenanceLink, RecipeSymbol
RecipeMaintenanceLink, RecipeSymbol, RecipeUpgradeGroupRule, \
RecipeUpgradeGroup
class MaintenancePlanLayerBranchFormSet(BaseInlineFormSet):
def __init__(self, *args, **kwargs):
@ -210,3 +211,5 @@ admin.site.register(RecipeUpstreamHistory, RecipeUpstreamHistoryAdmin)
admin.site.register(RecipeUpstream, RecipeUpstreamAdmin)
admin.site.register(RecipeMaintenanceLink, RecipeMaintenanceLinkAdmin)
admin.site.register(RecipeSymbol, RecipeSymbolAdmin)
admin.site.register(RecipeUpgradeGroupRule)
admin.site.register(RecipeUpgradeGroup)

View File

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.22 on 2019-08-19 00:56
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('layerindex', '0041_recipe_configopts'),
('rrs', '0025_recipeupgrade_move'),
]
operations = [
migrations.CreateModel(
name='RecipeUpgradeGroup',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(help_text='Group title', max_length=100)),
('recipesymbol', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rrs.RecipeSymbol')),
],
),
migrations.CreateModel(
name='RecipeUpgradeGroupRule',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('pn', models.CharField(help_text='Regular expression to match recipe to apply to', max_length=100)),
('version', models.CharField(help_text='Regular expression to split version component on', max_length=100)),
('layerbranch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='layerindex.LayerBranch')),
],
),
migrations.AddField(
model_name='recipeupgrade',
name='group',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='rrs.RecipeUpgradeGroup'),
),
]

View File

@ -6,7 +6,7 @@
import sys
import os
import os.path
import re
sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), '../')))
from datetime import date, datetime
@ -429,6 +429,38 @@ class RecipeDistro(models.Model):
return recipe_distros
class RecipeUpgradeGroup(models.Model):
recipesymbol = models.ForeignKey(RecipeSymbol)
title = models.CharField(max_length=100, help_text='Group title')
def __str__(self):
return '%s: %s' % (self.recipesymbol, self.title)
class RecipeUpgradeGroupRule(models.Model):
layerbranch = models.ForeignKey(LayerBranch)
pn = models.CharField(max_length=100, help_text='Regular expression to match recipe to apply to')
version = models.CharField(max_length=100, help_text='Regular expression to split version component on')
@staticmethod
def group_for_params(recipesymbol, version):
for rule in RecipeUpgradeGroupRule.objects.filter(layerbranch=recipesymbol.layerbranch):
if re.match(rule.pn, recipesymbol.pn):
res = re.match(rule.version, version)
if res:
if res.groups():
match = res.groups()[0]
else:
match = res.string[res.start(0):res.end(0)]
group, _ = RecipeUpgradeGroup.objects.get_or_create(recipesymbol=recipesymbol, title=match)
group.save()
return group
return None
def __str__(self):
return '%s: %s' % (self.layerbranch, self.pn)
class RecipeUpgrade(models.Model):
UPGRADE_TYPE_CHOICES = (
('U', 'Upgrade'),
@ -448,6 +480,7 @@ class RecipeUpgrade(models.Model):
upgrade_type = models.CharField(max_length=1, choices=UPGRADE_TYPE_CHOICES, default='U', db_index=True)
filepath = models.CharField(max_length=512, blank=True)
orig_filepath = models.CharField(max_length=512, blank=True)
group = models.ForeignKey(RecipeUpgradeGroup, blank=True, null=True, on_delete=models.SET_NULL)
@staticmethod
def get_by_recipe_and_date(recipe, end_date):
@ -462,6 +495,14 @@ class RecipeUpgrade(models.Model):
def commit_url(self):
return self.recipesymbol.layerbranch.commit_url(self.sha1)
def regroup(self):
group = RecipeUpgradeGroupRule.group_for_params(self.recipesymbol, self.version)
if group != self.group:
self.group = group
return True
else:
return False
def __str__(self):
if self.upgrade_type == 'R':
return '%s: deleted [final] (%s)' % (self.recipesymbol.pn,

View File

@ -86,7 +86,7 @@ def run_internal(maintplanlayerbranch, commit, commitdate, options, logger, bitb
Upgrade history handler.
"""
def upgrade_history(options, logger):
from rrs.models import MaintenancePlan, RecipeUpgrade, Release, Milestone
from rrs.models import MaintenancePlan, RecipeUpgrade, Release, Milestone, RecipeUpgradeGroupRule
logger.debug('=== BEGIN; cmdline: %s' % (' '.join(sys.argv)))
@ -101,6 +101,16 @@ def upgrade_history(options, logger):
logger.error('No enabled maintenance plans found')
sys.exit(1)
if options.regroup:
for maintplan in maintplans:
for maintplanbranch in maintplan.maintenanceplanlayerbranch_set.all():
layerbranch = maintplanbranch.layerbranch
if RecipeUpgradeGroupRule.objects.filter(layerbranch=layerbranch).exists():
for ru in RecipeUpgrade.objects.filter(recipesymbol__layerbranch=layerbranch):
if ru.regroup():
ru.save()
sys.exit(0)
lockfn = os.path.join(fetchdir, "layerindex.lock")
lockfile = utils.lock_file(lockfn)
if not lockfile:
@ -237,6 +247,10 @@ if __name__=="__main__":
help="Specify maintenance plan to operate on (default is all plans that have updates enabled)",
action="store", dest="plan", default=None)
parser.add_option("--regroup",
help="Re-group records only",
action="store_true", dest="regroup", default=False)
options, args = parser.parse_args(sys.argv)
logger.setLevel(options.loglevel)

View File

@ -117,11 +117,12 @@ oecore_bad_revs = {
],
}
"""
Store upgrade into RecipeUpgrade model.
"""
def _save_upgrade(recipesymbol, layerbranch, pv, commit, title, info, filepath, logger, upgrade_type=None, orig_filepath=None):
from rrs.models import Maintainer, RecipeUpgrade, RecipeSymbol
from rrs.models import Maintainer, RecipeUpgrade
maintainer_name = info.split(';')[0]
maintainer_email = info.split(';')[1]
@ -143,13 +144,14 @@ def _save_upgrade(recipesymbol, layerbranch, pv, commit, title, info, filepath,
upgrade.upgrade_type = upgrade_type
if orig_filepath:
upgrade.orig_filepath = orig_filepath
upgrade.regroup()
upgrade.save()
"""
Create upgrade receives new recipe_data and cmp versions.
"""
def _create_upgrade(recipe_data, layerbranch, ct, title, info, filepath, logger, pn_recipes, initial=False, orig_filepath=None):
from rrs.models import RecipeUpgrade, RecipeSymbol
from rrs.models import RecipeUpgrade, RecipeSymbol, RecipeUpgradeGroupRule
from bb.utils import vercmp_string
pn = recipe_data.getVar('PN', True)

View File

@ -624,9 +624,11 @@ class RecipeUpgradeDetail():
commit = None
commit_url = None
upgrade_type = None
group = None
def __init__(self, title, version, maintplan_name, release_name, milestone_name, date,
maintainer_name, is_recipe_maintainer, commit, commit_url, upgrade_type):
maintainer_name, is_recipe_maintainer, commit, commit_url, upgrade_type,
group):
self.title = title
self.version = version
self.maintplan_name = maintplan_name
@ -638,6 +640,7 @@ class RecipeUpgradeDetail():
self.commit = commit
self.commit_url = commit_url
self.upgrade_type = upgrade_type
self.group = group
def _get_recipe_upgrade_detail(maintplan, recipe_upgrade):
release_name = ''
@ -672,7 +675,8 @@ def _get_recipe_upgrade_detail(maintplan, recipe_upgrade):
rud = RecipeUpgradeDetail(recipe_upgrade.title, recipe_upgrade.version, \
maintplan.name, release_name, milestone_name, commit_date, maintainer_name, \
is_recipe_maintainer, commit, commit_url, recipe_upgrade.upgrade_type)
is_recipe_maintainer, commit, commit_url, recipe_upgrade.upgrade_type, \
recipe_upgrade.group)
return rud
@ -730,10 +734,13 @@ class RecipeDetailView(DetailView):
else:
context['maintainer_name'] = 'No maintainer'
context['recipe_upgrade_details'] = []
for ru in RecipeUpgrade.objects.filter(recipesymbol=recipesymbol).exclude(upgrade_type='M').order_by('-commit_date'):
context['recipe_upgrade_details'].append(_get_recipe_upgrade_detail(maintplan, ru))
context['recipe_upgrade_detail_count'] = len(context['recipe_upgrade_details'])
details = []
for ru in RecipeUpgrade.objects.filter(recipesymbol=recipesymbol).exclude(upgrade_type='M').order_by('group', '-commit_date'):
details.append(_get_recipe_upgrade_detail(maintplan, ru))
details.sort(key=lambda s: list(map(int, s.group.title.split('.') if s.group else [])), reverse=True)
context['recipe_upgrade_details'] = details
context['recipe_upgrade_detail_count'] = len(details)
if not recipe:
ru = RecipeUpgrade.objects.filter(recipesymbol=recipesymbol).order_by('-commit_date').first()

View File

@ -93,6 +93,9 @@
<th>Commit</th>
</tr>
{% for rud in recipe_upgrade_details %}
{% ifchanged rud.group %}
<tr><td colspan="6"><b>{{ rud.group.title }}</b></td></tr>
{% endifchanged %}
<tr>
<td>{{ rud.title }}</td>
<td>{% if rud.upgrade_type != 'R' %}{{ rud.version }}{% if rud.upgrade_type == 'D' %} <span class="label label-warning">downgrade</span>{% endif %}{% endif %}</td>