diff options
| -rw-r--r-- | bitbake/lib/toaster/toastergui/templates/configvars.html | 10 | ||||
| -rw-r--r-- | bitbake/lib/toaster/toastergui/templatetags/projecttags.py | 76 | ||||
| -rwxr-xr-x | bitbake/lib/toaster/toastergui/views.py | 19 |
3 files changed, 42 insertions, 63 deletions
diff --git a/bitbake/lib/toaster/toastergui/templates/configvars.html b/bitbake/lib/toaster/toastergui/templates/configvars.html index 3e4c7e85ea..42c42a57ad 100644 --- a/bitbake/lib/toaster/toastergui/templates/configvars.html +++ b/bitbake/lib/toaster/toastergui/templates/configvars.html | |||
| @@ -54,9 +54,11 @@ | |||
| 54 | <td class="variable_name"><a data-toggle="modal" href="#variable-{{variable.pk}}">{{variable.variable_name}}</a></td> | 54 | <td class="variable_name"><a data-toggle="modal" href="#variable-{{variable.pk}}">{{variable.variable_name}}</a></td> |
| 55 | <td class="variable_value"><a data-toggle="modal" href="#variable-{{variable.pk}}">{{variable.variable_value|truncatechars:153}}</a></td> | 55 | <td class="variable_value"><a data-toggle="modal" href="#variable-{{variable.pk}}">{{variable.variable_value|truncatechars:153}}</a></td> |
| 56 | <td class="file"><a data-toggle="modal" href="#variable-{{variable.pk}}"> | 56 | <td class="file"><a data-toggle="modal" href="#variable-{{variable.pk}}"> |
| 57 | {% if variable.vhistory.all %} {% autoescape off %} | 57 | {% if variable.vhistory.all %} |
| 58 | {{variable.vhistory.all | filter_setin_files:file_filter | cut_layer_path_prefix:layer_names}} | 58 | {% for path in variable.vhistory.all|filter_setin_files:file_filter %} |
| 59 | {% endautoescape %} {% endif %} | 59 | {{path|cut_path_prefix:dirstostrip}}<p> |
| 60 | {% endfor %} | ||
| 61 | {% endif %} | ||
| 60 | </a></td> | 62 | </a></td> |
| 61 | <td class="description"> | 63 | <td class="description"> |
| 62 | {% if variable.description %} | 64 | {% if variable.description %} |
| @@ -115,7 +117,7 @@ | |||
| 115 | <tbody> | 117 | <tbody> |
| 116 | {% for vh in variable.vhistory.all %} | 118 | {% for vh in variable.vhistory.all %} |
| 117 | <tr> | 119 | <tr> |
| 118 | <td>{{forloop.counter}}</td><td>{{vh.file_name|cut_layer_path_prefix:layer_names}}</td><td>{{vh.operation}}</td><td>{{vh.line_number}}</td> | 120 | <td>{{forloop.counter}}</td><td>{{vh.file_name|cut_path_prefix:dirstostrip}}</td><td>{{vh.operation}}</td><td>{{vh.line_number}}</td> |
| 119 | </tr> | 121 | </tr> |
| 120 | {%endfor%} | 122 | {%endfor%} |
| 121 | </tbody> | 123 | </tbody> |
diff --git a/bitbake/lib/toaster/toastergui/templatetags/projecttags.py b/bitbake/lib/toaster/toastergui/templatetags/projecttags.py index 54700e3842..1bc3bc2319 100644 --- a/bitbake/lib/toaster/toastergui/templatetags/projecttags.py +++ b/bitbake/lib/toaster/toastergui/templatetags/projecttags.py | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 20 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| 21 | 21 | ||
| 22 | from datetime import datetime, timedelta | 22 | from datetime import datetime, timedelta |
| 23 | from os.path import relpath | ||
| 23 | import re | 24 | import re |
| 24 | from django import template | 25 | from django import template |
| 25 | from django.utils import timezone | 26 | from django.utils import timezone |
| @@ -182,47 +183,23 @@ def variable_parent_name(value): | |||
| 182 | return re.sub('_[a-z].*', '', value) | 183 | return re.sub('_[a-z].*', '', value) |
| 183 | 184 | ||
| 184 | @register.filter | 185 | @register.filter |
| 185 | def filter_setin_files(file_list,matchstr): | 186 | def filter_setin_files(file_list, matchstr): |
| 186 | """ filter/search the 'set in' file lists. Note | 187 | """Filter/search the 'set in' file lists.""" |
| 187 | that this output is not autoescaped to allow | 188 | result = [] |
| 188 | the <p> marks, but this is safe as the data | 189 | search, filter = matchstr.split(':') |
| 189 | is file paths | 190 | for pattern in (search, filter): |
| 190 | """ | 191 | if pattern: |
| 191 | 192 | for fobj in file_list: | |
| 192 | # no filters, show last file (if any) | 193 | fname = fobj.file_name |
| 193 | if matchstr == ":": | 194 | if fname not in result and re.search(pattern, fname): |
| 194 | if file_list: | 195 | result.append(fname) |
| 195 | return file_list[len(file_list)-1].file_name | 196 | |
| 196 | else: | 197 | # no filter, show last file (if any) |
| 197 | return '' | 198 | last = list(file_list)[-1].file_name |
| 198 | 199 | if not filter and last not in result: | |
| 199 | search, filter = matchstr.partition(':')[::2] | 200 | result.append(last) |
| 200 | htmlstr="" | 201 | |
| 201 | # match only filters | 202 | return result |
| 202 | if search == '': | ||
| 203 | for i in range(len(file_list)): | ||
| 204 | if re.search(filter, file_list[i].file_name): | ||
| 205 | if htmlstr.find(file_list[i].file_name + "<p>") < 0: | ||
| 206 | htmlstr += file_list[i].file_name + "<p>" | ||
| 207 | return htmlstr | ||
| 208 | |||
| 209 | # match only search string, plus always last file | ||
| 210 | if filter == "": | ||
| 211 | for i in range(len(file_list)-1): | ||
| 212 | if re.search(search,file_list[i].file_name): | ||
| 213 | if htmlstr.find(file_list[i].file_name + "<p>") < 0: | ||
| 214 | htmlstr += file_list[i].file_name + "<p>" | ||
| 215 | if htmlstr.find(file_list[len(file_list)-1].file_name) < 0: | ||
| 216 | htmlstr += file_list[len(file_list)-1].file_name | ||
| 217 | return htmlstr | ||
| 218 | |||
| 219 | # match filter or search string | ||
| 220 | for i in range(len(file_list)): | ||
| 221 | if re.search(filter, file_list[i].file_name) or re.search(search,file_list[i].file_name): | ||
| 222 | if htmlstr.find(file_list[i].file_name + "<p>") < 0: | ||
| 223 | htmlstr += file_list[i].file_name + "<p>" | ||
| 224 | return htmlstr | ||
| 225 | |||
| 226 | 203 | ||
| 227 | @register.filter | 204 | @register.filter |
| 228 | def string_slice(strvar,slicevar): | 205 | def string_slice(strvar,slicevar): |
| @@ -313,16 +290,9 @@ def is_shaid(text): | |||
| 313 | return False | 290 | return False |
| 314 | 291 | ||
| 315 | @register.filter | 292 | @register.filter |
| 316 | def cut_layer_path_prefix(fullpath,layer_names): | 293 | def cut_path_prefix(fullpath, prefixes): |
| 317 | ### if some part of the full local path to a layer matches | 294 | """Cut path prefix from fullpath.""" |
| 318 | ### an entry in layer_names (sorted desc), return the layer | 295 | for prefix in prefixes: |
| 319 | ### name relative path. | 296 | if fullpath.startswith(prefix): |
| 320 | for lname in layer_names: | 297 | return relpath(fullpath, prefix) |
| 321 | # import rpdb; rpdb.set_trace() | ||
| 322 | # only try layer names that are non-trivial to avoid false matches | ||
| 323 | if len(lname) >= 4: | ||
| 324 | # match layer name with as a subdir / or for remote layers /_ | ||
| 325 | if re.search('/' + lname, fullpath) or re.search('/_' + lname, fullpath): | ||
| 326 | parts = re.split(lname, fullpath, 1) | ||
| 327 | return lname + parts[1] | ||
| 328 | return fullpath | 298 | return fullpath |
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py index 761bf53a11..d451c3b927 100755 --- a/bitbake/lib/toaster/toastergui/views.py +++ b/bitbake/lib/toaster/toastergui/views.py | |||
| @@ -28,6 +28,8 @@ 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 |
| 29 | from orm.models import Task_Dependency, Recipe_Dependency, Package, Package_File, Package_Dependency | 29 | from orm.models import Task_Dependency, Recipe_Dependency, Package, Package_File, Package_Dependency |
| 30 | from orm.models import Target_Installed_Package, Target_File, Target_Image_File, BuildArtifact | 30 | from orm.models import Target_Installed_Package, Target_File, Target_Image_File, BuildArtifact |
| 31 | from bldcontrol.models import BuildEnvironment, BuildRequest | ||
| 32 | from bldcontrol import bbcontroller | ||
| 31 | from django.views.decorators.cache import cache_control | 33 | from django.views.decorators.cache import cache_control |
| 32 | from django.core.urlresolvers import reverse | 34 | from django.core.urlresolvers import reverse |
| 33 | from django.core.exceptions import MultipleObjectsReturned | 35 | from django.core.exceptions import MultipleObjectsReturned |
| @@ -39,6 +41,7 @@ from datetime import timedelta, datetime, date | |||
| 39 | from django.utils import formats | 41 | from django.utils import formats |
| 40 | from toastergui.templatetags.projecttags import json as jsonfilter | 42 | from toastergui.templatetags.projecttags import json as jsonfilter |
| 41 | import json | 43 | import json |
| 44 | from os.path import dirname | ||
| 42 | 45 | ||
| 43 | # all new sessions should come through the landing page; | 46 | # all new sessions should come through the landing page; |
| 44 | # determine in which mode we are running in, and redirect appropriately | 47 | # determine in which mode we are running in, and redirect appropriately |
| @@ -1300,11 +1303,6 @@ def configvars(request, build_id): | |||
| 1300 | 1303 | ||
| 1301 | variables = _build_page_range(Paginator(queryset, pagesize), request.GET.get('page', 1)) | 1304 | variables = _build_page_range(Paginator(queryset, pagesize), request.GET.get('page', 1)) |
| 1302 | 1305 | ||
| 1303 | layers = Layer.objects.filter(layer_version_layer__projectlayer__project__build=build_id).order_by("-name") | ||
| 1304 | layer_names = map(lambda layer : layer.name, layers) | ||
| 1305 | # special case for meta built-in layer | ||
| 1306 | layer_names.append('meta') | ||
| 1307 | |||
| 1308 | # show all matching files (not just the last one) | 1306 | # show all matching files (not just the last one) |
| 1309 | file_filter= search_term + ":" | 1307 | file_filter= search_term + ":" |
| 1310 | if filter_string.find('/conf/') > 0: | 1308 | if filter_string.find('/conf/') > 0: |
| @@ -1317,6 +1315,15 @@ def configvars(request, build_id): | |||
| 1317 | file_filter += '/bitbake.conf' | 1315 | file_filter += '/bitbake.conf' |
| 1318 | build_dir=re.sub("/tmp/log/.*","",Build.objects.get(pk=build_id).cooker_log_path) | 1316 | build_dir=re.sub("/tmp/log/.*","",Build.objects.get(pk=build_id).cooker_log_path) |
| 1319 | 1317 | ||
| 1318 | clones = [] | ||
| 1319 | for breq in BuildRequest.objects.filter(build_id=build_id): | ||
| 1320 | bc = bbcontroller.getBuildEnvironmentController(pk = breq.environment.id) | ||
| 1321 | for brl in breq.brlayer_set.all(): | ||
| 1322 | localdirname = bc.getGitCloneDirectory(brl.giturl, brl.commit) | ||
| 1323 | if not localdirname.startswith("/"): | ||
| 1324 | localdirname = os.path.join(bc.be.sourcedir, localdirname) | ||
| 1325 | clones.append(localdirname) | ||
| 1326 | |||
| 1320 | context = { | 1327 | context = { |
| 1321 | 'objectname': 'configvars', | 1328 | 'objectname': 'configvars', |
| 1322 | 'object_search_display':'BitBake variables', | 1329 | 'object_search_display':'BitBake variables', |
| @@ -1327,7 +1334,7 @@ def configvars(request, build_id): | |||
| 1327 | 'total_count':queryset_with_search.count(), | 1334 | 'total_count':queryset_with_search.count(), |
| 1328 | 'default_orderby' : 'variable_name:+', | 1335 | 'default_orderby' : 'variable_name:+', |
| 1329 | 'search_term':search_term, | 1336 | 'search_term':search_term, |
| 1330 | 'layer_names' : layer_names, | 1337 | 'dirstostrip': clones + [dirname(build_dir), dirname(dirname(build_dir))], |
| 1331 | # Specifies the display of columns for the table, appearance in "Edit columns" box, toggling default show/hide, and specifying filters for columns | 1338 | # Specifies the display of columns for the table, appearance in "Edit columns" box, toggling default show/hide, and specifying filters for columns |
| 1332 | 'tablecols' : [ | 1339 | 'tablecols' : [ |
| 1333 | {'name': 'Variable', | 1340 | {'name': 'Variable', |
