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 |
|
75 buildid = "" |
61 for line in af: |
76 for line in af: |
62 line = line.rstrip("\n\r") |
77 line = line.rstrip("\n\r") |
63 |
78 |
|
79 |
64 if not inOutput: |
80 if not inOutput: |
65 if line.startswith("<output>"): |
81 o = string_following("<output>", line) |
|
82 if not o: |
|
83 o = string_following('<output src="prog">', line) |
|
84 |
|
85 if o: |
66 inOutput = True |
86 inOutput = True |
67 yield unescape(line[8:])+'\n' |
87 yield unescape(o)+'\n' |
68 # This is make output so don't unescape it. |
88 continue |
69 elif line.startswith('<output src="prog">'): |
89 |
70 line = line[19:] |
90 |
71 inOutput = True |
91 o = string_following('<build id="',line) |
72 yield unescape(line)+'\n' |
92 if o: |
|
93 buildid = o[:o.find('"')] |
|
94 yield "Starting build: "+buildid+"\n" |
|
95 continue |
|
96 |
|
97 o = string_following('<metric name="duration">', line) |
|
98 if o: |
|
99 secs = int(o[:o.find('<')]) |
|
100 if secs != 0: |
|
101 duration = "%d:%d" % (secs/60, secs % 60) |
|
102 else: |
|
103 duration = "0:0" |
|
104 continue |
|
105 |
|
106 |
|
107 o = string_following('<metric name="clusterAvailability">', line) |
|
108 if o: |
|
109 availability = o[:o.find('<')] |
|
110 continue |
|
111 |
73 else: |
112 else: |
74 end_output = line.find("</output>") |
113 end_output = line.find("</output>") |
75 |
114 |
76 if end_output != -1: |
115 if end_output != -1: |
77 line = line[:end_output] |
116 line = line[:end_output] |
78 inOutput = False |
117 inOutput = False |
79 |
118 |
80 yield unescape(line)+'\n' |
119 if line != "": |
81 |
120 yield unescape(line)+'\n' |
|
121 |
|
122 yield "Finished build: %s Duration: %s (m:s) Cluster availability: %s%%\n" %(buildid,duration,availability) |
82 af.close() |
123 af.close() |
83 |
124 |
84 |
125 |
85 |
126 |
86 # raptor_make module classes |
127 # raptor_make module classes |
144 self.copyLogFromAnnoFile = (evaluator.Get("copylogfromannofile") == "true") |
185 self.copyLogFromAnnoFile = (evaluator.Get("copylogfromannofile") == "true") |
145 self.annoFileName = None |
186 self.annoFileName = None |
146 |
187 |
147 if self.copyLogFromAnnoFile: |
188 if self.copyLogFromAnnoFile: |
148 for o in self.raptor.makeOptions: |
189 for o in self.raptor.makeOptions: |
149 if o.startswith("--emake-annofile="): |
190 self.annoFileName = string_following("--emake-annofile=", o) |
150 self.annoFileName = o[17:] |
191 if self.annoFileName: |
151 self.raptor.Info("annofile: " + o) |
192 self.raptor.Info("annofile: " + o) |
152 |
193 |
153 if not self.annoFileName: |
194 if not self.annoFileName: |
154 self.raptor.Info("Cannot copy log from annotation file as no annotation filename was specified via the option --mo=--emake-annofile=<filename>") |
195 self.raptor.Info("Cannot copy log from annotation file as no annotation filename was specified via the option --mo=--emake-annofile=<filename>") |
155 self.copyLogFromAnnoFile = False |
196 self.copyLogFromAnnoFile = False |