1 /* Title: Pure/Tools/build_log.scala |
1 /* Title: Pure/Tools/build_log.scala |
2 Author: Makarius |
2 Author: Makarius |
3 |
3 |
4 Build log parsing for current and historic versions. |
4 Build log parsing for current and historic formats. |
5 */ |
5 */ |
6 |
6 |
7 package isabelle |
7 package isabelle |
8 |
8 |
9 |
9 |
10 import java.io.{File => JFile} |
10 import java.io.{File => JFile} |
11 import java.time.ZoneId |
11 import java.time.ZoneId |
12 import java.time.format.DateTimeParseException |
12 import java.time.format.{DateTimeFormatter, DateTimeParseException} |
13 import java.util.Locale |
13 import java.util.Locale |
14 |
14 |
15 import scala.collection.mutable |
15 import scala.collection.mutable |
16 import scala.util.matching.Regex |
16 import scala.util.matching.Regex |
17 |
17 |
88 apply(base_name, text) |
88 apply(base_name, text) |
89 } |
89 } |
90 |
90 |
91 def apply(path: Path): Log_File = apply(path.file) |
91 def apply(path: Path): Log_File = apply(path.file) |
92 |
92 |
|
93 |
|
94 /* date format */ |
|
95 |
93 val Date_Format = |
96 val Date_Format = |
94 { |
97 { |
95 val fmts = |
98 val fmts = |
96 Date.Formatter.variants( |
99 Date.Formatter.variants( |
97 List("EEE MMM d HH:mm:ss VV yyyy", "EEE MMM d HH:mm:ss O yyyy"), |
100 List("EEE MMM d HH:mm:ss VV yyyy", "EEE MMM d HH:mm:ss O yyyy"), |
98 List(Locale.ENGLISH, Locale.GERMAN)) ::: |
101 List(Locale.ENGLISH, Locale.GERMAN)) ::: |
99 List(Date.Formatter.pattern("EEE MMM d HH:mm:ss yyyy").withZone(ZoneId.of("Europe/Berlin"))) |
102 List( |
|
103 DateTimeFormatter.RFC_1123_DATE_TIME, |
|
104 Date.Formatter.pattern("EEE MMM d HH:mm:ss yyyy").withZone(ZoneId.of("Europe/Berlin"))) |
100 |
105 |
101 def tune_timezone(s: String): String = |
106 def tune_timezone(s: String): String = |
102 s match { |
107 s match { |
103 case "CET" | "MET" => "GMT+1" |
108 case "CET" | "MET" => "GMT+1" |
104 case "CEST" | "MEST" => "GMT+2" |
109 case "CEST" | "MEST" => "GMT+2" |
247 val Isabelle_Version = new Regex("""^Isabelle version: .* -- hg id (\S+)$""") |
252 val Isabelle_Version = new Regex("""^Isabelle version: .* -- hg id (\S+)$""") |
248 val AFP_Version = new Regex("""^AFP version: .* -- hg id (\S+)$""") |
253 val AFP_Version = new Regex("""^AFP version: .* -- hg id (\S+)$""") |
249 val Bad_Init = new Regex("""^cp:.*: Disc quota exceeded$""") |
254 val Bad_Init = new Regex("""^cp:.*: Disc quota exceeded$""") |
250 } |
255 } |
251 |
256 |
|
257 object Jenkins |
|
258 { |
|
259 val engine = "jenkins" |
|
260 val Start = new Regex("""^Started .*$""") |
|
261 val Start_Date = new Regex("""^Build started at (.+)$""") |
|
262 val No_End = new Regex("""$.""") |
|
263 val Isabelle_Version = new Regex("""^Isabelle id (\S+)$""") |
|
264 val AFP_Version = new Regex("""^AFP id (\S+)$""") |
|
265 val CONFIGURATION = "=== CONFIGURATION ===" |
|
266 val BUILD = "=== BUILD ===" |
|
267 val FINISHED = "Finished: " |
|
268 } |
|
269 |
252 private def parse_meta_info(log_file: Log_File): Meta_Info = |
270 private def parse_meta_info(log_file: Log_File): Meta_Info = |
253 { |
271 { |
254 def parse(engine: String, host: String, start: Date, |
272 def parse(engine: String, host: String, start: Date, |
255 End: Regex, Isabelle_Version: Regex, AFP_Version: Regex): Meta_Info = |
273 End: Regex, Isabelle_Version: Regex, AFP_Version: Regex): Meta_Info = |
256 { |
274 { |
286 |
304 |
287 case AFP_Test.Start_Old(log_file.Strict_Date(start)) :: _ => |
305 case AFP_Test.Start_Old(log_file.Strict_Date(start)) :: _ => |
288 parse(AFP_Test.engine, "", start, AFP_Test.End, |
306 parse(AFP_Test.engine, "", start, AFP_Test.End, |
289 AFP_Test.Isabelle_Version, AFP_Test.AFP_Version) |
307 AFP_Test.Isabelle_Version, AFP_Test.AFP_Version) |
290 |
308 |
|
309 case Jenkins.Start() :: _ |
|
310 if log_file.lines.contains(Jenkins.CONFIGURATION) || |
|
311 log_file.lines.last.startsWith(Jenkins.FINISHED) => |
|
312 log_file.lines.dropWhile(_ != Jenkins.BUILD) match { |
|
313 case Jenkins.BUILD :: _ :: Jenkins.Start_Date(log_file.Strict_Date(start)) :: _ => |
|
314 parse(Jenkins.engine, "", start, Jenkins.No_End, |
|
315 Jenkins.Isabelle_Version, Jenkins.AFP_Version) |
|
316 case _ => Meta_Info.empty |
|
317 } |
|
318 |
291 case line :: _ if line.startsWith("\0") => Meta_Info.empty |
319 case line :: _ if line.startsWith("\0") => Meta_Info.empty |
292 case List(Isatest.End(_)) => Meta_Info.empty |
320 case List(Isatest.End(_)) => Meta_Info.empty |
293 case _ :: AFP_Test.Bad_Init() :: _ => Meta_Info.empty |
321 case _ :: AFP_Test.Bad_Init() :: _ => Meta_Info.empty |
294 case Nil => Meta_Info.empty |
322 case Nil => Meta_Info.empty |
295 |
323 |
296 case _ => log_file.err("cannot detect log header format") |
324 case _ => log_file.err("cannot detect log file format") |
297 } |
325 } |
298 } |
326 } |
299 |
327 |
300 |
328 |
301 |
329 |