summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru DAMIAN <alexandru.damian@intel.com>2014-10-20 16:26:14 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-10-30 13:39:51 +0000
commit24dab21567eae1b993f21e9ba8a5e7d4d31bfa13 (patch)
tree98abce80aeb44f17510ee8ab1bfe11114b7648da
parent298c3d52bab5cf38c37438c54853d6803ca194bd (diff)
downloadpoky-24dab21567eae1b993f21e9ba8a5e7d4d31bfa13.tar.gz
bitbake: toaster: update web vcs fields for layers
We update the layer vcs web fields to record extra URLs for directory and file viewing. Updating the layers view to show this data. (Bitbake rev: 14762e182c8af22fd0fa96f0ba0db1ecd2495fbc) Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--bitbake/lib/toaster/orm/migrations/0015_auto__add_field_layer_vcs_web_url__add_field_layer_vcs_web_tree_base_u.py336
-rw-r--r--bitbake/lib/toaster/orm/models.py53
-rw-r--r--bitbake/lib/toaster/toastergui/templates/layers.html6
3 files changed, 388 insertions, 7 deletions
diff --git a/bitbake/lib/toaster/orm/migrations/0015_auto__add_field_layer_vcs_web_url__add_field_layer_vcs_web_tree_base_u.py b/bitbake/lib/toaster/orm/migrations/0015_auto__add_field_layer_vcs_web_url__add_field_layer_vcs_web_tree_base_u.py
new file mode 100644
index 0000000000..6e664c9fc8
--- /dev/null
+++ b/bitbake/lib/toaster/orm/migrations/0015_auto__add_field_layer_vcs_web_url__add_field_layer_vcs_web_tree_base_u.py
@@ -0,0 +1,336 @@
1# -*- coding: utf-8 -*-
2from south.utils import datetime_utils as datetime
3from south.db import db
4from south.v2 import SchemaMigration
5from django.db import models
6
7
8class Migration(SchemaMigration):
9
10 def forwards(self, orm):
11 # Adding field 'Layer.vcs_web_url'
12 db.add_column(u'orm_layer', 'vcs_web_url',
13 self.gf('django.db.models.fields.URLField')(default=None, max_length=200, null=True),
14 keep_default=False)
15
16 # Adding field 'Layer.vcs_web_tree_base_url'
17 db.add_column(u'orm_layer', 'vcs_web_tree_base_url',
18 self.gf('django.db.models.fields.URLField')(default=None, max_length=200, null=True),
19 keep_default=False)
20
21
22 def backwards(self, orm):
23 # Deleting field 'Layer.vcs_web_url'
24 db.delete_column(u'orm_layer', 'vcs_web_url')
25
26 # Deleting field 'Layer.vcs_web_tree_base_url'
27 db.delete_column(u'orm_layer', 'vcs_web_tree_base_url')
28
29
30 models = {
31 u'orm.bitbakeversion': {
32 'Meta': {'object_name': 'BitbakeVersion'},
33 'branch': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
34 'dirpath': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
35 'giturl': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
36 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
37 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'})
38 },
39 u'orm.branch': {
40 'Meta': {'unique_together': "(('layer_source', 'name'), ('layer_source', 'up_id'))", 'object_name': 'Branch'},
41 'bitbake_branch': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
42 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
43 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'True', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
44 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
45 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
46 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
47 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'})
48 },
49 u'orm.build': {
50 'Meta': {'object_name': 'Build'},
51 'bitbake_version': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
52 'build_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
53 'completed_on': ('django.db.models.fields.DateTimeField', [], {}),
54 'cooker_log_path': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
55 'distro': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
56 'distro_version': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
57 'errors_no': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
58 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
59 'machine': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
60 'outcome': ('django.db.models.fields.IntegerField', [], {'default': '2'}),
61 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']", 'null': 'True'}),
62 'started_on': ('django.db.models.fields.DateTimeField', [], {}),
63 'timespent': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
64 'warnings_no': ('django.db.models.fields.IntegerField', [], {'default': '0'})
65 },
66 u'orm.helptext': {
67 'Meta': {'object_name': 'HelpText'},
68 'area': ('django.db.models.fields.IntegerField', [], {}),
69 'build': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'helptext_build'", 'to': u"orm['orm.Build']"}),
70 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
71 'key': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
72 'text': ('django.db.models.fields.TextField', [], {})
73 },
74 u'orm.layer': {
75 'Meta': {'unique_together': "(('layer_source', 'up_id'), ('layer_source', 'name'))", 'object_name': 'Layer'},
76 'description': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True'}),
77 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
78 'layer_index_url': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
79 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
80 'local_path': ('django.db.models.fields.FilePathField', [], {'default': 'None', 'max_length': '255', 'null': 'True'}),
81 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
82 'summary': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True'}),
83 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
84 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'}),
85 'vcs_url': ('django.db.models.fields.URLField', [], {'default': 'None', 'max_length': '200', 'null': 'True'}),
86 'vcs_web_file_base_url': ('django.db.models.fields.URLField', [], {'default': 'None', 'max_length': '200', 'null': 'True'}),
87 'vcs_web_tree_base_url': ('django.db.models.fields.URLField', [], {'default': 'None', 'max_length': '200', 'null': 'True'}),
88 'vcs_web_url': ('django.db.models.fields.URLField', [], {'default': 'None', 'max_length': '200', 'null': 'True'})
89 },
90 u'orm.layer_version': {
91 'Meta': {'unique_together': "(('layer_source', 'up_id'),)", 'object_name': 'Layer_Version'},
92 'branch': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
93 'build': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'layer_version_build'", 'null': 'True', 'to': u"orm['orm.Build']"}),
94 'commit': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
95 'dirpath': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True'}),
96 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
97 'layer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'layer_version_layer'", 'to': u"orm['orm.Layer']"}),
98 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
99 'priority': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
100 'up_branch': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.Branch']", 'null': 'True'}),
101 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
102 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'})
103 },
104 u'orm.layersource': {
105 'Meta': {'unique_together': "(('sourcetype', 'apiurl'),)", 'object_name': 'LayerSource'},
106 'apiurl': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True'}),
107 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
108 'name': ('django.db.models.fields.CharField', [], {'max_length': '63'}),
109 'sourcetype': ('django.db.models.fields.IntegerField', [], {})
110 },
111 u'orm.layerversiondependency': {
112 'Meta': {'unique_together': "(('layer_source', 'up_id'),)", 'object_name': 'LayerVersionDependency'},
113 'depends_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'dependees'", 'to': u"orm['orm.Layer_Version']"}),
114 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
115 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
116 'layer_version': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'dependencies'", 'to': u"orm['orm.Layer_Version']"}),
117 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'})
118 },
119 u'orm.logmessage': {
120 'Meta': {'object_name': 'LogMessage'},
121 'build': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Build']"}),
122 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
123 'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
124 'lineno': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
125 'message': ('django.db.models.fields.CharField', [], {'max_length': '240'}),
126 'pathname': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'}),
127 'task': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Task']", 'null': 'True', 'blank': 'True'})
128 },
129 u'orm.machine': {
130 'Meta': {'unique_together': "(('layer_source', 'up_id'),)", 'object_name': 'Machine'},
131 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
132 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
133 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
134 'layer_version': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Layer_Version']"}),
135 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
136 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
137 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'})
138 },
139 u'orm.package': {
140 'Meta': {'object_name': 'Package'},
141 'build': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Build']"}),
142 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
143 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
144 'installed_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '100'}),
145 'installed_size': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
146 'license': ('django.db.models.fields.CharField', [], {'max_length': '80', 'blank': 'True'}),
147 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
148 'recipe': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Recipe']", 'null': 'True'}),
149 'revision': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
150 'section': ('django.db.models.fields.CharField', [], {'max_length': '80', 'blank': 'True'}),
151 'size': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
152 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
153 'version': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
154 },
155 u'orm.package_dependency': {
156 'Meta': {'object_name': 'Package_Dependency'},
157 'dep_type': ('django.db.models.fields.IntegerField', [], {}),
158 'depends_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'package_dependencies_target'", 'to': u"orm['orm.Package']"}),
159 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
160 'package': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'package_dependencies_source'", 'to': u"orm['orm.Package']"}),
161 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Target']", 'null': 'True'})
162 },
163 u'orm.package_file': {
164 'Meta': {'object_name': 'Package_File'},
165 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
166 'package': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'buildfilelist_package'", 'to': u"orm['orm.Package']"}),
167 'path': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'}),
168 'size': ('django.db.models.fields.IntegerField', [], {})
169 },
170 u'orm.project': {
171 'Meta': {'object_name': 'Project'},
172 'bitbake_version': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.BitbakeVersion']"}),
173 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
174 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
175 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
176 'release': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Release']"}),
177 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
178 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
179 'user_id': ('django.db.models.fields.IntegerField', [], {'null': 'True'})
180 },
181 u'orm.projectlayer': {
182 'Meta': {'object_name': 'ProjectLayer'},
183 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
184 'layercommit': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Layer_Version']", 'null': 'True'}),
185 'optional': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
186 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']"})
187 },
188 u'orm.projecttarget': {
189 'Meta': {'object_name': 'ProjectTarget'},
190 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
191 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']"}),
192 'target': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
193 'task': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'})
194 },
195 u'orm.projectvariable': {
196 'Meta': {'object_name': 'ProjectVariable'},
197 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
198 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
199 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']"}),
200 'value': ('django.db.models.fields.TextField', [], {'blank': 'True'})
201 },
202 u'orm.recipe': {
203 'Meta': {'object_name': 'Recipe'},
204 'bugtracker': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
205 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
206 'file_path': ('django.db.models.fields.FilePathField', [], {'max_length': '255'}),
207 'homepage': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
208 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
209 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
210 'layer_version': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'recipe_layer_version'", 'to': u"orm['orm.Layer_Version']"}),
211 'license': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
212 'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
213 'section': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
214 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
215 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
216 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'}),
217 'version': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
218 },
219 u'orm.recipe_dependency': {
220 'Meta': {'object_name': 'Recipe_Dependency'},
221 'dep_type': ('django.db.models.fields.IntegerField', [], {}),
222 'depends_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'r_dependencies_depends'", 'to': u"orm['orm.Recipe']"}),
223 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
224 'recipe': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'r_dependencies_recipe'", 'to': u"orm['orm.Recipe']"})
225 },
226 u'orm.release': {
227 'Meta': {'object_name': 'Release'},
228 'bitbake_version': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.BitbakeVersion']"}),
229 'branch': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
230 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
231 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
232 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'})
233 },
234 u'orm.releasedefaultlayer': {
235 'Meta': {'object_name': 'ReleaseDefaultLayer'},
236 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
237 'layer': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Layer']"}),
238 'release': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Release']"})
239 },
240 u'orm.target': {
241 'Meta': {'object_name': 'Target'},
242 'build': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Build']"}),
243 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
244 'image_size': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
245 'is_image': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
246 'license_manifest_path': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True'}),
247 'target': ('django.db.models.fields.CharField', [], {'max_length': '100'})
248 },
249 u'orm.target_file': {
250 'Meta': {'object_name': 'Target_File'},
251 'directory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'directory_set'", 'null': 'True', 'to': u"orm['orm.Target_File']"}),
252 'group': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
253 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
254 'inodetype': ('django.db.models.fields.IntegerField', [], {}),
255 'owner': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
256 'path': ('django.db.models.fields.FilePathField', [], {'max_length': '100'}),
257 'permission': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
258 'size': ('django.db.models.fields.IntegerField', [], {}),
259 'sym_target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'symlink_set'", 'null': 'True', 'to': u"orm['orm.Target_File']"}),
260 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Target']"})
261 },
262 u'orm.target_image_file': {
263 'Meta': {'object_name': 'Target_Image_File'},
264 'file_name': ('django.db.models.fields.FilePathField', [], {'max_length': '254'}),
265 'file_size': ('django.db.models.fields.IntegerField', [], {}),
266 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
267 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Target']"})
268 },
269 u'orm.target_installed_package': {
270 'Meta': {'object_name': 'Target_Installed_Package'},
271 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
272 'package': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'buildtargetlist_package'", 'to': u"orm['orm.Package']"}),
273 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Target']"})
274 },
275 u'orm.task': {
276 'Meta': {'ordering': "('order', 'recipe')", 'unique_together': "(('build', 'recipe', 'task_name'),)", 'object_name': 'Task'},
277 'build': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_build'", 'to': u"orm['orm.Build']"}),
278 'cpu_usage': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '6', 'decimal_places': '2'}),
279 'disk_io': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
280 'elapsed_time': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '6', 'decimal_places': '2'}),
281 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
282 'line_number': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
283 'logfile': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'}),
284 'message': ('django.db.models.fields.CharField', [], {'max_length': '240'}),
285 'order': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
286 'outcome': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
287 'path_to_sstate_obj': ('django.db.models.fields.FilePathField', [], {'max_length': '500', 'blank': 'True'}),
288 'recipe': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'build_recipe'", 'to': u"orm['orm.Recipe']"}),
289 'script_type': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
290 'source_url': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'}),
291 'sstate_checksum': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
292 'sstate_result': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
293 'task_executed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
294 'task_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
295 'work_directory': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'})
296 },
297 u'orm.task_dependency': {
298 'Meta': {'object_name': 'Task_Dependency'},
299 'depends_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_dependencies_depends'", 'to': u"orm['orm.Task']"}),
300 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
301 'task': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_dependencies_task'", 'to': u"orm['orm.Task']"})
302 },
303 u'orm.toastersetting': {
304 'Meta': {'object_name': 'ToasterSetting'},
305 'helptext': ('django.db.models.fields.TextField', [], {}),
306 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
307 'name': ('django.db.models.fields.CharField', [], {'max_length': '63'}),
308 'value': ('django.db.models.fields.CharField', [], {'max_length': '255'})
309 },
310 u'orm.toastersettingdefaultlayer': {
311 'Meta': {'object_name': 'ToasterSettingDefaultLayer'},
312 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
313 'layer_version': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Layer_Version']"})
314 },
315 u'orm.variable': {
316 'Meta': {'object_name': 'Variable'},
317 'build': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'variable_build'", 'to': u"orm['orm.Build']"}),
318 'changed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
319 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
320 'human_readable_name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
321 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
322 'variable_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
323 'variable_value': ('django.db.models.fields.TextField', [], {'blank': 'True'})
324 },
325 u'orm.variablehistory': {
326 'Meta': {'object_name': 'VariableHistory'},
327 'file_name': ('django.db.models.fields.FilePathField', [], {'max_length': '255'}),
328 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
329 'line_number': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
330 'operation': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
331 'value': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
332 'variable': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'vhistory'", 'to': u"orm['orm.Variable']"})
333 }
334 }
335
336 complete_apps = ['orm'] \ No newline at end of file
diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py
index 2fd504cb5b..503b43c5db 100644
--- a/bitbake/lib/toaster/orm/models.py
+++ b/bitbake/lib/toaster/orm/models.py
@@ -609,6 +609,8 @@ class LayerIndexLayerSource(LayerSource):
609 l.up_date = li['updated'] 609 l.up_date = li['updated']
610 l.name = li['name'] 610 l.name = li['name']
611 l.vcs_url = li['vcs_url'] 611 l.vcs_url = li['vcs_url']
612 l.vcs_web_url = li['vcs_web_url']
613 l.vcs_web_tree_base_url = li['vcs_web_tree_base_url']
612 l.vcs_web_file_base_url = li['vcs_web_file_base_url'] 614 l.vcs_web_file_base_url = li['vcs_web_file_base_url']
613 l.summary = li['summary'] 615 l.summary = li['summary']
614 l.description = li['description'] 616 l.description = li['description']
@@ -738,6 +740,8 @@ class Layer(models.Model):
738 local_path = models.FilePathField(max_length=255, null = True, default = None) 740 local_path = models.FilePathField(max_length=255, null = True, default = None)
739 layer_index_url = models.URLField() 741 layer_index_url = models.URLField()
740 vcs_url = GitURLField(default = None, null = True) 742 vcs_url = GitURLField(default = None, null = True)
743 vcs_web_url = models.URLField(null = True, default = None)
744 vcs_web_tree_base_url = models.URLField(null = True, default = None)
741 vcs_web_file_base_url = models.URLField(null = True, default = None) 745 vcs_web_file_base_url = models.URLField(null = True, default = None)
742 746
743 summary = models.TextField(help_text='One-line description of the layer', null = True, default = None) 747 summary = models.TextField(help_text='One-line description of the layer', null = True, default = None)
@@ -766,13 +770,54 @@ class Layer_Version(models.Model):
766 dirpath = models.CharField(max_length=255, null = True, default = None) # LayerBranch.vcs_subdir 770 dirpath = models.CharField(max_length=255, null = True, default = None) # LayerBranch.vcs_subdir
767 priority = models.IntegerField(default = 0) # if -1, this is a default layer 771 priority = models.IntegerField(default = 0) # if -1, this is a default layer
768 772
769 def get_vcs_link_url(self, file_path="/"): 773 # code lifted, with adaptations, from the layerindex-web application https://git.yoctoproject.org/cgit/cgit.cgi/layerindex-web/
774 def _handle_url_path(self, base_url, path):
775 import re
776 if base_url:
777 if self.dirpath:
778 if path:
779 extra_path = self.dirpath + '/' + path
780 # Normalise out ../ in path for usage URL
781 extra_path = posixpath.normpath(extra_path)
782 # Minor workaround to handle case where subdirectory has been added between branches
783 # (should probably support usage URL per branch to handle this... sigh...)
784 if extra_path.startswith('../'):
785 extra_path = extra_path[3:]
786 else:
787 extra_path = self.dirpath
788 else:
789 extra_path = path
790 branchname = self.up_branch.name
791 url = base_url.replace('%branch%', branchname)
792
793 # If there's a % in the path (e.g. a wildcard bbappend) we need to encode it
794 if extra_path:
795 extra_path = extra_path.replace('%', '%25')
796
797 if '%path%' in base_url:
798 if extra_path:
799 url = re.sub(r'\[([^\]]*%path%[^\]]*)\]', '\\1', url)
800 else:
801 url = re.sub(r'\[([^\]]*%path%[^\]]*)\]', '', url)
802 return url.replace('%path%', extra_path)
803 else:
804 return url + extra_path
805 return None
806
807 def get_vcs_link_url(self):
808 if self.layer.vcs_web_url is None:
809 return None
810 return self.layer.vcs_web_url
811
812 def get_vcs_file_link_url(self, file_path=""):
770 if self.layer.vcs_web_file_base_url is None: 813 if self.layer.vcs_web_file_base_url is None:
771 return None 814 return None
772 return self.layer.vcs_web_file_base_url.replace('%path%', file_path).replace('%branch%', self.up_branch.name) 815 return self._handle_url_path(self.layer.vcs_web_file_base_url, file_path)
773 816
774 def get_vcs_link_url_dirpath(self): 817 def get_vcs_dirpath_link_url(self):
775 return self.get_vcs_link_url(self.dirpath) 818 if self.layer.vcs_web_tree_base_url is None:
819 return None
820 return self._handle_url_path(self.layer.vcs_web_tree_base_url, '')
776 821
777 822
778 def __unicode__(self): 823 def __unicode__(self):
diff --git a/bitbake/lib/toaster/toastergui/templates/layers.html b/bitbake/lib/toaster/toastergui/templates/layers.html
index 52eed86657..51f4dd96e7 100644
--- a/bitbake/lib/toaster/toastergui/templates/layers.html
+++ b/bitbake/lib/toaster/toastergui/templates/layers.html
@@ -40,9 +40,9 @@
40 {% endif %} 40 {% endif %}
41 </td> 41 </td>
42 <td class="git-subdir" style="display: table-cell;"><a href="{% url 'layerdetails' lv.pk %}"><code>{{lv.dirpath}}</code></a> 42 <td class="git-subdir" style="display: table-cell;"><a href="{% url 'layerdetails' lv.pk %}"><code>{{lv.dirpath}}</code></a>
43 {% if lv.get_vcs_link_url %} 43 {% if lv.dirpath and lv.get_vcs_dirpath_link_url %}
44 <a target="_blank" href="{{ lv.get_vcs_link_url_dirpath }}"><i class="icon-share get-info"></i></a> 44 <a target="_blank" href="{{ lv.get_vcs_dirpath_link_url }}"><i class="icon-share get-info"></i></a>
45 {% endif %} 45 {% endif %}
46 </td> 46 </td>
47 <td class="branch">{% if lv.branch %}{{lv.branch}}{% else %}{{lv.up_branch.name}}{% endif %}</td> 47 <td class="branch">{% if lv.branch %}{{lv.branch}}{% else %}{{lv.up_branch.name}}{% endif %}</td>
48 <td class="dependencies"> 48 <td class="dependencies">