src/Pure/Tools/build_log.scala
changeset 64091 f8dfba90e73f
parent 64090 5a68280112b3
child 64092 95469c544b82
equal deleted inserted replaced
64090:5a68280112b3 64091:f8dfba90e73f
    98         map(res => res.get.head)
    98         map(res => res.get.head)
    99 
    99 
   100 
   100 
   101     /* settings */
   101     /* settings */
   102 
   102 
   103     def get_setting(a: String): Settings.Entry =
   103     def get_setting(a: String): Option[Settings.Entry] =
   104       Settings.Entry.unapply(
   104       lines.find(_.startsWith(a + "=")) match {
   105         lines.find(_.startsWith(a + "=")) getOrElse err("missing " + a)).get
   105         case Some(line) => Settings.Entry.unapply(line)
   106 
   106         case None => None
   107     def get_settings(as: List[String]): Settings.T = as.map(get_setting(_))
   107       }
       
   108 
       
   109     def get_settings(as: List[String]): Settings.T =
       
   110       for { a <- as; entry <- get_setting(a) } yield entry
   108 
   111 
   109 
   112 
   110     /* properties (YXML) */
   113     /* properties (YXML) */
   111 
   114 
   112     val xml_cache = new XML.Cache()
   115     val xml_cache = new XML.Cache()
   200   object AFP
   203   object AFP
   201   {
   204   {
   202     val Date_Format =
   205     val Date_Format =
   203       Date.Format.make_patterns(List("EEE MMM d HH:mm:ss VV yyyy", "EEE MMM d HH:mm:ss O yyyy"),
   206       Date.Format.make_patterns(List("EEE MMM d HH:mm:ss VV yyyy", "EEE MMM d HH:mm:ss O yyyy"),
   204         // workaround for jdk-8u102
   207         // workaround for jdk-8u102
   205         s => Word.implode(Word.explode(s).map({ case "CEST" => "GMT+2" case a => a })))
   208         s => Word.implode(Word.explode(s).map({
   206 
   209           case "CET" | "MET" => "GMT+1"
   207     val Test_Start = new Regex("""^Start test (?:for \S+)? at (.+), (\S+)$""")
   210           case "CEST" | "MEST" => "GMT+2"
   208     val Test_End = new Regex("""^End test on (.+), \S+, elapsed time:.*$""")
   211           case a => a })))
       
   212 
       
   213     object Strict_Date
       
   214     {
       
   215       def unapply(s: String): Some[Date] = Some(Date_Format.parse(s))
       
   216     }
       
   217 
       
   218     val Test_Start = new Regex("""^Start test(?: for .+)? at ([^,]+), (.*)$""")
       
   219     val Test_Start_Old = new Regex("""^Start test(?: for .+)? at ([^,]+)$""")
       
   220     val Test_End = new Regex("""^End test on (.+), .+, elapsed time:.*$""")
   209     val Isabelle_Version = new Regex("""^Isabelle version: .* -- hg id (\S+)$""")
   221     val Isabelle_Version = new Regex("""^Isabelle version: .* -- hg id (\S+)$""")
   210     val AFP_Version = new Regex("""^AFP version: .* -- hg id (\S+)$""")
   222     val AFP_Version = new Regex("""^AFP version: .* -- hg id (\S+)$""")
   211   }
   223   }
   212 
   224 
   213   private def parse_header(log_file: Log_File): Header =
   225   private def parse_header(log_file: Log_File): Header =
   214   {
   226   {
       
   227     def parse_afp(start: Date, hostname: String): Header =
       
   228     {
       
   229       val start_date = Field.build_start -> start.toString
       
   230       val end_date =
       
   231         log_file.lines.last match {
       
   232           case AFP.Test_End(AFP.Strict_Date(end_date)) =>
       
   233             List(Field.build_end -> end_date.toString)
       
   234           case _ => Nil
       
   235         }
       
   236 
       
   237       val build_host = if (hostname == "") Nil else List(Field.build_host -> hostname)
       
   238 
       
   239       val isabelle_version =
       
   240         log_file.find_match(AFP.Isabelle_Version).map(Field.isabelle_version -> _)
       
   241 
       
   242       val afp_version =
       
   243         log_file.find_match(AFP.AFP_Version).map(Field.afp_version -> _)
       
   244 
       
   245       Header(Header_Kind.AFP_TEST,
       
   246         start_date :: end_date ::: build_host ::: isabelle_version.toList ::: afp_version.toList,
       
   247         log_file.get_settings(Settings.all_settings))
       
   248     }
       
   249 
   215     log_file.lines match {
   250     log_file.lines match {
   216       case AFP.Test_Start(start, hostname) :: _ =>
   251       case AFP.Test_Start(AFP.Strict_Date(start_date), hostname) :: _ =>
   217         (start, log_file.lines.last) match {
   252         parse_afp(start_date, hostname)
   218           case (AFP.Date_Format(start_date), AFP.Test_End(AFP.Date_Format(end_date))) =>
   253       case AFP.Test_Start_Old(AFP.Strict_Date(start_date)) :: _ =>
   219             val isabelle_version =
   254         parse_afp(start_date, "")
   220               log_file.find_match(AFP.Isabelle_Version).map((Field.isabelle_version, _))
       
   221             val afp_version =
       
   222               log_file.find_match(AFP.AFP_Version).map((Field.afp_version, _))
       
   223 
       
   224             Header(Header_Kind.AFP_TEST,
       
   225               List(
       
   226                 Field.build_host -> hostname,
       
   227                 Field.build_start -> start_date.toString,
       
   228                 Field.build_end -> end_date.toString) :::
       
   229               isabelle_version.toList :::
       
   230               afp_version.toList,
       
   231               log_file.get_settings(Settings.all_settings))
       
   232 
       
   233           case _ => log_file.err("cannot detect start/end date in afp-test log")
       
   234         }
       
   235       case _ => log_file.err("cannot detect log header format")
   255       case _ => log_file.err("cannot detect log header format")
   236     }
   256     }
   237   }
   257   }
   238 
   258 
   239 
   259