c6872528de
svn path=/dists/trunk/linux-2.6/; revision=14698
228 lines
6.7 KiB
Python
228 lines
6.7 KiB
Python
#!/usr/bin/env python
|
|
|
|
import os, os.path, re, sys
|
|
from warnings import warn
|
|
|
|
sys.path.append("/usr/share/linux-support-@linux_upstream@@abiname@/lib/python")
|
|
|
|
from debian_linux.patches import PatchSeries, PatchSeriesList
|
|
|
|
_default_home = "/usr/src/kernel-patches/all/@linux_upstream@/debian"
|
|
revisions = "@revisions@".split()
|
|
upstream = "@upstream@"
|
|
|
|
class MatchExtra(object):
|
|
def __init__(self, arch, featureset):
|
|
self.arch, self.featureset = arch, featureset
|
|
|
|
self.matched_arch = self.matched_featureset = False
|
|
|
|
def __call__(self, obj):
|
|
if not self:
|
|
return False
|
|
|
|
data = obj.data
|
|
|
|
match_arch = []
|
|
match_featureset = []
|
|
for i in data:
|
|
if i.startswith("arch="):
|
|
match_arch.append(i[5:])
|
|
elif i.startswith("featureset="):
|
|
match_featureset.append(i[11:])
|
|
else:
|
|
raise RuntimeError('Ignored unknown modifier: %s' % i)
|
|
|
|
ret_arch = ret_featureset = False
|
|
|
|
if match_arch:
|
|
if self.arch is not None:
|
|
if self.arch in match_arch:
|
|
self.matched_arch = True
|
|
ret_arch = True
|
|
|
|
else:
|
|
ret_arch = True
|
|
|
|
if match_featureset:
|
|
if self.featureset is not None:
|
|
if self.featureset in match_featureset:
|
|
self.matched_featureset = True
|
|
ret_featureset = True
|
|
|
|
else:
|
|
ret_featureset = True
|
|
|
|
return ret_arch and ret_featureset
|
|
|
|
def __nonzero__(self):
|
|
return self.arch is not None or self.featureset is not None
|
|
|
|
def info(self):
|
|
ret = []
|
|
if self.matched_arch:
|
|
ret.append("arch=%s" % self.arch)
|
|
if self.matched_featureset:
|
|
ret.append("featureset=%s" % self.featureset)
|
|
return ret
|
|
|
|
_marker = object()
|
|
|
|
class version_file(object):
|
|
_file = 'version.Debian'
|
|
extra = None
|
|
in_progress = False
|
|
|
|
def __init__(self, upstream = None):
|
|
if os.path.exists(self._file):
|
|
s = file(self._file).readline().strip()
|
|
self._read(s)
|
|
elif upstream:
|
|
warn('No %s file, assuming Debian Linux %s' % (self._file, upstream))
|
|
self.upstream = upstream
|
|
self.revision = 'orig'
|
|
else:
|
|
raise RuntimeError, "Not possible to determine version"
|
|
|
|
def __str__(self):
|
|
if self.in_progress:
|
|
return "unstable"
|
|
ret = [self.upstream, self.revision]
|
|
if self.extra is not None:
|
|
ret.extend(self.extra.info())
|
|
return ' '.join(ret)
|
|
|
|
def _read(self, s):
|
|
if s == 'unstable':
|
|
raise RuntimeError("Tree is in an unstable condition. Can't continue!")
|
|
list = s.split()
|
|
self.upstream, self.revision = list[0:2]
|
|
|
|
arch = featureset = None
|
|
for i in list[2:]:
|
|
if i.startswith("arch="):
|
|
arch = i[5:]
|
|
elif i.startswith("featureset="):
|
|
featureset = i[11:]
|
|
else:
|
|
raise RuntimeError("Can't parse extra information")
|
|
self.extra = MatchExtra(arch, featureset)
|
|
|
|
def _write(self):
|
|
if os.path.lexists(self._file):
|
|
os.unlink(self._file)
|
|
file(self._file, 'w').write('%s\n' % self)
|
|
|
|
def begin(self):
|
|
self.in_progress = True
|
|
self._write()
|
|
|
|
def commit(self, revision, extra = _marker):
|
|
self.in_progress = False
|
|
self.revision = revision
|
|
if extra is not _marker:
|
|
self.extra = extra
|
|
self._write()
|
|
|
|
def main():
|
|
options, args = parse_options()
|
|
|
|
if len(args) > 1:
|
|
print "Too much arguments"
|
|
return
|
|
|
|
home = options.home
|
|
|
|
vfile = version_file(upstream)
|
|
current_revision = vfile.revision
|
|
current_extra = vfile.extra
|
|
|
|
if len(args) == 1:
|
|
target_revision = args[0]
|
|
else:
|
|
target_revision = revisions[-1]
|
|
target_extra = MatchExtra(options.arch, options.featureset)
|
|
|
|
if vfile.upstream != upstream:
|
|
raise RuntimeError("Upstream version differs between tree (%s) and package (%s)" % (vfile.upstream, upstream))
|
|
if current_revision not in revisions:
|
|
raise RuntimeError, "Current revision is not in our list of revisions"
|
|
if target_revision not in revisions:
|
|
raise RuntimeError, "Target revision is not in our list of revisions"
|
|
|
|
if current_revision == target_revision and current_extra == target_extra:
|
|
print "Nothing to do"
|
|
return
|
|
|
|
current_index = revisions.index(current_revision)
|
|
target_index = revisions.index(target_revision)
|
|
|
|
if current_extra:
|
|
if current_revision != revisions[-1]:
|
|
raise RuntimeError, "Can't patch from %s with options %s" % (current, ' '.join(current_extra))
|
|
consider = ['%s-extra' % i for i in revisions[1:current_index + 1]]
|
|
s = PatchSeriesList.read(home, consider)
|
|
vfile.begin()
|
|
s(cond = current_extra, reverse = True)
|
|
vfile.commit(current_revision, None)
|
|
|
|
if current_index < target_index:
|
|
consider = revisions[current_index + 1:target_index + 1]
|
|
s = PatchSeriesList.read(home, consider)
|
|
vfile.begin()
|
|
s()
|
|
vfile.commit(target_revision)
|
|
elif current_index > target_index:
|
|
consider = revisions[target_index + 1:current_index + 1]
|
|
s = PatchSeriesList.read(home, consider)
|
|
vfile.begin()
|
|
s(reverse = True)
|
|
vfile.commit(target_revision)
|
|
|
|
if target_extra:
|
|
consider = ['%s-extra' % i for i in revisions[1:target_index + 1]]
|
|
s = PatchSeriesList.read(home, consider)
|
|
vfile.begin()
|
|
s(cond = target_extra)
|
|
vfile.commit(target_revision, target_extra)
|
|
|
|
def parse_options():
|
|
from optparse import OptionParser
|
|
parser = OptionParser(
|
|
usage = "%prog [OPTION]... [TARGET]",
|
|
)
|
|
parser.add_option(
|
|
'-a', '--arch',
|
|
dest = 'arch',
|
|
help = "arch",
|
|
)
|
|
parser.add_option(
|
|
'-f', '--featureset',
|
|
dest = 'featureset',
|
|
help = "featureset",
|
|
)
|
|
parser.add_option(
|
|
'-H', '--overwrite-home',
|
|
default = _default_home, dest = 'home',
|
|
help = "overwrite home [default: %default]",
|
|
)
|
|
|
|
options, args = parser.parse_args()
|
|
|
|
if options.arch is None and options.featureset is not None:
|
|
raise RuntimeError('You specified a featureset without an arch, this is not really working')
|
|
|
|
return options, args
|
|
|
|
if __name__ == '__main__':
|
|
def showwarning(message, category, filename, lineno):
|
|
sys.stderr.write("Warning: %s\n" % message)
|
|
import warnings
|
|
warnings.showwarning = showwarning
|
|
try:
|
|
main()
|
|
except RuntimeError, e:
|
|
sys.stderr.write("Error: %s\n" % e)
|
|
raise SystemExit, 1
|
|
|