linux/debian/templates/patch.apply.in

205 lines
5.9 KiB
Python

#!/usr/bin/env python
import os, os.path, re, sys
from warnings import warn
sys.path.append("/usr/share/linux-support-@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, featureset):
self.featureset = featureset
self.matched_featureset = False
def __call__(self, obj):
if not self:
return False
data = obj.data
match_featureset = []
for i in data:
if i.startswith("featureset="):
match_featureset.append(i[11:])
else:
raise RuntimeError('Ignored unknown modifier: %s' % i)
ret_featureset = False
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_featureset
def __nonzero__(self):
return self.featureset is not None
def info(self):
ret = []
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]
featureset = None
for i in list[2:]:
if i.startswith("featureset="):
featureset = i[11:]
else:
raise RuntimeError("Can't parse extra information")
self.extra = MatchExtra(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.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(
'-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()
return options, args
if __name__ == '__main__':
def showwarning(message, category, filename, lineno,
file=sys.stderr, line=''):
file.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