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
, selections
9 from zeroinstall
.injector
.iface_cache
import iface_cache
10 from zeroinstall
.injector
.policy
import Policy
11 from zeroinstall
import SafeException
16 "setup [--no-prompt] [ SOURCE-URI [ DIR ] ]"
18 if args
and args
[0] == '--no-prompt':
23 if not os
.path
.isfile(ENV_FILE
):
24 raise SafeException("Run 0compile from a directory containing a '%s' file, or "
25 "specify a source URI as an argument." % ENV_FILE
)
28 interface
= buildenv
.interface
34 create_dir
= os
.path
.basename(interface
)
35 if create_dir
.endswith('.xml'):
36 create_dir
= create_dir
[:-4]
37 assert '/' not in create_dir
41 raise __main__
.UsageError()
43 interface
= model
.canonical_iface_uri(args
[0])
45 if os
.path
.exists(create_dir
):
46 raise SafeException("Directory '%s' already exists." % create_dir
)
48 setup(interface
, create_dir
, prompt
)
50 def setup(interface
, create_dir
, prompt
):
54 gui_options
= '--offline'
56 # Prompt user to choose versions
57 if os
.spawnvp(os
.P_WAIT
, '0launch', ['0launch', gui_options
, '--source', '--download-only', interface
]):
58 raise SafeException('Failed to select source files.')
60 # Get the chosen versions
61 policy
= Policy(interface
, src
= True)
66 raise Exception('Internal error: required source components not found!')
68 root_iface
= iface_cache
.get_interface(policy
.root
)
69 impl
= policy
.implementation
[root_iface
]
70 min_version
= parse_version(impl
.metadata
.get(XMLNS_0COMPILE
+ ' min-version', None))
71 if min_version
and min_version
> parse_version(__main__
.version
):
72 raise SafeException("%s-%s requires 0compile >= %s, but we are only version %s" %
73 (root_iface
.get_name(), impl
.get_version(), format_version(min_version
), __main__
.version
))
76 if os
.path
.exists(create_dir
):
77 raise SafeException("Directory '%s' already exists." % create_dir
)
82 save_environment(policy
)
84 def save_environment(policy
):
86 if os
.path
.exists(ENV_FILE
):
87 # Don't lose existing download URL
88 download_base
= BuildEnv().download_base_url
90 sels
= selections
.Selections(policy
)
92 # Copy mappings metadata
93 for iface
, impl
in policy
.implementation
.iteritems():
94 mappings
= impl
.metadata
.get(XMLNS_0COMPILE
+ ' lib-mappings', None)
96 sels
.selections
[iface
.uri
].attrs
[XMLNS_0COMPILE
+ ' lib-mappings'] = mappings
99 root
= doc
.documentElement
101 root
.setAttributeNS(XMLNS_NAMESPACE
, 'xmlns:compile', XMLNS_0COMPILE
)
104 root
.setAttributeNS(XMLNS_0COMPILE
, 'compile:download-base-url', download_base
)
106 impl
= policy
.implementation
[iface_cache
.get_interface(policy
.root
)]
107 command
= impl
.metadata
.get(XMLNS_0COMPILE
+ ' command', None)
108 if not command
: raise SafeException("Missing 'compile:command' attribute on <implementation>.")
109 root
.setAttributeNS(XMLNS_0COMPILE
, 'compile:command', command
)
111 for name
in ['binary-main', 'binary-lib-mappings', 'metadir']:
112 value
= impl
.metadata
.get(XMLNS_0COMPILE
+ ' ' + name
, None)
114 root
.setAttributeNS(XMLNS_0COMPILE
, 'compile:' + name
, value
)
116 doc
.writexml(file(ENV_FILE
, 'w'), addindent
= ' ', newl
= '\n')
118 __main__
.commands
.append(do_setup
)