diff options
7 files changed, 157 insertions, 36 deletions
diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py index 88967a23f57..7c26fcf79c3 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 17de3693053..e237e4ecb66 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 2bb05f5786d..891c38e25d4 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 @@ -696,6 +696,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') @@ -767,7 +768,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 0a24e9217ec..5be409ca448 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 d470712121b..65c2b29d0be 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 75f2261be8c..9ee7a590b65 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 + + +@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 ed29c930286..bba956ae42f 100755 --- a/bitbake/lib/toaster/toastergui/views.py +++ b/bitbake/lib/toaster/toastergui/views.py @@ -2042,7 +2042,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'), |