Updated Compile GUI for Python 3
[zeroinstall/solver.git] / zeroinstall / 0launch-gui / compile.py
blobcd171c46770259dd88fa763ce9a365f8ca1bdaf6
1 # Copyright (C) 2009, Thomas Leonard
2 # See the README file for details, or visit http://0install.net.
4 import os, subprocess
5 from zeroinstall import gobject
6 import dialog
7 from io import BytesIO
9 from zeroinstall import _
10 from zeroinstall.injector import model, selections, qdom
12 XMLNS_0COMPILE = 'http://zero-install.sourceforge.net/2006/namespaces/0compile'
14 class Command:
15 def __init__(self):
16 self.child = None
17 self.error = b""
18 self.stdout = b""
19 self.watched_streams = 0
21 def run(self, command, success, get_stdout = False):
22 assert self.child is None
23 self.success = success
24 if get_stdout:
25 self.child = subprocess.Popen(command,
26 stdout = subprocess.PIPE,
27 stderr = subprocess.PIPE)
28 gobject.io_add_watch(self.child.stdout, gobject.IO_IN | gobject.IO_HUP, self.got_stdout)
29 gobject.io_add_watch(self.child.stderr, gobject.IO_IN | gobject.IO_HUP, self.got_errors)
30 self.watched_streams = 2
31 else:
32 self.child = subprocess.Popen(command,
33 stdout = subprocess.PIPE,
34 stderr = subprocess.STDOUT)
35 gobject.io_add_watch(self.child.stdout, gobject.IO_IN | gobject.IO_HUP, self.got_errors)
36 self.watched_streams = 1
38 def got_stdout(self, src, cond):
39 data = os.read(src.fileno(), 100)
40 if data:
41 self.stdout += data
42 return True
43 else:
44 self.done()
45 return False
47 def done(self):
48 self.watched_streams -= 1
49 if self.watched_streams == 0:
50 status = self.child.wait()
51 self.child = None
53 if status == 0:
54 self.success(self.stdout)
55 else:
56 if status == 1 and not self.error:
57 return False # Cancelled
58 dialog.alert(None, _("Command failed with exit code %(status)d:\n%(error)s\n") %
59 {'status': status, 'error': self.error})
61 def got_errors(self, src, cond):
62 data = os.read(src.fileno(), 100)
63 if data:
64 self.error += data
65 return True
66 else:
67 self.done()
68 return False
70 def compile(on_success, interface_uri, autocompile = False):
71 our_min_version = '0.18' # The oldest version of 0compile we support
73 def build(selections_xml):
74 # Get the chosen versions
75 sels = selections.Selections(qdom.parse(BytesIO(selections_xml)))
77 impl = sels.selections[interface_uri]
79 min_version = impl.attrs.get(XMLNS_0COMPILE + ' min-version', our_min_version)
80 # Check the syntax is valid and the version is high enough
81 if model.parse_version(min_version) < model.parse_version(our_min_version):
82 min_version = our_min_version
84 # Do the whole build-and-register-feed
85 c = Command()
86 c.run(("0launch",
87 '--message', _('Download the 0compile tool, to compile the source code'),
88 '--not-before=' + min_version,
89 "http://0install.net/2006/interfaces/0compile.xml",
90 'gui',
91 interface_uri), lambda unused: on_success())
93 if autocompile:
94 c = Command()
95 c.run(("0launch",
96 '--message', 'Download the 0compile tool, to compile the source code',
97 '--not-before=' + our_min_version,
98 "http://0install.net/2006/interfaces/0compile.xml",
99 'autocompile',
100 '--gui',
101 interface_uri), lambda unused: on_success())
102 else:
103 # Prompt user to choose source version
104 c = Command()
105 c.run(['0install', 'download', '--xml',
106 '--message', _('Download the source code to be compiled'),
107 '--gui', '--source', '--', interface_uri], build, get_stdout = True)