[Toaster] [-M] toaster: Rework displaying package dependencies across Toaster
Ed Bartosh
ed.bartosh at linux.intel.com
Tue Jun 7 01:52:16 PDT 2016
sorry, wrong patch. please, ignore.
On Tue, Jun 07, 2016 at 11:47:22AM +0300, Ed Bartosh wrote:
> From: Michael Wood <michael.g.wood at intel.com>
>
> 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 <michael.g.wood at intel.com>
> Signed-off-by: Ed Bartosh <ed.bartosh at linux.intel.com>
> ---
> 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
> +
> +
> + at register.filter
> +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
More information about the toaster
mailing list