35 |
35 |
36 |
36 |
37 class BadMakeEngineException(Exception): |
37 class BadMakeEngineException(Exception): |
38 pass |
38 pass |
39 |
39 |
|
40 def string_following(prefix, str): |
|
41 """If str starts with prefix then return the rest of str, otherwise None""" |
|
42 if str.startswith(prefix): |
|
43 return str[len(prefix):] |
|
44 else: |
|
45 return None |
|
46 |
40 def XMLEscapeLog(stream): |
47 def XMLEscapeLog(stream): |
|
48 """ A generator that reads a raptor log from a stream and performs an XML escape |
|
49 on all text between tags, which is usually make output that could contain |
|
50 illegal characters that upset XML-based log parsers. |
|
51 This function yields "xml-safe" output line by line. |
|
52 """ |
41 inRecipe = False |
53 inRecipe = False |
42 |
54 |
43 for line in stream: |
55 for line in stream: |
44 if line.startswith("<recipe"): |
56 if line.startswith("<recipe"): |
45 inRecipe = True |
57 inRecipe = True |
52 yield line |
64 yield line |
53 else: |
65 else: |
54 yield escape(line) |
66 yield escape(line) |
55 |
67 |
56 def AnnoFileParseOutput(annofile): |
68 def AnnoFileParseOutput(annofile): |
|
69 """ A generator that extracts log output from an emake annotation file, |
|
70 perform an XML-unescape on it and "yields" it line by line. """ |
57 af = open(annofile, "r") |
71 af = open(annofile, "r") |
58 |
72 |
59 inOutput = False |
73 inOutput = False |
60 inParseJob = False |
74 inParseJob = False |
|
75 |
|
76 buildid = "" |
61 for line in af: |
77 for line in af: |
62 line = line.rstrip("\n\r") |
78 line = line.rstrip("\n\r") |
63 |
79 |
|
80 |
64 if not inOutput: |
81 if not inOutput: |
65 if line.startswith("<output>"): |
82 o = string_following("<output>", line) |
|
83 if not o: |
|
84 o = string_following('<output src="prog">', line) |
|
85 |
|
86 if o: |
66 inOutput = True |
87 inOutput = True |
67 yield unescape(line[8:])+'\n' |
88 yield unescape(o)+'\n' |
68 # This is make output so don't unescape it. |
89 continue |
69 elif line.startswith('<output src="prog">'): |
90 |
70 line = line[19:] |
91 |
71 inOutput = True |
92 o = string_following('<build id="',line) |
72 yield unescape(line)+'\n' |
93 if o: |
|
94 buildid = o[:o.find('"')] |
|
95 yield "Starting build: "+buildid+"\n" |
|
96 continue |
|
97 |
|
98 o = string_following('<metric name="duration">', line) |
|
99 if o: |
|
100 secs = int(o[:o.find('<')]) |
|
101 if secs != 0: |
|
102 duration = "%d:%d" % (secs/60, secs % 60) |
|
103 else: |
|
104 duration = "0:0" |
|
105 continue |
|
106 |
|
107 |
|
108 o = string_following('<metric name="clusterAvailability">', line) |
|
109 if o: |
|
110 availability = o[:o.find('<')] |
|
111 continue |
|
112 |
73 else: |
113 else: |
74 end_output = line.find("</output>") |
114 end_output = line.find("</output>") |
75 |
115 |
76 if end_output != -1: |
116 if end_output != -1: |
77 line = line[:end_output] |
117 line = line[:end_output] |
78 inOutput = False |
118 inOutput = False |
79 |
119 |
80 yield unescape(line)+'\n' |
120 if line != "": |
81 |
121 yield unescape(line)+'\n' |
|
122 |
|
123 yield "Finished build: %s Duration: %s (m:s) Cluster availability: %s%%\n" %(buildid,duration,availability) |
82 af.close() |
124 af.close() |
83 |
125 |
84 |
126 |
85 |
127 |
86 # raptor_make module classes |
128 # raptor_make module classes |
138 self.copyLogFromAnnoFile = (evaluator.Get("copylogfromannofile") == "true") |
180 self.copyLogFromAnnoFile = (evaluator.Get("copylogfromannofile") == "true") |
139 self.annoFileName = None |
181 self.annoFileName = None |
140 |
182 |
141 if self.copyLogFromAnnoFile: |
183 if self.copyLogFromAnnoFile: |
142 for o in self.raptor.makeOptions: |
184 for o in self.raptor.makeOptions: |
143 if o.startswith("--emake-annofile="): |
185 self.annoFileName = string_following("--emake-annofile=", o) |
144 self.annoFileName = o[17:] |
186 if self.annoFileName: |
145 self.raptor.Info("annofile: " + o) |
187 self.raptor.Info("annofile: " + o) |
146 |
188 |
147 if not self.annoFileName: |
189 if not self.annoFileName: |
148 self.raptor.Info("Cannot copy log from annotation file as no annotation filename was specified via the option --mo=--emake-annofile=<filename>") |
190 self.raptor.Info("Cannot copy log from annotation file as no annotation filename was specified via the option --mo=--emake-annofile=<filename>") |
149 self.copyLogFromAnnoFile = False |
191 self.copyLogFromAnnoFile = False |