1 import glob, os, shutil
3 class Operation(object):
4 def __init__(self, name, data):
5 self.name, self.data = name, data
7 def __call__(self, dir = '.', reverse = False):
18 def _log(self, result):
23 print """ (%s) %-4s %s""" % (self.operation, s, self.name)
26 raise NotImplementedError
28 def do_reverse(self, dir):
29 raise NotImplementedError
31 class OperationPatch(Operation):
32 def __init__(self, name, fp, data):
33 super(OperationPatch, self).__init__(name, data)
36 def _call(self, dir, extraargs):
37 cmdline = "cd %s; patch -p1 -f -s -t --no-backup-if-mismatch %s" % (dir, extraargs)
38 f = os.popen(cmdline, 'wb')
39 shutil.copyfileobj(self.fp, f)
41 raise RuntimeError("Patch failed")
43 def patch_push(self, dir):
44 self._call(dir, '--fuzz=1')
46 def patch_pop(self, dir):
49 class OperationPatchPush(OperationPatch):
52 do = OperationPatch.patch_push
53 do_reverse = OperationPatch.patch_pop
55 class OperationPatchPop(OperationPatch):
58 do = OperationPatch.patch_pop
59 do_reverse = OperationPatch.patch_push
61 class SubOperation(Operation):
62 def _log(self, result):
67 print """ %-10s %-4s %s""" % ('(%s)' % self.operation, s, self.name)
69 class SubOperationFilesRemove(SubOperation):
73 name = os.path.join(dir, self.name)
74 for n in glob.iglob(name):
80 class SubOperationFilesUnifdef(SubOperation):
84 filename = os.path.join(dir, self.name)
85 cmdline = "unifdef %s %s" % (filename, ' '.join(self.data))
86 f = os.popen(cmdline, 'rb')
90 raise RuntimeError("unifdef of %s removed nothing" % self.name)
92 raise RuntimeError("unifdef failed")
93 f1 = file(filename, 'wb')
97 class OperationFiles(Operation):
101 'remove': SubOperationFilesRemove,
102 'rm': SubOperationFilesRemove,
103 'unifdef': SubOperationFilesUnifdef,
106 def __init__(self, name, fp, data):
107 super(OperationFiles, self).__init__(name, data)
113 if not line or line[0] == '#':
117 operation, filename = items[:2]
120 if operation not in self.suboperations:
121 raise RuntimeError('Undefined operation "%s" in series %s' % (operation, name))
123 ops.append(self.suboperations[operation](filename, data))
131 class PatchSeries(list):
133 '+': OperationPatchPush,
134 '-': OperationPatchPop,
138 def __init__(self, name, root, fp):
139 self.name, self.root = name, root
141 from gzip import GzipFile
142 from bz2 import BZ2File
147 if not len(line) or line[0] == '#':
150 items = line.split(' ')
151 operation, filename = items[:2]
154 if operation in self.operations:
155 f = os.path.join(self.root, filename)
156 for suffix, cls in (('', file), ('.bz2', BZ2File), ('.gz', GzipFile)):
158 if os.path.exists(f1):
162 raise RuntimeError("Can't find patch %s for series %s" % (filename, self.name))
164 raise RuntimeError('Undefined operation "%s" in series %s' % (operation, name))
166 self.append(self.operations[operation](filename, fp, data))
168 def __call__(self, cond = bool, dir = '.', reverse = False):
175 i(dir = dir, reverse = reverse)
178 return '<%s object for %s>' % (self.__class__.__name__, self.name)
180 class PatchSeriesList(list):
181 def __call__(self, cond = bool, reverse = False):
188 print "--> Try to unapply %s." % i.name
190 print "--> Try to apply %s." % i.name
191 i(cond = cond, reverse = reverse)
193 print "--> %s fully unapplied." % i.name
195 print "--> %s fully applied." % i.name
198 def read(cls, home, files):
202 fp = file(os.path.join(home, 'series', i))
203 ret.append(PatchSeries(i, home, fp))