Added '0compile gui' command. This uses a GTK file selector to let you
[0compile.git] / setup.py
blob3013a5efad6bd14119f703e0448a3487f693314c
1 # Copyright (C) 2006, Thomas Leonard
2 # See http://0install.net/0compile.html
4 import sys, os, __main__
5 from logging import info
6 from xml.dom import minidom, XMLNS_NAMESPACE
8 from zeroinstall.injector import model
9 from zeroinstall.injector.policy import Policy
10 from zeroinstall import SafeException
12 from support import *
14 def do_setup(args):
15 "setup [ SOURCE-URI [ DIR ] ]"
16 if len(args) == 0:
17 if not os.path.isfile(ENV_FILE):
18 raise SafeException("Run 0compile from a directory containing a '%s' file, or "
19 "specify a source URI as an argument." % ENV_FILE)
20 doc = get_env_doc()
21 interface = doc.documentElement.getAttributeNS(None, 'interface')
22 assert interface
23 else:
24 interface = args[0]
25 if len(args) == 1:
26 dir = os.path.basename(interface)
27 if dir.endswith('.xml'):
28 dir = dir[:-4]
29 assert '/' not in dir
30 elif len(args) == 2:
31 dir = args[1]
32 else:
33 raise __main__.UsageError()
35 interface = model.canonical_iface_uri(args[0])
37 if os.path.exists(dir):
38 raise SafeException("Directory '%s' already exists." % dir)
40 setup(interface, dir, prompt = True, create_dir = len(args) > 0)
42 def setup(interface, dir, prompt, create_dir):
43 if prompt:
44 gui_options = '--gui'
45 else:
46 gui_options = '--offline'
48 # Prompt user to choose versions
49 if os.spawnvp(os.P_WAIT, '0launch', ['0launch', gui_options, '--source', '--download-only', interface]):
50 raise SafeException('Failed to select source files.')
52 # Get the chosen versions
53 policy = Policy(interface, src = True)
54 policy.freshness = 0
56 policy.recalculate()
57 if not policy.ready:
58 raise Exception('Internal error: required source components not found!')
60 root_iface = policy.get_interface(policy.root)
61 impl = policy.implementation[root_iface]
62 min_version = parse_version(impl.metadata.get(XMLNS_0COMPILE + ' min-version', None))
63 if min_version and min_version > parse_version(__main__.version):
64 raise SafeException("%s-%s requires 0compile >= %s, but we are only version %s" %
65 (root_iface.get_name(), impl.get_version(), format_version(min_version), __main__.version))
67 if create_dir:
68 if os.path.exists(dir):
69 raise SafeException("Directory '%s' already exists." % dir)
70 os.mkdir(dir)
71 os.chdir(dir)
73 # Store choices
74 save_environment(policy)
76 def save_environment(policy):
77 impl = minidom.getDOMImplementation()
79 doc = impl.createDocument(XMLNS_0COMPILE, "build-environment", None)
81 root = doc.documentElement
82 root.setAttributeNS(XMLNS_NAMESPACE, 'xmlns', XMLNS_0COMPILE)
84 root.setAttributeNS(None, 'interface', policy.root)
86 for needed_iface in policy.implementation:
87 iface_elem = doc.createElementNS(XMLNS_0COMPILE, 'interface')
88 iface_elem.setAttributeNS(None, 'uri', needed_iface.uri)
89 root.appendChild(iface_elem)
91 impl = policy.implementation[needed_iface]
92 assert impl
94 impl_elem = doc.createElementNS(XMLNS_0COMPILE, 'implementation')
95 impl_elem.setAttributeNS(None, 'id', impl.id)
96 impl_elem.setAttributeNS(None, 'version', impl.get_version())
97 if impl.interface is not needed_iface:
98 impl_elem.setAttributeNS(None, 'from-feed', impl.interface.uri)
100 if needed_iface.uri == policy.root:
101 command = impl.metadata.get(XMLNS_0COMPILE + ' command', None)
102 if not command: raise SafeException("Missing 'compile:command' attribute on <implementation>.")
103 impl_elem.setAttributeNS(XMLNS_0COMPILE, 'command', command)
104 binary_main = impl.metadata.get(XMLNS_0COMPILE + ' binary-main', None)
105 if binary_main:
106 impl_elem.setAttributeNS(XMLNS_0COMPILE, 'binary-main', binary_main)
107 metadir = impl.metadata.get(XMLNS_0COMPILE + ' metadir', None)
108 if metadir:
109 impl_elem.setAttributeNS(XMLNS_0COMPILE, 'metadir', metadir)
111 iface_elem.appendChild(impl_elem)
113 for dep in impl.dependencies.values():
115 dep_iface = policy.get_interface(dep.interface)
116 dep_impl = policy.get_implementation(dep_iface)
118 dep_elem = doc.createElementNS(XMLNS_0COMPILE, 'requires')
119 dep_elem.setAttributeNS(None, 'interface', dep.interface)
120 impl_elem.appendChild(dep_elem)
122 for m in dep.metadata:
123 if m.startswith(XMLNS_0COMPILE + ' '):
124 dep_elem.setAttributeNS(None, m.split(' ', 1)[1], dep.metadata[m])
126 for b in dep.bindings:
127 if isinstance(b, model.EnvironmentBinding):
128 env_elem = doc.createElementNS(XMLNS_0COMPILE, 'environment')
129 env_elem.setAttributeNS(None, 'name', b.name)
130 env_elem.setAttributeNS(None, 'insert', b.insert)
131 if b.default:
132 env_elem.setAttributeNS(None, 'default', b.default)
133 dep_elem.appendChild(env_elem)
134 else:
135 raise Exception('Unknown binding type ' + b)
137 doc.writexml(file(ENV_FILE, 'w'), addindent = ' ', newl = '\n')
139 __main__.commands.append(do_setup)