diff options
author | Alexandru DAMIAN <alexandru.damian@intel.com> | 2015-02-02 17:57:36 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2015-02-10 23:07:48 +0000 |
commit | 202d808f890b03958cd6873486e6a37f3f437098 (patch) | |
tree | 7b88e2cb5ab7b85648821bec4d2f4c16d290207f /bitbake/lib/toaster/toastergui | |
parent | b741c9a4b4047439c6c5428e36a72c22a784feda (diff) | |
download | poky-202d808f890b03958cd6873486e6a37f3f437098.tar.gz |
bitbake: toastergui: improvements in layer selection logic
This patch clearers and bring fixes for the layer selection
logic in order to enable information collected during build to be used
in configuring projects, specifically targeting the recipes
learned through the building process.
The patch also adds tests to verify the layer selection logic.
[YOCTO #7189]
(Bitbake rev: f0faba8ef0f08c98ac4bddf5b3954d540820d215)
Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/toaster/toastergui')
-rw-r--r-- | bitbake/lib/toaster/toastergui/templates/targets.html | 14 | ||||
-rwxr-xr-x | bitbake/lib/toaster/toastergui/views.py | 35 |
2 files changed, 31 insertions, 18 deletions
diff --git a/bitbake/lib/toaster/toastergui/templates/targets.html b/bitbake/lib/toaster/toastergui/templates/targets.html index 590ecb9a0e..3038649303 100644 --- a/bitbake/lib/toaster/toastergui/templates/targets.html +++ b/bitbake/lib/toaster/toastergui/templates/targets.html | |||
@@ -52,11 +52,11 @@ | |||
52 | </td> | 52 | </td> |
53 | <td class="target-section">{{o.section}}</td> | 53 | <td class="target-section">{{o.section}}</td> |
54 | <td class="license">{{o.license}}</td> | 54 | <td class="license">{{o.license}}</td> |
55 | <td class="layer"><a href="{% url 'layerdetails' o.layer_version.id%}">{{o.layer_version.layer.name}}</a></td> | 55 | <td class="layer"><a href="{% url 'layerdetails' o.preffered_layerversion.id%}">{{o.preffered_layerversion.layer.name}}</a></td> |
56 | <td class="source">{{o.layer_source.name}}</td> | 56 | <td class="source">{{o.preffered_layerversion.layer_source.name}}</td> |
57 | <td class="branch"> | 57 | <td class="branch"> |
58 | {% if o.layer_version.up_branch %} | 58 | {% if o.preffered_layerversion.up_branch %} |
59 | {{o.layer_version.up_branch.name}} | 59 | {{o.preffered_layerversion.up_branch.name}} |
60 | {% else %} | 60 | {% else %} |
61 | <a class="btn" | 61 | <a class="btn" |
62 | data-content="<ul class='unstyled'> | 62 | data-content="<ul class='unstyled'> |
@@ -66,15 +66,15 @@ | |||
66 | </a> | 66 | </a> |
67 | {% endif %} | 67 | {% endif %} |
68 | </td> | 68 | </td> |
69 | <td class="add-layer" value="{{o.pk}}" layerversion_id="{{o.layer_version.pk}}"> | 69 | <td class="add-layer" value="{{o.pk}}" layerversion_id="{{o.preffered_layerversion.pk}}"> |
70 | <div id="layer-tooltip-{{o.pk}}" style="display: none; font-size: 11px; line-height: 1.3;" class="tooltip-inner">layer was modified</div> | 70 | <div id="layer-tooltip-{{o.pk}}" style="display: none; font-size: 11px; line-height: 1.3;" class="tooltip-inner">layer was modified</div> |
71 | <a href="{% url 'project' project.id %}#/targetbuild={{o.name}}" id="target-build-{{o.pk}}" class="btn btn-block remove-layer" style="display:none;" > | 71 | <a href="{% url 'project' project.id %}#/targetbuild={{o.name}}" id="target-build-{{o.pk}}" class="btn btn-block remove-layer" style="display:none;" > |
72 | Build target | 72 | Build target |
73 | </a> | 73 | </a> |
74 | <a id="layer-add-{{o.pk}}" class="btn btn-block" style="display:none;" href="javascript:layerAdd({{o.layer_version.pk}}, '{{o.layer_version.layer.name}}', '{%url 'layerdetails' o.layer_version.pk%}', {{o.pk}})" > | 74 | <a id="layer-add-{{o.pk}}" class="btn btn-block" style="display:none;" href="javascript:layerAdd({{o.preffered_layerversion.pk}}, '{{o.preffered_layerversion.layer.name}}', '{%url 'layerdetails' o.preffered_layerversion.pk%}', {{o.pk}})" > |
75 | <i class="icon-plus"></i> | 75 | <i class="icon-plus"></i> |
76 | Add layer | 76 | Add layer |
77 | <i title="" class="icon-question-sign get-help" data-original-title="To build this target, you must first add the {{o.layer_version.layer.name}} layer to your project"></i> | 77 | <i title="" class="icon-question-sign get-help" data-original-title="To build this target, you must first add the {{o.preffered_layerversion.layer.name}} layer to your project"></i> |
78 | </a> | 78 | </a> |
79 | </td> | 79 | </td> |
80 | </tr> | 80 | </tr> |
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py index 6ccbf5452d..7353844bf1 100755 --- a/bitbake/lib/toaster/toastergui/views.py +++ b/bitbake/lib/toaster/toastergui/views.py | |||
@@ -22,7 +22,7 @@ | |||
22 | import operator,re | 22 | import operator,re |
23 | import HTMLParser | 23 | import HTMLParser |
24 | 24 | ||
25 | from django.db.models import Q, Sum, Count | 25 | from django.db.models import Q, Sum, Count, Max |
26 | from django.db import IntegrityError | 26 | from django.db import IntegrityError |
27 | from django.shortcuts import render, redirect | 27 | from django.shortcuts import render, redirect |
28 | from orm.models import Build, Target, Task, Layer, Layer_Version, Recipe, LogMessage, Variable | 28 | from orm.models import Build, Target, Task, Layer, Layer_Version, Recipe, LogMessage, Variable |
@@ -236,7 +236,7 @@ def _get_queryset(model, queryset, filter_string, search_term, ordering_string, | |||
236 | if search_term: | 236 | if search_term: |
237 | queryset = _get_search_results(search_term, queryset, model) | 237 | queryset = _get_search_results(search_term, queryset, model) |
238 | 238 | ||
239 | if ordering_string and queryset: | 239 | if ordering_string: |
240 | column, order = ordering_string.split(':') | 240 | column, order = ordering_string.split(':') |
241 | if column == re.sub('-','',ordering_secondary): | 241 | if column == re.sub('-','',ordering_secondary): |
242 | ordering_secondary='' | 242 | ordering_secondary='' |
@@ -2046,7 +2046,7 @@ if toastermain.settings.MANAGED: | |||
2046 | "url": x.layercommit.layer.layer_index_url, | 2046 | "url": x.layercommit.layer.layer_index_url, |
2047 | "layerdetailurl": reverse("layerdetails", args=(x.layercommit.pk,)), | 2047 | "layerdetailurl": reverse("layerdetails", args=(x.layercommit.pk,)), |
2048 | # This branch name is actually the release | 2048 | # This branch name is actually the release |
2049 | "branch" : { "name" : x.layercommit.commit, "layersource" : x.layercommit.up_branch.layer_source.name}}, | 2049 | "branch" : { "name" : x.layercommit.commit, "layersource" : x.layercommit.up_branch.layer_source.name if x.layercommit.up_branch != None else None}}, |
2050 | prj.projectlayer_set.all().order_by("id")), | 2050 | prj.projectlayer_set.all().order_by("id")), |
2051 | "targets" : map(lambda x: {"target" : x.target, "task" : x.task, "pk": x.pk}, prj.projecttarget_set.all()), | 2051 | "targets" : map(lambda x: {"target" : x.target, "task" : x.task, "pk": x.pk}, prj.projecttarget_set.all()), |
2052 | "freqtargets": freqtargets, | 2052 | "freqtargets": freqtargets, |
@@ -2243,11 +2243,11 @@ if toastermain.settings.MANAGED: | |||
2243 | 2243 | ||
2244 | # returns layer versions that provide the named targets | 2244 | # returns layer versions that provide the named targets |
2245 | if request.GET['type'] == "layers4target": | 2245 | if request.GET['type'] == "layers4target": |
2246 | # we returnd ata only if the recipe can't be provided by the current project layer set | 2246 | # we return data only if the recipe can't be provided by the current project layer set |
2247 | if reduce(lambda x, y: x + y, [x.recipe_layer_version.filter(name="anki").count() for x in prj.projectlayer_equivalent_set()], 0): | 2247 | if reduce(lambda x, y: x + y, [x.recipe_layer_version.filter(name=request.GET['value']).count() for x in prj.projectlayer_equivalent_set()], 0): |
2248 | final_list = [] | 2248 | final_list = [] |
2249 | else: | 2249 | else: |
2250 | queryset_all = prj.compatible_layerversions().filter(recipe_layer_version__name = request.GET.get('value', '__none__')) | 2250 | queryset_all = prj.compatible_layerversions().filter(recipe_layer_version__name = request.GET['value']) |
2251 | 2251 | ||
2252 | # exclude layers in the project | 2252 | # exclude layers in the project |
2253 | queryset_all = queryset_all.exclude(pk__in = [x.id for x in prj.projectlayer_equivalent_set()]) | 2253 | queryset_all = queryset_all.exclude(pk__in = [x.id for x in prj.projectlayer_equivalent_set()]) |
@@ -2259,14 +2259,20 @@ if toastermain.settings.MANAGED: | |||
2259 | 2259 | ||
2260 | # returns targets provided by current project layers | 2260 | # returns targets provided by current project layers |
2261 | if request.GET['type'] == "targets": | 2261 | if request.GET['type'] == "targets": |
2262 | queryset_all = Recipe.objects.all() | 2262 | queryset_all = Recipe.objects.filter(name__icontains=request.GET.get('value','')) |
2263 | layer_equivalent_set = [] | 2263 | layer_equivalent_set = [] |
2264 | for i in prj.projectlayer_set.all(): | 2264 | for i in prj.projectlayer_set.all(): |
2265 | layer_equivalent_set += i.layercommit.get_equivalents_wpriority(prj) | 2265 | layer_equivalent_set += i.layercommit.get_equivalents_wpriority(prj) |
2266 | queryset_all = queryset_all.filter(layer_version__in = layer_equivalent_set) | 2266 | queryset_all = queryset_all.filter(layer_version__in = layer_equivalent_set) |
2267 | |||
2268 | # if we have more than one hit here (for distinct name and version), max the id it out | ||
2269 | queryset_all_maxids = queryset_all.values('name').distinct().annotate(max_id=Max('id')).values_list('max_id') | ||
2270 | queryset_all = queryset_all.filter(id__in = queryset_all_maxids) | ||
2271 | |||
2272 | |||
2267 | return HttpResponse(jsonfilter({ "error":"ok", | 2273 | return HttpResponse(jsonfilter({ "error":"ok", |
2268 | "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name+ (" | " + x.layer_version.up_branch.name + "]" if x.layer_version.up_branch is not None else "]")}, | 2274 | "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name + (" | " + x.layer_version.up_branch.name + "]" if x.layer_version.up_branch is not None else "]")}, |
2269 | queryset_all.filter(name__icontains=request.GET.get('value',''))[:8]), | 2275 | queryset_all[:8]), |
2270 | 2276 | ||
2271 | }), content_type = "application/json") | 2277 | }), content_type = "application/json") |
2272 | 2278 | ||
@@ -2663,10 +2669,17 @@ if toastermain.settings.MANAGED: | |||
2663 | 2669 | ||
2664 | queryset_with_search = _get_queryset(Recipe, queryset_all, None, search_term, ordering_string, '-name') | 2670 | queryset_with_search = _get_queryset(Recipe, queryset_all, None, search_term, ordering_string, '-name') |
2665 | 2671 | ||
2666 | queryset_with_search.prefetch_related("layer_source") | 2672 | # get unique values for 'name' and 'version', and select the maximum ID for each entry (the max id is the newest one) |
2673 | queryset_with_search_maxids = queryset_with_search.values('name').distinct().annotate(max_id=Max('id')).values_list('max_id') | ||
2674 | |||
2675 | queryset_with_search = queryset_with_search.filter(id__in=queryset_with_search_maxids).select_related('layer_version', 'layer_version__layer') | ||
2676 | |||
2677 | objects = list(queryset_with_search) | ||
2678 | for e in objects: | ||
2679 | e.preffered_layerversion = e.layer_version.get_equivalents_wpriority(prj)[0] | ||
2667 | 2680 | ||
2668 | # retrieve the objects that will be displayed in the table; targets a paginator and gets a page range to display | 2681 | # retrieve the objects that will be displayed in the table; targets a paginator and gets a page range to display |
2669 | target_info = _build_page_range(Paginator(queryset_with_search, request.GET.get('count', 10)),request.GET.get('page', 1)) | 2682 | target_info = _build_page_range(Paginator(objects, request.GET.get('count', 10)),request.GET.get('page', 1)) |
2670 | 2683 | ||
2671 | 2684 | ||
2672 | context = { | 2685 | context = { |