upload tizen1.0 source
[kernel/linux-2.6.36.git] / debian / bin / patch.apply
1 #!/usr/bin/env python
2
3 import os, os.path, re, sys
4 from warnings import warn
5
6 sys.path.append("/usr/share/linux-support-2.6.36-trunk/lib/python")
7
8 from debian_linux.patches import PatchSeries, PatchSeriesList
9
10 _default_home = "/usr/src/kernel-patches/all/2.6.36/debian"
11 revisions = "orig base 1~experimental.1 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10 4.11".split()
12 upstream = "2.6.36"
13
14 class MatchExtra(object):
15     def __init__(self, arch, featureset):
16         self.arch, self.featureset = arch, featureset
17
18         self.matched_arch = self.matched_featureset = False
19
20     def __call__(self, obj):
21         if not self:
22             return False
23
24         data = obj.data
25
26         match_arch = []
27         match_featureset = []
28         for i in data:
29             if i.startswith("arch="):
30                 match_arch.append(i[5:])
31             elif i.startswith("featureset="):
32                 match_featureset.append(i[11:])
33             else:
34                 raise RuntimeError('Ignored unknown modifier: %s' % i)
35
36         ret_arch = ret_featureset = False
37
38         if match_arch:
39             if self.arch is not None:
40                 if self.arch in match_arch:
41                     self.matched_arch = True
42                     ret_arch = True
43
44         else:
45             ret_arch = True
46
47         if match_featureset:
48             if self.featureset is not None:
49                 if self.featureset in match_featureset:
50                     self.matched_featureset = True
51                     ret_featureset = True
52
53         else:
54             ret_featureset = True
55
56         return ret_arch and ret_featureset
57
58     def __nonzero__(self):
59         return self.arch is not None or self.featureset is not None
60
61     def info(self):
62         ret = []
63         if self.matched_arch:
64             ret.append("arch=%s" % self.arch)
65         if self.matched_featureset:
66             ret.append("featureset=%s" % self.featureset)
67         return ret
68
69 _marker = object()
70
71 class version_file(object):
72     _file = 'version.Debian'
73     extra = None
74     in_progress = False
75
76     def __init__(self, upstream = None):
77         if os.path.exists(self._file):
78             s = file(self._file).readline().strip()
79             self._read(s)
80         elif upstream:
81             warn('No %s file, assuming Debian Linux %s' % (self._file, upstream))
82             self.upstream = upstream
83             self.revision = 'orig'
84         else:
85             raise RuntimeError, "Not possible to determine version"
86
87     def __str__(self):
88         if self.in_progress:
89             return "unstable"
90         ret = [self.upstream, self.revision]
91         if self.extra is not None:
92             ret.extend(self.extra.info())
93         return ' '.join(ret)
94
95     def _read(self, s):
96         if s == 'unstable':
97             raise RuntimeError("Tree is in an unstable condition. Can't continue!")
98         list = s.split()
99         self.upstream, self.revision = list[0:2]
100
101         arch = featureset = None
102         for i in list[2:]:
103             if i.startswith("arch="):
104                 arch = i[5:]
105             elif i.startswith("featureset="):
106                 featureset = i[11:]
107             else:
108                 raise RuntimeError("Can't parse extra information")
109         self.extra = MatchExtra(arch, featureset)
110
111     def _write(self):
112         if os.path.lexists(self._file):
113             os.unlink(self._file)
114         file(self._file, 'w').write('%s\n' % self)
115
116     def begin(self):
117         self.in_progress = True
118         self._write()
119
120     def commit(self, revision, extra = _marker):
121         self.in_progress = False
122         self.revision = revision
123         if extra is not _marker:
124             self.extra = extra
125         self._write()
126
127 def main():
128     options, args = parse_options()
129
130     if len(args) > 1:
131         print "Too much arguments"
132         return
133
134     home = options.home
135
136     vfile = version_file(upstream)
137     current_revision = vfile.revision
138     current_extra = vfile.extra
139
140     if len(args) == 1:
141         target_revision = args[0]
142     else:
143         target_revision = revisions[-1]
144     target_extra = MatchExtra(options.arch, options.featureset)
145
146     if vfile.upstream != upstream:
147         raise RuntimeError("Upstream version differs between tree (%s) and package (%s)" % (vfile.upstream, upstream))
148     if current_revision not in revisions:
149         raise RuntimeError, "Current revision is not in our list of revisions"
150     if target_revision not in revisions:
151         raise RuntimeError, "Target revision is not in our list of revisions"
152
153     if current_revision == target_revision and current_extra == target_extra:
154         print "Nothing to do"
155         return
156
157     current_index = revisions.index(current_revision)
158     target_index = revisions.index(target_revision)
159
160     if current_extra:
161         if current_revision != revisions[-1]:
162             raise RuntimeError, "Can't patch from %s with options %s" % (current, ' '.join(current_extra))
163         consider = ['%s-extra' % i for i in revisions[1:current_index + 1]]
164         s = PatchSeriesList.read(home, consider)
165         vfile.begin()
166         s(cond = current_extra, reverse = True)
167         vfile.commit(current_revision, None)
168
169     if current_index < target_index:
170         consider = revisions[current_index + 1:target_index + 1]
171         s = PatchSeriesList.read(home, consider)
172         vfile.begin()
173         s()
174         vfile.commit(target_revision)
175     elif current_index > target_index:
176         consider = revisions[target_index + 1:current_index + 1]
177         s = PatchSeriesList.read(home, consider)
178         vfile.begin()
179         s(reverse = True)
180         vfile.commit(target_revision)
181
182     if target_extra:
183         consider = ['%s-extra' % i for i in revisions[1:target_index + 1]]
184         s = PatchSeriesList.read(home, consider)
185         vfile.begin()
186         s(cond = target_extra)
187         vfile.commit(target_revision, target_extra)
188
189 def parse_options():
190     from optparse import OptionParser
191     parser = OptionParser(
192         usage = "%prog [OPTION]... [TARGET]",
193     )
194     parser.add_option(
195         '-a', '--arch',
196         dest = 'arch',
197         help = "arch",
198     )
199     parser.add_option(
200         '-f', '--featureset',
201         dest = 'featureset',
202         help = "featureset",
203     )
204     parser.add_option(
205         '-H', '--overwrite-home',
206         default = _default_home, dest = 'home',
207         help = "overwrite home [default: %default]",
208     )
209
210     options, args = parser.parse_args()
211
212     if options.arch is None and options.featureset is not None:
213         raise RuntimeError('You specified a featureset without an arch, this is not really working')
214
215     return options, args
216
217 if __name__ == '__main__':
218     def showwarning(message, category, filename, lineno):
219         sys.stderr.write("Warning: %s\n" % message)
220     import warnings
221     warnings.showwarning = showwarning
222     try:
223         main()
224     except RuntimeError, e:
225         sys.stderr.write("Error: %s\n" % e)
226         raise SystemExit, 1
227