summaryrefslogtreecommitdiffstats
path: root/bitbake
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 /bitbake
parent31d4bf8484ee42690386c6b7a6bd6c7a2be54464 (diff)
downloadast2050-yocto-poky-4717749fd651e6983a31e3cefe3f210d2646ca87.zip
ast2050-yocto-poky-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>
Diffstat (limited to 'bitbake')
-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 8d4771c..96f093f 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) {
}
</script>
+
+<script>
+ $(document).ready(function() {
+ //show or hide selected columns on load
+ $("input:checkbox").each(function(){
+ var selectedType = $(this).val();
+ if($(this).is(":checked")){
+ $("."+selectedType).show();
+ }
+ else{
+ $("."+selectedType).hide();
+ }
+ });
+ //edit columns functionality (show / hide table columns)
+ $("input:checkbox").change();
+ $("input:checkbox").change(function(){
+ var selectedType = $(this).val();
+ if($(this).is(":checked")){
+ $("."+selectedType).show();
+ }
+ else{
+ $("."+selectedType).hide();
+ }
+ });
+ //turn edit columns dropdown into a multi-select menu
+ $('.dropdown-menu input, .dropdown-menu label').click(function(e) {
+ e.stopPropagation();
+ });
+ //show help information inside modal dialogs
+ $("#filter-variables i").tooltip({ html: true, delay: {show: 500} });
+ //show applied filter tooltip
+ $('.filtered').tooltip({container:'body', placement:'bottom', delay:{hide:1500}, html:true});
+ //hide the applied filter tooltip when you click the filter button
+ $('.btn-primary').on('click', function () {
+ $('.tooltip').hide();
+ });
+
+ $('.full-variable, .full-variable-hide').hide();
+ $('.full-variable-show').click(function(){
+ $('.full-variable').slideDown(function(){
+ $('.full-variable-hide').show();
+ });
+ $(this).hide();
+ });
+ $('.full-variable-hide').click(function(){
+ $(this).hide();
+ $('.full-variable').slideUp(function(){
+ $('.full-variable-show').show();
+ });
+ });
+ });
+</script>
+
</head>
<body style="height: 100%">
diff --git a/bitbake/lib/toaster/toastergui/templates/configuration.html b/bitbake/lib/toaster/toastergui/templates/configuration.html
index 467fbd0..ddfa5af 100644
--- a/bitbake/lib/toaster/toastergui/templates/configuration.html
+++ b/bitbake/lib/toaster/toastergui/templates/configuration.html
@@ -3,6 +3,8 @@
<li>Configuration</li>
{% endblock %}
+{% load projecttags %}
+
{% block buildinfomain %}
<!-- page title -->
<div class="row-fluid span10">
@@ -22,15 +24,19 @@
<div id="summary" class="tab-pane active">
<h3>Build configuration</h3>
<dl class="dl-horizontal">
- <dt>BitBake version</dt><dd>1.19.1</dd>
- <dt>Build system</dt><dd>x86_64-linux</dd>
- <dt>Host distribution</dt><dd>Ubuntu-12.04</dd>
- <dt>Target system</dt><dd>i586-poky-linux</dd>
- <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>
- <dt><i class="icon-question-sign get-help" data-toggle="tooltip" title="The short name of the distribution"></i> Distro</dt><dd>poky</dd>
- <dt>Distro version</dt><dd>1.4+snapshot-20130718</dd>
- <dt>Tune features</dt><dd>m32 i586</dd>
- <dt>Target(s)</dt><dd>core-image-sato</dd>
+ {%if BB_VERSION %}<dt>BitBake version</dt><dd>{{BB_VERSION}}</dd> {% endif %}
+ {%if BUILD_SYS %}<dt>Build system</dt><dd>{{BUILD_SYS}}</dd> {% endif %}
+ {%if NATIVELSBSTRING %}<dt>Host distribution</dt><dd>{{NATIVELSBSTRING}}</dd> {% endif %}
+ {%if TARGET_SYS %}<dt>Target system</dt><dd>{{TARGET_SYS}}</dd> {% endif %}
+ {%if MACHINE %}<dt>Machine</dt><dd>{{MACHINE}}</dd> {% endif %}
+ {%if DISTRO %}<dt>Distro</dt><dd>{{DISTRO}}</dd> {% endif %}
+ {%if DISTRO_VERSION %}<dt>Distro version</dt><dd>{{DISTRO_VERSION}}</dd> {% endif %}
+ {%if TUNE_FEATURES %}<dt>Tune features</dt><dd>{{TUNE_FEATURES}}</dd> {% endif %}
+ {%if TARGET_FPU %}<dt>Target FPU</dt><dd>{{TARGET_FPU}}</dd> {% endif %}
+ {%if targets.all %}<dt>Target(s)</dt>
+ <dd> <ul> {% for target in targets.all %}
+ <li>{{target.target}}{%if forloop.counter > 1 %}<br>{% endif %}</li>
+ {% endfor %} </ul> </dd> {% endif %}
</dl>
<h3>Layers</h3>
<div class="span9" style="margin-left:0px;">
@@ -45,7 +51,13 @@
</thead>
<tbody>{% for lv in build.layer_version_build.all %}
<tr>
- <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>
+ <td>{{lv.layer.name}}</td>
+ <td>{{lv.branch}}</td>
+ <td> <a class="btn" data-content="<ul class='unstyled'>
+ <li>{{lv.commit}}</li> </ul>">
+ {{lv.commit|truncatechars:13}}
+ </a></td>
+ <td>{{lv.layer.local_path}}</td>
</tr>{% endfor %}
</tbody>
</table>
diff --git a/bitbake/lib/toaster/toastergui/templates/configvars.html b/bitbake/lib/toaster/toastergui/templates/configvars.html
index ae45119..cd41cca 100644
--- a/bitbake/lib/toaster/toastergui/templates/configvars.html
+++ b/bitbake/lib/toaster/toastergui/templates/configvars.html
@@ -3,38 +3,110 @@
<li>Configuration</li>
{% endblock %}
+{% load projecttags %}
+
{% block buildinfomain %}
<!-- page title -->
<div class="row-fluid span10">
<div class="page-header">
- <h1>Configuration</h1>
+ <h1>
+ {% if request.GET.filter or request.GET.search and objects.count > 0 %}
+ {{objects.paginator.count}} variable{{objects.paginator.count|pluralize}} found
+ {%elif objects.paginator.count == 0%}
+ No variables
+ {%else%}
+ Configuration
+ {%endif%}
+ </h1>
</div>
</div>
<!-- configuration table -->
<div class="row-fluid pull-right span10" id="navTab">
-<ul class="nav nav-pills">
+ <ul class="nav nav-pills">
<li class=""><a href="{% url 'configuration' build.id %}">Summary</a></li>
<li class="active"><a href="#" >BitBake variables</a></li>
-</ul>
-
+ </ul>
<!-- variables -->
<div id="variables" class="tab-pane">
-{% include "basetable_top.html" %}
+ {% include "basetable_top.html" %}
-{% for variable in objects %}
- <tr class="data">
- <td class="variable">{{variable.variable_name}}</td>
- <td class="variable_value">{{variable.variable_value}}</td>
- <td class="file">{% for vh in variable.vhistory_set.all %}{{vh.operation}} in {{vh.file_name}}:{{vh.line_number}}<br/>{%endfor%}</td>
- <td class="description">{% if variable.description %}{{variable.description}}{% endif %}</td>
+ {% for variable in objects %}
+ <tr class="data">
+ <td class="variable_name"><a data-toggle="modal" href="#variable-{{variable.pk}}">{{variable.variable_name}}</a></td>
+ <td class="variable_value"><a data-toggle="modal" href="#variable-{{variable.pk}}">{{variable.variable_value|truncatechars:153}}</a></td>
+ <td class="file"><a data-toggle="modal" href="#variable-{{variable.pk}}">
+ {% if variable.vhistory.all %} {% autoescape off %}
+ {{variable.vhistory.all | filter_setin_files:file_filter }}
+ {% endautoescape %} {% endif %}
+ </a></td>
+ <td class="description">
+ {% if variable.description %}
+ {{variable.description}}
+ <a href="http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-{{variable.variable_name|variable_parent_name}}" target="_blank">
+ <i class="icon-share get-info"></i></a>
+ {% endif %}
+ </td>
</tr>
{% endfor %}
{% include "basetable_bottom.html" %}
+</div> <!-- endvariables -->
- </div> <!-- endvariables -->
+<!-- file list popups -->
+{% for variable in objects %}
+ {% if variable.vhistory.count %}
+ <div id="variable-{{variable.pk}}" class="modal hide fade" tabindex="-1" role="dialog">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
+ <h3>History of {{variable.variable_name}}</h3>
+ </div>
+ <div class="modal-body">
+ {% if variable.variable_value %}
+ {% if variable.variable_value|length < 570 %}
+ <h4>{{variable.variable_name}} value is:</h4>
+ <p>
+ {{variable.variable_value}}
+ </p>
+ {% else %}
+ <h4>{{variable.variable_name}} value is:</h4>
+ <p>
+ <span>{{variable.variable_value|string_slice:':570'}}
+ <span class="full-variable"> {{variable.variable_value|string_slice:'570:'}}
+ </span>
+ <a class="btn btn-mini full-variable-show">...</a>
+ </span>
+ </p>
+ <a class="btn btn-mini full-variable-hide">Collapse variable value<i class="icon-caret-up"></i>
+ </a>
+ {% endif %}
+ {% else %}
+ <div class="alert alert-info">The value of <strong>{{variable.variable_name}}</strong> is an empty string</div>
+ {% endif %}
+ <h4>The value was set in the following configuration files:</h4>
+ <table class="table table-bordered table-hover">
+ <thead>
+ <tr>
+ <th>Order</th>
+ <th>Configuration file</th>
+ <th>Operation</th>
+ <th>Line number</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for vh in variable.vhistory.all %}
+ <tr>
+ <td>{{forloop.counter}}</td><td>{{vh.file_name}}</td><td>{{vh.operation}}</td><td>{{vh.line_number}}</td>
+ </tr>
+ {%endfor%}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ {% endif %}
+{% endfor %}
+
+</div> <!-- buildinfomain -->
-</div>
{% endblock %}
diff --git a/bitbake/lib/toaster/toastergui/templatetags/projecttags.py b/bitbake/lib/toaster/toastergui/templatetags/projecttags.py
index b1e573b..857680b 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):
if filter == option[1]:
return ""
return "checked"
+
+@register.filter
+def variable_parent_name(value):
+ """ filter extended variable names to the parent name
+ """
+ value=re.sub('_\$.*', '', value)
+ return re.sub('_[a-z].*', '', value)
+
+@register.filter
+def filter_setin_files(file_list,matchstr):
+ """ filter/search the 'set in' file lists. Note
+ that this output is not autoescaped to allow
+ the <p> marks, but this is safe as the data
+ is file paths
+ """
+
+ # no filters, show last file (if any)
+ if matchstr == ":":
+ if file_list:
+ return file_list[len(file_list)-1].file_name
+ else:
+ return ''
+
+ search, filter = matchstr.partition(':')[::2]
+ htmlstr=""
+ # match only filters
+ if search == '':
+ for i in range(len(file_list)):
+ if file_list[i].file_name.find(filter) >= 0:
+ htmlstr += file_list[i].file_name + "<p>"
+ return htmlstr
+
+ # match only search string, plus always last file
+ if filter == "":
+ for i in range(len(file_list)-1):
+ if file_list[i].file_name.find(search) >= 0:
+ htmlstr += file_list[i].file_name + "<p>"
+ htmlstr += file_list[len(file_list)-1].file_name
+ return htmlstr
+
+ # match filter or search string
+ for i in range(len(file_list)):
+ if (file_list[i].file_name.find(filter) >= 0) or (file_list[i].file_name.find(search) >= 0):
+ htmlstr += file_list[i].file_name + "<p>"
+ return htmlstr
+
+
+@register.filter
+def string_slice(strvar,slicevar):
+ """ slice a string with |string_slice:'[first]:[last]'
+ """
+ first,last= slicevar.partition(':')[::2]
+ if first=='':
+ return strvar[:int(last)]
+ elif last=='':
+ return strvar[int(first):]
+ else:
+ return strvar[int(first):int(last)]
+
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py
index b77be1a..3a362e6 100644
--- a/bitbake/lib/toaster/toastergui/views.py
+++ b/bitbake/lib/toaster/toastergui/views.py
@@ -733,59 +733,118 @@ def recipes(request, build_id):
def configuration(request, build_id):
template = 'configuration.html'
- context = {'build': Build.objects.filter(pk=build_id)[0]}
+
+ variables = Variable.objects.filter(build=build_id)
+ BB_VERSION=variables.filter(variable_name='BB_VERSION')[0].variable_value
+ BUILD_SYS=variables.filter(variable_name='BUILD_SYS')[0].variable_value
+ NATIVELSBSTRING=variables.filter(variable_name='NATIVELSBSTRING')[0].variable_value
+ TARGET_SYS=variables.filter(variable_name='TARGET_SYS')[0].variable_value
+ MACHINE=variables.filter(variable_name='MACHINE')[0].variable_value
+ DISTRO=variables.filter(variable_name='DISTRO')[0].variable_value
+ DISTRO_VERSION=variables.filter(variable_name='DISTRO_VERSION')[0].variable_value
+ TUNE_FEATURES=variables.filter(variable_name='TUNE_FEATURES')[0].variable_value
+ TARGET_FPU=variables.filter(variable_name='TARGET_FPU')[0].variable_value
+
+ targets = Target.objects.filter(build=build_id)
+
+ context = {
+ 'objectname': 'configuration',
+ 'object_search_display':'variables',
+ 'filter_search_display':'variables',
+ 'build': Build.objects.filter(pk=build_id)[0],
+ 'BB_VERSION':BB_VERSION,
+ 'BUILD_SYS':BUILD_SYS,
+ 'NATIVELSBSTRING':NATIVELSBSTRING,
+ 'TARGET_SYS':TARGET_SYS,
+ 'MACHINE':MACHINE,
+ 'DISTRO':DISTRO,
+ 'DISTRO_VERSION':DISTRO_VERSION,
+ 'TUNE_FEATURES':TUNE_FEATURES,
+ 'TARGET_FPU':TARGET_FPU,
+ 'targets':targets,
+ }
return render(request, template, context)
def configvars(request, build_id):
template = 'configvars.html'
- mandatory_parameters = { 'count': 100, 'page' : 1};
+ mandatory_parameters = { 'count': 100, 'page' : 1, 'orderby':'variable_name:+', 'filter':'description__regex:.+'};
retval = _verify_parameters( request.GET, mandatory_parameters )
if retval:
return _redirect_parameters( 'configvars', request.GET, mandatory_parameters, build_id = build_id)
(filter_string, search_term, ordering_string) = _search_tuple(request, Variable)
- queryset = Variable.objects.filter(build=build_id)
+ queryset = Variable.objects.filter(build=build_id).exclude(variable_name__istartswith='B_').exclude(variable_name__istartswith='do_')
queryset = _get_queryset(Variable, queryset, filter_string, search_term, ordering_string)
+ # remove duplicate records from multiple search hits in the VariableHistory table
+ queryset = queryset.distinct()
+ # remove records where the value is empty AND there are no history files
+ queryset = queryset.exclude(variable_value='',vhistory__file_name__isnull=True)
variables = _build_page_range(Paginator(queryset, request.GET.get('count', 50)), request.GET.get('page', 1))
+ file_filter= search_term + ":"
+ if filter_string.find('conf/local.conf') > 0:
+ file_filter += 'conf/local.conf'
+ if filter_string.find('conf/machine/') > 0:
+ file_filter += 'conf/machine/'
+ if filter_string.find('conf/distro/') > 0:
+ file_filter += 'conf/distro/'
+ if filter_string.find('/bitbake.conf') > 0:
+ file_filter += '/bitbake.conf'
+
context = {
+ 'objectname': 'configvars',
+ 'object_search_display':'variables',
+ 'filter_search_display':'variables',
+ 'file_filter': file_filter,
'build': Build.objects.filter(pk=build_id)[0],
'objects' : variables,
# Specifies the display of columns for the table, appearance in "Edit columns" box, toggling default show/hide, and specifying filters for columns
'tablecols' : [
{'name': 'Variable ',
- 'qhelp': "Base variable expanded name",
- 'clclass' : 'variable',
+ '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",
'dclass' : "span3",
'orderfield': _get_toggle_order(request, "variable_name"),
+ 'ordericon':_get_toggle_order_icon(request, "variable_name"),
},
{'name': 'Value ',
'qhelp': "The value assigned to the variable",
- 'clclass': 'variable_value',
'dclass': "span4",
'orderfield': _get_toggle_order(request, "variable_value"),
+ 'ordericon':_get_toggle_order_icon(request, "variable_value"),
},
- {'name': 'Configuration file(s) ',
- 'qhelp': "The configuration file(s) that touched the variable value",
- 'clclass': 'file',
+ {'name': 'Set in file',
+ 'qhelp': "The last configuration file that touched the variable value",
+ 'clclass': 'file', 'hidden' : 0,
'dclass': "span6",
- 'orderfield': _get_toggle_order(request, "variable_vhistory__file_name"),
- 'filter' : { 'class': 'file', 'label' : 'Show only', 'options' : {
- }
- }
+ 'orderfield': _get_toggle_order(request, "vhistory__file_name"),
+ 'ordericon':_get_toggle_order_icon(request, "vhistory__file_name"),
+ 'filter' : {
+ 'class' : 'vhistory__file_name',
+ 'label': 'Show:',
+ 'options' : [
+ ('Local configuration variables', 'vhistory__file_name__contains:conf/local.conf'),
+ ('Machine configuration variables', 'vhistory__file_name__contains:conf/machine/'),
+ ('Distro configuration variables', 'vhistory__file_name__contains:conf/distro/'),
+ ('Layer configuration variables', 'vhistory__file_name__contains:conf/layer.conf'),
+ ('bitbake.conf variables', 'vhistory__file_name__contains:/bitbake.conf'),
+ ]
+ },
},
{'name': 'Description ',
- 'qhelp': "A brief explanation of a variable",
- 'clclass': 'description',
+ 'qhelp': "A brief explanation of the variable",
+ 'clclass': 'description', 'hidden' : 0,
'dclass': "span5",
- 'orderfield': _get_toggle_order(request, "description"),
- 'filter' : { 'class' : 'description', 'label' : 'No', 'options' : {
- }
- },
- }
- ]
+ 'filter' : {
+ 'class' : 'description',
+ 'label': 'Show:',
+ 'options' : [
+ ('Variables with description', 'description__regex:.+'),
+ ]
+ },
+ },
+ ],
}
return render(request, template, context)
OpenPOWER on IntegriCloud