653391077f0fb56f2f1a5737c8566789d37d9bb9
1 import sys
2 import os
3 import errno
4 from glob import glob
5 import tarfile
7 class Diffstat:
8 def __init__(self, patch):
9 self.patch = patch
10 i,o = os.popen2("diffstat -p1")
11 i.write(str(patch))
12 i.close()
13 self.output = o.readlines()
15 def stats(self):
16 i,o = os.popen2("diffstat -p1 -t")
17 i.write(str(self.patch))
18 i.close()
19 o.readline()
20 return [map(lambda x: x.strip(), l.split(",")) for l in o.readlines()]
22 def summary(self):
23 return self.output[-1]
25 def __str__(self):
26 return "".join(self.output)
28 class Patch:
29 def __init__(self, fh, level=1):
30 self.p = fh.readlines()
31 self.lvl = level
33 def __str__(self):
34 return "".join(self.p)
36 def lines(self):
37 return len(self.p)
39 def diffstat(self):
40 return Diffstat(self)
42 class GenericPatchSeries (list):
43 def blank(self):
44 self.names = []
45 self.style = "unknown"
46 self.patches = {}
47 self.patchargs = {}
49 # WTF am i doing this for, again?
50 def iterpatches(self):
51 for p in self.names:
52 yield (p, self.patches[p])
54 def __iter__(self):
55 return self.iterpatches()
57 def __getitem__(self, y):
58 return self.patches[self.names[y]]
60 def __len__(self):
61 return len(self.names)
63 def fetch(self, name):
64 return self.patches[name]
66 def __str__(self):
67 return "\n".join(self.names)
69 # XXX this entire __init__ stuff is way to ugly
70 class PatchSeries (GenericPatchSeries):
71 def __init__(self, dir):
72 fd = None
73 self.blank()
74 self.style = "simple"
75 try:
76 fd = file(os.sep.join([dir, "00list"]))
77 self.style = "dpatch"
78 except IOError, e:
79 if e.errno != errno.ENOENT:
80 #print "ERROR: unable to open dpatch list..."
81 self.blank()
82 return
83 try:
84 fd = file(os.sep.join([dir, "series"]))
85 self.style = "quilt"
86 except IOError, e:
87 if e.errno != errno.ENOENT:
88 #print "ERROR: series file is a directory..."
89 self.blank()
90 return
92 if fd:
93 # remove blank lines
94 for line in filter(None, [n.strip() for n in fd.readlines()]):
95 stuff = line.split(' ')
96 # skip comments
97 if stuff[0][0] == "#":
98 continue
99 # here's the name
100 name = stuff[0]
101 #print "\t\t\t%s: %s"%(self.style,name)
102 self.names.append(name)
103 # anything else are either patch args or comments
104 self.patchargs[name] = []
105 for rest in filter(None, stuff[1:]):
106 if rest[0][0] == "#":
107 break
108 else:
109 self.patchargs[name].append(rest)
111 else:
112 self.names = os.listdir(dir)
113 self.names.sort()
114 for n in self.names:
115 self.patchargs[n] = []
117 # XXX this code is too ugly
118 removelater=[]
119 for p in self.names:
120 try:
121 self.patches[p] = Patch(file(os.sep.join([dir, p])))
122 except IOError, e:
123 if e.errno == errno.ENOENT and self.style == "dpatch":
124 try:
125 self.patches[p] = Patch(file(os.sep.join([dir, p+".dpatch"])))
126 except:
127 #print "ERROR: could not find patch",p
128 self.blank()
129 return
130 elif e.errno == errno.EISDIR:
131 #print "WARNING: directory %s in patch dir, patch list incomplete"%(p)
132 removelater.append(p)
133 else:
134 #print "ERROR: could not find patch",p
135 self.blank()
136 return
137 for p in removelater:
138 self.names.remove(p)
140 class Quilt30PatchSeries (GenericPatchSeries):
141 def __init__(self, tarBall):
142 self.blank()
143 self.style = "quilt (3.0)"
144 self.tarfh = tarfile.open(tarBall, 'r:*')
145 try:
146 try:
147 series_fh = self.tarfh.extractfile("debian/patches/debian.series")
148 except KeyError:
149 series_fh = self.tarfh.extractfile("debian/patches/series")
150 except KeyError:
151 series_fh = None
153 if series_fh:
154 for line in filter(None, [fn.strip() for fn in series_fh.readlines()]):
155 stuff = line.split(' ')
156 # skip comments
157 if stuff[0][0] == "#":
158 continue
159 # here's the name
160 name = stuff[0]
161 self.names.append(name)
163 # XXX to lazy eval this might be better
164 for name in self.names:
165 self.patches[name] = Patch(self.tarfh.extractfile("debian/patches/"+name))
167 if __name__ == "__main__":
168 print "Patch.py testing"
169 try:
170 p = Patch(file(sys.argv[1]))
171 print "patch contents:"
172 print p
173 except IndexError:
174 print "usage: %s <patch>"
