diff options
author | Dave Lerner <dave.lerner@windriver.com> | 2014-01-23 11:47:41 -0600 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2014-02-17 15:38:52 +0000 |
commit | 620553df864634e7061c9124ea70a90e5c067cde (patch) | |
tree | d196d7dbea61da09846e9a645f245ab931889516 /bitbake/lib/toaster | |
parent | 47634378ac516496bcc155e001983973f241ee61 (diff) | |
download | poky-620553df864634e7061c9124ea70a90e5c067cde.tar.gz |
bitbake: toaster: Implementation of package detail views
Adds new package detail views. The views are based on
specifications found in attachments to:
https://bugzilla.yoctoproject.org/show_bug.cgi?id=4328
specifically:
design-1.5.1-package-details.pdf, and
design-1.1.1-included-package-details.
This patch includes a redefinition of constant numbers for
task dependency tasks. This is needed in order to achieve
sorting criteria from the design.
This change invalidates currently dependency information for
currently existing builds, as it breaks compatibility.
[YOCTO #4328]
(Bitbake rev: 6855925c06e7e5bb15ae9d0c08d77f3a9a2574bc)
Signed-off-by: Dave Lerner <dave.lerner@windriver.com>
Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/toaster')
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 | ||