diff options
13 files changed, 777 insertions, 32 deletions
diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py index 3abee016c4..113631def0 100644 --- a/bitbake/lib/toaster/orm/models.py +++ b/bitbake/lib/toaster/orm/models.py | |||
| @@ -145,6 +145,7 @@ class Task_Dependency(models.Model): | |||
| 145 | 145 | ||
| 146 | 146 | ||
| 147 | class Package(models.Model): | 147 | class Package(models.Model): |
| 148 | search_allowed_fields = ['name', 'installed_name', 'section', 'summary'] | ||
| 148 | build = models.ForeignKey('Build') | 149 | build = models.ForeignKey('Build') |
| 149 | recipe = models.ForeignKey('Recipe', null=True) | 150 | recipe = models.ForeignKey('Recipe', null=True) |
| 150 | name = models.CharField(max_length=100) | 151 | name = models.CharField(max_length=100) |
| @@ -160,23 +161,39 @@ class Package(models.Model): | |||
| 160 | 161 | ||
| 161 | class Package_Dependency(models.Model): | 162 | class Package_Dependency(models.Model): |
| 162 | TYPE_RDEPENDS = 0 | 163 | TYPE_RDEPENDS = 0 |
| 163 | TYPE_RPROVIDES = 1 | 164 | TYPE_TRDEPENDS = 1 |
| 164 | TYPE_RRECOMMENDS = 2 | 165 | TYPE_RRECOMMENDS = 2 |
| 165 | TYPE_RSUGGESTS = 3 | 166 | TYPE_TRECOMMENDS = 3 |
| 166 | TYPE_RREPLACES = 4 | 167 | TYPE_RSUGGESTS = 4 |
| 167 | TYPE_RCONFLICTS = 5 | 168 | TYPE_RPROVIDES = 5 |
| 168 | TYPE_TRDEPENDS = 6 | 169 | TYPE_RREPLACES = 6 |
| 169 | TYPE_TRECOMMENDS = 7 | 170 | TYPE_RCONFLICTS = 7 |
| 171 | ' TODO: bpackage should be changed to remove the DEPENDS_TYPE access ' | ||
| 170 | DEPENDS_TYPE = ( | 172 | DEPENDS_TYPE = ( |
| 171 | (TYPE_RDEPENDS, "rdepends"), | 173 | (TYPE_RDEPENDS, "depends"), |
| 172 | (TYPE_RPROVIDES, "rprovides"), | 174 | (TYPE_TRDEPENDS, "depends"), |
| 173 | (TYPE_RRECOMMENDS, "rrecommends"), | 175 | (TYPE_TRECOMMENDS, "recommends"), |
| 174 | (TYPE_RSUGGESTS, "rsuggests"), | 176 | (TYPE_RRECOMMENDS, "recommends"), |
| 175 | (TYPE_RREPLACES, "rreplaces"), | 177 | (TYPE_RSUGGESTS, "suggests"), |
| 176 | (TYPE_RCONFLICTS, "rconflicts"), | 178 | (TYPE_RPROVIDES, "provides"), |
| 177 | (TYPE_TRDEPENDS, "trdepends"), | 179 | (TYPE_RREPLACES, "replaces"), |
| 178 | (TYPE_TRECOMMENDS, "trecommends"), | 180 | (TYPE_RCONFLICTS, "conflicts"), |
| 179 | ) | 181 | ) |
| 182 | ''' Indexed by dep_type, in view order, key for short name and help | ||
| 183 | description which when viewed will be printf'd with the | ||
| 184 | package name. | ||
| 185 | ''' | ||
| 186 | DEPENDS_DICT = { | ||
| 187 | TYPE_RDEPENDS : ("depends", "%s is required to run %s"), | ||
| 188 | TYPE_TRDEPENDS : ("depends", "%s is required to run %s"), | ||
| 189 | TYPE_TRECOMMENDS : ("recommends", "%s extends the usability of %s"), | ||
| 190 | TYPE_RRECOMMENDS : ("recommends", "%s extends the usability of %s"), | ||
| 191 | TYPE_RSUGGESTS : ("suggests", "%s is suggested for installation with %s"), | ||
| 192 | TYPE_RPROVIDES : ("provides", "%s is provided by %s"), | ||
| 193 | TYPE_RREPLACES : ("replaces", "%s is replaced by %s"), | ||
| 194 | TYPE_RCONFLICTS : ("conflicts", "%s conflicts with %s, which will not be installed if this package is not first removed"), | ||
| 195 | } | ||
| 196 | |||
| 180 | package = models.ForeignKey(Package, related_name='package_dependencies_source') | 197 | package = models.ForeignKey(Package, related_name='package_dependencies_source') |
| 181 | depends_on = models.ForeignKey(Package, related_name='package_dependencies_target') # soft dependency | 198 | depends_on = models.ForeignKey(Package, related_name='package_dependencies_target') # soft dependency |
| 182 | dep_type = models.IntegerField(choices=DEPENDS_TYPE) | 199 | dep_type = models.IntegerField(choices=DEPENDS_TYPE) |
| @@ -184,7 +201,7 @@ class Package_Dependency(models.Model): | |||
| 184 | 201 | ||
| 185 | class Target_Installed_Package(models.Model): | 202 | class Target_Installed_Package(models.Model): |
| 186 | target = models.ForeignKey(Target) | 203 | target = models.ForeignKey(Target) |
| 187 | package = models.ForeignKey(Package) | 204 | package = models.ForeignKey(Package, related_name='buildtargetlist_package') |
| 188 | 205 | ||
| 189 | class Package_File(models.Model): | 206 | class Package_File(models.Model): |
| 190 | package = models.ForeignKey(Package, related_name='buildfilelist_package') | 207 | package = models.ForeignKey(Package, related_name='buildfilelist_package') |
diff --git a/bitbake/lib/toaster/toastergui/templates/bpackage.html b/bitbake/lib/toaster/toastergui/templates/bpackage.html index 3329ddae51..b78ae4644f 100644 --- a/bitbake/lib/toaster/toastergui/templates/bpackage.html +++ b/bitbake/lib/toaster/toastergui/templates/bpackage.html | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | {% for package in objects %} | 26 | {% for package in objects %} |
| 27 | 27 | ||
| 28 | <tr class="data"> | 28 | <tr class="data"> |
| 29 | <td><a name="#{{package.name}}" href="{% url "package" build.pk package.pk %}">{{package.name}} ({{package.filelist_bpackage.count}} files)</a></td> | 29 | <td><a name="#{{package.name}}" href="{% url "package_built_detail" build.pk package.pk %}">{{package.name}} ({{package.filelist_bpackage.count}} files)</a></td> |
| 30 | <td>{{package.version}}-{{package.revision}}</td> | 30 | <td>{{package.version}}-{{package.revision}}</td> |
| 31 | <td>{%if package.recipe%}<a href="{% url "layer_versions_recipes" package.recipe.layer_version_id %}#{{package.recipe.name}}">{{package.recipe.name}}</a>{{package.package_name}}</a>{%endif%}</td> | 31 | <td>{%if package.recipe%}<a href="{% url "layer_versions_recipes" package.recipe.layer_version_id %}#{{package.recipe.name}}">{{package.recipe.name}}</a>{{package.package_name}}</a>{%endif%}</td> |
| 32 | 32 | ||
diff --git a/bitbake/lib/toaster/toastergui/templates/package_built_dependencies.html b/bitbake/lib/toaster/toastergui/templates/package_built_dependencies.html new file mode 100644 index 0000000000..c67f60e20b --- /dev/null +++ b/bitbake/lib/toaster/toastergui/templates/package_built_dependencies.html | |||
| @@ -0,0 +1,112 @@ | |||
| 1 | {% extends "package_detail_base.html" %} | ||
| 2 | {% load projecttags %} | ||
| 3 | |||
| 4 | {% block tabcontent %} | ||
| 5 | {% with fullPackageSpec=package.name|add:"-"|add:package.version|add:"-"|add:package.revision|filtered_packagespec %} | ||
| 6 | <ul class="nav nav-pills"> | ||
| 7 | <li class=""> | ||
| 8 | <a href="{% url 'package_built_detail' build.id package.id %}"> | ||
| 9 | <i class="icon-question-sign get-help" data-toggle="tooltip" title="Shows the files produced by this package."></i> | ||
| 10 | Generated files ({{package.buildfilelist_package.count}}) | ||
| 11 | </a> | ||
| 12 | </li> | ||
| 13 | <li class="active"> | ||
| 14 | <a href="{% url 'package_built_dependencies' build.id package.id %}"> | ||
| 15 | <i class="icon-question-sign get-help" data-toggle="tooltip" title="Shows the runtime packages required by this package."></i> | ||
| 16 | Runtime dependencies ({{dependency_count}}) | ||
| 17 | </a> | ||
| 18 | </li> | ||
| 19 | </ul> | ||
| 20 | <div class="tab-content"> | ||
| 21 | <div class="tab-pane active" id="dependencies"> | ||
| 22 | {% ifequal runtime_deps|length 0 %} | ||
| 23 | <div class="alert alert-info"> | ||
| 24 | <strong>{{fullPackageSpec}}</strong> has no runtime dependencies. | ||
| 25 | </div> | ||
| 26 | {% else %} | ||
| 27 | <div class="alert alert-info"> | ||
| 28 | <strong>{{fullPackageSpec}}</strong> is <strong>not included</strong> in any image. These are its projected runtime dependencies if you were to include it in future builds. | ||
| 29 | </div> | ||
| 30 | <table class="table table-bordered table-hover"> | ||
| 31 | <thead> | ||
| 32 | <tr> | ||
| 33 | <th>Package</th> | ||
| 34 | <th>Version</th> | ||
| 35 | <th>Size</th> | ||
| 36 | </tr> | ||
| 37 | </thead> | ||
| 38 | {% for runtime_dep in runtime_deps %} | ||
| 39 | <tbody> | ||
| 40 | {% ifequal runtime_dep.version '' %} | ||
| 41 | <tr class="muted"> | ||
| 42 | <td>{{runtime_dep.name}}</td> | ||
| 43 | <td>{{runtime_dep.version}}</td> | ||
| 44 | <td></td> | ||
| 45 | </div> | ||
| 46 | </tr> | ||
| 47 | {% else %} | ||
| 48 | <tr> | ||
| 49 | <td> | ||
| 50 | <a href="{% url 'package_built_detail' build.id runtime_dep.depends_on_id %}"> | ||
| 51 | {{runtime_dep.name}} | ||
| 52 | </a> | ||
| 53 | </td> | ||
| 54 | <td>{{runtime_dep.version}}</td> | ||
| 55 | <td>{{runtime_dep.size|filtered_filesizeformat}}</td> | ||
| 56 | </tr> | ||
| 57 | {% endifequal %} | ||
| 58 | </tbody> | ||
| 59 | {% endfor %} | ||
| 60 | </table> | ||
| 61 | {% endifequal %} | ||
| 62 | {% ifnotequal other_deps|length 0 %} | ||
| 63 | <h3>Other runtime relationships</h3> | ||
| 64 | <table class="table table-bordered table-hover"> | ||
| 65 | <thead> | ||
| 66 | <tr> | ||
| 67 | <th>Package</th> | ||
| 68 | <th>Version</th> | ||
| 69 | <th>Size</th> | ||
| 70 | |||
| 71 | <th> | ||
| 72 | <i class="icon-question-sign get-help" title="There are 5 relationship types: recommends, suggests, provides, replaces and conflicts"></i> | ||
| 73 | Relationship type | ||
| 74 | </th> | ||
| 75 | </tr> | ||
| 76 | </thead> | ||
| 77 | |||
| 78 | {% for other_dep in other_deps %} | ||
| 79 | <tbody> | ||
| 80 | {% ifequal other_dep.version '' %} | ||
| 81 | <tr class="muted"> | ||
| 82 | <td>{{other_dep.name}}</td> | ||
| 83 | <td>{{other_dep.version}}</td> | ||
| 84 | <td></td> | ||
| 85 | <td> | ||
| 86 | {{other_dep.dep_type_display}} | ||
| 87 | <i class="icon-question-sign get-help hover-help" title="{{other_dep.dep_type_help}}" ></i> | ||
| 88 | </td> | ||
| 89 | </tr> | ||
| 90 | {% else %} | ||
| 91 | <tr> | ||
| 92 | <td> | ||
| 93 | <a href="{% url 'package_built_detail' build.id other_dep.depends_on_id %}"> | ||
| 94 | {{other_dep.name}} | ||
| 95 | </a> | ||
| 96 | </td> | ||
| 97 | <td>{{other_dep.version}}</td> | ||
| 98 | <td>{{other_dep.size|filtered_filesizeformat}}</td> | ||
| 99 | <td> | ||
| 100 | {{other_dep.dep_type_display}} | ||
| 101 | <i class="icon-question-sign get-help hover-help" title="{{other_dep.dep_type_help}}" ></i> | ||
| 102 | </td> | ||
| 103 | </tr> | ||
| 104 | </tbody> | ||
| 105 | {% endifequal %} | ||
| 106 | {% endfor %} | ||
| 107 | </table> | ||
| 108 | {% endifnotequal %} | ||
| 109 | </div> <!-- tab-pane --> | ||
| 110 | </div> <!-- tab-content --> | ||
| 111 | {% endwith %} | ||
| 112 | {% endblock tabcontent %} | ||
diff --git a/bitbake/lib/toaster/toastergui/templates/package_built_detail.html b/bitbake/lib/toaster/toastergui/templates/package_built_detail.html new file mode 100644 index 0000000000..fe856a3cb6 --- /dev/null +++ b/bitbake/lib/toaster/toastergui/templates/package_built_detail.html | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | {% extends "package_detail_base.html" %} | ||
| 2 | {% load projecttags %} | ||
| 3 | |||
| 4 | {% block tabcontent %} | ||
| 5 | {% with fullPackageSpec=package.name|add:"-"|add:package.version|add:"-"|add:package.revision|filtered_packagespec packageFileCount=package.buildfilelist_package.count %} | ||
| 6 | <!-- Generated Files --> | ||
| 7 | {% if package.buildtargetlist_package.count == 0 %} | ||
| 8 | {# Not included case #} | ||
| 9 | <ul class="nav nav-pills"> | ||
| 10 | <li class="active"> <a href="#"> | ||
| 11 | <i class="icon-question-sign get-help" data-toggle="tooltip" title="Shows the files produced by this package."></i> | ||
| 12 | Generated files ({{packageFileCount}}) | ||
| 13 | </a></li> | ||
| 14 | <li class=""><a href="{% url 'package_built_dependencies' build.id package.id %}"> | ||
| 15 | <i class="icon-question-sign get-help" data-toggle="tooltip" title="Shows the runtime packages required by this package."></i> | ||
| 16 | Runtime dependencies ({{dependency_count}}) | ||
| 17 | </a></li> | ||
| 18 | </ul> | ||
| 19 | <div class="tab-content"> | ||
| 20 | <div class="tab-pane active" id="files"> | ||
| 21 | <!-- Package file list or if empty, alert pane --> | ||
| 22 | {% if packageFileCount > 0 %} | ||
| 23 | <div class="alert alert-info"> | ||
| 24 | {{fullPackageSpec}} is <strong>not included</strong> in any image. These are the files that would be added to an image root file system if you were to include it in future builds. | ||
| 25 | </div> | ||
| 26 | <table class="table table-bordered table-hover"> | ||
| 27 | <thead> | ||
| 28 | <tr> | ||
| 29 | <th>File</th> | ||
| 30 | <th>Size</th> | ||
| 31 | </tr> | ||
| 32 | </thead> | ||
| 33 | {% for file in package.buildfilelist_package.all|dictsort:"path" %} | ||
| 34 | <tbody> | ||
| 35 | <tr> | ||
| 36 | <td>{{file.path}}</td> | ||
| 37 | <td>{{file.size|filtered_filesizeformat}}</td> | ||
| 38 | </tr> | ||
| 39 | </tbody> | ||
| 40 | {% endfor %} | ||
| 41 | </table> | ||
| 42 | |||
| 43 | {% else %} | ||
| 44 | <div class="alert alert-info"> | ||
| 45 | <strong>{{fullPackageSpec}}</strong> does not generate any files. | ||
| 46 | </div> | ||
| 47 | {% endif %} | ||
| 48 | |||
| 49 | </div> <!-- tab-pane active --> | ||
| 50 | </div> <!-- tab-content --> | ||
| 51 | {% else %} | ||
| 52 | {# Included case #} | ||
| 53 | <div class="tab-content"> | ||
| 54 | <div class="tab-pane active"> | ||
| 55 | <div class="lead well"> | ||
| 56 | Package included in: | ||
| 57 | {% for itarget in package.buildtargetlist_package.all|dictsort:"target.target" %} | ||
| 58 | <a href="{% url 'package_included_detail' build.id itarget.target.id package.id %}"> | ||
| 59 | {% if forloop.counter0 > 0 %} | ||
| 60 | , | ||
| 61 | {% endif %} | ||
| 62 | {{itarget.target.target}} | ||
| 63 | </a> | ||
| 64 | {% endfor %} | ||
| 65 | </div> | ||
| 66 | </div> <!-- tab-pane active --> | ||
| 67 | </div> <!-- tab-content --> | ||
| 68 | {% endif %} | ||
| 69 | |||
| 70 | {% endwith %} | ||
| 71 | {% endblock tabcontent %} | ||
diff --git a/bitbake/lib/toaster/toastergui/templates/package_detail_base.html b/bitbake/lib/toaster/toastergui/templates/package_detail_base.html new file mode 100644 index 0000000000..a7aaab6de7 --- /dev/null +++ b/bitbake/lib/toaster/toastergui/templates/package_detail_base.html | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | {% extends "basebuilddetailpage.html" %} | ||
| 2 | {% load projecttags %} | ||
| 3 | |||
| 4 | {% block localbreadcrumb %} | ||
| 5 | {% with fullPackageSpec=package.name|add:"-"|add:package.version|add:"-"|add:package.revision|filtered_packagespec %} | ||
| 6 | {% if target %} | ||
| 7 | <li><a href="{% url "target" build.id target.id %}">{{target.target}}</a></li> | ||
| 8 | {% else %} | ||
| 9 | <li><a href="{% url "packages" build.id %}"> Packages </a></li> | ||
| 10 | {% endif %} | ||
| 11 | <li>{{fullPackageSpec}}</li> | ||
| 12 | {% endwith %} | ||
| 13 | {% endblock localbreadcrumb %} | ||
| 14 | |||
| 15 | {% block pagedetailinfomain %} | ||
| 16 | {% with fullPackageSpec=package.name|add:"-"|add:package.version|add:"-"|add:package.revision|filtered_packagespec %} | ||
| 17 | |||
| 18 | <div class="row span11"> | ||
| 19 | <div class="page-header"> | ||
| 20 | {% block title %} | ||
| 21 | <h1>{{fullPackageSpec}}</h1> | ||
| 22 | {% endblock title %} | ||
| 23 | </div> <!-- page-header --> | ||
| 24 | </div> <!-- row span11 page-header --> | ||
| 25 | |||
| 26 | {% block twocolumns %} | ||
| 27 | <div class="row span7 tabbable"> | ||
| 28 | {% block tabcontent %} | ||
| 29 | {% endblock tabcontent %} | ||
| 30 | </div> <!-- row span7 --> | ||
| 31 | |||
| 32 | <div class="row span4 well"> | ||
| 33 | <h2>Package information</h2> | ||
| 34 | |||
| 35 | <!-- info presented as definition list --> | ||
| 36 | <dl> | ||
| 37 | <dt> | ||
| 38 | Size | ||
| 39 | <i class="icon-question-sign get-help" data-toggle="tooltip" title="The size of the package"></i> | ||
| 40 | </dt> | ||
| 41 | <dd> | ||
| 42 | {% comment %} | ||
| 43 | if recipe is absent, filesize is not 0 | ||
| 44 | {% endcomment %} | ||
| 45 | {% if package.recipe_id > 0 %} | ||
| 46 | {{package.size|filtered_filesizeformat}} | ||
| 47 | {% if target.file_size %} | ||
| 48 | ({{package.size|multiply:100|divide:target.file_size}}% of included package size) | ||
| 49 | {% endif %} | ||
| 50 | |||
| 51 | {% endif %} | ||
| 52 | </dd> | ||
| 53 | |||
| 54 | <dt> | ||
| 55 | License | ||
| 56 | <i class="icon-question-sign get-help" data-toggle="tooltip" title="The license under which this package is distributed"></i> | ||
| 57 | </dt> | ||
| 58 | <dd>{{package.license}}</dd> | ||
| 59 | |||
| 60 | {% comment %} | ||
| 61 | # Removed per review on 1/18/2014 until license data population | ||
| 62 | # problemse are resolved. | ||
| 63 | <dt> | ||
| 64 | License files | ||
| 65 | <i class="icon-question-sign get-help" data-toggle="tooltip" title="Location in disk of the license files that apply to the package"></i> | ||
| 66 | </dt> | ||
| 67 | <dd></dd> | ||
| 68 | {% endcomment %} | ||
| 69 | |||
| 70 | <dt> | ||
| 71 | Recipe | ||
| 72 | <i class="icon-question-sign get-help" data-toggle="tooltip" title="The name of the recipe building this package"></i> | ||
| 73 | </dt> | ||
| 74 | <dd> | ||
| 75 | {% if package.recipe_id > 0 %} | ||
| 76 | <a href="{% url "recipe" build.id package.recipe_id %}"> {{package.recipe.name}} </a> | ||
| 77 | {% else %} | ||
| 78 | {{package.recipe.name}} | ||
| 79 | {% endif %} | ||
| 80 | </dd> | ||
| 81 | |||
| 82 | <dt> | ||
| 83 | Recipe version | ||
| 84 | <i class="icon-question-sign get-help" data-toggle="tooltip" title="The version of the recipe building this package"></i> | ||
| 85 | </dt> | ||
| 86 | <dd>{{package.recipe.version}}</dd> | ||
| 87 | |||
| 88 | <dt> | ||
| 89 | Layer | ||
| 90 | <i class="icon-question-sign get-help" data-toggle="tooltip" title="The name of the layer providing the recipe that builds this package"></i> | ||
| 91 | </dt> | ||
| 92 | <dd> | ||
| 93 | {{package.recipe.layer_version.layer.name}} | ||
| 94 | {% if package.recipe.layer_version.layer.name|format_none_and_zero != "" %} | ||
| 95 | {% comment %} | ||
| 96 | # Removed per team meeting of 1/29/2014 until | ||
| 97 | # decision on index search algorithm | ||
| 98 | <a href="http://layers.openembedded.org" target="_blank"> | ||
| 99 | <i class="icon-share get-info"></i> | ||
| 100 | {% endcomment %} | ||
| 101 | </a> | ||
| 102 | {% endif %} | ||
| 103 | </dd> | ||
| 104 | |||
| 105 | <dt> | ||
| 106 | Layer branch | ||
| 107 | <i class="icon-question-sign get-help" data-toggle="tooltip" title="The Git branch of the layer providing the recipe that builds this package"></i> | ||
| 108 | </dt> | ||
| 109 | <dd>{{package.recipe.layer_version.branch}}</dd> | ||
| 110 | <dt> | ||
| 111 | Layer commit | ||
| 112 | <i class="icon-question-sign get-help" data-toggle="tooltip" title="The Git commit of the layer providing the recipe that builds this package"></i> | ||
| 113 | </dt> | ||
| 114 | |||
| 115 | <dd class="iscommit">{{package.recipe.layer_version.commit}}</dd> | ||
| 116 | <dt> | ||
| 117 | Layer directory | ||
| 118 | <i class="icon-question-sign get-help" data-toggle="tooltip" title="Location in disk of the layer providing the recipe that builds this package"></i> | ||
| 119 | </dt> | ||
| 120 | <dd><code>{{package.recipe.layer_version.layer.local_path}}</code></dd> | ||
| 121 | </dl> | ||
| 122 | </div> <!-- row4 well --> | ||
| 123 | {% endblock twocolumns %} | ||
| 124 | {% endwith %} | ||
| 125 | {% endblock pagedetailinfomain %} | ||
diff --git a/bitbake/lib/toaster/toastergui/templates/package_included_dependencies.html b/bitbake/lib/toaster/toastergui/templates/package_included_dependencies.html new file mode 100644 index 0000000000..c8c2dddf29 --- /dev/null +++ b/bitbake/lib/toaster/toastergui/templates/package_included_dependencies.html | |||
| @@ -0,0 +1,93 @@ | |||
| 1 | {% extends "package_detail_base.html" %} | ||
| 2 | {% load projecttags %} | ||
| 3 | |||
| 4 | {% block title %} | ||
| 5 | {% with fullPackageSpec=package.name|add:"-"|add:package.version|add:"-"|add:package.revision|filtered_packagespec %} | ||
| 6 | <h1>{{fullPackageSpec}} <small>({{target.target}})</small></h1> | ||
| 7 | {% endwith %} | ||
| 8 | {% endblock title %} | ||
| 9 | |||
| 10 | {% block tabcontent %} | ||
| 11 | {% with fullPackageSpec=package.name|add:"-"|add:package.version|add:"-"|add:package.revision|filtered_packagespec packageFileCount=package.buildfilelist_package.count %} | ||
| 12 | {% include "package_included_tabs.html" with active_tab="dependencies" %} | ||
| 13 | <div class="tab-content"> | ||
| 14 | <div class="tab-pane active" id="dependencies"> | ||
| 15 | {% ifnotequal runtime_deps|length 0 %} | ||
| 16 | <table class="table table-bordered table-hover"> | ||
| 17 | <thead> | ||
| 18 | <tr> | ||
| 19 | <th>Package</th> | ||
| 20 | <th>Version</th> | ||
| 21 | <th>Size</th> | ||
| 22 | </tr> | ||
| 23 | </thead> | ||
| 24 | {% for runtime_dep in runtime_deps %} | ||
| 25 | <tbody> | ||
| 26 | <tr> | ||
| 27 | <td> | ||
| 28 | <a href="{% url 'package_included_detail' build.id target.id runtime_dep.depends_on_id %}"> | ||
| 29 | {{runtime_dep.name}} | ||
| 30 | </a> | ||
| 31 | </td> | ||
| 32 | <td>{{runtime_dep.version}}</td> | ||
| 33 | <td>{{runtime_dep.size|filtered_filesizeformat}}</td> | ||
| 34 | </tr> | ||
| 35 | </tbody> | ||
| 36 | {% endfor %} | ||
| 37 | </table> | ||
| 38 | {% else %} | ||
| 39 | <div class="alert alert-info"> | ||
| 40 | <strong>{{fullPackageSpec}}</strong> has no runtime dependencies. | ||
| 41 | </div> | ||
| 42 | {% endifnotequal %} | ||
| 43 | |||
| 44 | {% ifnotequal other_deps|length 0 %} | ||
| 45 | <h3>Other runtime relationships</h3> | ||
| 46 | <table class="table table-bordered table-hover"> | ||
| 47 | <thead> | ||
| 48 | <tr> | ||
| 49 | <th>Package</th> | ||
| 50 | <th>Version</th> | ||
| 51 | <th>Size</th> | ||
| 52 | <th> | ||
| 53 | <i class="icon-question-sign get-help" title="There are 5 relationship types: recommends, suggests, provides, replaces and conflicts"></i> | ||
| 54 | Relationship type | ||
| 55 | </th> | ||
| 56 | </tr> | ||
| 57 | </thead> | ||
| 58 | |||
| 59 | {% for other_dep in other_deps %} | ||
| 60 | <tbody> | ||
| 61 | {% if other_dep.installed %} | ||
| 62 | <tr> | ||
| 63 | <td> | ||
| 64 | <a href="{% url 'package_included_detail' build.id target.id other_dep.depends_on_id %}"> | ||
| 65 | {{other_dep.name}} | ||
| 66 | </a> | ||
| 67 | </td> | ||
| 68 | <td>{{other_dep.version}}</td> | ||
| 69 | <td>{{other_dep.size|filtered_filesizeformat}}</td> | ||
| 70 | <td> | ||
| 71 | {{other_dep.dep_type_display}} | ||
| 72 | <i class="icon-question-sign get-help hover-help" title="{{other_dep.dep_type_help}}" ></i> | ||
| 73 | </td> | ||
| 74 | </tr> | ||
| 75 | {% else %} | ||
| 76 | <tr class="muted"> | ||
| 77 | <td>{{other_dep.name}}</td> | ||
| 78 | <td>{{other_dep.version}}</td> | ||
| 79 | <td></td> | ||
| 80 | <td> | ||
| 81 | {{other_dep.dep_type_display}} | ||
| 82 | <i class="icon-question-sign get-help hover-help" title="{{other_dep.dep_type_help}}" ></i> | ||
| 83 | </td> | ||
| 84 | </tr> | ||
| 85 | {% endif %} | ||
| 86 | </tbody> | ||
| 87 | {% endfor %} | ||
| 88 | </table> | ||
| 89 | {% endifnotequal %} | ||
| 90 | </div> <!-- end tab-pane --> | ||
| 91 | </div> <!-- end tab content --> | ||
| 92 | {% endwith %} | ||
| 93 | {% endblock tabcontent %} | ||
diff --git a/bitbake/lib/toaster/toastergui/templates/package_included_detail.html b/bitbake/lib/toaster/toastergui/templates/package_included_detail.html new file mode 100644 index 0000000000..018de3eb42 --- /dev/null +++ b/bitbake/lib/toaster/toastergui/templates/package_included_detail.html | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | {% extends "package_detail_base.html" %} | ||
| 2 | {% load projecttags %} | ||
| 3 | |||
| 4 | {% block title %} | ||
| 5 | {% with fullPackageSpec=package.name|add:"-"|add:package.version|add:"-"|add:package.revision|filtered_packagespec %} | ||
| 6 | <h1>{{fullPackageSpec}} <small>({{target.target}})</small></h1> | ||
| 7 | {% endwith %} | ||
| 8 | {% endblock title %} | ||
| 9 | |||
| 10 | {% block tabcontent %} | ||
| 11 | {% with fullPackageSpec=package.name|add:"-"|add:package.version|add:"-"|add:package.revision|filtered_packagespec packageFileCount=package.buildfilelist_package.count %} | ||
| 12 | {% include "package_included_tabs.html" with active_tab="detail" %} | ||
| 13 | <div class="tab-content"> | ||
| 14 | <div class="tab-pane active" id="files"> | ||
| 15 | {% if packageFileCount > 0 %} | ||
| 16 | <table class="table table-bordered table-hover"> | ||
| 17 | <thead> | ||
| 18 | <tr> | ||
| 19 | <th>File</th> | ||
| 20 | <th>Size</th> | ||
| 21 | </tr> | ||
| 22 | </thead> | ||
| 23 | {% for file in package.buildfilelist_package.all|dictsort:"path" %} | ||
| 24 | <tbody> | ||
| 25 | <tr> | ||
| 26 | <td> | ||
| 27 | <a href="{% url 'image_information_dir' build.id target.id file.id %}"> | ||
| 28 | {{file.path}} | ||
| 29 | </a> | ||
| 30 | </td> | ||
| 31 | <td>{{file.size|filtered_filesizeformat}}</td> | ||
| 32 | </tr> | ||
| 33 | </tbody> | ||
| 34 | {% endfor %} | ||
| 35 | </table> | ||
| 36 | |||
| 37 | {% else %} | ||
| 38 | <div class="alert alert-info"> | ||
| 39 | <strong>{{fullPackageSpec}}</strong> does not generate any files. | ||
| 40 | </div> | ||
| 41 | {% endif %} | ||
| 42 | </div> <!-- end tab-pane --> | ||
| 43 | </div> <!-- end tab content --> | ||
| 44 | |||
| 45 | {% endwith %} | ||
| 46 | {% endblock tabcontent %} | ||
diff --git a/bitbake/lib/toaster/toastergui/templates/package_included_reverse_dependencies.html b/bitbake/lib/toaster/toastergui/templates/package_included_reverse_dependencies.html new file mode 100644 index 0000000000..9cfc7fe7c2 --- /dev/null +++ b/bitbake/lib/toaster/toastergui/templates/package_included_reverse_dependencies.html | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | {% extends "package_detail_base.html" %} | ||
| 2 | {% load projecttags %} | ||
| 3 | |||
| 4 | {% block title %} | ||
| 5 | {% with fullPackageSpec=package.name|add:"-"|add:package.version|add:"-"|add:package.revision|filtered_packagespec %} | ||
| 6 | <h1>{{fullPackageSpec}} <small>({{target.target}})</small></h1> | ||
| 7 | {% endwith %} | ||
| 8 | {% endblock title %} | ||
| 9 | |||
| 10 | {% block tabcontent %} | ||
| 11 | {% with fullPackageSpec=package.name|add:"-"|add:package.version|add:"-"|add:package.revision|filtered_packagespec packageFileCount=package.buildfilelist_package.count %} | ||
| 12 | {% include "package_included_tabs.html" with active_tab="reverse" %} | ||
| 13 | <div class="tab-content"> | ||
| 14 | <div class="tab-pane active" id="brought-in-by"> | ||
| 15 | |||
| 16 | {% ifequal reverse_deps|length 0 %} | ||
| 17 | <div class="alert alert-info"> | ||
| 18 | <strong>{{fullPackageSpec}}</strong> has no reverse runtime dependencies. | ||
| 19 | </div> | ||
| 20 | {% else %} | ||
| 21 | <table class="table table-bordered table-hover"> | ||
| 22 | <thead> | ||
| 23 | <tr> | ||
| 24 | <th>Package</th> | ||
| 25 | <th>Package Version</th> | ||
| 26 | <th>Size</th> | ||
| 27 | </tr> | ||
| 28 | </thead> | ||
| 29 | {% for reverse_dep in reverse_deps|dictsort:"name" %} | ||
| 30 | <tbody> | ||
| 31 | <tr> | ||
| 32 | <td> | ||
| 33 | <a href="{% url 'package_included_detail' build.id target.id reverse_dep.dependent_id %}"> | ||
| 34 | {{reverse_dep.name}} | ||
| 35 | </a> | ||
| 36 | </td> | ||
| 37 | <td>{{reverse_dep.version}}</td> | ||
| 38 | <td>{{reverse_dep.size|filtered_filesizeformat}}</td> | ||
| 39 | </tr> | ||
| 40 | </tbody> | ||
| 41 | {% endfor %} | ||
| 42 | </table> | ||
| 43 | {% endifequal %} | ||
| 44 | </div> <!-- end tab-pane --> | ||
| 45 | </div> <!-- end tab content --> | ||
| 46 | {% endwith %} | ||
| 47 | {% endblock tabcontent %} | ||
diff --git a/bitbake/lib/toaster/toastergui/templates/package_included_tabs.html b/bitbake/lib/toaster/toastergui/templates/package_included_tabs.html new file mode 100644 index 0000000000..5a97ba36b3 --- /dev/null +++ b/bitbake/lib/toaster/toastergui/templates/package_included_tabs.html | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | |||
| 2 | <ul class="nav nav-pills"> | ||
| 3 | {% if active_tab == "detail" %} | ||
| 4 | <li class="active"> | ||
| 5 | {% else %} | ||
| 6 | <li class=""> | ||
| 7 | {% endif %} | ||
| 8 | <a href="{% url 'package_included_detail' build.id target.id package.id %}"> | ||
| 9 | <i class="icon-question-sign get-help" title="The files this package adds to the image root file system"></i> | ||
| 10 | Files in root file system ({{packageFileCount}}) | ||
| 11 | </a> | ||
| 12 | </li> | ||
| 13 | {% if active_tab == "dependencies" %} | ||
| 14 | <li class="active"> | ||
| 15 | {% else %} | ||
| 16 | <li class=""> | ||
| 17 | {% endif %} | ||
| 18 | <a href="{% url 'package_included_dependencies' build.id target.id package.id %}"> | ||
| 19 | <i class="icon-question-sign get-help" data-toggle="tooltip" title="Package runtime dependencies"></i> | ||
| 20 | Runtime dependencies ({{dependency_count}}) | ||
| 21 | </a> | ||
| 22 | </li> | ||
| 23 | {% if active_tab == "reverse" %} | ||
| 24 | <li class="active"> | ||
| 25 | {% else %} | ||
| 26 | <li class=""> | ||
| 27 | {% endif %} | ||
| 28 | <a href="{% url 'package_included_reverse_dependencies' build.id target.id package.id %}"> | ||
| 29 | <i class="icon-question-sign get-help" data-toggle="tooltip" title="The package runtime reverse dependencies (i.e. which other packages in this image depend on this package). Reverse dependencies reflect only the 'depends' dependency type"></i> | ||
| 30 | Reverse Runtime dependencies ({{reverse_count}}) | ||
| 31 | </a> | ||
| 32 | </li> | ||
| 33 | </ul> | ||
diff --git a/bitbake/lib/toaster/toastergui/templates/recipe.html b/bitbake/lib/toaster/toastergui/templates/recipe.html index 5dea75382f..eba15baad3 100644 --- a/bitbake/lib/toaster/toastergui/templates/recipe.html +++ b/bitbake/lib/toaster/toastergui/templates/recipe.html | |||
| @@ -161,9 +161,9 @@ | |||
| 161 | {% for package in packages %} | 161 | {% for package in packages %} |
| 162 | 162 | ||
| 163 | <tr> | 163 | <tr> |
| 164 | <td><a href="{% url "package" build.pk package.pk %}">{{package.name}}</a></td> | 164 | <td><a href="{% url "package_built_detail" build.pk package.pk %}">{{package.name}}</a></td> |
| 165 | <td><a href="{% url "package" build.pk package.pk %}">{{package.version}}-{{package.revision}}</a></td> | 165 | <td><a href="{% url "package_built_detail" build.pk package.pk %}">{{package.version}}_{{package.revision}}</a></td> |
| 166 | <td><a href="{% url "package" build.pk package.pk %}">{{package.size}}</a></td> | 166 | <td><a href="{% url "package_built_detail" build.pk package.pk %}">{{package.size}}</a></td> |
| 167 | </tr> | 167 | </tr> |
| 168 | 168 | ||
| 169 | {% endfor %} | 169 | {% endfor %} |
diff --git a/bitbake/lib/toaster/toastergui/templatetags/projecttags.py b/bitbake/lib/toaster/toastergui/templatetags/projecttags.py index 5105be48d2..667bc38420 100644 --- a/bitbake/lib/toaster/toastergui/templatetags/projecttags.py +++ b/bitbake/lib/toaster/toastergui/templatetags/projecttags.py | |||
| @@ -20,8 +20,10 @@ | |||
| 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 | import re | ||
| 23 | from django import template | 24 | from django import template |
| 24 | from django.utils import timezone | 25 | from django.utils import timezone |
| 26 | from django.template.defaultfilters import filesizeformat | ||
| 25 | 27 | ||
| 26 | register = template.Library() | 28 | register = template.Library() |
| 27 | 29 | ||
| @@ -101,3 +103,14 @@ def format_none_and_zero(value): | |||
| 101 | """Return empty string if the value is None, zero or Not Applicable | 103 | """Return empty string if the value is None, zero or Not Applicable |
| 102 | """ | 104 | """ |
| 103 | return "" if (not value) or (value == 0) or (value == "0") or (value == 'Not Applicable') else value | 105 | return "" if (not value) or (value == 0) or (value == "0") or (value == 'Not Applicable') else value |
| 106 | |||
| 107 | @register.filter | ||
| 108 | def filtered_filesizeformat(value): | ||
| 109 | """Change output from fileformatsize to suppress trailing '.0' and change 'bytes' to 'B' | ||
| 110 | """ | ||
| 111 | return filesizeformat(value).replace("bytes", "B").replace(".0", "") | ||
| 112 | |||
| 113 | @register.filter | ||
| 114 | def filtered_packagespec(value): | ||
| 115 | """Strip off empty version and revision""" | ||
| 116 | return re.sub(r'(--$)', '', value) | ||
diff --git a/bitbake/lib/toaster/toastergui/urls.py b/bitbake/lib/toaster/toastergui/urls.py index 6e7595b087..8be27b08bc 100644 --- a/bitbake/lib/toaster/toastergui/urls.py +++ b/bitbake/lib/toaster/toastergui/urls.py | |||
| @@ -1,7 +1,4 @@ | |||
| 1 | # | 1 | # |
| 2 | # ex:ts=4:sw=4:sts=4:et | ||
| 3 | # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- | ||
| 4 | # | ||
| 5 | # BitBake Toaster Implementation | 2 | # BitBake Toaster Implementation |
| 6 | # | 3 | # |
| 7 | # Copyright (C) 2013 Intel Corporation | 4 | # Copyright (C) 2013 Intel Corporation |
| @@ -35,7 +32,16 @@ urlpatterns = patterns('toastergui.views', | |||
| 35 | url(r'^build/(?P<build_id>\d+)/recipe/(?P<recipe_id>\d+)$', 'recipe', name='recipe'), | 32 | url(r'^build/(?P<build_id>\d+)/recipe/(?P<recipe_id>\d+)$', 'recipe', name='recipe'), |
| 36 | 33 | ||
| 37 | url(r'^build/(?P<build_id>\d+)/packages/$', 'bpackage', name='packages'), | 34 | url(r'^build/(?P<build_id>\d+)/packages/$', 'bpackage', name='packages'), |
| 38 | url(r'^build/(?P<build_id>\d+)/package/(?P<package_id>\d+)$', 'bfile', name='package'), | 35 | url(r'^build/(?P<build_id>\d+)/package/(?P<package_id>\d+)$', 'package_built_detail', |
| 36 | name='package_built_detail'), | ||
| 37 | url(r'^build/(?P<build_id>\d+)/package_built_dependencies/(?P<package_id>\d+)$', | ||
| 38 | 'package_built_dependencies', name='package_built_dependencies'), | ||
| 39 | url(r'^build/(?P<build_id>\d+)/package_included_detail/(?P<target_id>\d+)/(?P<package_id>\d+)$', | ||
| 40 | 'package_included_detail', name='package_included_detail'), | ||
| 41 | url(r'^build/(?P<build_id>\d+)/package_included_dependencies/(?P<target_id>\d+)/(?P<package_id>\d+)$', | ||
| 42 | 'package_included_dependencies', name='package_included_dependencies'), | ||
| 43 | url(r'^build/(?P<build_id>\d+)/package_included_reverse_dependencies/(?P<target_id>\d+)/(?P<package_id>\d+)$', | ||
| 44 | 'package_included_reverse_dependencies', name='package_included_reverse_dependencies'), | ||
| 39 | 45 | ||
| 40 | # images are known as targets in the internal model | 46 | # images are known as targets in the internal model |
| 41 | url(r'^build/(?P<build_id>\d+)/target/(?P<target_id>\d+)$', 'target', name='target'), | 47 | url(r'^build/(?P<build_id>\d+)/target/(?P<target_id>\d+)$', 'target', name='target'), |
| @@ -47,6 +53,10 @@ urlpatterns = patterns('toastergui.views', | |||
| 47 | url(r'^build/(?P<build_id>\d+)/cpuusage$', 'cpuusage', name='cpuusage'), | 53 | url(r'^build/(?P<build_id>\d+)/cpuusage$', 'cpuusage', name='cpuusage'), |
| 48 | url(r'^build/(?P<build_id>\d+)/diskio$', 'diskio', name='diskio'), | 54 | url(r'^build/(?P<build_id>\d+)/diskio$', 'diskio', name='diskio'), |
| 49 | 55 | ||
| 56 | # image information dir - not yet implemented | ||
| 57 | url(r'^build/(?P<build_id>\d+)/target/(?P<target_id>\d+)/packagefile/(?P<packagefile_id>\d+)$', | ||
| 58 | 'image_information_dir', name='image_information_dir'), | ||
| 59 | |||
| 50 | 60 | ||
| 51 | # urls not linked from the dashboard | 61 | # urls not linked from the dashboard |
| 52 | url(r'^layers/$', 'layer', name='all-layers'), | 62 | url(r'^layers/$', 'layer', name='all-layers'), |
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py index 7b84df3340..37e2af2574 100644 --- a/bitbake/lib/toaster/toastergui/views.py +++ b/bitbake/lib/toaster/toastergui/views.py | |||
| @@ -378,15 +378,6 @@ def recipe(request, build_id, recipe_id): | |||
| 378 | } | 378 | } |
| 379 | return render(request, template, context) | 379 | return render(request, template, context) |
| 380 | 380 | ||
| 381 | def package(request, build_id, package_id): | ||
| 382 | template = "singlepackage.html" | ||
| 383 | if Build.objects.filter(pk=build_id).count() == 0 : | ||
| 384 | return redirect(builds) | ||
| 385 | context = { | ||
| 386 | 'build' : Build.objects.filter(pk=build_id)[0], | ||
| 387 | } | ||
| 388 | return render(request, template, context) | ||
| 389 | |||
| 390 | def target(request, build_id, target_id): | 381 | def target(request, build_id, target_id): |
| 391 | template = "target.html" | 382 | template = "target.html" |
| 392 | if Build.objects.filter(pk=build_id).count() == 0 : | 383 | if Build.objects.filter(pk=build_id).count() == 0 : |
| @@ -705,4 +696,191 @@ def layer_versions_recipes(request, layerversion_id): | |||
| 705 | 696 | ||
| 706 | return render(request, template, context) | 697 | return render(request, template, context) |
| 707 | 698 | ||
| 699 | # A set of dependency types valid for both included and built package views | ||
| 700 | OTHER_DEPENDS_BASE = [ | ||
| 701 | Package_Dependency.TYPE_RSUGGESTS, | ||
| 702 | Package_Dependency.TYPE_RPROVIDES, | ||
| 703 | Package_Dependency.TYPE_RREPLACES, | ||
| 704 | Package_Dependency.TYPE_RCONFLICTS, | ||
| 705 | ] | ||
| 706 | |||
| 707 | # value for invalid row id | ||
| 708 | INVALID_KEY = -1 | ||
| 709 | |||
| 710 | """ | ||
| 711 | Given a package id, target_id retrieves two sets of this image and package's | ||
| 712 | dependencies. The return value is a dictionary consisting of two other | ||
| 713 | lists: a list of 'runtime' dependencies, that is, having RDEPENDS | ||
| 714 | values in source package's recipe, and a list of other dependencies, that is | ||
| 715 | the list of possible recipe variables as found in OTHER_DEPENDS_BASE plus | ||
| 716 | the RRECOMENDS or TRECOMENDS value. | ||
| 717 | The lists are built in the sort order specified for the package runtime | ||
| 718 | dependency views. | ||
| 719 | """ | ||
| 720 | def get_package_dependencies(package_id, target_id = INVALID_KEY): | ||
| 721 | runtime_deps = [] | ||
| 722 | other_deps = [] | ||
| 723 | other_depends_types = OTHER_DEPENDS_BASE | ||
| 724 | |||
| 725 | if target_id != INVALID_KEY : | ||
| 726 | rdepends_type = Package_Dependency.TYPE_TRDEPENDS | ||
| 727 | other_depends_types += [Package_Dependency.TYPE_TRECOMMENDS] | ||
| 728 | else : | ||
| 729 | rdepends_type = Package_Dependency.TYPE_RDEPENDS | ||
| 730 | other_depends_types += [Package_Dependency.TYPE_RRECOMMENDS] | ||
| 731 | |||
| 732 | package = Package.objects.get(pk=package_id) | ||
| 733 | if target_id != INVALID_KEY : | ||
| 734 | alldeps = package.package_dependencies_source.filter(target_id__exact = target_id) | ||
| 735 | else : | ||
| 736 | alldeps = package.package_dependencies_source.all() | ||
| 737 | for idep in alldeps: | ||
| 738 | dep_package = Package.objects.get(pk=idep.depends_on_id) | ||
| 739 | dep_entry = Package_Dependency.DEPENDS_DICT[idep.dep_type] | ||
| 740 | if dep_package.version == '' : | ||
| 741 | version = '' | ||
| 742 | else : | ||
| 743 | version = dep_package.version + "-" + dep_package.revision | ||
| 744 | installed = False | ||
| 745 | if target_id != INVALID_KEY : | ||
| 746 | if Target_Installed_Package.objects.filter(target_id__exact = target_id, package_id__exact = dep_package.id).count() > 0: | ||
| 747 | installed = True | ||
| 748 | dep = { | ||
| 749 | 'name' : dep_package.name, | ||
| 750 | 'version' : version, | ||
| 751 | 'size' : dep_package.size, | ||
| 752 | 'dep_type' : idep.dep_type, | ||
| 753 | 'dep_type_display' : dep_entry[0].capitalize(), | ||
| 754 | 'dep_type_help' : dep_entry[1] % (dep_package.name, package.name), | ||
| 755 | 'depends_on_id' : dep_package.id, | ||
| 756 | 'installed' : installed, | ||
| 757 | } | ||
| 758 | if idep.dep_type == rdepends_type : | ||
| 759 | runtime_deps.append(dep) | ||
| 760 | elif idep.dep_type in other_depends_types : | ||
| 761 | other_deps.append(dep) | ||
| 762 | |||
| 763 | rdep_sorted = sorted(runtime_deps, key=lambda k: k['name']) | ||
| 764 | odep_sorted = sorted( | ||
| 765 | sorted(other_deps, key=lambda k: k['name']), | ||
| 766 | key=lambda k: k['dep_type']) | ||
| 767 | retvalues = {'runtime_deps' : rdep_sorted, 'other_deps' : odep_sorted} | ||
| 768 | return retvalues | ||
| 769 | |||
| 770 | # Return the count of packages dependent on package for this target_id image | ||
| 771 | def get_package_reverse_dep_count(package, target_id): | ||
| 772 | return package.package_dependencies_target.filter(target_id__exact=target_id, dep_type__exact = Package_Dependency.TYPE_TRDEPENDS).count() | ||
| 773 | |||
| 774 | # Return the count of the packages that this package_id is dependent on. | ||
| 775 | # Use one of the two RDEPENDS types, either TRDEPENDS if the package was | ||
| 776 | # installed, or else RDEPENDS if only built. | ||
| 777 | def get_package_dependency_count(package, target_id, is_installed): | ||
| 778 | if is_installed : | ||
| 779 | return package.package_dependencies_source.filter(target_id__exact = target_id, | ||
| 780 | dep_type__exact = Package_Dependency.TYPE_TRDEPENDS).count() | ||
| 781 | else : | ||
| 782 | return package.package_dependencies_source.filter(dep_type__exact = Package_Dependency.TYPE_RDEPENDS).count() | ||
| 783 | |||
| 784 | def package_built_detail(request, build_id, package_id): | ||
| 785 | template = "package_built_detail.html" | ||
| 786 | if Build.objects.filter(pk=build_id).count() == 0 : | ||
| 787 | return redirect(builds) | ||
| 788 | package = Package.objects.filter(pk=package_id)[0] | ||
| 789 | context = { | ||
| 790 | 'build' : Build.objects.filter(pk=build_id)[0], | ||
| 791 | 'package' : package, | ||
| 792 | 'dependency_count' : get_package_dependency_count(package, -1, False), | ||
| 793 | } | ||
| 794 | return render(request, template, context) | ||
| 795 | |||
| 796 | def package_built_dependencies(request, build_id, package_id): | ||
| 797 | template = "package_built_dependencies.html" | ||
| 798 | if Build.objects.filter(pk=build_id).count() == 0 : | ||
| 799 | return redirect(builds) | ||
| 800 | |||
| 801 | package = Package.objects.filter(pk=package_id)[0] | ||
| 802 | dependencies = get_package_dependencies(package_id) | ||
| 803 | context = { | ||
| 804 | 'build' : Build.objects.filter(pk=build_id)[0], | ||
| 805 | 'package' : package, | ||
| 806 | 'runtime_deps' : dependencies['runtime_deps'], | ||
| 807 | 'other_deps' : dependencies['other_deps'], | ||
| 808 | 'dependency_count' : get_package_dependency_count(package, -1, False) | ||
| 809 | } | ||
| 810 | return render(request, template, context) | ||
| 811 | |||
| 812 | |||
| 813 | def package_included_detail(request, build_id, target_id, package_id): | ||
| 814 | template = "package_included_detail.html" | ||
| 815 | if Build.objects.filter(pk=build_id).count() == 0 : | ||
| 816 | return redirect(builds) | ||
| 817 | |||
| 818 | package = Package.objects.filter(pk=package_id)[0] | ||
| 819 | target = Target.objects.filter(pk=target_id)[0] | ||
| 820 | context = { | ||
| 821 | 'build' : Build.objects.filter(pk=build_id)[0], | ||
| 822 | 'target' : target, | ||
| 823 | 'package' : package, | ||
| 824 | 'reverse_count' : get_package_reverse_dep_count(package, target_id), | ||
| 825 | 'dependency_count' : get_package_dependency_count(package, target_id, True) | ||
| 826 | } | ||
| 827 | return render(request, template, context) | ||
| 828 | |||
| 829 | def package_included_dependencies(request, build_id, target_id, package_id): | ||
| 830 | template = "package_included_dependencies.html" | ||
| 831 | if Build.objects.filter(pk=build_id).count() == 0 : | ||
| 832 | return redirect(builds) | ||
| 833 | |||
| 834 | package = Package.objects.filter(pk=package_id)[0] | ||
| 835 | target = Target.objects.filter(pk=target_id)[0] | ||
| 836 | |||
| 837 | dependencies = get_package_dependencies(package_id, target_id) | ||
| 838 | context = { | ||
| 839 | 'build' : Build.objects.filter(pk=build_id)[0], | ||
| 840 | 'package' : package, | ||
| 841 | 'target' : target, | ||
| 842 | 'runtime_deps' : dependencies['runtime_deps'], | ||
| 843 | 'other_deps' : dependencies['other_deps'], | ||
| 844 | 'reverse_count' : get_package_reverse_dep_count(package, target_id), | ||
| 845 | 'dependency_count' : get_package_dependency_count(package, target_id, True) | ||
| 846 | } | ||
| 847 | return render(request, template, context) | ||
| 848 | |||
| 849 | def package_included_reverse_dependencies(request, build_id, target_id, package_id): | ||
| 850 | template = "package_included_reverse_dependencies.html" | ||
| 851 | if Build.objects.filter(pk=build_id).count() == 0 : | ||
| 852 | return redirect(builds) | ||
| 853 | |||
| 854 | package = Package.objects.filter(pk=package_id)[0] | ||
| 855 | target = Target.objects.filter(pk=target_id)[0] | ||
| 856 | |||
| 857 | reverse_deps = [] | ||
| 858 | alldeps = package.package_dependencies_target.filter(target_id__exact=target_id) | ||
| 859 | for idep in alldeps: | ||
| 860 | dep_package = Package.objects.get(pk=idep.package_id) | ||
| 861 | version = dep_package.version | ||
| 862 | if version != '' : | ||
| 863 | version += '-' + dep_package.revision | ||
| 864 | dep = { | ||
| 865 | 'name' : dep_package.name, | ||
| 866 | 'dependent_id' : dep_package.id, | ||
| 867 | 'version' : version, | ||
| 868 | 'size' : dep_package.size | ||
| 869 | } | ||
| 870 | if idep.dep_type == Package_Dependency.TYPE_TRDEPENDS : | ||
| 871 | reverse_deps.append(dep) | ||
| 872 | |||
| 873 | context = { | ||
| 874 | 'build' : Build.objects.filter(pk=build_id)[0], | ||
| 875 | 'package' : package, | ||
| 876 | 'target' : target, | ||
| 877 | 'reverse_deps' : reverse_deps, | ||
| 878 | 'reverse_count' : get_package_reverse_dep_count(package, target_id), | ||
| 879 | 'dependency_count' : get_package_dependency_count(package, target_id, True) | ||
| 880 | } | ||
| 881 | return render(request, template, context) | ||
| 882 | |||
| 883 | def image_information_dir(request, build_id, target_id, packagefile_id): | ||
| 884 | # stubbed for now | ||
| 885 | return redirect(builds) | ||
| 708 | 886 | ||
