Also show compile boxes if we inherit 'src' from a group.
[0publish-gui.git] / implementation.py
blob1503c2177a018d369a102a2b95a0ae77bbd601fe
1 from xml.dom import Node, minidom
3 import rox, os, pango, sys, textwrap, traceback, subprocess, time, urlparse
4 from rox import g, tasks, loading
5 import gtk.glade
7 import main
8 from xmltools import *
10 from zeroinstall.injector import model
11 from zeroinstall.zerostore import unpack, NotStored
13 RESPONSE_SAVE_AND_TEST = 1
15 class ImplementationProperties:
16 def __init__(self, feed_editor, element = None, is_group = False):
17 self.feed_editor = feed_editor
18 self.element = element
20 widgets = gtk.glade.XML(main.gladefile, 'version')
22 #attributes = g.ListStore(str, str)
23 #attr_view = widgets.get_widget('attributes')
24 #attr_view.set_model(attributes)
26 #attr_view.append_column(g.TreeViewColumn('Name'))
27 #attr_view.append_column(g.TreeViewColumn('Value'))
29 inherit_arch = widgets.get_widget('inherit_arch')
30 def shade_os_cpu():
31 s = not inherit_arch.get_active()
32 widgets.get_widget('cpu').set_sensitive(s)
33 widgets.get_widget('os').set_sensitive(s)
34 if s:
35 cpu = widgets.get_widget('cpu').get_active_text()
36 else:
37 cpu = None
38 if element:
39 parent = element.parentNode
40 while parent.nodeType == Node.ELEMENT_NODE and not cpu:
41 arch = parent.getAttribute('arch')
42 if arch and '-' in arch:
43 cpu = arch.split('-')[1]
44 parent = parent.parentNode
46 if cpu == 'src':
47 widgets.get_widget('source_frame').show()
48 else:
49 widgets.get_widget('source_frame').hide()
50 command = widgets.get_widget('compile_command')
51 if command.get_text() == '':
52 command.set_text('"$SRCDIR/configure" --prefix="$DISTDIR" && make install')
53 inherit_arch.connect('toggled', lambda cb: shade_os_cpu())
54 widgets.get_widget('cpu').connect('changed', lambda cb: shade_os_cpu())
56 main_menu = widgets.get_widget('main_binary')
57 doc_menu = widgets.get_widget('doc_dir')
59 if element:
60 if element.localName == 'group':
61 is_group = True
62 id = None
63 else:
64 id = element.getAttribute('id')
66 version = element.getAttribute('version') + \
67 (element.getAttribute('version-modifier') or '')
68 widgets.get_widget('version_number').set_text(version)
69 widgets.get_widget('released').set_text(element.getAttribute('released'))
71 widgets.get_widget('compile_command').set_text(element.getAttributeNS(XMLNS_COMPILE, 'command'))
72 widgets.get_widget('compile_binary_main').set_text(element.getAttributeNS(XMLNS_COMPILE, 'binary-main'))
74 main_binary = element.getAttribute('main')
75 doc_dir = element.getAttribute('doc-dir')
77 stability_menu = widgets.get_widget('stability')
78 stability = element.getAttribute('stability')
79 if stability:
80 i = 0
81 for row in stability_menu.get_model():
82 if row[0].lower() == stability:
83 stability_menu.set_active(i)
84 break
85 i += 1
86 else:
87 stability_menu.set_active(0)
89 main.combo_set_text(widgets.get_widget('license'), element.getAttribute('license'))
90 arch = element.getAttribute('arch')
91 if arch:
92 arch_os, arch_cpu = arch.split('-')
93 main.combo_set_text(widgets.get_widget('os'), arch_os)
94 main.combo_set_text(widgets.get_widget('cpu'), arch_cpu)
95 inherit_arch.set_active(False)
96 else:
97 widgets.get_widget('os').set_active(0)
98 widgets.get_widget('cpu').set_active(0)
100 def ok():
101 self.update_impl(element, widgets)
102 else:
103 released = widgets.get_widget('released')
105 id = '.'
106 if is_group:
107 widgets.get_widget('version_number').set_text('')
108 released.set_text('')
109 else:
110 widgets.get_widget('version_number').set_text('1.0')
111 released.set_text(time.strftime('%Y-%m-%d'))
113 widgets.get_widget('cpu').set_active(0)
114 widgets.get_widget('os').set_active(0)
115 widgets.get_widget('stability').set_active(0)
116 main_binary = None
117 doc_dir = None
119 def ok():
120 if is_group:
121 element_name = 'group'
122 else:
123 element_name = 'implementation'
124 element = create_element(self.feed_editor.doc.documentElement, element_name)
125 if not is_group:
126 element.setAttribute('id', '.')
127 try:
128 self.update_impl(element, widgets)
129 except:
130 remove_element(element)
131 raise
133 shade_os_cpu()
135 self.is_group = is_group
137 id_label = widgets.get_widget('id_label')
139 if is_group:
140 id_label.set_text('(group)')
141 elif id:
142 id_label.set_text(id)
143 if id.startswith('.') or id.startswith('/'):
144 id_label.set_sensitive(True)
145 else:
146 id_label.set_text('-')
148 def resp(dialog, r):
149 if r in (g.RESPONSE_OK, RESPONSE_SAVE_AND_TEST):
150 ok()
151 self.feed_editor.update_version_model()
152 if r == RESPONSE_SAVE_AND_TEST:
153 is_src = bool(widgets.get_widget('source_frame').flags() & gtk.VISIBLE)
154 self.feed_editor.save(lambda: self.test(element, is_src))
155 else:
156 dialog.destroy()
158 if is_group and element:
159 # Find a cached implementation for getting main
160 for x in child_elements(element):
161 if x.localName == 'implementation' and x.namespaceURI == XMLNS_INTERFACE:
162 id = x.getAttribute('id')
163 try:
164 if id and (id.startswith('.') or id.startswith('/') or main.stores.lookup(id)):
165 break
166 except NotStored, ex:
167 pass
168 if id and (element or id != '.'):
169 # Find possible main settings, if possible
170 if id.startswith('/') or id.startswith('.'):
171 cached_impl = os.path.abspath(os.path.join(os.path.dirname(feed_editor.pathname), id))
172 else:
173 try:
174 cached_impl = main.stores.lookup(id)
175 except NotStored, ex:
176 cached_impl = None
177 if cached_impl:
178 for (dirpath, dirnames, filenames) in os.walk(cached_impl):
179 relbasedir = dirpath[len(cached_impl) + 1:]
180 for file in filenames:
181 info = os.lstat(os.path.join(dirpath, file))
182 if info.st_mode & 0111:
183 new = os.path.join(relbasedir, file)
184 main_menu.append_text(new)
185 for d in dirnames[:]:
186 if d.startswith('.'):
187 dirnames.remove(d)
188 else:
189 doc_menu.append_text(os.path.join(relbasedir, d))
190 main.combo_set_text(main_menu, main_binary)
191 main.combo_set_text(doc_menu, doc_dir)
193 dialog = widgets.get_widget('version')
194 dialog.connect('response', resp)
196 def update_impl(self, element, widgets):
197 version = widgets.get_widget('version_number').get_text()
198 released = widgets.get_widget('released').get_text()
199 inherit_arch = widgets.get_widget('inherit_arch')
201 def get_combo(name):
202 widget = widgets.get_widget(name)
203 return widget.get_active_text()
205 cpu = get_combo('cpu')
206 os = get_combo('os')
207 license = get_combo('license')
209 widget = widgets.get_widget('stability')
210 if widget.get_active() == 0:
211 stability = None
212 else:
213 stability = get_combo('stability').lower()
215 if inherit_arch.get_active():
216 arch = None
217 else:
218 arch = os + '-' + cpu
220 main = widgets.get_widget('main_binary').get_active_text()
221 docs = widgets.get_widget('doc_dir').get_active_text()
223 old_id = element.getAttribute('id')
224 if old_id.startswith('/') or old_id.startswith('.'):
225 # Local paths are editable
226 new_id = widgets.get_widget('id_label').get_text()
227 if new_id.startswith('.') or new_id.startswith('/'):
228 element.setAttribute('id', new_id)
229 else:
230 raise Exception('Local IDs must start with "." or "/"')
232 version_modifier = None
233 if version:
234 model.parse_version(version)
235 if '-' in version:
236 version, version_modifier = version.split('-', 1)
237 version_modifier = '-' + version_modifier
239 for name, value in [('version', version),
240 ('version-modifier', version_modifier),
241 ('arch', arch),
242 ('main', main),
243 ('doc-dir', docs),
244 ('released', released),
245 ('license', license),
246 ('stability', stability)]:
247 if value:
248 element.setAttribute(name, value)
249 elif element.hasAttribute(name):
250 element.removeAttribute(name)
252 # Source packages
253 if widgets.get_widget('source_frame').flags() & gtk.VISIBLE:
254 compile_command = widgets.get_widget('compile_command').get_text()
255 compile_binary_main = widgets.get_widget('compile_binary_main').get_text()
256 self.feed_editor.doc.documentElement.setAttribute('xmlns:compile', XMLNS_COMPILE)
257 else:
258 compile_command = compile_binary_main = None
260 for name, value in [('command', compile_command),
261 ('binary-main', compile_binary_main)]:
262 if value:
263 element.setAttributeNS(XMLNS_COMPILE, 'compile:' + name, value)
264 elif element.hasAttributeNS(XMLNS_COMPILE, name):
265 element.removeAttributeNS(XMLNS_COMPILE, name)
267 def test(self, element, compile):
268 version = None
269 while element:
270 if element.hasAttribute('version'):
271 version = element.getAttribute('version')
272 break
273 element = element.parentNode
274 if element.namespaceURI != XMLNS_INTERFACE:
275 break
276 if element.localName != 'group':
277 break
279 if compile:
280 # TODO: 0compile doesn't allow setting the version
281 self.feed_editor.test_compile([])
282 else:
283 if version:
284 args = ['--not-before', version, '--before', version + '-0-pre9999']
285 else:
286 args = []
287 self.feed_editor.test(args)