Update Python debian_linux module from linux and use it in gencontrol.py
svn path=/dists/trunk/linux-tools/; revision=19890
This commit is contained in:
parent
2725cdf944
commit
8c00a1b1a9
|
@ -4,10 +4,10 @@ import sys
|
||||||
sys.path.append("debian/lib/python")
|
sys.path.append("debian/lib/python")
|
||||||
|
|
||||||
from debian_linux.debian import *
|
from debian_linux.debian import *
|
||||||
from debian_linux.gencontrol import PackagesList, Makefile, MakeFlags
|
from debian_linux.gencontrol import PackagesList, Makefile, MakeFlags, Gencontrol
|
||||||
from debian_linux.utils import *
|
from debian_linux.utils import *
|
||||||
|
|
||||||
class gencontrol(object):
|
class gencontrol(Gencontrol):
|
||||||
makefile_targets = ('binary-arch', 'build')
|
makefile_targets = ('binary-arch', 'build')
|
||||||
|
|
||||||
def __init__(self, underlay = None):
|
def __init__(self, underlay = None):
|
||||||
|
@ -60,63 +60,5 @@ class gencontrol(object):
|
||||||
'source_upstream': version.upstream,
|
'source_upstream': version.upstream,
|
||||||
}
|
}
|
||||||
|
|
||||||
def process_relation(self, key, e, in_e, vars):
|
|
||||||
import copy
|
|
||||||
dep = copy.deepcopy(in_e[key])
|
|
||||||
for groups in dep:
|
|
||||||
for item in groups:
|
|
||||||
item.name = self.substitute(item.name, vars)
|
|
||||||
e[key] = dep
|
|
||||||
|
|
||||||
def process_description(self, e, in_e, vars):
|
|
||||||
in_desc = in_e['Description']
|
|
||||||
desc = in_desc.__class__()
|
|
||||||
desc.short = self.substitute(in_desc.short, vars)
|
|
||||||
for i in in_desc.long:
|
|
||||||
desc.append(self.substitute(i, vars))
|
|
||||||
e['Description'] = desc
|
|
||||||
|
|
||||||
def process_package(self, in_entry, vars):
|
|
||||||
e = Package()
|
|
||||||
for key, value in in_entry.iteritems():
|
|
||||||
if isinstance(value, PackageRelation):
|
|
||||||
self.process_relation(key, e, in_entry, vars)
|
|
||||||
elif key == 'Description':
|
|
||||||
self.process_description(e, in_entry, vars)
|
|
||||||
elif key[:2] == 'X-':
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
e[key] = self.substitute(value, vars)
|
|
||||||
return e
|
|
||||||
|
|
||||||
def process_packages(self, in_entries, vars):
|
|
||||||
entries = []
|
|
||||||
for i in in_entries:
|
|
||||||
entries.append(self.process_package(i, vars))
|
|
||||||
return entries
|
|
||||||
|
|
||||||
def substitute(self, s, vars):
|
|
||||||
if isinstance(s, (list, tuple)):
|
|
||||||
for i in xrange(len(s)):
|
|
||||||
s[i] = self.substitute(s[i], vars)
|
|
||||||
return s
|
|
||||||
def subst(match):
|
|
||||||
return vars[match.group(1)]
|
|
||||||
return re.sub(r'@([a-z_]+)@', subst, s)
|
|
||||||
|
|
||||||
def write_control(self, list):
|
|
||||||
self.write_rfc822(file("debian/control", 'w'), list)
|
|
||||||
|
|
||||||
def write_makefile(self, makefile):
|
|
||||||
f = file("debian/rules.gen", 'w')
|
|
||||||
makefile.write(f)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
def write_rfc822(self, f, list):
|
|
||||||
for entry in list:
|
|
||||||
for key, value in entry.iteritems():
|
|
||||||
f.write("%s: %s\n" % (key, value))
|
|
||||||
f.write('\n')
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
gencontrol()()
|
gencontrol()()
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
# Module
|
|
@ -1,10 +1,17 @@
|
||||||
import os, os.path, re, sys, textwrap
|
import os
|
||||||
|
import os.path
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import textwrap
|
||||||
|
import cPickle
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
'ConfigCoreDump',
|
||||||
|
'ConfigCoreHierarchy',
|
||||||
'ConfigParser',
|
'ConfigParser',
|
||||||
'ConfigReaderCore',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class SchemaItemBoolean(object):
|
class SchemaItemBoolean(object):
|
||||||
def __call__(self, i):
|
def __call__(self, i):
|
||||||
i = i.strip().lower()
|
i = i.strip().lower()
|
||||||
|
@ -14,8 +21,9 @@ class SchemaItemBoolean(object):
|
||||||
return False
|
return False
|
||||||
raise Error
|
raise Error
|
||||||
|
|
||||||
|
|
||||||
class SchemaItemList(object):
|
class SchemaItemList(object):
|
||||||
def __init__(self, type = "\s+"):
|
def __init__(self, type="\s+"):
|
||||||
self.type = type
|
self.type = type
|
||||||
|
|
||||||
def __call__(self, i):
|
def __call__(self, i):
|
||||||
|
@ -24,108 +32,38 @@ class SchemaItemList(object):
|
||||||
return []
|
return []
|
||||||
return [j.strip() for j in re.split(self.type, i)]
|
return [j.strip() for j in re.split(self.type, i)]
|
||||||
|
|
||||||
class ConfigReaderCore(dict):
|
|
||||||
config_name = "defines"
|
|
||||||
|
|
||||||
schemas = {
|
class ConfigCore(dict):
|
||||||
'base': {
|
def get_merge(self, section, arch, featureset, flavour, key, default=None):
|
||||||
'arches': SchemaItemList(),
|
temp = []
|
||||||
'enabled': SchemaItemBoolean(),
|
|
||||||
'featuresets': SchemaItemList(),
|
|
||||||
'flavours': SchemaItemList(),
|
|
||||||
'modules': SchemaItemBoolean(),
|
|
||||||
},
|
|
||||||
'image': {
|
|
||||||
'configs': SchemaItemList(),
|
|
||||||
'initramfs': SchemaItemBoolean(),
|
|
||||||
'initramfs-generators': SchemaItemList(),
|
|
||||||
},
|
|
||||||
'relations': {
|
|
||||||
},
|
|
||||||
'xen': {
|
|
||||||
'dom0-support': SchemaItemBoolean(),
|
|
||||||
'versions': SchemaItemList(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self, dirs = []):
|
if arch and featureset and flavour:
|
||||||
self._dirs = dirs
|
temp.append(self.get((section, arch, featureset, flavour), {}).get(key))
|
||||||
self._read_base()
|
temp.append(self.get((section, arch, None, flavour), {}).get(key))
|
||||||
|
if arch and featureset:
|
||||||
|
temp.append(self.get((section, arch, featureset), {}).get(key))
|
||||||
|
if arch:
|
||||||
|
temp.append(self.get((section, arch), {}).get(key))
|
||||||
|
if featureset:
|
||||||
|
temp.append(self.get((section, None, featureset), {}).get(key))
|
||||||
|
temp.append(self.get((section,), {}).get(key))
|
||||||
|
|
||||||
def _read_arch(self, arch):
|
ret = []
|
||||||
config = ConfigParser(self.schemas)
|
|
||||||
config.read(self.get_files("%s/%s" % (arch, self.config_name)))
|
|
||||||
|
|
||||||
featuresets = config['base',].get('featuresets', [])
|
for i in temp:
|
||||||
flavours = config['base',].get('flavours', [])
|
if i is None:
|
||||||
|
continue
|
||||||
for section in iter(config):
|
elif isinstance(i, (list, tuple)):
|
||||||
if section[0] in featuresets:
|
ret.extend(i)
|
||||||
real = (section[-1], arch, section[0])
|
elif ret:
|
||||||
elif len(section) > 1:
|
# TODO
|
||||||
real = (section[-1], arch, None) + section[:-1]
|
return ret
|
||||||
else:
|
else:
|
||||||
real = (section[-1], arch) + section[:-1]
|
return i
|
||||||
s = self.get(real, {})
|
|
||||||
s.update(config[section])
|
|
||||||
self[tuple(real)] = s
|
|
||||||
|
|
||||||
for featureset in featuresets:
|
return ret or default
|
||||||
self._read_arch_featureset(arch, featureset)
|
|
||||||
|
|
||||||
if flavours:
|
def merge(self, section, arch=None, featureset=None, flavour=None):
|
||||||
base = self['base', arch]
|
|
||||||
featuresets.insert(0, 'none')
|
|
||||||
base['featuresets'] = featuresets
|
|
||||||
del base['flavours']
|
|
||||||
self['base', arch] = base
|
|
||||||
self['base', arch, 'none'] = {'flavours': flavours, 'implicit-flavour': True}
|
|
||||||
|
|
||||||
def _read_arch_featureset(self, arch, featureset):
|
|
||||||
config = ConfigParser(self.schemas)
|
|
||||||
config.read(self.get_files("%s/%s/%s" % (arch, featureset, self.config_name)))
|
|
||||||
|
|
||||||
flavours = config['base',].get('flavours', [])
|
|
||||||
|
|
||||||
for section in iter(config):
|
|
||||||
real = (section[-1], arch, featureset) + section[:-1]
|
|
||||||
s = self.get(real, {})
|
|
||||||
s.update(config[section])
|
|
||||||
self[tuple(real)] = s
|
|
||||||
|
|
||||||
def _read_base(self):
|
|
||||||
config = ConfigParser(self.schemas)
|
|
||||||
config.read(self.get_files(self.config_name))
|
|
||||||
|
|
||||||
arches = config['base',]['arches']
|
|
||||||
featuresets = config['base',]['featuresets']
|
|
||||||
|
|
||||||
for section in iter(config):
|
|
||||||
if section[0].startswith('featureset-'):
|
|
||||||
real = (section[-1], None, section[0].lstrip('featureset-'))
|
|
||||||
else:
|
|
||||||
real = (section[-1],) + section[1:]
|
|
||||||
self[real] = config[section]
|
|
||||||
|
|
||||||
for arch in arches:
|
|
||||||
self._read_arch(arch)
|
|
||||||
for featureset in featuresets:
|
|
||||||
self._read_featureset(featureset)
|
|
||||||
|
|
||||||
def _read_featureset(self, featureset):
|
|
||||||
config = ConfigParser(self.schemas)
|
|
||||||
config.read(self.get_files("featureset-%s/%s" % (featureset, self.config_name)))
|
|
||||||
|
|
||||||
for section in iter(config):
|
|
||||||
real = (section[-1], None, featureset)
|
|
||||||
s = self.get(real, {})
|
|
||||||
s.update(config[section])
|
|
||||||
self[real] = s
|
|
||||||
|
|
||||||
def get_files(self, name):
|
|
||||||
return [os.path.join(i, name) for i in self._dirs if i]
|
|
||||||
|
|
||||||
def merge(self, section, arch = None, featureset = None, flavour = None):
|
|
||||||
ret = {}
|
ret = {}
|
||||||
ret.update(self.get((section,), {}))
|
ret.update(self.get((section,), {}))
|
||||||
if featureset:
|
if featureset:
|
||||||
|
@ -139,6 +77,118 @@ class ConfigReaderCore(dict):
|
||||||
ret.update(self.get((section, arch, featureset, flavour), {}))
|
ret.update(self.get((section, arch, featureset, flavour), {}))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def dump(self, fp):
|
||||||
|
cPickle.dump(self, fp, 0)
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigCoreDump(object):
|
||||||
|
def __new__(self, fp):
|
||||||
|
return cPickle.load(fp)
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigCoreHierarchy(object):
|
||||||
|
schema_base = {
|
||||||
|
'base': {
|
||||||
|
'arches': SchemaItemList(),
|
||||||
|
'enabled': SchemaItemBoolean(),
|
||||||
|
'featuresets': SchemaItemList(),
|
||||||
|
'flavours': SchemaItemList(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
def __new__(cls, schema, dirs=[]):
|
||||||
|
schema_complete = cls.schema_base.copy()
|
||||||
|
for key, value in schema.iteritems():
|
||||||
|
schema_complete.setdefault(key, {}).update(value)
|
||||||
|
return cls.Reader(dirs, schema_complete)()
|
||||||
|
|
||||||
|
class Reader(object):
|
||||||
|
config_name = "defines"
|
||||||
|
|
||||||
|
def __init__(self, dirs, schema):
|
||||||
|
self.dirs, self.schema = dirs, schema
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
ret = ConfigCore()
|
||||||
|
self.read(ret)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def get_files(self, *dirs):
|
||||||
|
dirs = list(dirs)
|
||||||
|
dirs.append(self.config_name)
|
||||||
|
return (os.path.join(i, *dirs) for i in self.dirs if i)
|
||||||
|
|
||||||
|
def read_arch(self, ret, arch):
|
||||||
|
config = ConfigParser(self.schema)
|
||||||
|
config.read(self.get_files(arch))
|
||||||
|
|
||||||
|
featuresets = config['base', ].get('featuresets', [])
|
||||||
|
flavours = config['base', ].get('flavours', [])
|
||||||
|
|
||||||
|
for section in iter(config):
|
||||||
|
if section[0] in featuresets:
|
||||||
|
real = (section[-1], arch, section[0])
|
||||||
|
elif len(section) > 1:
|
||||||
|
real = (section[-1], arch, None) + section[:-1]
|
||||||
|
else:
|
||||||
|
real = (section[-1], arch) + section[:-1]
|
||||||
|
s = ret.get(real, {})
|
||||||
|
s.update(config[section])
|
||||||
|
ret[tuple(real)] = s
|
||||||
|
|
||||||
|
for featureset in featuresets:
|
||||||
|
self.read_arch_featureset(ret, arch, featureset)
|
||||||
|
|
||||||
|
if flavours:
|
||||||
|
base = ret['base', arch]
|
||||||
|
featuresets.insert(0, 'none')
|
||||||
|
base['featuresets'] = featuresets
|
||||||
|
del base['flavours']
|
||||||
|
ret['base', arch] = base
|
||||||
|
ret['base', arch, 'none'] = {'flavours': flavours, 'implicit-flavour': True}
|
||||||
|
|
||||||
|
def read_arch_featureset(self, ret, arch, featureset):
|
||||||
|
config = ConfigParser(self.schema)
|
||||||
|
config.read(self.get_files(arch, featureset))
|
||||||
|
|
||||||
|
flavours = config['base', ].get('flavours', [])
|
||||||
|
|
||||||
|
for section in iter(config):
|
||||||
|
real = (section[-1], arch, featureset) + section[:-1]
|
||||||
|
s = ret.get(real, {})
|
||||||
|
s.update(config[section])
|
||||||
|
ret[tuple(real)] = s
|
||||||
|
|
||||||
|
def read(self, ret):
|
||||||
|
config = ConfigParser(self.schema)
|
||||||
|
config.read(self.get_files())
|
||||||
|
|
||||||
|
arches = config['base', ]['arches']
|
||||||
|
featuresets = config['base', ].get('featuresets', [])
|
||||||
|
|
||||||
|
for section in iter(config):
|
||||||
|
if section[0].startswith('featureset-'):
|
||||||
|
real = (section[-1], None, section[0][11:])
|
||||||
|
else:
|
||||||
|
real = (section[-1],) + section[1:]
|
||||||
|
ret[real] = config[section]
|
||||||
|
|
||||||
|
for arch in arches:
|
||||||
|
self.read_arch(ret, arch)
|
||||||
|
for featureset in featuresets:
|
||||||
|
self.read_featureset(ret, featureset)
|
||||||
|
|
||||||
|
def read_featureset(self, ret, featureset):
|
||||||
|
config = ConfigParser(self.schema)
|
||||||
|
config.read(self.get_files('featureset-%s' % featureset))
|
||||||
|
|
||||||
|
for section in iter(config):
|
||||||
|
real = (section[-1], None, featureset)
|
||||||
|
s = ret.get(real, {})
|
||||||
|
s.update(config[section])
|
||||||
|
ret[real] = s
|
||||||
|
|
||||||
|
|
||||||
class ConfigParser(object):
|
class ConfigParser(object):
|
||||||
__slots__ = '_config', 'schemas'
|
__slots__ = '_config', 'schemas'
|
||||||
|
|
||||||
|
@ -163,11 +213,22 @@ class ConfigParser(object):
|
||||||
data = {}
|
data = {}
|
||||||
for key, value in self._config.items(section):
|
for key, value in self._config.items(section):
|
||||||
data[key] = value
|
data[key] = value
|
||||||
s1 = section.split('_')
|
section_list = section.split('_')
|
||||||
if s1[-1] in self.schemas:
|
section_base = section_list[-1]
|
||||||
ret[tuple(s1)] = self.SectionSchema(data, self.schemas[s1[-1]])
|
if section_base in self.schemas:
|
||||||
|
section_ret = tuple(section_list)
|
||||||
|
data = self._convert_one(self.schemas[section_base], data)
|
||||||
else:
|
else:
|
||||||
ret[(section,)] = self.Section(data)
|
section_ret = (section, )
|
||||||
|
ret[section_ret] = data
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def _convert_one(self, schema, data):
|
||||||
|
ret = {}
|
||||||
|
for key, value in data.iteritems():
|
||||||
|
if key in schema:
|
||||||
|
value = schema[key](value)
|
||||||
|
ret[key] = value
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def keys(self):
|
def keys(self):
|
||||||
|
@ -176,34 +237,13 @@ class ConfigParser(object):
|
||||||
def read(self, data):
|
def read(self, data):
|
||||||
return self._config.read(data)
|
return self._config.read(data)
|
||||||
|
|
||||||
class Section(dict):
|
|
||||||
def __init__(self, data):
|
|
||||||
super(ConfigParser.Section, self).__init__(data)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return '<%s(%s)>' % (self.__class__.__name__, self._data)
|
|
||||||
|
|
||||||
class SectionSchema(Section):
|
|
||||||
__slots__ = ()
|
|
||||||
|
|
||||||
def __init__(self, data, schema):
|
|
||||||
for key in data.keys():
|
|
||||||
try:
|
|
||||||
data[key] = schema[key](data[key])
|
|
||||||
except KeyError: pass
|
|
||||||
super(ConfigParser.SectionSchema, self).__init__(data)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import sys
|
import sys
|
||||||
config = ConfigReaderCore(['debian/config'])
|
sys.path.append('debian/lib/python')
|
||||||
sections = config.keys()
|
config = ConfigCoreDump(open('debian/config.defines.dump'))
|
||||||
sections.sort()
|
for section, items in sorted(config.iteritems()):
|
||||||
for section in sections:
|
print u"[%s]" % (section,)
|
||||||
print "[%s]" % (section,)
|
for item, value in sorted(items.iteritems()):
|
||||||
items = config[section]
|
print u"%s: %s" % (item, value)
|
||||||
items_keys = items.keys()
|
|
||||||
items_keys.sort()
|
|
||||||
for item in items:
|
|
||||||
print "%s: %s" % (item, items[item])
|
|
||||||
print
|
print
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
import itertools, os.path, re, utils
|
import collections
|
||||||
|
import itertools
|
||||||
|
import os.path
|
||||||
|
import re
|
||||||
|
|
||||||
|
from . import utils
|
||||||
|
|
||||||
|
|
||||||
class Changelog(list):
|
class Changelog(list):
|
||||||
_rules = r"""
|
_rules = r"""
|
||||||
|
@ -26,7 +32,7 @@ class Changelog(list):
|
||||||
def __init__(self, distribution, source, version):
|
def __init__(self, distribution, source, version):
|
||||||
self.distribution, self.source, self.version = distribution, source, version
|
self.distribution, self.source, self.version = distribution, source, version
|
||||||
|
|
||||||
def __init__(self, dir = '', version = None):
|
def __init__(self, dir='', version=None):
|
||||||
if version is None:
|
if version is None:
|
||||||
version = Version
|
version = Version
|
||||||
f = file(os.path.join(dir, "debian/changelog"))
|
f = file(os.path.join(dir, "debian/changelog"))
|
||||||
|
@ -45,6 +51,7 @@ class Changelog(list):
|
||||||
v = Version(match.group('version'))
|
v = Version(match.group('version'))
|
||||||
self.append(self.Entry(match.group('distribution'), match.group('source'), v))
|
self.append(self.Entry(match.group('distribution'), match.group('source'), v))
|
||||||
|
|
||||||
|
|
||||||
class Version(object):
|
class Version(object):
|
||||||
_version_rules = ur"""
|
_version_rules = ur"""
|
||||||
^
|
^
|
||||||
|
@ -59,7 +66,7 @@ class Version(object):
|
||||||
)
|
)
|
||||||
(?:
|
(?:
|
||||||
-
|
-
|
||||||
(?P<debian>[^-]+)
|
(?P<revision>[^-]+)
|
||||||
)?
|
)?
|
||||||
$
|
$
|
||||||
"""
|
"""
|
||||||
|
@ -68,37 +75,45 @@ $
|
||||||
def __init__(self, version):
|
def __init__(self, version):
|
||||||
match = self._version_re.match(version)
|
match = self._version_re.match(version)
|
||||||
if match is None:
|
if match is None:
|
||||||
raise RuntimeError, "Invalid debian version"
|
raise RuntimeError(u"Invalid debian version")
|
||||||
self.epoch = None
|
self.epoch = None
|
||||||
if match.group("epoch") is not None:
|
if match.group("epoch") is not None:
|
||||||
self.epoch = int(match.group("epoch"))
|
self.epoch = int(match.group("epoch"))
|
||||||
self.upstream = match.group("upstream")
|
self.upstream = match.group("upstream")
|
||||||
self.debian = match.group("debian")
|
self.revision = match.group("revision")
|
||||||
|
|
||||||
def __str__(self):
|
def __unicode__(self):
|
||||||
return self.complete
|
return self.complete
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def complete(self):
|
def complete(self):
|
||||||
if self.epoch is not None:
|
if self.epoch is not None:
|
||||||
return "%d:%s" % (self.epoch, self.complete_noepoch)
|
return u"%d:%s" % (self.epoch, self.complete_noepoch)
|
||||||
return self.complete_noepoch
|
return self.complete_noepoch
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def complete_noepoch(self):
|
def complete_noepoch(self):
|
||||||
if self.debian is not None:
|
if self.revision is not None:
|
||||||
return "%s-%s" % (self.upstream, self.debian)
|
return u"%s-%s" % (self.upstream, self.revision)
|
||||||
return self.upstream
|
return self.upstream
|
||||||
|
|
||||||
|
@property
|
||||||
|
def debian(self):
|
||||||
|
from warnings import warn
|
||||||
|
warn(u"debian argument was replaced by revision", DeprecationWarning, stacklevel=2)
|
||||||
|
return self.revision
|
||||||
|
|
||||||
|
|
||||||
class VersionLinux(Version):
|
class VersionLinux(Version):
|
||||||
_version_linux_rules = ur"""
|
_version_linux_rules = ur"""
|
||||||
^
|
^
|
||||||
(?P<version>
|
(?P<version>
|
||||||
\d+\.\d+
|
\d+\.\d+
|
||||||
)
|
)
|
||||||
(?:
|
(?P<update>
|
||||||
\.\d+
|
\.\d+
|
||||||
|
|
)?
|
||||||
|
(?:
|
||||||
~
|
~
|
||||||
(?P<modifier>
|
(?P<modifier>
|
||||||
.+?
|
.+?
|
||||||
|
@ -111,7 +126,17 @@ class VersionLinux(Version):
|
||||||
)
|
)
|
||||||
)?
|
)?
|
||||||
-
|
-
|
||||||
(?:[^-]+)
|
\d+
|
||||||
|
(\.\d+)?
|
||||||
|
(?:
|
||||||
|
(?P<revision_experimental>
|
||||||
|
~experimental\.\d+
|
||||||
|
)
|
||||||
|
|
|
||||||
|
(?P<revision_other>
|
||||||
|
[^-]+
|
||||||
|
)
|
||||||
|
)?
|
||||||
$
|
$
|
||||||
"""
|
"""
|
||||||
_version_linux_re = re.compile(_version_linux_rules, re.X)
|
_version_linux_re = re.compile(_version_linux_rules, re.X)
|
||||||
|
@ -120,125 +145,159 @@ $
|
||||||
super(VersionLinux, self).__init__(version)
|
super(VersionLinux, self).__init__(version)
|
||||||
match = self._version_linux_re.match(version)
|
match = self._version_linux_re.match(version)
|
||||||
if match is None:
|
if match is None:
|
||||||
raise RuntimeError, "Invalid debian linux version"
|
raise RuntimeError(u"Invalid debian linux version")
|
||||||
d = match.groupdict()
|
d = match.groupdict()
|
||||||
self.linux_modifier = d['modifier']
|
self.linux_modifier = d['modifier']
|
||||||
self.linux_version = d['version']
|
self.linux_version = d['version']
|
||||||
if d['modifier'] is not None:
|
if d['modifier'] is not None:
|
||||||
self.linux_upstream = '-'.join((d['version'], d['modifier']))
|
assert not d['update']
|
||||||
|
self.linux_upstream = u'-'.join((d['version'], d['modifier']))
|
||||||
else:
|
else:
|
||||||
self.linux_upstream = d['version']
|
self.linux_upstream = d['version']
|
||||||
|
self.linux_upstream_full = self.linux_upstream + (d['update'] or u'')
|
||||||
self.linux_dfsg = d['dfsg']
|
self.linux_dfsg = d['dfsg']
|
||||||
|
self.linux_revision_experimental = match.group('revision_experimental') and True
|
||||||
|
self.linux_revision_other = match.group('revision_other') and True
|
||||||
|
|
||||||
class PackageFieldList(list):
|
|
||||||
def __init__(self, value = None):
|
|
||||||
self.extend(value)
|
|
||||||
|
|
||||||
def __str__(self):
|
class PackageArchitecture(collections.MutableSet):
|
||||||
return ' '.join(self)
|
__slots__ = '_data'
|
||||||
|
|
||||||
def _extend(self, value):
|
def __init__(self, value=None):
|
||||||
if value is not None:
|
self._data = set()
|
||||||
self.extend([j.strip() for j in re.split('\s', value.strip())])
|
if value:
|
||||||
|
self.extend(value)
|
||||||
|
|
||||||
|
def __contains__(self, value):
|
||||||
|
return self._data.__contains__(value)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return self._data.__iter__()
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return self._data.__len__()
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return u' '.join(sorted(self))
|
||||||
|
|
||||||
|
def add(self, value):
|
||||||
|
self._data.add(value)
|
||||||
|
|
||||||
|
def discard(self, value):
|
||||||
|
self._data.discard(value)
|
||||||
|
|
||||||
def extend(self, value):
|
def extend(self, value):
|
||||||
if isinstance(value, str):
|
if isinstance(value, basestring):
|
||||||
self._extend(value)
|
for i in re.split('\s', value.strip()):
|
||||||
|
self.add(i)
|
||||||
else:
|
else:
|
||||||
super(PackageFieldList, self).extend(value)
|
raise RuntimeError
|
||||||
|
|
||||||
|
|
||||||
class PackageDescription(object):
|
class PackageDescription(object):
|
||||||
__slots__ = "short", "long"
|
__slots__ = "short", "long"
|
||||||
|
|
||||||
def __init__(self, value = None):
|
def __init__(self, value=None):
|
||||||
|
self.short = []
|
||||||
self.long = []
|
self.long = []
|
||||||
if value is not None:
|
if value is not None:
|
||||||
self.short, long = value.split("\n", 1)
|
short, long = value.split(u"\n", 1)
|
||||||
self.append(long)
|
self.append(long)
|
||||||
else:
|
self.append_short(short)
|
||||||
self.short = None
|
|
||||||
|
|
||||||
def __str__(self):
|
def __unicode__(self):
|
||||||
ret = self.short + '\n'
|
wrap = utils.TextWrapper(width=74, fix_sentence_endings=True).wrap
|
||||||
w = utils.TextWrapper(width = 74, fix_sentence_endings = True)
|
short = u', '.join(self.short)
|
||||||
pars = []
|
long_pars = []
|
||||||
for i in self.long:
|
for i in self.long:
|
||||||
pars.append('\n '.join(w.wrap(i)))
|
long_pars.append(wrap(i))
|
||||||
return self.short + '\n ' + '\n .\n '.join(pars)
|
long = u'\n .\n '.join([u'\n '.join(i) for i in long_pars])
|
||||||
|
return short + u'\n ' + long
|
||||||
|
|
||||||
def append(self, str):
|
def append(self, str):
|
||||||
str = str.strip()
|
str = str.strip()
|
||||||
if str:
|
if str:
|
||||||
self.long.extend(str.split("\n.\n"))
|
self.long.extend(str.split(u"\n.\n"))
|
||||||
|
|
||||||
|
def append_short(self, str):
|
||||||
|
for i in [i.strip() for i in str.split(u",")]:
|
||||||
|
if i:
|
||||||
|
self.short.append(i)
|
||||||
|
|
||||||
|
def extend(self, desc):
|
||||||
|
if isinstance(desc, PackageDescription):
|
||||||
|
self.short.extend(desc.short)
|
||||||
|
self.long.extend(desc.long)
|
||||||
|
else:
|
||||||
|
raise TypeError
|
||||||
|
|
||||||
|
|
||||||
class PackageRelation(list):
|
class PackageRelation(list):
|
||||||
def __init__(self, value = None):
|
def __init__(self, value=None, override_arches=None):
|
||||||
if value is not None:
|
if value:
|
||||||
self.extend(value)
|
self.extend(value, override_arches)
|
||||||
|
|
||||||
def __str__(self):
|
def __unicode__(self):
|
||||||
return ', '.join([str(i) for i in self])
|
return u', '.join((unicode(i) for i in self))
|
||||||
|
|
||||||
def _match(self, value):
|
def _search_value(self, value):
|
||||||
for i in self:
|
for i in self:
|
||||||
if i._match(value):
|
if i._search_value(value):
|
||||||
return i
|
return i
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def append(self, value):
|
def append(self, value, override_arches=None):
|
||||||
if isinstance(value, basestring):
|
if isinstance(value, basestring):
|
||||||
value = PackageRelationGroup(value)
|
value = PackageRelationGroup(value, override_arches)
|
||||||
elif not isinstance(value, PackageRelationGroup):
|
elif not isinstance(value, PackageRelationGroup):
|
||||||
raise ValueError, "got %s" % type(value)
|
raise ValueError(u"got %s" % type(value))
|
||||||
j = self._match(value)
|
j = self._search_value(value)
|
||||||
if j:
|
if j:
|
||||||
j._updateArches(value)
|
j._update_arches(value)
|
||||||
else:
|
else:
|
||||||
super(PackageRelation, self).append(value)
|
super(PackageRelation, self).append(value)
|
||||||
|
|
||||||
def extend(self, value):
|
def extend(self, value, override_arches=None):
|
||||||
if isinstance(value, basestring):
|
if isinstance(value, basestring):
|
||||||
value = [j.strip() for j in re.split(',', value.strip())]
|
value = (j.strip() for j in re.split(u',', value.strip()))
|
||||||
elif not isinstance(value, (list, tuple)):
|
|
||||||
raise ValueError, "got %s" % type(value)
|
|
||||||
for i in value:
|
for i in value:
|
||||||
self.append(i)
|
self.append(i, override_arches)
|
||||||
|
|
||||||
|
|
||||||
class PackageRelationGroup(list):
|
class PackageRelationGroup(list):
|
||||||
def __init__(self, value = None):
|
def __init__(self, value=None, override_arches=None):
|
||||||
if value is not None:
|
if value:
|
||||||
self.extend(value)
|
self.extend(value, override_arches)
|
||||||
|
|
||||||
def __str__(self):
|
def __unicode__(self):
|
||||||
return ' | '.join([str(i) for i in self])
|
return u' | '.join((unicode(i) for i in self))
|
||||||
|
|
||||||
def _match(self, value):
|
def _search_value(self, value):
|
||||||
for i, j in itertools.izip(self, value):
|
for i, j in itertools.izip(self, value):
|
||||||
if i.name != j.name or i.version != j.version:
|
if i.name != j.name or i.version != j.version:
|
||||||
return None
|
return None
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def _updateArches(self, value):
|
def _update_arches(self, value):
|
||||||
for i, j in itertools.izip(self, value):
|
for i, j in itertools.izip(self, value):
|
||||||
if i.arches:
|
if i.arches:
|
||||||
for arch in j.arches:
|
for arch in j.arches:
|
||||||
if arch not in i.arches:
|
if arch not in i.arches:
|
||||||
i.arches.append(arch)
|
i.arches.append(arch)
|
||||||
|
|
||||||
def append(self, value):
|
def append(self, value, override_arches=None):
|
||||||
if isinstance(value, basestring):
|
if isinstance(value, basestring):
|
||||||
value = PackageRelationEntry(value)
|
value = PackageRelationEntry(value, override_arches)
|
||||||
elif not isinstance(value, PackageRelationEntry):
|
elif not isinstance(value, PackageRelationEntry):
|
||||||
raise ValueError
|
raise ValueError
|
||||||
super(PackageRelationGroup, self).append(value)
|
super(PackageRelationGroup, self).append(value)
|
||||||
|
|
||||||
def extend(self, value):
|
def extend(self, value, override_arches=None):
|
||||||
if isinstance(value, basestring):
|
if isinstance(value, basestring):
|
||||||
value = [j.strip() for j in re.split('\|', value.strip())]
|
value = (j.strip() for j in re.split('\|', value.strip()))
|
||||||
elif not isinstance(value, (list, tuple)):
|
|
||||||
raise ValueError
|
|
||||||
for i in value:
|
for i in value:
|
||||||
self.append(i)
|
self.append(i, override_arches)
|
||||||
|
|
||||||
|
|
||||||
class PackageRelationEntry(object):
|
class PackageRelationEntry(object):
|
||||||
__slots__ = "name", "operator", "version", "arches"
|
__slots__ = "name", "operator", "version", "arches"
|
||||||
|
@ -246,9 +305,31 @@ class PackageRelationEntry(object):
|
||||||
_re = re.compile(r'^(\S+)(?: \((<<|<=|=|!=|>=|>>)\s*([^)]+)\))?(?: \[([^]]+)\])?$')
|
_re = re.compile(r'^(\S+)(?: \((<<|<=|=|!=|>=|>>)\s*([^)]+)\))?(?: \[([^]]+)\])?$')
|
||||||
|
|
||||||
class _operator(object):
|
class _operator(object):
|
||||||
OP_LT = 1; OP_LE = 2; OP_EQ = 3; OP_NE = 4; OP_GE = 5; OP_GT = 6
|
OP_LT = 1
|
||||||
operators = { '<<': OP_LT, '<=': OP_LE, '=': OP_EQ, '!=': OP_NE, '>=': OP_GE, '>>': OP_GT }
|
OP_LE = 2
|
||||||
operators_neg = { OP_LT: OP_GE, OP_LE: OP_GT, OP_EQ: OP_NE, OP_NE: OP_EQ, OP_GE: OP_LT, OP_GT: OP_LE }
|
OP_EQ = 3
|
||||||
|
OP_NE = 4
|
||||||
|
OP_GE = 5
|
||||||
|
OP_GT = 6
|
||||||
|
|
||||||
|
operators = {
|
||||||
|
u'<<': OP_LT,
|
||||||
|
u'<=': OP_LE,
|
||||||
|
u'=': OP_EQ,
|
||||||
|
u'!=': OP_NE,
|
||||||
|
u'>=': OP_GE,
|
||||||
|
u'>>': OP_GT,
|
||||||
|
}
|
||||||
|
|
||||||
|
operators_neg = {
|
||||||
|
OP_LT: OP_GE,
|
||||||
|
OP_LE: OP_GT,
|
||||||
|
OP_EQ: OP_NE,
|
||||||
|
OP_NE: OP_EQ,
|
||||||
|
OP_GE: OP_LT,
|
||||||
|
OP_GT: OP_LE,
|
||||||
|
}
|
||||||
|
|
||||||
operators_text = dict([(b, a) for a, b in operators.iteritems()])
|
operators_text = dict([(b, a) for a, b in operators.iteritems()])
|
||||||
|
|
||||||
__slots__ = '_op',
|
__slots__ = '_op',
|
||||||
|
@ -259,27 +340,30 @@ class PackageRelationEntry(object):
|
||||||
def __neg__(self):
|
def __neg__(self):
|
||||||
return self.__class__(self.operators_text[self.operators_neg[self._op]])
|
return self.__class__(self.operators_text[self.operators_neg[self._op]])
|
||||||
|
|
||||||
def __str__(self):
|
def __unicode__(self):
|
||||||
return self.operators_text[self._op]
|
return self.operators_text[self._op]
|
||||||
|
|
||||||
def __init__(self, value = None):
|
def __init__(self, value=None, override_arches=None):
|
||||||
if isinstance(value, basestring):
|
if not isinstance(value, basestring):
|
||||||
self.parse(value)
|
|
||||||
else:
|
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
def __str__(self):
|
self.parse(value)
|
||||||
|
|
||||||
|
if override_arches:
|
||||||
|
self.arches = list(override_arches)
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
ret = [self.name]
|
ret = [self.name]
|
||||||
if self.operator is not None and self.version is not None:
|
if self.operator is not None and self.version is not None:
|
||||||
ret.extend([' (', str(self.operator), ' ', self.version, ')'])
|
ret.extend((u' (', unicode(self.operator), u' ', self.version, u')'))
|
||||||
if self.arches:
|
if self.arches:
|
||||||
ret.extend([' [', ' '.join(self.arches), ']'])
|
ret.extend((u' [', u' '.join(self.arches), u']'))
|
||||||
return ''.join(ret)
|
return u''.join(ret)
|
||||||
|
|
||||||
def parse(self, value):
|
def parse(self, value):
|
||||||
match = self._re.match(value)
|
match = self._re.match(value)
|
||||||
if match is None:
|
if match is None:
|
||||||
raise RuntimeError, "Can't parse dependency %s" % value
|
raise RuntimeError(u"Can't parse dependency %s" % value)
|
||||||
match = match.groups()
|
match = match.groups()
|
||||||
self.name = match[0]
|
self.name = match[0]
|
||||||
if match[1] is not None:
|
if match[1] is not None:
|
||||||
|
@ -292,16 +376,17 @@ class PackageRelationEntry(object):
|
||||||
else:
|
else:
|
||||||
self.arches = []
|
self.arches = []
|
||||||
|
|
||||||
|
|
||||||
class Package(dict):
|
class Package(dict):
|
||||||
_fields = utils.SortedDict((
|
_fields = collections.OrderedDict((
|
||||||
('Package', str),
|
('Package', unicode),
|
||||||
('Source', str),
|
('Source', unicode),
|
||||||
('Architecture', PackageFieldList),
|
('Architecture', PackageArchitecture),
|
||||||
('Section', str),
|
('Section', unicode),
|
||||||
('Priority', str),
|
('Priority', unicode),
|
||||||
('Maintainer', str),
|
('Maintainer', unicode),
|
||||||
('Uploaders', str),
|
('Uploaders', unicode),
|
||||||
('Standards-Version', str),
|
('Standards-Version', unicode),
|
||||||
('Build-Depends', PackageRelation),
|
('Build-Depends', PackageRelation),
|
||||||
('Build-Depends-Indep', PackageRelation),
|
('Build-Depends-Indep', PackageRelation),
|
||||||
('Provides', PackageRelation),
|
('Provides', PackageRelation),
|
||||||
|
@ -310,6 +395,7 @@ class Package(dict):
|
||||||
('Recommends', PackageRelation),
|
('Recommends', PackageRelation),
|
||||||
('Suggests', PackageRelation),
|
('Suggests', PackageRelation),
|
||||||
('Replaces', PackageRelation),
|
('Replaces', PackageRelation),
|
||||||
|
('Breaks', PackageRelation),
|
||||||
('Conflicts', PackageRelation),
|
('Conflicts', PackageRelation),
|
||||||
('Description', PackageDescription),
|
('Description', PackageDescription),
|
||||||
))
|
))
|
||||||
|
@ -319,13 +405,14 @@ class Package(dict):
|
||||||
cls = self._fields[key]
|
cls = self._fields[key]
|
||||||
if not isinstance(value, cls):
|
if not isinstance(value, cls):
|
||||||
value = cls(value)
|
value = cls(value)
|
||||||
except KeyError: pass
|
except KeyError:
|
||||||
|
pass
|
||||||
super(Package, self).__setitem__(key, value)
|
super(Package, self).__setitem__(key, value)
|
||||||
|
|
||||||
def iterkeys(self):
|
def iterkeys(self):
|
||||||
keys = set(self.keys())
|
keys = set(self.keys())
|
||||||
for i in self._fields.iterkeys():
|
for i in self._fields.iterkeys():
|
||||||
if self.has_key(i):
|
if i in self:
|
||||||
keys.remove(i)
|
keys.remove(i)
|
||||||
yield i
|
yield i
|
||||||
for i in keys:
|
for i in keys:
|
||||||
|
@ -338,4 +425,3 @@ class Package(dict):
|
||||||
def itervalues(self):
|
def itervalues(self):
|
||||||
for i in self.iterkeys():
|
for i in self.iterkeys():
|
||||||
yield self[i]
|
yield self[i]
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
from config import *
|
import codecs
|
||||||
from debian import *
|
from collections import OrderedDict
|
||||||
from utils import *
|
|
||||||
|
|
||||||
class PackagesList(SortedDict):
|
from .debian import *
|
||||||
|
|
||||||
|
|
||||||
|
class PackagesList(OrderedDict):
|
||||||
def append(self, package):
|
def append(self, package):
|
||||||
self[package['Package']] = package
|
self[package['Package']] = package
|
||||||
|
|
||||||
|
@ -10,16 +12,21 @@ class PackagesList(SortedDict):
|
||||||
for package in packages:
|
for package in packages:
|
||||||
self[package['Package']] = package
|
self[package['Package']] = package
|
||||||
|
|
||||||
|
|
||||||
class Makefile(object):
|
class Makefile(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.rules = {}
|
self.rules = {}
|
||||||
self.add('.NOTPARALLEL')
|
self.add('.NOTPARALLEL')
|
||||||
|
|
||||||
def add(self, name, deps = None, cmds = None):
|
def add(self, name, deps=None, cmds=None):
|
||||||
if name in self.rules:
|
if name in self.rules:
|
||||||
self.rules[name].add(deps, cmds)
|
self.rules[name].add(deps, cmds)
|
||||||
else:
|
else:
|
||||||
self.rules[name] = self.Rule(name, deps, cmds)
|
self.rules[name] = self.Rule(name, deps, cmds)
|
||||||
|
if deps is not None:
|
||||||
|
for i in deps:
|
||||||
|
if i not in self.rules:
|
||||||
|
self.rules[i] = self.Rule(i)
|
||||||
|
|
||||||
def write(self, out):
|
def write(self, out):
|
||||||
r = self.rules.keys()
|
r = self.rules.keys()
|
||||||
|
@ -28,12 +35,12 @@ class Makefile(object):
|
||||||
self.rules[i].write(out)
|
self.rules[i].write(out)
|
||||||
|
|
||||||
class Rule(object):
|
class Rule(object):
|
||||||
def __init__(self, name, deps = None, cmds = None):
|
def __init__(self, name, deps=None, cmds=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.deps, self.cmds = set(), []
|
self.deps, self.cmds = set(), []
|
||||||
self.add(deps, cmds)
|
self.add(deps, cmds)
|
||||||
|
|
||||||
def add(self, deps = None, cmds = None):
|
def add(self, deps=None, cmds=None):
|
||||||
if deps is not None:
|
if deps is not None:
|
||||||
self.deps.update(deps)
|
self.deps.update(deps)
|
||||||
if cmds is not None:
|
if cmds is not None:
|
||||||
|
@ -56,22 +63,25 @@ class Makefile(object):
|
||||||
else:
|
else:
|
||||||
out.write('%s:%s\n' % (self.name, deps_string))
|
out.write('%s:%s\n' % (self.name, deps_string))
|
||||||
|
|
||||||
|
|
||||||
class MakeFlags(dict):
|
class MakeFlags(dict):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
repr = super(flags, self).__repr__()
|
repr = super(flags, self).__repr__()
|
||||||
return "%s(%s)" % (self.__class__.__name__, repr)
|
return "%s(%s)" % (self.__class__.__name__, repr)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return ' '.join(["%s='%s'" % i for i in self.iteritems()])
|
return ' '.join(["%s='%s'" % i for i in sorted(self.iteritems())])
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
return self.__class__(super(MakeFlags, self).copy())
|
return self.__class__(super(MakeFlags, self).copy())
|
||||||
|
|
||||||
class Gencontrol(object):
|
|
||||||
makefile_targets = ('binary-arch', 'build', 'setup', 'source')
|
|
||||||
|
|
||||||
def __init__(self, config, templates):
|
class Gencontrol(object):
|
||||||
|
makefile_targets = ('binary-arch', 'build-arch', 'setup')
|
||||||
|
|
||||||
|
def __init__(self, config, templates, version=Version):
|
||||||
self.config, self.templates = config, templates
|
self.config, self.templates = config, templates
|
||||||
|
self.changelog = Changelog(version=version)
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
packages = PackagesList()
|
packages = PackagesList()
|
||||||
|
@ -81,45 +91,42 @@ class Gencontrol(object):
|
||||||
self.do_main(packages, makefile)
|
self.do_main(packages, makefile)
|
||||||
self.do_extra(packages, makefile)
|
self.do_extra(packages, makefile)
|
||||||
|
|
||||||
self.write_control(packages.itervalues())
|
self.write(packages, makefile)
|
||||||
self.write_makefile(makefile)
|
|
||||||
|
|
||||||
def do_source(self, packages):
|
def do_source(self, packages):
|
||||||
source = self.templates["control.source"]
|
source = self.templates["control.source"][0]
|
||||||
packages['source'] = self.process_package(source[0], self.vars)
|
source['Source'] = self.changelog[0].source
|
||||||
|
packages['source'] = self.process_package(source)
|
||||||
|
|
||||||
def do_main(self, packages, makefile):
|
def do_main(self, packages, makefile):
|
||||||
config_entry = self.config['base',]
|
config_entry = self.config['base', ]
|
||||||
vars = self.vars.copy()
|
vars = self.vars.copy()
|
||||||
vars.update(config_entry)
|
|
||||||
|
|
||||||
makeflags = MakeFlags()
|
makeflags = MakeFlags()
|
||||||
extra = {}
|
extra = {}
|
||||||
|
|
||||||
self.do_main_setup(vars, makeflags, extra)
|
self.do_main_setup(vars, makeflags, extra)
|
||||||
self.do_main_packages(packages, extra)
|
|
||||||
self.do_main_makefile(makefile, makeflags, extra)
|
self.do_main_makefile(makefile, makeflags, extra)
|
||||||
|
self.do_main_packages(packages, vars, makeflags, extra)
|
||||||
for arch in iter(self.config['base',]['arches']):
|
self.do_main_recurse(packages, makefile, vars, makeflags, extra)
|
||||||
self.do_arch(packages, makefile, arch, vars.copy(), makeflags.copy(), extra)
|
|
||||||
|
|
||||||
def do_main_setup(self, vars, makeflags, extra):
|
def do_main_setup(self, vars, makeflags, extra):
|
||||||
makeflags.update({
|
|
||||||
'VERSION': self.version.linux_version,
|
|
||||||
'UPSTREAMVERSION': self.version.linux_upstream,
|
|
||||||
'ABINAME': self.abiname,
|
|
||||||
})
|
|
||||||
|
|
||||||
def do_main_makefile(self, makefile, makeflags, extra):
|
|
||||||
makefile.add('binary-indep', cmds = ["$(MAKE) -f debian/rules.real binary-indep %s" % makeflags])
|
|
||||||
|
|
||||||
def do_main_packages(self, packages, extra):
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def do_main_makefile(self, makefile, makeflags, extra):
|
||||||
|
makefile.add('build-indep', cmds=["$(MAKE) -f debian/rules.real build-indep %s" % makeflags])
|
||||||
|
makefile.add('binary-indep', cmds=["$(MAKE) -f debian/rules.real binary-indep %s" % makeflags])
|
||||||
|
|
||||||
|
def do_main_packages(self, packages, vars, makeflags, extra):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def do_main_recurse(self, packages, makefile, vars, makeflags, extra):
|
||||||
|
for arch in iter(self.config['base', ]['arches']):
|
||||||
|
self.do_arch(packages, makefile, arch, vars.copy(), makeflags.copy(), extra)
|
||||||
|
|
||||||
def do_extra(self, packages, makefile):
|
def do_extra(self, packages, makefile):
|
||||||
try:
|
templates_extra = self.templates.get("control.extra", None)
|
||||||
templates_extra = self.templates["control.extra"]
|
if templates_extra is None:
|
||||||
except IOError:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
packages.extend(self.process_packages(templates_extra, {}))
|
packages.extend(self.process_packages(templates_extra, {}))
|
||||||
|
@ -136,19 +143,15 @@ class Gencontrol(object):
|
||||||
cmds = []
|
cmds = []
|
||||||
for i in extra_arches[arch]:
|
for i in extra_arches[arch]:
|
||||||
tmp = []
|
tmp = []
|
||||||
if i.has_key('X-Version-Overwrite-Epoch'):
|
if 'X-Version-Overwrite-Epoch' in i:
|
||||||
tmp.append("-v1:%s" % self.version['source'])
|
tmp.append("-v1:%s" % self.version['source'])
|
||||||
cmds.append("$(MAKE) -f debian/rules.real install-dummy DH_OPTIONS='-p%s' GENCONTROL_ARGS='%s'" % (i['Package'], ' '.join(tmp)))
|
cmds.append("$(MAKE) -f debian/rules.real install-dummy DH_OPTIONS='-p%s' GENCONTROL_ARGS='%s'" % (i['Package'], ' '.join(tmp)))
|
||||||
makefile.add('binary-arch_%s' % arch ['binary-arch_%s_extra' % arch])
|
makefile.add('binary-arch_%s' % arch['binary-arch_%s_extra' % arch])
|
||||||
makefile.add("binary-arch_%s_extra" % arch, cmds = cmds)
|
makefile.add("binary-arch_%s_extra" % arch, cmds=cmds)
|
||||||
|
|
||||||
def do_arch(self, packages, makefile, arch, vars, makeflags, extra):
|
def do_arch(self, packages, makefile, arch, vars, makeflags, extra):
|
||||||
config_base = self.config['base', arch]
|
|
||||||
vars.update(config_base)
|
|
||||||
vars['arch'] = arch
|
vars['arch'] = arch
|
||||||
|
|
||||||
makeflags['ARCH'] = arch
|
|
||||||
|
|
||||||
self.do_arch_setup(vars, makeflags, arch, extra)
|
self.do_arch_setup(vars, makeflags, arch, extra)
|
||||||
self.do_arch_makefile(makefile, arch, makeflags, extra)
|
self.do_arch_makefile(makefile, arch, makeflags, extra)
|
||||||
self.do_arch_packages(packages, makefile, arch, vars, makeflags, extra)
|
self.do_arch_packages(packages, makefile, arch, vars, makeflags, extra)
|
||||||
|
@ -158,29 +161,27 @@ class Gencontrol(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def do_arch_makefile(self, makefile, arch, makeflags, extra):
|
def do_arch_makefile(self, makefile, arch, makeflags, extra):
|
||||||
|
makeflags['ARCH'] = arch
|
||||||
|
|
||||||
for i in self.makefile_targets:
|
for i in self.makefile_targets:
|
||||||
target1 = i
|
target1 = i
|
||||||
target2 = "%s_%s" % (i, arch)
|
target2 = '_'.join((target1, arch))
|
||||||
|
target3 = '_'.join((target2, 'real'))
|
||||||
makefile.add(target1, [target2])
|
makefile.add(target1, [target2])
|
||||||
makefile.add(target2, ['%s_real' % target2])
|
makefile.add(target2, [target3])
|
||||||
makefile.add('%s_real' % target2)
|
|
||||||
|
|
||||||
def do_arch_packages(self, packages, makefile, arch, vars, makeflags, extra):
|
def do_arch_packages(self, packages, makefile, arch, vars, makeflags, extra):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def do_arch_recurse(self, packages, makefile, arch, vars, makeflags, extra):
|
def do_arch_recurse(self, packages, makefile, arch, vars, makeflags, extra):
|
||||||
for featureset in self.config['base', arch]['featuresets']:
|
for featureset in self.config['base', arch].get('featuresets', ()):
|
||||||
self.do_featureset(packages, makefile, arch, featureset, vars.copy(), makeflags.copy(), extra)
|
self.do_featureset(packages, makefile, arch, featureset, vars.copy(), makeflags.copy(), extra)
|
||||||
|
|
||||||
def do_featureset(self, packages, makefile, arch, featureset, vars, makeflags, extra):
|
def do_featureset(self, packages, makefile, arch, featureset, vars, makeflags, extra):
|
||||||
config_base = self.config.merge('base', arch, featureset)
|
config_base = self.config.merge('base', arch, featureset)
|
||||||
vars.update(config_base)
|
|
||||||
|
|
||||||
if not config_base.get('enabled', True):
|
if not config_base.get('enabled', True):
|
||||||
return
|
return
|
||||||
|
|
||||||
makeflags['FEATURESET'] = featureset
|
|
||||||
|
|
||||||
vars['localversion'] = ''
|
vars['localversion'] = ''
|
||||||
if featureset != 'none':
|
if featureset != 'none':
|
||||||
vars['localversion'] = '-' + featureset
|
vars['localversion'] = '-' + featureset
|
||||||
|
@ -194,12 +195,14 @@ class Gencontrol(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def do_featureset_makefile(self, makefile, arch, featureset, makeflags, extra):
|
def do_featureset_makefile(self, makefile, arch, featureset, makeflags, extra):
|
||||||
|
makeflags['FEATURESET'] = featureset
|
||||||
|
|
||||||
for i in self.makefile_targets:
|
for i in self.makefile_targets:
|
||||||
target1 = "%s_%s" % (i, arch)
|
target1 = '_'.join((i, arch))
|
||||||
target2 = "%s_%s_%s" % (i, arch, featureset)
|
target2 = '_'.join((target1, featureset))
|
||||||
|
target3 = '_'.join((target2, 'real'))
|
||||||
makefile.add(target1, [target2])
|
makefile.add(target1, [target2])
|
||||||
makefile.add(target2, ['%s_real' % target2])
|
makefile.add(target2, [target3])
|
||||||
makefile.add('%s_real' % target2)
|
|
||||||
|
|
||||||
def do_featureset_packages(self, packages, makefile, arch, featureset, vars, makeflags, extra):
|
def do_featureset_packages(self, packages, makefile, arch, featureset, vars, makeflags, extra):
|
||||||
pass
|
pass
|
||||||
|
@ -210,12 +213,7 @@ class Gencontrol(object):
|
||||||
|
|
||||||
def do_flavour(self, packages, makefile, arch, featureset, flavour, vars, makeflags, extra):
|
def do_flavour(self, packages, makefile, arch, featureset, flavour, vars, makeflags, extra):
|
||||||
config_base = self.config.merge('base', arch, featureset, flavour)
|
config_base = self.config.merge('base', arch, featureset, flavour)
|
||||||
vars.update(config_base)
|
|
||||||
|
|
||||||
if not vars.has_key('longclass'):
|
|
||||||
vars['longclass'] = vars['class']
|
|
||||||
|
|
||||||
makeflags['FLAVOUR'] = flavour
|
|
||||||
vars['localversion'] += '-' + flavour
|
vars['localversion'] += '-' + flavour
|
||||||
|
|
||||||
self.do_flavour_setup(vars, makeflags, arch, featureset, flavour, extra)
|
self.do_flavour_setup(vars, makeflags, arch, featureset, flavour, extra)
|
||||||
|
@ -227,74 +225,74 @@ class Gencontrol(object):
|
||||||
('kernel-arch', 'KERNEL_ARCH'),
|
('kernel-arch', 'KERNEL_ARCH'),
|
||||||
('localversion', 'LOCALVERSION'),
|
('localversion', 'LOCALVERSION'),
|
||||||
):
|
):
|
||||||
if vars.has_key(i[0]):
|
if i[0] in vars:
|
||||||
makeflags[i[1]] = vars[i[0]]
|
makeflags[i[1]] = vars[i[0]]
|
||||||
|
|
||||||
def do_flavour_makefile(self, makefile, arch, featureset, flavour, makeflags, extra):
|
def do_flavour_makefile(self, makefile, arch, featureset, flavour, makeflags, extra):
|
||||||
|
makeflags['FLAVOUR'] = flavour
|
||||||
|
|
||||||
for i in self.makefile_targets:
|
for i in self.makefile_targets:
|
||||||
target1 = "%s_%s_%s" % (i, arch, featureset)
|
target1 = '_'.join((i, arch, featureset))
|
||||||
target2 = "%s_%s_%s_%s" % (i, arch, featureset, flavour)
|
target2 = '_'.join((target1, flavour))
|
||||||
|
target3 = '_'.join((target2, 'real'))
|
||||||
makefile.add(target1, [target2])
|
makefile.add(target1, [target2])
|
||||||
makefile.add(target2, ['%s_real' % target2])
|
makefile.add(target2, [target3])
|
||||||
makefile.add('%s_real' % target2)
|
|
||||||
|
|
||||||
def do_flavour_packages(self, packages, makefile, arch, featureset, flavour, vars, makeflags, extra):
|
def do_flavour_packages(self, packages, makefile, arch, featureset, flavour, vars, makeflags, extra):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def process_relation(self, key, e, in_e, vars):
|
def process_relation(self, dep, vars):
|
||||||
import copy
|
import copy
|
||||||
dep = copy.deepcopy(in_e[key])
|
dep = copy.deepcopy(dep)
|
||||||
for groups in dep:
|
for groups in dep:
|
||||||
for item in groups:
|
for item in groups:
|
||||||
item.name = self.substitute(item.name, vars)
|
item.name = self.substitute(item.name, vars)
|
||||||
e[key] = dep
|
if item.version:
|
||||||
|
item.version = self.substitute(item.version, vars)
|
||||||
|
return dep
|
||||||
|
|
||||||
def process_description(self, e, in_e, vars):
|
def process_description(self, in_desc, vars):
|
||||||
in_desc = in_e['Description']
|
|
||||||
desc = in_desc.__class__()
|
desc = in_desc.__class__()
|
||||||
desc.short = self.substitute(in_desc.short, vars)
|
desc.short = self.substitute(in_desc.short, vars)
|
||||||
for i in in_desc.long:
|
for i in in_desc.long:
|
||||||
desc.append(self.substitute(i, vars))
|
desc.append(self.substitute(i, vars))
|
||||||
e['Description'] = desc
|
return desc
|
||||||
|
|
||||||
def process_package(self, in_entry, vars):
|
def process_package(self, in_entry, vars={}):
|
||||||
e = Package()
|
entry = in_entry.__class__()
|
||||||
for key, value in in_entry.iteritems():
|
for key, value in in_entry.iteritems():
|
||||||
if isinstance(value, PackageRelation):
|
if isinstance(value, PackageRelation):
|
||||||
self.process_relation(key, e, in_entry, vars)
|
value = self.process_relation(value, vars)
|
||||||
elif key == 'Description':
|
elif isinstance(value, PackageDescription):
|
||||||
self.process_description(e, in_entry, vars)
|
value = self.process_description(value, vars)
|
||||||
elif key[:2] == 'X-':
|
|
||||||
pass
|
|
||||||
else:
|
else:
|
||||||
e[key] = self.substitute(value, vars)
|
value = self.substitute(value, vars)
|
||||||
return e
|
entry[key] = value
|
||||||
|
return entry
|
||||||
|
|
||||||
def process_packages(self, in_entries, vars):
|
def process_packages(self, entries, vars):
|
||||||
entries = []
|
return [self.process_package(i, vars) for i in entries]
|
||||||
for i in in_entries:
|
|
||||||
entries.append(self.process_package(i, vars))
|
|
||||||
return entries
|
|
||||||
|
|
||||||
def process_version_linux(self, version, abiname):
|
|
||||||
return {
|
|
||||||
'upstreamversion': version.linux_upstream,
|
|
||||||
'version': version.linux_version,
|
|
||||||
'source_upstream': version.upstream,
|
|
||||||
'abiname': abiname,
|
|
||||||
}
|
|
||||||
|
|
||||||
def substitute(self, s, vars):
|
def substitute(self, s, vars):
|
||||||
if isinstance(s, (list, tuple)):
|
if isinstance(s, (list, tuple)):
|
||||||
for i in xrange(len(s)):
|
return [self.substitute(i, vars) for i in s]
|
||||||
s[i] = self.substitute(s[i], vars)
|
|
||||||
return s
|
|
||||||
def subst(match):
|
def subst(match):
|
||||||
return vars[match.group(1)]
|
return vars[match.group(1)]
|
||||||
return re.sub(r'@([-_a-z]+)@', subst, s)
|
|
||||||
|
return re.sub(r'@([-_a-z]+)@', subst, unicode(s))
|
||||||
|
|
||||||
|
def write(self, packages, makefile):
|
||||||
|
self.write_control(packages.itervalues())
|
||||||
|
self.write_makefile(makefile)
|
||||||
|
|
||||||
|
def write_config(self):
|
||||||
|
f = file("debian/config.dump", 'w')
|
||||||
|
self.config.write(f)
|
||||||
|
f.close()
|
||||||
|
|
||||||
def write_control(self, list):
|
def write_control(self, list):
|
||||||
self.write_rfc822(file("debian/control", 'w'), list)
|
self.write_rfc822(codecs.open("debian/control", 'w', 'utf-8'), list)
|
||||||
|
|
||||||
def write_makefile(self, makefile):
|
def write_makefile(self, makefile):
|
||||||
f = file("debian/rules.gen", 'w')
|
f = file("debian/rules.gen", 'w')
|
||||||
|
@ -304,7 +302,5 @@ class Gencontrol(object):
|
||||||
def write_rfc822(self, f, list):
|
def write_rfc822(self, f, list):
|
||||||
for entry in list:
|
for entry in list:
|
||||||
for key, value in entry.iteritems():
|
for key, value in entry.iteritems():
|
||||||
f.write("%s: %s\n" % (key, value))
|
f.write(u"%s: %s\n" % (key, value))
|
||||||
f.write('\n')
|
f.write(u'\n')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,50 +1,20 @@
|
||||||
import debian, re, os, textwrap
|
import codecs
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import textwrap
|
||||||
|
|
||||||
class SortedDict(dict):
|
|
||||||
__slots__ = '_list',
|
|
||||||
|
|
||||||
def __init__(self, entries = None):
|
class Templates(object):
|
||||||
super(SortedDict, self).__init__()
|
def __init__(self, dirs=["debian/templates"]):
|
||||||
self._list = []
|
|
||||||
if entries is not None:
|
|
||||||
for key, value in entries:
|
|
||||||
self[key] = value
|
|
||||||
|
|
||||||
def __delitem__(self, key):
|
|
||||||
super(SortedDict, self).__delitem__(key)
|
|
||||||
self._list.remove(key)
|
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
|
||||||
super(SortedDict, self).__setitem__(key, value)
|
|
||||||
if key not in self._list:
|
|
||||||
self._list.append(key)
|
|
||||||
|
|
||||||
def iterkeys(self):
|
|
||||||
for i in iter(self._list):
|
|
||||||
yield i
|
|
||||||
|
|
||||||
def iteritems(self):
|
|
||||||
for i in iter(self._list):
|
|
||||||
yield (i, self[i])
|
|
||||||
|
|
||||||
def itervalues(self):
|
|
||||||
for i in iter(self._list):
|
|
||||||
yield self[i]
|
|
||||||
|
|
||||||
class Templates(dict):
|
|
||||||
def __init__(self, dirs = ["debian/templates"]):
|
|
||||||
self.dirs = dirs
|
self.dirs = dirs
|
||||||
|
|
||||||
def __getitem__(self, key):
|
self._cache = {}
|
||||||
try:
|
|
||||||
return super(Templates, self).__getitem__(key)
|
|
||||||
except KeyError: pass
|
|
||||||
value = self._read(key)
|
|
||||||
super(Templates, self).__setitem__(key, value)
|
|
||||||
return value
|
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __getitem__(self, key):
|
||||||
raise NotImplemented()
|
ret = self.get(key)
|
||||||
|
if ret is not None:
|
||||||
|
return ret
|
||||||
|
raise KeyError(key)
|
||||||
|
|
||||||
def _read(self, name):
|
def _read(self, name):
|
||||||
prefix, id = name.split('.', 1)
|
prefix, id = name.split('.', 1)
|
||||||
|
@ -52,49 +22,60 @@ class Templates(dict):
|
||||||
for dir in self.dirs:
|
for dir in self.dirs:
|
||||||
filename = "%s/%s.in" % (dir, name)
|
filename = "%s/%s.in" % (dir, name)
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
f = file(filename)
|
f = codecs.open(filename, 'r', 'utf-8')
|
||||||
if prefix == 'control':
|
if prefix == 'control':
|
||||||
return self._read_control(f)
|
return read_control(f)
|
||||||
return f.read()
|
return f.read()
|
||||||
raise KeyError(name)
|
|
||||||
|
|
||||||
def _read_control(self, f):
|
def get(self, key, default=None):
|
||||||
entries = []
|
if key in self._cache:
|
||||||
|
return self._cache[key]
|
||||||
|
|
||||||
|
value = self._cache.setdefault(key, self._read(key))
|
||||||
|
if value is None:
|
||||||
|
return default
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def read_control(f):
|
||||||
|
from .debian import Package
|
||||||
|
|
||||||
|
entries = []
|
||||||
|
eof = False
|
||||||
|
|
||||||
|
while not eof:
|
||||||
|
e = Package()
|
||||||
|
last = None
|
||||||
|
lines = []
|
||||||
while True:
|
while True:
|
||||||
e = debian.Package()
|
line = f.readline()
|
||||||
last = None
|
if not line:
|
||||||
lines = []
|
eof = True
|
||||||
while True:
|
|
||||||
line = f.readline()
|
|
||||||
if not line:
|
|
||||||
break
|
|
||||||
line = line.strip('\n')
|
|
||||||
if not line:
|
|
||||||
break
|
|
||||||
if line[0] in ' \t':
|
|
||||||
if not last:
|
|
||||||
raise ValueError('Continuation line seen before first header')
|
|
||||||
lines.append(line.lstrip())
|
|
||||||
continue
|
|
||||||
if last:
|
|
||||||
e[last] = '\n'.join(lines)
|
|
||||||
i = line.find(':')
|
|
||||||
if i < 0:
|
|
||||||
raise ValueError("Not a header, not a continuation: ``%s''" % line)
|
|
||||||
last = line[:i]
|
|
||||||
lines = [line[i+1:].lstrip()]
|
|
||||||
if last:
|
|
||||||
e[last] = '\n'.join(lines)
|
|
||||||
if not e:
|
|
||||||
break
|
break
|
||||||
|
line = line.strip('\n')
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
if line[0] in ' \t':
|
||||||
|
if not last:
|
||||||
|
raise ValueError(u'Continuation line seen before first header')
|
||||||
|
lines.append(line.lstrip())
|
||||||
|
continue
|
||||||
|
if last:
|
||||||
|
e[last] = u'\n'.join(lines)
|
||||||
|
i = line.find(':')
|
||||||
|
if i < 0:
|
||||||
|
raise ValueError(u"Not a header, not a continuation: ``%s''" % line)
|
||||||
|
last = line[:i]
|
||||||
|
lines = [line[i + 1:].lstrip()]
|
||||||
|
if last:
|
||||||
|
e[last] = '\n'.join(lines)
|
||||||
|
if e:
|
||||||
entries.append(e)
|
entries.append(e)
|
||||||
|
|
||||||
return entries
|
return entries
|
||||||
|
|
||||||
|
|
||||||
class TextWrapper(textwrap.TextWrapper):
|
class TextWrapper(textwrap.TextWrapper):
|
||||||
wordsep_re = re.compile(
|
wordsep_re = re.compile(
|
||||||
r'(\s+|' # any whitespace
|
r'(\s+|' # any whitespace
|
||||||
r'(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))') # em-dash
|
r'(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))') # em-dash
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue