6 from xml.etree
import ElementTree
as ET
7 from subprocess
import Popen, PIPE
13 Add spaces and newlines to elements to allow pretty-printing of XML.
15 http://effbot.org/zone/element-lib.htm#prettyprint
19 if not elem.text
or not elem.text.strip():
21 if not elem.tail
or not elem.tail.strip():
25 if not elem.tail
or not elem.tail.strip():
28 if level
and (
not elem.tail
or not elem.tail.strip()):
33 Parse a list or strings using the logic of the CMake function
34 CMAKE_PARSE_ARGUMENTS.
36 >>> res = CMakeParseArguments(['USE', 'Gaudi', 'v25r0', 'DATA', 'Det/SQLDDDB'],
37 ... multi_value=['USE', 'DATA'])
44 >>> res = CMakeParseArguments('a b OPTION1 c FLAG1 d OPTION2 e f'.split(),
45 ... options=['FLAG1', 'FLAG2'],
46 ... single_value=['OPTION1', 'OPTION2'])
59 options = set(options
or [])
60 single_value = set(single_value
or [])
61 multi_value = set(multi_value
or [])
62 all_keywords = options.union(single_value).union(multi_value)
63 result = {
'UNPARSED': []}
64 result.update((k,
False)
for k
in options)
65 result.update((k,
None)
for k
in single_value)
66 result.update((k, [])
for k
in multi_value)
72 elif arg
in single_value:
73 result[arg] = args.pop(0)
74 elif arg
in multi_value:
75 while args
and args[0]
not in all_keywords:
76 result[arg].append(args.pop(0))
78 result[
'UNPARSED'].append(arg)
81 if __name__ ==
'__main__':
82 from optparse
import OptionParser
83 parser = OptionParser(usage=
'%prog [options] <cmake_lists> <lcg_version> <platform>')
84 parser.add_option(
'-o',
'--output', action=
'store',
85 help=
'output filename')
87 opts, args = parser.parse_args()
90 parser.error(
'wrong number of arguments')
92 cmake_lists, lcg_version, platform = args
94 logging.basicConfig(level=logging.INFO)
97 if not os.path.exists(cmake_lists):
98 print 'The project does not have a CMake configuration, I cannot produce a manifest.xml'
102 m = re.search(
r'gaudi_project\s*\(([^)]*)\)',
103 open(cmake_lists).read(), re.MULTILINE)
105 project_args = m.group(1).split()
106 if len(project_args) < 2:
107 print 'error: invalid content of CMakeLists.txt'
111 name, version = project_args[:2]
112 project_args = project_args[2:]
116 multi_value=[
'USE',
'DATA'])
119 if opts.output
in (
'-',
None):
125 manifest = ET.Element(
'manifest')
126 manifest.append(ET.Element(
'project', name=name, version=version))
128 heptools = ET.Element(
'heptools')
129 ht_version = ET.Element(
'version')
130 ht_version.text = lcg_version
131 ht_bin_tag = ET.Element(
'binary_tag')
132 ht_bin_tag.text = platform
133 ht_system = ET.Element(
'lcg_system')
134 ht_system.text =
'-'.join(platform.split(
'-')[:-1])
135 heptools.extend([ht_version, ht_bin_tag, ht_system])
136 manifest.append(heptools)
138 if parsed_args[
'USE']:
139 used_projects = ET.Element(
'used_projects')
140 used_projects.extend(ET.Element(
'project', name=name, version=version)
141 for name, version
in zip(parsed_args[
'USE'][::2],
142 parsed_args[
'USE'][1::2]))
143 manifest.append(used_projects)
145 if parsed_args[
'DATA']:
146 used_data_pkgs = ET.Element(
'used_data_pkgs')
148 '''helper to translate the list of data packages'''
152 if len(args) >= 2
and args[0] ==
'VERSION':
158 used_data_pkgs.extend(ET.Element(
'package', name=pkg, version=vers)
159 for pkg, vers
in data_pkgs(parsed_args[
'DATA']))
160 manifest.append(used_data_pkgs)
163 logging.debug(
'collecting external dependencies info (with CMT)')
164 p = Popen([
'cmt',
'show',
'uses'], stdout=PIPE)
165 externals = [l.split()[1]
167 if l.startswith(
'use')
and
168 'LCG_Interfaces' in l]
172 def get_ext_vers(ext):
174 Ask CMT the version of an external.
176 logging.debug(
'getting version of %s', ext)
177 vers = Popen([
'cmt',
'show',
'macro_value',
178 '%s_native_version' % ext],
179 stdout=PIPE).communicate()[0].strip()
180 logging.debug(
'using %s %s', ext, vers)
186 rpm_names = {
'Expat':
'expat'}
187 fix_rpm_name =
lambda n: rpm_names.get(n, n)
189 packages = ET.Element(
'packages')
190 packages.extend([ET.Element(
'package', name=fix_rpm_name(ext), version=vers)
191 for ext, vers
in [(ext, get_ext_vers(ext))
192 for ext
in externals]
194 heptools.append(packages)
196 destdir = os.path.dirname(output)
197 if not os.path.exists(destdir):
198 logging.debug(
'creating directory %s', destdir)
202 logging.debug(
'writing manifest file %s', output)
204 ET.ElementTree(manifest).write(output,
205 encoding=
"UTF-8", xml_declaration=
True)
207 logging.debug(
'%s written', output)