Merge lp:~mvo/gdebi/add-linitan into lp:gdebi

Proposed by Michael Vogt
Status: Merged
Merged at revision: 442
Proposed branch: lp:~mvo/gdebi/add-linitan
Merge into: lp:gdebi
Diff against target: 921 lines (+242/-107) (has conflicts)
4 files modified
GDebi/GDebi.py (+109/-45)
GDebi/GDebiCommon.py (+9/-8)
data/gdebi.ui (+61/-54)
tests/test_gdebi_gtk_lintian.py (+63/-0)
Text conflict in GDebi/GDebi.py
To merge this branch: bzr merge lp:~mvo/gdebi/add-linitan
Reviewer Review Type Date Requested Status
gdebi-developers Pending
Review via email: mp+128427@code.launchpad.net

Description of the change

This branch adds a "lintian" tab to the main notebook that show the
lintian status of the deb in question

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'GDebi/GDebi.py'
2--- GDebi/GDebi.py 2012-10-05 10:32:37 +0000
3+++ GDebi/GDebi.py 2012-10-08 06:56:32 +0000
4@@ -52,7 +52,7 @@
5 from gettext import gettext as _
6
7 # the timeout when the termial is expanded if no activity from dpkg
8-# is happening
9+# is happening
10 GDEBI_TERMINAL_TIMEOUT=4*60.0
11
12 # HACK - there are two ubuntu specific patches, one for VTE, one
13@@ -67,7 +67,7 @@
14 class GDebi(SimpleGtkbuilderApp, GDebiCommon):
15
16 def __init__(self, datadir, options, file=""):
17- GDebiCommon.__init__(self,datadir,options,file)
18+ GDebiCommon.__init__(self,datadir, options, file)
19 localesApp="gdebi"
20 localesDir="/usr/share/locale"
21
22@@ -79,13 +79,13 @@
23 logo=icons.load_icon("gnome-mime-application-x-deb", 48, 0)
24 if logo != "":
25 Gtk.Window.set_default_icon_list([logo])
26- except Exception, e:
27+ except Exception as e:
28 print "Error loading logo"
29 pass
30
31 # create terminal
32 self.vte_terminal = Vte.Terminal()
33- # FIXME: this sucks but without it the terminal window is only
34+ # FIXME: this sucks but without it the terminal window is only
35 # 1 line height
36 self.vte_terminal.set_size_request(80*10, 25*10)
37 menu = Gtk.Menu()
38@@ -124,7 +124,7 @@
39 self.show_alert(Gtk.MessageType.ERROR, self.error_header, self.error_body)
40 sys.exit(1)
41 self.statusbar_main.push(self.context, "")
42-
43+
44 # setup the details treeview
45 self.details_list = Gtk.ListStore(GObject.TYPE_STRING)
46 column = Gtk.TreeViewColumn("")
47@@ -145,6 +145,7 @@
48 self.synaptic_config = apt_pkg.Configuration()
49
50 if file != "" and os.path.exists(file):
51+<<<<<<< TREE
52 self.open(file)
53 self.window_main.set_sensitive(True)
54
55@@ -158,6 +159,15 @@
56 Gtk.main_iteration()
57 else:
58 win.set_cursor(None)
59+=======
60+ self.window_main.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH))
61+ while Gtk.events_pending():
62+ Gtk.main_iteration()
63+ self.open(file)
64+ self.window_main.get_window().set_cursor(None)
65+
66+ self.window_main.set_sensitive(True)
67+>>>>>>> MERGE-SOURCE
68
69 def gio_progress_callback(self, bytes_read, bytes_total, data):
70 self.progressbar_download.set_fraction(bytes_read/float(bytes_total))
71@@ -173,7 +183,7 @@
72 if (gio_file.get_uri_scheme() == "file"):
73 return file
74 if (os.getuid()==0):
75- self.show_alert(Gtk.MessageType.ERROR,
76+ self.show_alert(Gtk.MessageType.ERROR,
77 _("Can not download as root"),
78 _("Remote packages can not be downloaded when "
79 "running as root. Please try again as a "
80@@ -194,7 +204,7 @@
81 file = gio_dest.get_path()
82 self.dialog_gio_download.hide()
83 except Exception, e:
84- self.show_alert(Gtk.MessageType.ERROR,
85+ self.show_alert(Gtk.MessageType.ERROR,
86 _("Download failed"),
87 _("Downloading the package failed: "
88 "file '%s' '%s'") % (file, e))
89@@ -213,7 +223,7 @@
90 elif path.startswith('file:'): # xffm
91 path = path[5:] # 5 is len('file:')
92 return path
93-
94+
95 def on_menuitem_quit_activate(self, widget):
96 try:
97 Gtk.main_quit()
98@@ -230,20 +240,31 @@
99 path = self._get_file_path_from_dnd_dropped_uri(uri)
100 #print 'path to open', path
101 if path.endswith(".deb"):
102+<<<<<<< TREE
103+=======
104+ self.window_main.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH))
105+ while Gtk.events_pending():
106+ Gtk.main_iteration()
107+>>>>>>> MERGE-SOURCE
108 self.open(path)
109
110+<<<<<<< TREE
111 def open(self, file, downloaded=False):
112 self._show_busy_cursor(True)
113 res = GDebiCommon.open(self, file, downloaded)
114 self._show_busy_cursor(False)
115+=======
116+ def open(self, filename, downloaded=False):
117+ res = GDebiCommon.open(self, filename, downloaded)
118+>>>>>>> MERGE-SOURCE
119 if res == False:
120 self.show_alert(Gtk.MessageType.ERROR, self.error_header, self.error_body)
121 return False
122-
123+
124 self.statusbar_main.push(self.context, "")
125
126 # set window title
127- self.window_main.set_title(_("Package Installer - %s") %
128+ self.window_main.set_title(_("Package Installer - %s") %
129 self._deb.pkgname)
130
131 # set name and ungrey some widgets
132@@ -315,6 +336,11 @@
133 # and the file content textview
134 font_desc = Pango.FontDescription('monospace')
135 self.textview_file_content.modify_font(font_desc)
136+ self.textview_lintian_output.modify_font(font_desc)
137+
138+ # run lintian async
139+ if self._options and self._options.non_interactive is False:
140+ self._run_lintian(filename)
141
142 # check the deps
143 if not self._deb.check():
144@@ -322,7 +348,7 @@
145 "<span foreground=\"red\" weight=\"bold\">"+
146 _("Error: ") +
147 #glib.markup_escape_text(self._deb._failure_string) +
148- self._deb._failure_string +
149+ self._deb._failure_string +
150 "</span>")
151 self.button_install.set_label(_("_Install Package"))
152
153@@ -376,7 +402,7 @@
154 self.button_details.hide()
155 else:
156 self.button_details.show()
157-
158+
159 self.label_status.set_markup(self.deps)
160 #img = Gtk.Image()
161 #img.set_from_stock(Gtk.STOCK_APPLY,Gtk.IconSize.BUTTON)
162@@ -386,6 +412,44 @@
163 self.button_install.grab_default()
164 self.button_remove.hide()
165
166+ def _run_lintian(self, filename):
167+ buf = self.textview_lintian_output.get_buffer()
168+ if not os.path.exists("/usr/bin/lintian"):
169+ buf.set_text(
170+ _("No lintian available.\n"
171+ "Please install using sudo apt-get install lintian"))
172+ return
173+ buf.set_text(_("Running lintian..."))
174+ self._lintian_output = ""
175+ self._lintian_exit_status = None
176+ cmd = ["/usr/bin/lintian", filename]
177+ (pid, stdin, stdout, stderr) = GLib.spawn_async(
178+ cmd, flags=GObject.SPAWN_DO_NOT_REAP_CHILD,
179+ standard_output=True, standard_error=True)
180+ for fd in [stdout, stderr]:
181+ channel = GLib.IOChannel(filedes=fd)
182+ channel.set_flags(GLib.IOFlags.NONBLOCK)
183+ channel.add_watch(GLib.IOCondition.IN, self._on_lintian_output)
184+ GObject.child_watch_add(
185+ pid, self._on_lintian_finished)
186+
187+ def _on_lintian_finished(self, pid, condition):
188+ exit_status = os.WEXITSTATUS(condition)
189+ self._lintian_exit_status = exit_status
190+ text = _("\nLintian finished with exit status %s") % exit_status
191+ self._lintian_output += text
192+ buf = self.textview_lintian_output.get_buffer()
193+ buf.set_text(self._lintian_output)
194+
195+ def _on_lintian_output(self, gio_file, condition):
196+ if condition & GLib.IOCondition.IN:
197+ content = gio_file.read()
198+ if content:
199+ self._lintian_output += content
200+ buf = self.textview_lintian_output.get_buffer()
201+ buf.set_text(self._lintian_output)
202+ return True
203+
204 def on_treeview_files_cursor_changed(self, treeview):
205 " the selection in the files list chanaged "
206 model = treeview.get_model()
207@@ -437,9 +501,9 @@
208 # build dialog
209 self.window_main.set_sensitive(False)
210 fs = Gtk.FileChooserDialog(parent=self.window_main,
211- buttons=(Gtk.STOCK_CANCEL,
212- Gtk.ResponseType.CANCEL,
213- Gtk.STOCK_OPEN,
214+ buttons=(Gtk.STOCK_CANCEL,
215+ Gtk.ResponseType.CANCEL,
216+ Gtk.STOCK_OPEN,
217 Gtk.ResponseType.OK),
218 action=Gtk.FileChooserAction.OPEN,
219 title=_("Open Software Package"))
220@@ -466,7 +530,7 @@
221 self.window_main.set_sensitive(True)
222
223 def on_copy_activate(self, widget):
224- clipboard = Gtk.Clipboard.get(Gdk.atom_intern('CLIPBOARD', True))
225+ clipboard = Gtk.Clipboard.get(Gdk.atom_intern('CLIPBOARD', True))
226 buf = self.textview_description.get_buffer()
227 if buf.get_has_selection():
228 buf.copy_clipboard(clipboard)
229@@ -535,7 +599,7 @@
230 scrolled = Gtk.ScrolledWindow()
231 textview = Gtk.TextView()
232 textview.set_cursor_visible(False)
233- textview.set_editable(False)
234+ textview.set_editable(False)
235 buf = textview.get_buffer()
236 buf.set_text("\n".join(self.unauthenticated))
237 scrolled.add(textview)
238@@ -584,13 +648,13 @@
239 self.statusbar_main.push(self.context, msgstring)
240 self.show_alert(Gtk.MessageType.ERROR, self.error_header, self.error_body)
241 return False
242-
243+
244 # lock for install
245 self.window_main.set_sensitive(False)
246 self.button_deb_install_close.set_sensitive(False)
247 # clear terminal
248 #self.vte_terminal.feed(str(0x1b)+"[2J")
249-
250+
251 # Get whether we auto close from synaptic's config file and
252 # update the toggle button as neccessary
253 config = apt_pkg.Configuration()
254@@ -602,7 +666,7 @@
255 config["Synaptic::closeZvt"] = "false"
256 self.synaptic_config = config.subtree("Synaptic")
257 self.checkbutton_autoclose.set_active(self.synaptic_config.find_b("closeZvt"))
258-
259+
260 self.dialog_deb_install.set_transient_for(self.window_main)
261 self.dialog_deb_install.show_all()
262
263@@ -638,13 +702,13 @@
264 if not res:
265 self.show_alert(Gtk.MessageType.ERROR, header, body, msg,
266 parent=self.dialog_deb_install)
267-
268+
269 self.label_install_status.set_markup("<span foreground=\"red\" weight=\"bold\">%s</span>" % header)
270 self.button_deb_install_close.set_sensitive(True)
271 self.button_deb_install_close.grab_default()
272 self.statusbar_main.push(self.context,_("Failed to install package file"))
273- return
274-
275+ return
276+
277 # install the package itself
278 self.dialog_deb_install.set_title(self.window_main.get_title())
279 if install:
280@@ -683,10 +747,10 @@
281 self.label_install_status.set_markup("<i>"+_("Package '%s' was removed") % os.path.basename(self._deb.pkgname)+"</i>")
282 else:
283 if install:
284- self.label_install_status.set_markup("<b>"+_("Failed to install package '%s'") %
285+ self.label_install_status.set_markup("<b>"+_("Failed to install package '%s'") %
286 os.path.basename(self._deb.filename)+"</b>")
287 else:
288- self.label_install_status.set_markup("<b>"+_("Failed to remove package '%s'") %
289+ self.label_install_status.set_markup("<b>"+_("Failed to remove package '%s'") %
290 os.path.basename(self._deb.pkgname)+"</b>")
291 self.expander_install.set_expanded(True)
292 if install:
293@@ -718,7 +782,7 @@
294
295 def on_button_remove_clicked(self, widget):
296 self.dpkg_action(widget, False)
297-
298+
299 def on_button_deb_install_close_clicked(self, widget):
300 # Set the autoclose option when we close
301 autoclose = self.checkbutton_autoclose.get_active()
302@@ -731,17 +795,17 @@
303 self._gio_cancellable.cancel()
304 self.dialog_deb_install.hide()
305 self.window_main.set_sensitive(True)
306-
307+
308 def on_checkbutton_autoclose_clicked(self, widget):
309 if self.action_completed:
310- self.on_button_deb_install_close_clicked(None)
311+ self.on_button_deb_install_close_clicked(None)
312
313 def on_window_main_delete_event(self, *args):
314 if self.window_main.get_property("sensitive"):
315 if Gtk.main_level() > 0:
316 Gtk.main_quit()
317 return False
318- else:
319+ else:
320 return True
321
322 def show_alert(self, type, header, body=None, details=None, parent=None):
323@@ -754,26 +818,26 @@
324 if not body == None:
325 message = "%s\n\n%s" % (message, body)
326 self.label_hig.set_markup(message)
327-
328+
329 if not details == None:
330 buffer = self.textview_hig.get_buffer()
331 buffer.set_text(str(details))
332 self.expander_hig.set_expanded(False)
333 self.expander_hig.show()
334-
335+
336 if type == Gtk.MessageType.ERROR:
337 self.image_hig.set_property("stock", "gtk-dialog-error")
338 elif type == Gtk.MessageType.WARNING:
339 self.image_hig.set_property("stock", "gtk-dialog-warning")
340 elif type == Gtk.MessageType.INFO:
341 self.image_hig.set_property("stock", "gtk-dialog-info")
342-
343+
344 res = self.dialog_hig.run()
345 self.dialog_hig.hide()
346 if res == Gtk.ResponseType.CLOSE:
347 return True
348 return False
349-
350+
351 def write_synaptic_config_file(self, config, path):
352 if not os.path.exists(path):
353 return
354@@ -791,7 +855,7 @@
355
356 def menu_action(self, widget, terminal):
357 terminal.copy_clipboard()
358-
359+
360 # embedded classes
361 class DpkgActionProgress(object):
362 def __init__(self, debfile, status, progress, term, expander, install=True):
363@@ -838,7 +902,7 @@
364
365 # the command
366 argv = ["/usr/bin/dpkg", "--auto-deconfigure"]
367- # ubuntu supports VTE_PTY_KEEP_FD, see
368+ # ubuntu supports VTE_PTY_KEEP_FD, see
369 # https://bugzilla.gnome.org/320128 for the upstream bug
370 if UBUNTU:
371 argv += ["--status-fd", "%s"%writefd]
372@@ -857,8 +921,8 @@
373 self.term.connect("child-exited", finish_dpkg, lock)
374 (res, pid) =self.term.fork_command_full(
375 Vte.PtyFlags.DEFAULT,
376- "/",
377- argv,
378+ "/",
379+ argv,
380 env,
381 GLib.SpawnFlags.LEAVE_DESCRIPTORS_OPEN,
382 # FIXME: add setup_func that closes all fds excpet for writefd
383@@ -895,11 +959,11 @@
384 Gtk.main_iteration()
385 time.sleep(0.2)
386 # if the terminal has not reacted for some time, do something
387- if (not self.term_expander.get_expanded() and
388+ if (not self.term_expander.get_expanded() and
389 (self.time_last_update + GDEBI_TERMINAL_TIMEOUT) < time.time()):
390 self.term_expander.set_expanded(True)
391 self.progress.set_fraction(1.0)
392-
393+
394 class InstallProgressAdapter(InstallProgress):
395 def __init__(self,progress,term,label,term_expander):
396 InstallProgress.__init__(self)
397@@ -941,7 +1005,7 @@
398 InstallProgress.update_interface(self)
399 while Gtk.events_pending():
400 Gtk.main_iteration()
401- if (not self.term_expander.get_expanded() and
402+ if (not self.term_expander.get_expanded() and
403 (self.time_last_update + GDEBI_TERMINAL_TIMEOUT) < time.time()):
404 self.term_expander.set_expanded(True)
405 # sleep just long enough to not create a busy loop
406@@ -965,7 +1029,7 @@
407 while not self.finished:
408 self.update_interface()
409 return self.apt_status
410-
411+
412 class FetchProgressAdapter(apt.progress.base.AcquireProgress):
413 def __init__(self,progress,action,main):
414 super(GDebi.FetchProgressAdapter, self).__init__()
415@@ -1017,7 +1081,7 @@
416 Gtk.main_iteration()
417 def done(self):
418 self.progressbar.hide()
419-
420+
421 if __name__ == "__main__":
422 app = GDebi("data/",None)
423
424@@ -1033,16 +1097,16 @@
425 apt_pkg.pkgsystem_lock()
426 app.dialog_deb_install.set_transient_for(app.window_main)
427 app.dialog_deb_install.show_all()
428-
429+
430 # install the dependecnies
431 fprogress = app.FetchProgressAdapter(app.progressbar_install,
432 app.label_action,
433 app.dialog_deb_install)
434- iprogress = app.InstallProgressAdapter(app.progressbar_install,
435+ iprogress = app.InstallProgressAdapter(app.progressbar_install,
436 app.vte_terminal,
437 app.label_action,
438 app.expander_install)
439 res = app._cache.commit(fprogress,iprogress)
440 print "commit retured: %s" % res
441-
442+
443 Gtk.main()
444
445=== modified file 'GDebi/GDebiCommon.py'
446--- GDebi/GDebiCommon.py 2012-09-12 21:28:17 +0000
447+++ GDebi/GDebiCommon.py 2012-10-08 06:56:32 +0000
448@@ -49,6 +49,7 @@
449 return unicode(str, 'latin1')
450
451 class GDebiCommon(object):
452+
453 # cprogress may be different in child classes
454 def __init__(self, datadir, options, file=""):
455 self.cprogress = None
456@@ -64,14 +65,14 @@
457 def openCache(self):
458 self._cache = Cache(self.cprogress)
459 if self._cache._depcache.broken_count > 0:
460- self.error_header = _("Broken dependencies")
461- self.error_body = _("Your system has broken dependencies. "
462- "This application can not continue until "
463- "this is fixed. "
464- "To fix it run 'gksudo synaptic' or "
465- "'sudo apt-get install -f' "
466- "in a terminal window.")
467- return False
468+ self.error_header = _("Broken dependencies")
469+ self.error_body = _("Your system has broken dependencies. "
470+ "This application can not continue until "
471+ "this is fixed. "
472+ "To fix it run 'gksudo synaptic' or "
473+ "'sudo apt-get install -f' "
474+ "in a terminal window.")
475+ return False
476 return True
477
478 def open(self, file, downloaded=False):
479
480=== modified file 'data/gdebi.ui'
481--- data/gdebi.ui 2012-09-13 21:32:07 +0000
482+++ data/gdebi.ui 2012-10-08 06:56:32 +0000
483@@ -1,6 +1,6 @@
484 <?xml version="1.0" encoding="UTF-8"?>
485 <interface>
486- <requires lib="gtk+" version="2.16"/>
487+ <!-- interface-requires gtk+ 3.0 -->
488 <object class="GtkAccelGroup" id="accelgroup1"/>
489 <object class="GtkAboutDialog" id="dialog_about">
490 <property name="can_focus">False</property>
491@@ -69,7 +69,6 @@
492 <property name="can_focus">True</property>
493 <property name="can_default">True</property>
494 <property name="receives_default">False</property>
495- <property name="use_action_appearance">False</property>
496 <property name="use_stock">True</property>
497 <signal name="clicked" handler="on_button_deb_install_close_clicked" swapped="no"/>
498 </object>
499@@ -180,8 +179,8 @@
500 <property name="visible">True</property>
501 <property name="can_focus">True</property>
502 <property name="receives_default">False</property>
503- <property name="use_action_appearance">False</property>
504 <property name="use_underline">True</property>
505+ <property name="xalign">0.5</property>
506 <property name="draw_indicator">True</property>
507 <signal name="clicked" handler="on_checkbutton_autoclose_clicked" swapped="no"/>
508 </object>
509@@ -230,7 +229,6 @@
510 <property name="can_focus">True</property>
511 <property name="can_default">True</property>
512 <property name="receives_default">False</property>
513- <property name="use_action_appearance">False</property>
514 <property name="use_stock">True</property>
515 </object>
516 <packing>
517@@ -328,7 +326,6 @@
518 <property name="can_focus">True</property>
519 <property name="can_default">True</property>
520 <property name="receives_default">True</property>
521- <property name="use_action_appearance">False</property>
522 <property name="use_stock">True</property>
523 </object>
524 <packing>
525@@ -439,7 +436,6 @@
526 <property name="can_focus">True</property>
527 <property name="can_default">True</property>
528 <property name="receives_default">False</property>
529- <property name="use_action_appearance">False</property>
530 <property name="use_stock">True</property>
531 </object>
532 <packing>
533@@ -589,7 +585,6 @@
534 <object class="GtkMenuItem" id="menuitem1">
535 <property name="visible">True</property>
536 <property name="can_focus">False</property>
537- <property name="use_action_appearance">False</property>
538 <property name="label" translatable="yes">_File</property>
539 <property name="use_underline">True</property>
540 <child type="submenu">
541@@ -600,7 +595,6 @@
542 <property name="label" translatable="yes">_Open…</property>
543 <property name="visible">True</property>
544 <property name="can_focus">False</property>
545- <property name="use_action_appearance">False</property>
546 <property name="use_underline">True</property>
547 <property name="image">image1</property>
548 <property name="use_stock">False</property>
549@@ -614,7 +608,6 @@
550 <property name="label" translatable="yes">_Refresh</property>
551 <property name="visible">True</property>
552 <property name="can_focus">False</property>
553- <property name="use_action_appearance">False</property>
554 <property name="use_underline">True</property>
555 <property name="image">image2</property>
556 <property name="use_stock">False</property>
557@@ -634,7 +627,6 @@
558 <property name="label">gtk-quit</property>
559 <property name="visible">True</property>
560 <property name="can_focus">False</property>
561- <property name="use_action_appearance">False</property>
562 <property name="use_underline">True</property>
563 <property name="use_stock">True</property>
564 <property name="accel_group">accelgroup1</property>
565@@ -649,7 +641,6 @@
566 <object class="GtkMenuItem" id="menuitem3">
567 <property name="visible">True</property>
568 <property name="can_focus">False</property>
569- <property name="use_action_appearance">False</property>
570 <property name="label" translatable="yes">_Edit</property>
571 <property name="use_underline">True</property>
572 <child type="submenu">
573@@ -660,7 +651,6 @@
574 <property name="label">gtk-copy</property>
575 <property name="visible">True</property>
576 <property name="can_focus">False</property>
577- <property name="use_action_appearance">False</property>
578 <property name="use_underline">True</property>
579 <property name="use_stock">True</property>
580 <property name="accel_group">accelgroup1</property>
581@@ -675,7 +665,6 @@
582 <object class="GtkMenuItem" id="menuitem4">
583 <property name="visible">True</property>
584 <property name="can_focus">False</property>
585- <property name="use_action_appearance">False</property>
586 <property name="label" translatable="yes">_Help</property>
587 <property name="use_underline">True</property>
588 <child type="submenu">
589@@ -686,7 +675,6 @@
590 <property name="label">gtk-about</property>
591 <property name="visible">True</property>
592 <property name="can_focus">False</property>
593- <property name="use_action_appearance">False</property>
594 <property name="use_underline">True</property>
595 <property name="use_stock">True</property>
596 <property name="accel_group">accelgroup1</property>
597@@ -727,7 +715,7 @@
598 </object>
599 <packing>
600 <property name="x_options">GTK_FILL</property>
601- <property name="y_options"></property>
602+ <property name="y_options"/>
603 </packing>
604 </child>
605 <child>
606@@ -737,14 +725,12 @@
607 <property name="xalign">0</property>
608 <property name="label" translatable="yes">&lt;b&gt;&lt;big&gt; &lt;/big&gt;&lt;/b&gt;</property>
609 <property name="use_markup">True</property>
610- <property name="selectable">False</property>
611- <property name="sensitive">True</property>
612 </object>
613 <packing>
614 <property name="left_attach">1</property>
615 <property name="right_attach">2</property>
616 <property name="x_options">GTK_FILL</property>
617- <property name="y_options"></property>
618+ <property name="y_options"/>
619 </packing>
620 </child>
621 <child>
622@@ -758,8 +744,6 @@
623 <property name="xalign">0</property>
624 <property name="yalign">0</property>
625 <property name="wrap">True</property>
626- <property name="selectable">False</property>
627- <property name="sensitive">True</property>
628 </object>
629 <packing>
630 <property name="expand">True</property>
631@@ -777,7 +761,6 @@
632 <property name="label" translatable="yes">_Details</property>
633 <property name="can_focus">True</property>
634 <property name="receives_default">True</property>
635- <property name="use_action_appearance">False</property>
636 <property name="use_underline">True</property>
637 <signal name="clicked" handler="on_button_details_clicked" swapped="no"/>
638 </object>
639@@ -804,7 +787,7 @@
640 <property name="top_attach">2</property>
641 <property name="bottom_attach">3</property>
642 <property name="x_options">GTK_FILL</property>
643- <property name="y_options"></property>
644+ <property name="y_options"/>
645 </packing>
646 </child>
647 <child>
648@@ -832,7 +815,7 @@
649 <property name="top_attach">1</property>
650 <property name="bottom_attach">2</property>
651 <property name="x_options">GTK_FILL</property>
652- <property name="y_options"></property>
653+ <property name="y_options"/>
654 </packing>
655 </child>
656 <child>
657@@ -846,7 +829,7 @@
658 <property name="right_attach">2</property>
659 <property name="top_attach">1</property>
660 <property name="bottom_attach">2</property>
661- <property name="y_options"></property>
662+ <property name="y_options"/>
663 </packing>
664 </child>
665 </object>
666@@ -869,7 +852,6 @@
667 <property name="can_focus">True</property>
668 <property name="can_default">True</property>
669 <property name="receives_default">False</property>
670- <property name="use_action_appearance">False</property>
671 <property name="use_underline">True</property>
672 <signal name="clicked" handler="on_button_install_clicked" swapped="no"/>
673 </object>
674@@ -880,13 +862,28 @@
675 </packing>
676 </child>
677 <child>
678+ <object class="GtkButton" id="button_remove">
679+ <property name="label" translatable="yes">_Remove Package</property>
680+ <property name="sensitive">False</property>
681+ <property name="can_focus">True</property>
682+ <property name="can_default">True</property>
683+ <property name="receives_default">False</property>
684+ <property name="use_underline">True</property>
685+ <signal name="clicked" handler="on_button_remove_clicked" swapped="no"/>
686+ </object>
687+ <packing>
688+ <property name="expand">False</property>
689+ <property name="fill">False</property>
690+ <property name="position">1</property>
691+ </packing>
692+ </child>
693+ <child>
694 <object class="GtkButton" id="button_download">
695 <property name="label" translatable="yes">_Download Package</property>
696 <property name="sensitive">False</property>
697 <property name="can_focus">True</property>
698 <property name="can_default">True</property>
699 <property name="receives_default">False</property>
700- <property name="use_action_appearance">False</property>
701 <property name="use_underline">True</property>
702 <signal name="clicked" handler="on_button_download_clicked" swapped="no"/>
703 </object>
704@@ -897,24 +894,6 @@
705 </packing>
706 </child>
707 <child>
708- <object class="GtkButton" id="button_remove">
709- <property name="label" translatable="yes">_Remove Package</property>
710- <property name="visible">False</property>
711- <property name="sensitive">False</property>
712- <property name="can_focus">True</property>
713- <property name="can_default">True</property>
714- <property name="receives_default">False</property>
715- <property name="use_action_appearance">False</property>
716- <property name="use_underline">True</property>
717- <signal name="clicked" handler="on_button_remove_clicked" swapped="no"/>
718- </object>
719- <packing>
720- <property name="expand">False</property>
721- <property name="fill">False</property>
722- <property name="position">1</property>
723- </packing>
724- </child>
725- <child>
726 <placeholder/>
727 </child>
728 </object>
729@@ -987,7 +966,7 @@
730 </object>
731 <packing>
732 <property name="x_options">GTK_FILL</property>
733- <property name="y_options"></property>
734+ <property name="y_options"/>
735 </packing>
736 </child>
737 <child>
738@@ -1002,7 +981,7 @@
739 <property name="top_attach">1</property>
740 <property name="bottom_attach">2</property>
741 <property name="x_options">GTK_FILL</property>
742- <property name="y_options"></property>
743+ <property name="y_options"/>
744 </packing>
745 </child>
746 <child>
747@@ -1017,7 +996,7 @@
748 <property name="top_attach">2</property>
749 <property name="bottom_attach">3</property>
750 <property name="x_options">GTK_FILL</property>
751- <property name="y_options"></property>
752+ <property name="y_options"/>
753 </packing>
754 </child>
755 <child>
756@@ -1032,7 +1011,7 @@
757 <property name="top_attach">3</property>
758 <property name="bottom_attach">4</property>
759 <property name="x_options">GTK_FILL</property>
760- <property name="y_options"></property>
761+ <property name="y_options"/>
762 </packing>
763 </child>
764 <child>
765@@ -1047,7 +1026,7 @@
766 <property name="top_attach">4</property>
767 <property name="bottom_attach">5</property>
768 <property name="x_options">GTK_FILL</property>
769- <property name="y_options"></property>
770+ <property name="y_options"/>
771 </packing>
772 </child>
773 <child>
774@@ -1063,7 +1042,7 @@
775 <property name="top_attach">1</property>
776 <property name="bottom_attach">2</property>
777 <property name="x_options">GTK_FILL</property>
778- <property name="y_options"></property>
779+ <property name="y_options"/>
780 </packing>
781 </child>
782 <child>
783@@ -1079,7 +1058,7 @@
784 <property name="top_attach">2</property>
785 <property name="bottom_attach">3</property>
786 <property name="x_options">GTK_FILL</property>
787- <property name="y_options"></property>
788+ <property name="y_options"/>
789 </packing>
790 </child>
791 <child>
792@@ -1095,7 +1074,7 @@
793 <property name="top_attach">3</property>
794 <property name="bottom_attach">4</property>
795 <property name="x_options">GTK_FILL</property>
796- <property name="y_options"></property>
797+ <property name="y_options"/>
798 </packing>
799 </child>
800 <child>
801@@ -1109,7 +1088,7 @@
802 <property name="left_attach">1</property>
803 <property name="right_attach">2</property>
804 <property name="x_options">GTK_FILL</property>
805- <property name="y_options"></property>
806+ <property name="y_options"/>
807 </packing>
808 </child>
809 <child>
810@@ -1124,7 +1103,7 @@
811 <property name="right_attach">2</property>
812 <property name="top_attach">4</property>
813 <property name="bottom_attach">5</property>
814- <property name="y_options"></property>
815+ <property name="y_options"/>
816 </packing>
817 </child>
818 </object>
819@@ -1216,6 +1195,34 @@
820 <property name="tab_fill">False</property>
821 </packing>
822 </child>
823+ <child>
824+ <object class="GtkScrolledWindow" id="scrolledwindow3">
825+ <property name="visible">True</property>
826+ <property name="can_focus">True</property>
827+ <property name="shadow_type">in</property>
828+ <child>
829+ <object class="GtkTextView" id="textview_lintian_output">
830+ <property name="visible">True</property>
831+ <property name="can_focus">True</property>
832+ <property name="editable">False</property>
833+ </object>
834+ </child>
835+ </object>
836+ <packing>
837+ <property name="position">3</property>
838+ </packing>
839+ </child>
840+ <child type="tab">
841+ <object class="GtkLabel" id="label_lintian">
842+ <property name="visible">True</property>
843+ <property name="can_focus">False</property>
844+ <property name="label" translatable="yes">Lintian output</property>
845+ </object>
846+ <packing>
847+ <property name="position">3</property>
848+ <property name="tab_fill">False</property>
849+ </packing>
850+ </child>
851 </object>
852 <packing>
853 <property name="expand">True</property>
854
855=== added file 'tests/test_gdebi_gtk_lintian.py'
856--- tests/test_gdebi_gtk_lintian.py 1970-01-01 00:00:00 +0000
857+++ tests/test_gdebi_gtk_lintian.py 2012-10-08 06:56:32 +0000
858@@ -0,0 +1,63 @@
859+#!/usr/bin/python
860+
861+import os
862+import time
863+import unittest
864+
865+from gi.repository import GObject
866+from mock import patch
867+
868+from GDebi.GDebi import GDebi
869+from GDebi.GDebiCommon import GDebiCommon
870+
871+EXPECTED_LINTIAN_OUTPUT = """E: error-package: file-in-etc-not-marked-as-conffile etc/foo
872+E: error-package: control-file-has-bad-owner postinst egon/egon != root/root
873+E: error-package: no-copyright-file
874+E: error-package: package-has-no-description
875+E: error-package: no-maintainer-field
876+W: error-package: no-section-field
877+W: error-package: no-priority-field
878+E: error-package: wrong-file-owner-uid-or-gid etc/ 1000/1000
879+E: error-package: wrong-file-owner-uid-or-gid etc/foo 1000/1000
880+W: error-package: maintainer-script-ignores-errors postinst
881+
882+Lintian finished with exit status 1"""
883+
884+
885+def do_events():
886+ context = GObject.main_context_default()
887+ while context.pending():
888+ context.iteration()
889+
890+
891+class GDebiGtkTestCase(unittest.TestCase):
892+
893+ def setUp(self):
894+ self.testsdir = os.path.dirname(__file__)
895+ self.datadir = os.path.join(self.testsdir, "..", "data")
896+ self.options = None
897+
898+ # we don't need a cache for this test so patch it out
899+ @patch.object(GDebiCommon, "openCache")
900+ def test_lintian(self, mock_open_cache):
901+ gdebi = GDebi(self.datadir, self.options)
902+ gdebi._run_lintian(
903+ os.path.join(self.testsdir, "error-package_1.0_all.deb"))
904+ # wait for lintian to finish
905+ for i in range(25):
906+ time.sleep(0.2)
907+ do_events()
908+ if gdebi._lintian_exit_status is not None:
909+ break
910+ else:
911+ self.fail("lintian did not finish")
912+ # compare the results
913+ buf = gdebi.textview_lintian_output.get_buffer()
914+ start = buf.get_start_iter()
915+ end = buf.get_end_iter()
916+ lintian_output = buf.get_text(start, end, False)
917+ self.assertEqual(lintian_output.strip(), EXPECTED_LINTIAN_OUTPUT)
918+
919+
920+if __name__ == "__main__":
921+ unittest.main()

Subscribers

People subscribed via source and target branches

to status/vote changes: