summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Reyna <David.Reyna@windriver.com>2014-02-28 05:55:46 -0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-03-09 12:24:01 -0700
commit4717749fd651e6983a31e3cefe3f210d2646ca87 (patch)
tree5ba0090617b97f5d49b5c78ee84563a0cab6b7f5
parent31d4bf8484ee42690386c6b7a6bd6c7a2be54464 (diff)
downloadpoky-4717749fd651e6983a31e3cefe3f210d2646ca87.tar.gz
bitbake: toaster: implement the configuration pagedreyna/configure-detail-view
Update the configuration page with the file list pop-up, implement the file and description filters. [YOCTO #4259] (Bitbake rev: 54a767809960b66b2fe2d3bc46aa9c7e040c4ae3) Signed-off-by: David Reyna <David.Reyna@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--bitbake/lib/toaster/toastergui/templates/base.html53
-rw-r--r--bitbake/lib/toaster/toastergui/templates/configuration.html32
-rw-r--r--bitbake/lib/toaster/toastergui/templates/configvars.html98
-rw-r--r--bitbake/lib/toaster/toastergui/templatetags/projecttags.py59
-rw-r--r--bitbake/lib/toaster/toastergui/views.py101
5 files changed, 299 insertions, 44 deletions
diff --git a/bitbake/lib/toaster/toastergui/templates/base.html b/bitbake/lib/toaster/toastergui/templates/base.html
index 8d4771c10e..96f093f627 100644
--- a/bitbake/lib/toaster/toastergui/templates/base.html
+++ b/bitbake/lib/toaster/toastergui/templates/base.html
@@ -48,6 +48,59 @@ function reload_params(params) {
48 48
49} 49}
50</script> 50</script>
51
52<script>
53 $(document).ready(function() {
54 //show or hide selected columns on load
55 $("input:checkbox").each(function(){
56 var selectedType = $(this).val();
57 if($(this).is(":checked")){
58 $("."+selectedType).show();
59 }
60 else{
61 $("."+selectedType).hide();
62 }
63 });
64 //edit columns functionality (show / hide table columns)
65 $("input:checkbox").change();
66 $("input:checkbox").change(function(){
67 var selectedType = $(this).val();
68 if($(this).is(":checked")){
69 $("."+selectedType).show();
70 }
71 else{
72 $("."+selectedType).hide();
73 }
74 });
75 //turn edit columns dropdown into a multi-select menu
76 $('.dropdown-menu input, .dropdown-menu label').click(function(e) {
77 e.stopPropagation();
78 });
79 //show help information inside modal dialogs
80 $("#filter-variables i").tooltip({ html: true, delay: {show: 500} });
81 //show applied filter tooltip
82 $('.filtered').tooltip({container:'body', placement:'bottom', delay:{hide:1500}, html:true});
83 //hide the applied filter tooltip when you click the filter button
84 $('.btn-primary').on('click', function () {
85 $('.tooltip').hide();
86 });
87
88 $('.full-variable, .full-variable-hide').hide();
89 $('.full-variable-show').click(function(){
90 $('.full-variable').slideDown(function(){
91 $('.full-variable-hide').show();
92 });
93 $(this).hide();
94 });
95 $('.full-variable-hide').click(function(){
96 $(this).hide();
97 $('.full-variable').slideUp(function(){
98 $('.full-variable-show').show();
99 });
100 });
101 });
102</script>
103
51 </head> 104 </head>
52 105
53<body style="height: 100%"> 106<body style="height: 100%">
diff --git a/bitbake/lib/toaster/toastergui/templates/configuration.html b/bitbake/lib/toaster/toastergui/templates/configuration.html
index 467fbd02ad..ddfa5af9ca 100644
--- a/bitbake/lib/toaster/toastergui/templates/configuration.html
+++ b/bitbake/lib/toaster/toastergui/templates/configuration.html
@@ -3,6 +3,8 @@
3<li>Configuration</li> 3<li>Configuration</li>
4{% endblock %} 4{% endblock %}
5 5
6{% load projecttags %}
7
6{% block buildinfomain %} 8{% block buildinfomain %}
7<!-- page title --> 9<!-- page title -->
8<div class="row-fluid span10"> 10<div class="row-fluid span10">
@@ -22,15 +24,19 @@
22 <div id="summary" class="tab-pane active"> 24 <div id="summary" class="tab-pane active">
23 <h3>Build configuration</h3> 25 <h3>Build configuration</h3>
24 <dl class="dl-horizontal"> 26 <dl class="dl-horizontal">
25 <dt>BitBake version</dt><dd>1.19.1</dd> 27 {%if BB_VERSION %}<dt>BitBake version</dt><dd>{{BB_VERSION}}</dd> {% endif %}
26 <dt>Build system</dt><dd>x86_64-linux</dd> 28 {%if BUILD_SYS %}<dt>Build system</dt><dd>{{BUILD_SYS}}</dd> {% endif %}
27 <dt>Host distribution</dt><dd>Ubuntu-12.04</dd> 29 {%if NATIVELSBSTRING %}<dt>Host distribution</dt><dd>{{NATIVELSBSTRING}}</dd> {% endif %}
28 <dt>Target system</dt><dd>i586-poky-linux</dd> 30 {%if TARGET_SYS %}<dt>Target system</dt><dd>{{TARGET_SYS}}</dd> {% endif %}
29 <dt><i class="icon-question-sign get-help" data-toggle="tooltip" title="Specifies the target device for which the image is built"></i> Machine</dt><dd>atom-pc</dd> 31 {%if MACHINE %}<dt>Machine</dt><dd>{{MACHINE}}</dd> {% endif %}
30 <dt><i class="icon-question-sign get-help" data-toggle="tooltip" title="The short name of the distribution"></i> Distro</dt><dd>poky</dd> 32 {%if DISTRO %}<dt>Distro</dt><dd>{{DISTRO}}</dd> {% endif %}
31 <dt>Distro version</dt><dd>1.4+snapshot-20130718</dd> 33 {%if DISTRO_VERSION %}<dt>Distro version</dt><dd>{{DISTRO_VERSION}}</dd> {% endif %}
32 <dt>Tune features</dt><dd>m32 i586</dd> 34 {%if TUNE_FEATURES %}<dt>Tune features</dt><dd>{{TUNE_FEATURES}}</dd> {% endif %}
33 <dt>Target(s)</dt><dd>core-image-sato</dd> 35 {%if TARGET_FPU %}<dt>Target FPU</dt><dd>{{TARGET_FPU}}</dd> {% endif %}
36 {%if targets.all %}<dt>Target(s)</dt>
37 <dd> <ul> {% for target in targets.all %}
38 <li>{{target.target}}{%if forloop.counter > 1 %}<br>{% endif %}</li>
39 {% endfor %} </ul> </dd> {% endif %}
34 </dl> 40 </dl>
35 <h3>Layers</h3> 41 <h3>Layers</h3>
36 <div class="span9" style="margin-left:0px;"> 42 <div class="span9" style="margin-left:0px;">
@@ -45,7 +51,13 @@
45 </thead> 51 </thead>
46 <tbody>{% for lv in build.layer_version_build.all %} 52 <tbody>{% for lv in build.layer_version_build.all %}
47 <tr> 53 <tr>
48 <td>{{lv.layer.name}}<a href="{{lv.layer.layer_index_url}}" target="_blank">&nbsp;<i class="icon-share get-info"></i></a></td><td>{{lv.branch}}</td><td class="layer_commit"><a data-content="{{lv.commit}}" title="" href="#" class="btn" data-original-title="">{{lv.commit|slice:":8"}}...</a></td><td>{{lv.layer.local_path}}</td> 54 <td>{{lv.layer.name}}</td>
55 <td>{{lv.branch}}</td>
56 <td> <a class="btn" data-content="<ul class='unstyled'>
57 <li>{{lv.commit}}</li> </ul>">
58 {{lv.commit|truncatechars:13}}
59 </a></td>
60 <td>{{lv.layer.local_path}}</td>
49 </tr>{% endfor %} 61 </tr>{% endfor %}
50 </tbody> 62 </tbody>
51 </table> 63 </table>
diff --git a/bitbake/lib/toaster/toastergui/templates/configvars.html b/bitbake/lib/toaster/toastergui/templates/configvars.html
index ae45119f39..cd41cca7e5 100644
--- a/bitbake/lib/toaster/toastergui/templates/configvars.html
+++ b/bitbake/lib/toaster/toastergui/templates/configvars.html
@@ -3,38 +3,110 @@
3<li>Configuration</li> 3<li>Configuration</li>
4{% endblock %} 4{% endblock %}
5 5
6{% load projecttags %}
7
6{% block buildinfomain %} 8{% block buildinfomain %}
7<!-- page title --> 9<!-- page title -->
8<div class="row-fluid span10"> 10<div class="row-fluid span10">
9 <div class="page-header"> 11 <div class="page-header">
10 <h1>Configuration</h1> 12 <h1>
13 {% if request.GET.filter or request.GET.search and objects.count > 0 %}
14 {{objects.paginator.count}} variable{{objects.paginator.count|pluralize}} found
15 {%elif objects.paginator.count == 0%}
16 No variables
17 {%else%}
18 Configuration
19 {%endif%}
20 </h1>
11 </div> 21 </div>
12</div> 22</div>
13 23
14<!-- configuration table --> 24<!-- configuration table -->
15<div class="row-fluid pull-right span10" id="navTab"> 25<div class="row-fluid pull-right span10" id="navTab">
16<ul class="nav nav-pills"> 26 <ul class="nav nav-pills">
17 <li class=""><a href="{% url 'configuration' build.id %}">Summary</a></li> 27 <li class=""><a href="{% url 'configuration' build.id %}">Summary</a></li>
18 <li class="active"><a href="#" >BitBake variables</a></li> 28 <li class="active"><a href="#" >BitBake variables</a></li>
19</ul> 29 </ul>
20
21 30
22 <!-- variables --> 31 <!-- variables -->
23 <div id="variables" class="tab-pane"> 32 <div id="variables" class="tab-pane">
24{% include "basetable_top.html" %} 33 {% include "basetable_top.html" %}
25 34
26{% for variable in objects %} 35 {% for variable in objects %}
27 <tr class="data"> 36 <tr class="data">
28 <td class="variable">{{variable.variable_name}}</td> 37 <td class="variable_name"><a data-toggle="modal" href="#variable-{{variable.pk}}">{{variable.variable_name}}</a></td>
29 <td class="variable_value">{{variable.variable_value}}</td> 38 <td class="variable_value"><a data-toggle="modal" href="#variable-{{variable.pk}}">{{variable.variable_value|truncatechars:153}}</a></td>
30 <td class="file">{% for vh in variable.vhistory_set.all %}{{vh.operation}} in {{vh.file_name}}:{{vh.line_number}}<br/>{%endfor%}</td> 39 <td class="file"><a data-toggle="modal" href="#variable-{{variable.pk}}">
31 <td class="description">{% if variable.description %}{{variable.description}}{% endif %}</td> 40 {% if variable.vhistory.all %} {% autoescape off %}
41 {{variable.vhistory.all | filter_setin_files:file_filter }}
42 {% endautoescape %} {% endif %}
43 </a></td>
44 <td class="description">
45 {% if variable.description %}
46 {{variable.description}}
47 <a href="http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-{{variable.variable_name|variable_parent_name}}" target="_blank">
48 <i class="icon-share get-info"></i></a>
49 {% endif %}
50 </td>
32 </tr> 51 </tr>
33{% endfor %} 52{% endfor %}
34 53
35{% include "basetable_bottom.html" %} 54{% include "basetable_bottom.html" %}
55</div> <!-- endvariables -->
36 56
37 </div> <!-- endvariables --> 57<!-- file list popups -->
58{% for variable in objects %}
59 {% if variable.vhistory.count %}
60 <div id="variable-{{variable.pk}}" class="modal hide fade" tabindex="-1" role="dialog">
61 <div class="modal-header">
62 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
63 <h3>History of {{variable.variable_name}}</h3>
64 </div>
65 <div class="modal-body">
66 {% if variable.variable_value %}
67 {% if variable.variable_value|length < 570 %}
68 <h4>{{variable.variable_name}} value is:</h4>
69 <p>
70 {{variable.variable_value}}
71 </p>
72 {% else %}
73 <h4>{{variable.variable_name}} value is:</h4>
74 <p>
75 <span>{{variable.variable_value|string_slice:':570'}}
76 <span class="full-variable"> {{variable.variable_value|string_slice:'570:'}}
77 </span>
78 <a class="btn btn-mini full-variable-show">...</a>
79 </span>
80 </p>
81 <a class="btn btn-mini full-variable-hide">Collapse variable value<i class="icon-caret-up"></i>
82 </a>
83 {% endif %}
84 {% else %}
85 <div class="alert alert-info">The value of <strong>{{variable.variable_name}}</strong> is an empty string</div>
86 {% endif %}
87 <h4>The value was set in the following configuration files:</h4>
88 <table class="table table-bordered table-hover">
89 <thead>
90 <tr>
91 <th>Order</th>
92 <th>Configuration file</th>
93 <th>Operation</th>
94 <th>Line number</th>
95 </tr>
96 </thead>
97 <tbody>
98 {% for vh in variable.vhistory.all %}
99 <tr>
100 <td>{{forloop.counter}}</td><td>{{vh.file_name}}</td><td>{{vh.operation}}</td><td>{{vh.line_number}}</td>
101 </tr>
102 {%endfor%}
103 </tbody>
104 </table>
105 </div>
106 </div>
107 {% endif %}
108{% endfor %}
109
110</div> <!-- buildinfomain -->
38 111
39</div>
40{% endblock %} 112{% endblock %}
diff --git a/bitbake/lib/toaster/toastergui/templatetags/projecttags.py b/bitbake/lib/toaster/toastergui/templatetags/projecttags.py
index b1e573b16d..857680b350 100644
--- a/bitbake/lib/toaster/toastergui/templatetags/projecttags.py
+++ b/bitbake/lib/toaster/toastergui/templatetags/projecttags.py
@@ -129,3 +129,62 @@ def check_filter_status(options, filter):
129 if filter == option[1]: 129 if filter == option[1]:
130 return "" 130 return ""
131 return "checked" 131 return "checked"
132
133@register.filter
134def variable_parent_name(value):
135 """ filter extended variable names to the parent name
136 """
137 value=re.sub('_\$.*', '', value)
138 return re.sub('_[a-z].*', '', value)
139
140@register.filter
141def filter_setin_files(file_list,matchstr):
142 """ filter/search the 'set in' file lists. Note
143 that this output is not autoescaped to allow
144 the <p> marks, but this is safe as the data
145 is file paths
146 """
147
148 # no filters, show last file (if any)
149 if matchstr == ":":
150 if file_list:
151 return file_list[len(file_list)-1].file_name
152 else:
153 return ''
154
155 search, filter = matchstr.partition(':')[::2]
156 htmlstr=""
157 # match only filters
158 if search == '':
159 for i in range(len(file_list)):
160 if file_list[i].file_name.find(filter) >= 0:
161 htmlstr += file_list[i].file_name + "<p>"
162 return htmlstr
163
164 # match only search string, plus always last file
165 if filter == "":
166 for i in range(len(file_list)-1):
167 if file_list[i].file_name.find(search) >= 0:
168 htmlstr += file_list[i].file_name + "<p>"
169 htmlstr += file_list[len(file_list)-1].file_name
170 return htmlstr
171
172 # match filter or search string
173 for i in range(len(file_list)):
174 if (file_list[i].file_name.find(filter) >= 0) or (file_list[i].file_name.find(search) >= 0):
175 htmlstr += file_list[i].file_name + "<p>"
176 return htmlstr
177
178
179@register.filter
180def string_slice(strvar,slicevar):
181 """ slice a string with |string_slice:'[first]:[last]'
182 """
183 first,last= slicevar.partition(':')[::2]
184 if first=='':
185 return strvar[:int(last)]
186 elif last=='':
187 return strvar[int(first):]
188 else:
189 return strvar[int(first):int(last)]
190
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py
index b77be1a6e7..3a362e6fe6 100644
--- a/bitbake/lib/toaster/toastergui/views.py
+++ b/bitbake/lib/toaster/toastergui/views.py
@@ -733,59 +733,118 @@ def recipes(request, build_id):
733 733
734def configuration(request, build_id): 734def configuration(request, build_id):
735 template = 'configuration.html' 735 template = 'configuration.html'
736 context = {'build': Build.objects.filter(pk=build_id)[0]} 736
737 variables = Variable.objects.filter(build=build_id)
738 BB_VERSION=variables.filter(variable_name='BB_VERSION')[0].variable_value
739 BUILD_SYS=variables.filter(variable_name='BUILD_SYS')[0].variable_value
740 NATIVELSBSTRING=variables.filter(variable_name='NATIVELSBSTRING')[0].variable_value
741 TARGET_SYS=variables.filter(variable_name='TARGET_SYS')[0].variable_value
742 MACHINE=variables.filter(variable_name='MACHINE')[0].variable_value
743 DISTRO=variables.filter(variable_name='DISTRO')[0].variable_value
744 DISTRO_VERSION=variables.filter(variable_name='DISTRO_VERSION')[0].variable_value
745 TUNE_FEATURES=variables.filter(variable_name='TUNE_FEATURES')[0].variable_value
746 TARGET_FPU=variables.filter(variable_name='TARGET_FPU')[0].variable_value
747
748 targets = Target.objects.filter(build=build_id)
749
750 context = {
751 'objectname': 'configuration',
752 'object_search_display':'variables',
753 'filter_search_display':'variables',
754 'build': Build.objects.filter(pk=build_id)[0],
755 'BB_VERSION':BB_VERSION,
756 'BUILD_SYS':BUILD_SYS,
757 'NATIVELSBSTRING':NATIVELSBSTRING,
758 'TARGET_SYS':TARGET_SYS,
759 'MACHINE':MACHINE,
760 'DISTRO':DISTRO,
761 'DISTRO_VERSION':DISTRO_VERSION,
762 'TUNE_FEATURES':TUNE_FEATURES,
763 'TARGET_FPU':TARGET_FPU,
764 'targets':targets,
765 }
737 return render(request, template, context) 766 return render(request, template, context)
738 767
739 768
740def configvars(request, build_id): 769def configvars(request, build_id):
741 template = 'configvars.html' 770 template = 'configvars.html'
742 mandatory_parameters = { 'count': 100, 'page' : 1}; 771 mandatory_parameters = { 'count': 100, 'page' : 1, 'orderby':'variable_name:+', 'filter':'description__regex:.+'};
743 retval = _verify_parameters( request.GET, mandatory_parameters ) 772 retval = _verify_parameters( request.GET, mandatory_parameters )
744 if retval: 773 if retval:
745 return _redirect_parameters( 'configvars', request.GET, mandatory_parameters, build_id = build_id) 774 return _redirect_parameters( 'configvars', request.GET, mandatory_parameters, build_id = build_id)
746 775
747 (filter_string, search_term, ordering_string) = _search_tuple(request, Variable) 776 (filter_string, search_term, ordering_string) = _search_tuple(request, Variable)
748 queryset = Variable.objects.filter(build=build_id) 777 queryset = Variable.objects.filter(build=build_id).exclude(variable_name__istartswith='B_').exclude(variable_name__istartswith='do_')
749 queryset = _get_queryset(Variable, queryset, filter_string, search_term, ordering_string) 778 queryset = _get_queryset(Variable, queryset, filter_string, search_term, ordering_string)
779 # remove duplicate records from multiple search hits in the VariableHistory table
780 queryset = queryset.distinct()
781 # remove records where the value is empty AND there are no history files
782 queryset = queryset.exclude(variable_value='',vhistory__file_name__isnull=True)
750 783
751 variables = _build_page_range(Paginator(queryset, request.GET.get('count', 50)), request.GET.get('page', 1)) 784 variables = _build_page_range(Paginator(queryset, request.GET.get('count', 50)), request.GET.get('page', 1))
752 785
786 file_filter= search_term + ":"
787 if filter_string.find('conf/local.conf') > 0:
788 file_filter += 'conf/local.conf'
789 if filter_string.find('conf/machine/') > 0:
790 file_filter += 'conf/machine/'
791 if filter_string.find('conf/distro/') > 0:
792 file_filter += 'conf/distro/'
793 if filter_string.find('/bitbake.conf') > 0:
794 file_filter += '/bitbake.conf'
795
753 context = { 796 context = {
797 'objectname': 'configvars',
798 'object_search_display':'variables',
799 'filter_search_display':'variables',
800 'file_filter': file_filter,
754 'build': Build.objects.filter(pk=build_id)[0], 801 'build': Build.objects.filter(pk=build_id)[0],
755 'objects' : variables, 802 'objects' : variables,
756 # Specifies the display of columns for the table, appearance in "Edit columns" box, toggling default show/hide, and specifying filters for columns 803 # Specifies the display of columns for the table, appearance in "Edit columns" box, toggling default show/hide, and specifying filters for columns
757 'tablecols' : [ 804 'tablecols' : [
758 {'name': 'Variable ', 805 {'name': 'Variable ',
759 'qhelp': "Base variable expanded name", 806 'qhelp': "BitBake is a generic task executor that considers a list of tasks with dependencies and handles metadata that consists of variables in a certain format that get passed to the tasks",
760 'clclass' : 'variable',
761 'dclass' : "span3", 807 'dclass' : "span3",
762 'orderfield': _get_toggle_order(request, "variable_name"), 808 'orderfield': _get_toggle_order(request, "variable_name"),
809 'ordericon':_get_toggle_order_icon(request, "variable_name"),
763 }, 810 },
764 {'name': 'Value ', 811 {'name': 'Value ',
765 'qhelp': "The value assigned to the variable", 812 'qhelp': "The value assigned to the variable",
766 'clclass': 'variable_value',
767 'dclass': "span4", 813 'dclass': "span4",
768 'orderfield': _get_toggle_order(request, "variable_value"), 814 'orderfield': _get_toggle_order(request, "variable_value"),
815 'ordericon':_get_toggle_order_icon(request, "variable_value"),
769 }, 816 },
770 {'name': 'Configuration file(s) ', 817 {'name': 'Set in file',
771 'qhelp': "The configuration file(s) that touched the variable value", 818 'qhelp': "The last configuration file that touched the variable value",
772 'clclass': 'file', 819 'clclass': 'file', 'hidden' : 0,
773 'dclass': "span6", 820 'dclass': "span6",
774 'orderfield': _get_toggle_order(request, "variable_vhistory__file_name"), 821 'orderfield': _get_toggle_order(request, "vhistory__file_name"),
775 'filter' : { 'class': 'file', 'label' : 'Show only', 'options' : { 822 'ordericon':_get_toggle_order_icon(request, "vhistory__file_name"),
776 } 823 'filter' : {
777 } 824 'class' : 'vhistory__file_name',
825 'label': 'Show:',
826 'options' : [
827 ('Local configuration variables', 'vhistory__file_name__contains:conf/local.conf'),
828 ('Machine configuration variables', 'vhistory__file_name__contains:conf/machine/'),
829 ('Distro configuration variables', 'vhistory__file_name__contains:conf/distro/'),
830 ('Layer configuration variables', 'vhistory__file_name__contains:conf/layer.conf'),
831 ('bitbake.conf variables', 'vhistory__file_name__contains:/bitbake.conf'),
832 ]
833 },
778 }, 834 },
779 {'name': 'Description ', 835 {'name': 'Description ',
780 'qhelp': "A brief explanation of a variable", 836 'qhelp': "A brief explanation of the variable",
781 'clclass': 'description', 837 'clclass': 'description', 'hidden' : 0,
782 'dclass': "span5", 838 'dclass': "span5",
783 'orderfield': _get_toggle_order(request, "description"), 839 'filter' : {
784 'filter' : { 'class' : 'description', 'label' : 'No', 'options' : { 840 'class' : 'description',
785 } 841 'label': 'Show:',
786 }, 842 'options' : [
787 } 843 ('Variables with description', 'description__regex:.+'),
788 ] 844 ]
845 },
846 },
847 ],
789 } 848 }
790 849
791 return render(request, template, context) 850 return render(request, template, context)