sorry, wrong patch. please, ignore. On Tue, Jun 07, 2016 at 11:47:22AM +0300, Ed Bartosh wrote: > From: Michael Wood <[email protected]> > > After porting the build table to a unified mechanism for showing > dependencies in tables it highlighted that the dependencies selected to > be shown were un-filtered. i.e. all dependencies from all contexts were > shown. The context for a package's dependencies is based on the target > that they were installed onto, or if not installed then a "None" target. > > Depending on where the template for the dependencies are show we need to > switch this target which is why a filter and utility function on the > model is added. > > Additionally to use the same templates in the build analysis we also > need to optionally add links to the build data for the packages being > displayed as dependencies. > > Customising a Custom image recipes may or may not have a target > depending on whether they have been built or not, if not we do a best > effort at getting the dependencies by using the last known target on > that package to get the dependency information. > > [YOCTO #9676] > > Signed-off-by: Michael Wood <[email protected]> > Signed-off-by: Ed Bartosh <[email protected]> > --- > bitbake/lib/toaster/orm/models.py | 61 > ++++++++++++++++++---- > bitbake/lib/toaster/toastergui/buildtables.py | 15 +++++- > bitbake/lib/toaster/toastergui/tables.py | 15 +++++- > .../snippets/pkg_dependencies_popover.html | 44 ++++++++++++---- > .../snippets/pkg_revdependencies_popover.html | 46 ++++++++++++---- > .../toaster/toastergui/templatetags/projecttags.py | 8 +++ > bitbake/lib/toaster/toastergui/views.py | 4 +- > 7 files changed, 157 insertions(+), 36 deletions(-) > > diff --git a/bitbake/lib/toaster/orm/models.py > b/bitbake/lib/toaster/orm/models.py > index 25bc1db..caad2af 100644 > --- a/bitbake/lib/toaster/orm/models.py > +++ b/bitbake/lib/toaster/orm/models.py > @@ -862,31 +862,70 @@ class CustomImagePackage(Package): > related_name='appends_set') > > > - > class Package_DependencyManager(models.Manager): > use_for_related_fields = True > + TARGET_LATEST = "use-latest-target-for-target" > > def get_queryset(self): > return super(Package_DependencyManager, > self).get_queryset().exclude(package_id = F('depends_on__id')) > > - def get_total_source_deps_size(self): > - """ Returns the total file size of all the packages that depend on > - thispackage. > - """ > - return self.all().aggregate(Sum('depends_on__size')) > + def for_target_or_none(self, target): > + """ filter the dependencies to be displayed by the supplied target > + if no dependences are found for the target then try None as the > target > + which will return the dependences calculated without the context of a > + target e.g. non image recipes. > > - def get_total_revdeps_size(self): > - """ Returns the total file size of all the packages that depend on > - this package. > + returns: { size, packages } > """ > - return self.all().aggregate(Sum('package_id__size')) > + package_dependencies = > self.all_depends().order_by('depends_on__name') > > + if target is self.TARGET_LATEST: > + installed_deps =\ > + package_dependencies.filter(~Q(target__target=None)) > + else: > + installed_deps =\ > + package_dependencies.filter(Q(target__target=target)) > + > + packages_list = None > + total_size = 0 > + > + # If we have installed depdencies for this package and target then > use > + # these to display > + if installed_deps.count() > 0: > + packages_list = installed_deps > + total_size = installed_deps.aggregate( > + Sum('depends_on__size'))['depends_on__size__sum'] > + else: > + new_list = [] > + package_names = [] > + > + # Find dependencies for the package that we know about even if > + # it's not installed on a target e.g. from a non-image recipe > + for p in package_dependencies.filter(Q(target=None)): > + if p.depends_on.name in package_names: > + continue > + else: > + package_names.append(p.depends_on.name) > + new_list.append(p.pk) > + # while we're here we may as well total up the size to > + # avoid iterating again > + total_size += p.depends_on.size > + > + # We want to return a queryset here for consistency so pick the > + # deps from the new_list > + packages_list = package_dependencies.filter(Q(pk__in=new_list)) > + > + return {'packages': packages_list, > + 'size': total_size} > > def all_depends(self): > - """ Returns just the depends packages and not any other dep_type """ > + """ Returns just the depends packages and not any other dep_type > + Note that this is for any target > + """ > return self.filter(Q(dep_type=Package_Dependency.TYPE_RDEPENDS) | > Q(dep_type=Package_Dependency.TYPE_TRDEPENDS)) > > + > class Package_Dependency(models.Model): > TYPE_RDEPENDS = 0 > TYPE_TRDEPENDS = 1 > diff --git a/bitbake/lib/toaster/toastergui/buildtables.py > b/bitbake/lib/toaster/toastergui/buildtables.py > index 17de369..e237e4e 100644 > --- a/bitbake/lib/toaster/toastergui/buildtables.py > +++ b/bitbake/lib/toaster/toastergui/buildtables.py > @@ -47,6 +47,7 @@ class BuiltPackagesTableBase(tables.PackagesTable): > def setup_queryset(self, *args, **kwargs): > build = Build.objects.get(pk=kwargs['build_id']) > self.static_context_extra['build'] = build > + self.static_context_extra['target_name'] = None > self.queryset = build.package_set.all().exclude(recipe=None) > self.queryset = self.queryset.order_by(self.default_orderby) > > @@ -187,7 +188,15 @@ class InstalledPackagesTable(BuildTablesMixin, > BuiltPackagesTableBase): > self.static_context_extra['build'] = build > > target = Target.objects.get(pk=kwargs['target_id']) > + # We send these separately because in the case of image details table > + # we don't have a target just the recipe name as the target > + self.static_context_extra['target_name'] = target.target > + self.static_context_extra['target_id'] = target.pk > + > + self.static_context_extra['add_links'] = True > + > self.queryset = self.make_package_list(target) > + self.queryset = self.queryset.order_by(self.default_orderby) > > def setup_columns(self, *args, **kwargs): > super(InstalledPackagesTable, self).setup_columns(**kwargs) > @@ -195,11 +204,13 @@ class InstalledPackagesTable(BuildTablesMixin, > BuiltPackagesTableBase): > static_data_name="installed_size", > static_data_template="{% load projecttags %}" > "{{data.size|filtered_filesizeformat}}", > - orderable=True) > + orderable=True, > + hidden=True) > > # Add the template to show installed name for installed packages > install_name_tmpl =\ > - ('{{data.name}} ' > + ('<a href="{% url "package_included_detail" extra.build.pk' > + ' extra.target_id data.pk %}">{{data.name}}</a>' > '{% if data.installed_name and data.installed_name !=' > ' data.name %}' > '<span class="muted"> as {{data.installed_name}}</span>' > diff --git a/bitbake/lib/toaster/toastergui/tables.py > b/bitbake/lib/toaster/toastergui/tables.py > index 902f62f..79673f5 100644 > --- a/bitbake/lib/toaster/toastergui/tables.py > +++ b/bitbake/lib/toaster/toastergui/tables.py > @@ -22,7 +22,7 @@ > from toastergui.widgets import ToasterTable > from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project > from orm.models import CustomImageRecipe, Package, Target, Build, > LogMessage, Task > -from orm.models import CustomImagePackage > +from orm.models import CustomImagePackage, Package_DependencyManager > from django.db.models import Q, Max, Sum, Count, When, Case, Value, > IntegerField > from django.conf.urls import url > from django.core.urlresolvers import reverse, resolve > @@ -695,6 +695,7 @@ class PackagesTable(ToasterTable): > > def setup_queryset(self, *args, **kwargs): > recipe = Recipe.objects.get(pk=kwargs['recipe_id']) > + self.static_context_extra['target_name'] = recipe.name > > self.queryset = self.create_package_list(recipe, kwargs['pid']) > self.queryset = self.queryset.order_by('name') > @@ -766,7 +767,19 @@ class SelectPackagesTable(PackagesTable): > > self.queryset = self.queryset.order_by('name') > > + # This target is the target used to work out which group of > dependences > + # to display, if we've built the custom image we use it otherwise we > + # can use the based recipe instead > + if > prj.build_set.filter(target__target=self.cust_recipe.name).count()\ > + > 0: > + self.static_context_extra['target_name'] = self.cust_recipe.name > + else: > + self.static_context_extra['target_name'] =\ > + Package_DependencyManager.TARGET_LATEST > + > self.static_context_extra['recipe_id'] = kwargs['custrecipeid'] > + > + > self.static_context_extra['current_packages'] = \ > current_packages.values_list('pk', flat=True) > > diff --git > a/bitbake/lib/toaster/toastergui/templates/snippets/pkg_dependencies_popover.html > > b/bitbake/lib/toaster/toastergui/templates/snippets/pkg_dependencies_popover.html > index 0a24e92..5be409c 100644 > --- > a/bitbake/lib/toaster/toastergui/templates/snippets/pkg_dependencies_popover.html > +++ > b/bitbake/lib/toaster/toastergui/templates/snippets/pkg_dependencies_popover.html > @@ -1,14 +1,38 @@ > {# Popover that displays the dependences and sizes of a package 'data' used > in the Packages table #} > -{% with data.package_dependencies_source.all_depends.count as dep_count %} > {% load projecttags %} > -{% if dep_count %} > - <a data-content="<ul class='list-unstyled'> > - {% for dep in data.package_dependencies_source.all_depends %} > - <li>{{dep.depends_on.name}} {% if dep.depends_on.size > 0 > %}({{dep.depends_on.size|filtered_filesizeformat}}){% endif %}</li> > - {% endfor %} > - </ul>" class="btn btn-default" title=" > - <strong>{{data.name}}</strong> dependencies - > <strong>{{data.package_dependencies_source.get_total_source_deps_size.depends_on__size__sum|filtered_filesizeformat}}</strong>"> > - {{dep_count}} > -</a> > + > +{% with > package_deps=data.package_dependencies_source|for_target:extra.target_name %} > +{% with count_package=package_deps.packages|length %} > + > +{% if count_package > 0 %} > + <a data-content='<ul class="unstyled"> > + {% for dep in package_deps.packages %} > + <li> > + {% if extra.add_links %} > + <a href="{% url 'package_included_detail' extra.build.pk > extra.target_id dep.depends_on.pk %}"> > + {{dep.depends_on.name}}</a> > + {% else %} > + {{dep.depends_on.name}} > + {% endif %} > + {% if dep.depends_on.size > 0 %} > + ({{dep.depends_on.size|filtered_filesizeformat}}) > + {% endif %} > + </li> > + {% endfor %} > + </ul>' class="btn btn-default" title=' > + <strong> > + {% if extra.add_links %} > + <a href="{% url 'package_included_dependencies' extra.build.pk > extra.target_id data.pk %}"> > + {{data.name}}</a> > + {% else %} > + {{data.name}} > + {% endif %} > + </strong> > + dependencies - > + <strong>{{package_deps.size|filtered_filesizeformat}}</strong>'> > + {{count_package}} > + </a> > {% endif %} > + > +{% endwith %} > {% endwith %} > diff --git > a/bitbake/lib/toaster/toastergui/templates/snippets/pkg_revdependencies_popover.html > > b/bitbake/lib/toaster/toastergui/templates/snippets/pkg_revdependencies_popover.html > index d470712..65c2b29 100644 > --- > a/bitbake/lib/toaster/toastergui/templates/snippets/pkg_revdependencies_popover.html > +++ > b/bitbake/lib/toaster/toastergui/templates/snippets/pkg_revdependencies_popover.html > @@ -1,14 +1,38 @@ > -{# Popover that displays the reverse dependencies and sizes of a package > 'data' used in the Packages table #} > -{% with data.package_dependencies_target.all_depends.count as dep_count %} > +{# Popover that displays the reverse dependences and sizes of a package > 'data' used in the Packages table #} > {% load projecttags %} > -{% if dep_count %} > - <a data-content="<ul class='list-unstyled'> > - {% for dep in > data.package_dependencies_target.all_depends|dictsort:'package.name' %} > - <li>{{dep.package.name}} {% if dep.package.size > 0 > %}({{dep.package.size|filtered_filesizeformat}}){% endif %}</li> > - {% endfor %} > - </ul>" class="btn btn-default" title=" > - <strong>{{data.name}}</strong> reverse dependencies - > <strong>{{data.package_dependencies_target.get_total_revdeps_size.package_id__size__sum|filtered_filesizeformat}}</strong>"> > - {{dep_count}} > -</a> > + > +{% with > package_deps=data.package_dependencies_target|for_target:extra.target_name %} > +{% with count_package=package_deps.packages|length %} > + > +{% if count_package > 0 %} > + <a data-content='<ul class="unstyled"> > + {% for dep in package_deps.packages|dictsort:"package.name" %} > + <li> > + {% if extra.add_links %} > + <a href="{% url 'package_included_detail' extra.build.pk > extra.target_id dep.package.pk %}"> > + {{dep.package.name}}</a> > + {% else %} > + {{dep.package.name}} > + {% endif %} > + {% if dep.package.size > 0 %} > + ({{dep.package.size|filtered_filesizeformat}}) > + {% endif %} > + </li> > + {% endfor %} > + </ul>' class="btn btn-default" title=' > + <strong> > + {% if extra.add_links %} > + <a href="{% url 'package_included_reverse_dependencies' extra.build.pk > extra.target_id data.pk %}"> > + {{data.name}}</a> > + {% else %} > + {{data.name}} > + {% endif %} > + </strong> > + dependencies - > + <strong>{{package_deps.size|filtered_filesizeformat}}</strong>'> > + {{count_package}} > + </a> > {% endif %} > + > +{% endwith %} > {% endwith %} > diff --git a/bitbake/lib/toaster/toastergui/templatetags/projecttags.py > b/bitbake/lib/toaster/toastergui/templatetags/projecttags.py > index 1d68036..119311d 100644 > --- a/bitbake/lib/toaster/toastergui/templatetags/projecttags.py > +++ b/bitbake/lib/toaster/toastergui/templatetags/projecttags.py > @@ -297,3 +297,11 @@ def cut_path_prefix(fullpath, prefixes): > if fullpath.startswith(prefix): > return relpath(fullpath, prefix) > return fullpath > + > + > [email protected] > +def for_target(package_dependencies, target): > + """ filter the dependencies to be displayed by the supplied target > + if no dependences are found for the target then return the predicted > + dependences""" > + return package_dependencies.for_target_or_none(target) > diff --git a/bitbake/lib/toaster/toastergui/views.py > b/bitbake/lib/toaster/toastergui/views.py > index 88bc39a..1f908ea 100755 > --- a/bitbake/lib/toaster/toastergui/views.py > +++ b/bitbake/lib/toaster/toastergui/views.py > @@ -2060,7 +2060,9 @@ if True: > > # Dependencies for package which aren't satisfied by the > # current packages in the custom image recipe > - deps = package.package_dependencies_source.annotate( > + deps =\ > + package.package_dependencies_source.for_target_or_none( > + recipe.name)['packages'].annotate( > name=F('depends_on__name'), > pk=F('depends_on__pk'), > size=F('depends_on__size'), > -- > 2.6.6 >
-- -- Regards, Ed -- _______________________________________________ toaster mailing list [email protected] https://lists.yoctoproject.org/listinfo/toaster
