1 import os, os.path, re, sys, textwrap
9 class SchemaItemBoolean(object):
10 def __call__(self, i):
12 if i in ("true", "1"):
14 if i in ("false", "0"):
18 class SchemaItemList(object):
19 def __init__(self, type = "\s+"):
22 def __call__(self, i):
26 return [j.strip() for j in re.split(self.type, i)]
28 class ConfigCore(dict):
29 def get_merge(self, section, arch, featureset, flavour, key, default=None):
32 if arch and featureset and flavour:
33 temp.append(self.get((section, arch, featureset, flavour), {}).get(key))
34 temp.append(self.get((section, arch, None, flavour), {}).get(key))
35 if arch and featureset:
36 temp.append(self.get((section, arch, featureset), {}).get(key))
38 temp.append(self.get((section, arch), {}).get(key))
40 temp.append(self.get((section, None, featureset), {}).get(key))
41 temp.append(self.get((section,), {}).get(key))
48 elif isinstance(i, (list, tuple)):
58 def merge(self, section, arch = None, featureset = None, flavour = None):
60 ret.update(self.get((section,), {}))
62 ret.update(self.get((section, None, featureset), {}))
64 ret.update(self.get((section, arch), {}))
65 if arch and featureset:
66 ret.update(self.get((section, arch, featureset), {}))
67 if arch and featureset and flavour:
68 ret.update(self.get((section, arch, None, flavour), {}))
69 ret.update(self.get((section, arch, featureset, flavour), {}))
73 sections = self.keys()
75 for section in sections:
76 fp.write('[%r]\n' % (section,))
78 items_keys = items.keys()
81 fp.write('%s: %r\n' % (item, items[item]))
84 class ConfigCoreDump(ConfigCore):
85 def __init__(self, config = None, fp = None):
86 super(ConfigCoreDump, self).__init__(self)
87 if config is not None:
90 from ConfigParser import RawConfigParser
91 config = RawConfigParser()
93 for section in config.sections():
94 section_real = eval(section)
96 for key, value in config.items(section):
97 value_real = eval(value)
98 data[key] = value_real
99 self[section_real] = data
101 class ConfigCoreHierarchy(ConfigCore):
102 config_name = "defines"
106 'ignore-changes': SchemaItemList(),
109 'arches': SchemaItemList(),
110 'enabled': SchemaItemBoolean(),
111 'featuresets': SchemaItemList(),
112 'flavours': SchemaItemList(),
113 'modules': SchemaItemBoolean(),
117 'parts': SchemaItemList(),
120 'configs': SchemaItemList(),
121 'initramfs': SchemaItemBoolean(),
122 'initramfs-generators': SchemaItemList(),
125 'enabled': SchemaItemBoolean(),
130 'dom0-support': SchemaItemBoolean(),
131 'flavours': SchemaItemList(),
132 'versions': SchemaItemList(),
136 def __init__(self, dirs = []):
137 super(ConfigCoreHierarchy, self).__init__()
141 def _read_arch(self, arch):
142 config = ConfigParser(self.schemas)
143 config.read(self.get_files("%s/%s" % (arch, self.config_name)))
145 featuresets = config['base',].get('featuresets', [])
146 flavours = config['base',].get('flavours', [])
148 for section in iter(config):
149 if section[0] in featuresets:
150 real = (section[-1], arch, section[0])
151 elif len(section) > 1:
152 real = (section[-1], arch, None) + section[:-1]
154 real = (section[-1], arch) + section[:-1]
155 s = self.get(real, {})
156 s.update(config[section])
157 self[tuple(real)] = s
159 for featureset in featuresets:
160 self._read_arch_featureset(arch, featureset)
163 base = self['base', arch]
164 featuresets.insert(0, 'none')
165 base['featuresets'] = featuresets
167 self['base', arch] = base
168 self['base', arch, 'none'] = {'flavours': flavours, 'implicit-flavour': True}
170 def _read_arch_featureset(self, arch, featureset):
171 config = ConfigParser(self.schemas)
172 config.read(self.get_files("%s/%s/%s" % (arch, featureset, self.config_name)))
174 flavours = config['base',].get('flavours', [])
176 for section in iter(config):
177 real = (section[-1], arch, featureset) + section[:-1]
178 s = self.get(real, {})
179 s.update(config[section])
180 self[tuple(real)] = s
182 def _read_base(self):
183 config = ConfigParser(self.schemas)
184 config.read(self.get_files(self.config_name))
186 arches = config['base',]['arches']
187 featuresets = config['base',].get('featuresets', [])
189 for section in iter(config):
190 if section[0].startswith('featureset-'):
191 real = (section[-1], None, section[0].lstrip('featureset-'))
193 real = (section[-1],) + section[1:]
194 self[real] = config[section]
197 self._read_arch(arch)
198 for featureset in featuresets:
199 self._read_featureset(featureset)
201 def _read_featureset(self, featureset):
202 config = ConfigParser(self.schemas)
203 config.read(self.get_files("featureset-%s/%s" % (featureset, self.config_name)))
205 for section in iter(config):
206 real = (section[-1], None, featureset)
207 s = self.get(real, {})
208 s.update(config[section])
211 def get_files(self, name):
212 return [os.path.join(i, name) for i in self._dirs if i]
214 class ConfigParser(object):
215 __slots__ = '_config', 'schemas'
217 def __init__(self, schemas):
218 self.schemas = schemas
220 from ConfigParser import RawConfigParser
221 self._config = config = RawConfigParser()
223 def __getitem__(self, key):
224 return self._convert()[key]
227 return iter(self._convert())
230 return '<%s(%s)>' % (self.__class__.__name__, self._convert())
234 for section in self._config.sections():
236 for key, value in self._config.items(section):
238 s1 = section.split('_')
239 if s1[-1] in self.schemas:
240 ret[tuple(s1)] = self.SectionSchema(data, self.schemas[s1[-1]])
242 ret[(section,)] = self.Section(data)
246 return self._convert().keys()
248 def read(self, data):
249 return self._config.read(data)
252 def __init__(self, data):
253 super(ConfigParser.Section, self).__init__(data)
255 class SectionSchema(Section):
258 def __init__(self, data, schema):
259 for key in data.keys():
261 data[key] = schema[key](data[key])
262 except KeyError: pass
263 super(ConfigParser.SectionSchema, self).__init__(data)
265 if __name__ == '__main__':
267 config = ConfigCoreHierarchy(['debian/config'])
268 sections = config.keys()
270 for section in sections:
271 print "[%s]" % (section,)
272 items = config[section]
273 items_keys = items.keys()
276 print "%s: %s" % (item, items[item])