src/Pure/Build/build_manager.scala
changeset 80532 d5ff748321b7
parent 80531 c54a4c2db5b7
child 80533 464266fc956e
equal deleted inserted replaced
80531:c54a4c2db5b7 80532:d5ff748321b7
   597 
   597 
   598 
   598 
   599   /** build reports **/
   599   /** build reports **/
   600 
   600 
   601   object Report {
   601   object Report {
   602     case class Data(log: String, diffs: List[(String, String)])
   602     case class Data(build_log: String, component_diffs: List[(String, String)])
   603   }
   603   }
   604 
   604 
   605   case class Report(kind: String, id: Long, dir: Path) {
   605   case class Report(kind: String, id: Long, dir: Path) {
   606     private val log_name = "build-manager"
   606     private val log_name = "build-manager"
   607     private val diff_ext = "diff"
   607     private val diff_ext = "diff"
   618     private def read_gz(file: Path, ext: String): Option[(String, String)] =
   618     private def read_gz(file: Path, ext: String): Option[(String, String)] =
   619       if (!File.is_gz(file.file_name) || file.drop_ext.get_ext != ext) None
   619       if (!File.is_gz(file.file_name) || file.drop_ext.get_ext != ext) None
   620       else Some(file.drop_ext.drop_ext.file_name -> File.read_gzip(file))
   620       else Some(file.drop_ext.drop_ext.file_name -> File.read_gzip(file))
   621 
   621 
   622     def read: Report.Data = {
   622     def read: Report.Data = {
   623       val log =
   623       val build_log =
   624         if_proper(ok, if (log_file.is_file) File.read(log_file) else File.read_gzip(log_file_gz))
   624         if_proper(ok, if (log_file.is_file) File.read(log_file) else File.read_gzip(log_file_gz))
   625 
   625 
   626       val diffs = File.read_dir(dir).flatMap(name => read_gz(dir + Path.basic(name), diff_ext))
   626       val component_diffs =
   627 
   627         File.read_dir(dir).flatMap(name => read_gz(dir + Path.basic(name), diff_ext))
   628       Report.Data(log, diffs)
   628 
   629     }
   629       Report.Data(build_log, component_diffs)
   630 
   630     }
   631     def write_diff(name: String, diff: String): Unit =
   631 
       
   632     def write_component_diff(name: String, diff: String): Unit =
   632       if (diff.nonEmpty) File.write_gzip(dir + Path.basic(name).ext(diff_ext).gz, diff)
   633       if (diff.nonEmpty) File.write_gzip(dir + Path.basic(name).ext(diff_ext).gz, diff)
   633 
   634 
   634     def result(uuid: Option[UUID.T]): Result = {
   635     def result(uuid: Option[UUID.T]): Result = {
   635       val End = """^Job ended at [^,]+, with status (\w+)$""".r
   636       val End = """^Job ended at [^,]+, with status (\w+)$""".r
   636 
   637 
   637       val build_log_file = Build_Log.Log_File(log_name, Library.trim_split_lines(read.log))
   638       val build_log_file = Build_Log.Log_File(log_name, Library.trim_split_lines(read.build_log))
   638 
   639 
   639       val meta_info = build_log_file.parse_meta_info()
   640       val meta_info = build_log_file.parse_meta_info()
   640       val status =
   641       val status =
   641         build_log_file.lines.last match {
   642         build_log_file.lines.last match {
   642           case End(status) => Status.valueOf(status)
   643           case End(status) => Status.valueOf(status)
   852 
   853 
   853             if (task.kind != User_Build.name && _state.get_finished(task.kind).nonEmpty) {
   854             if (task.kind != User_Build.name && _state.get_finished(task.kind).nonEmpty) {
   854               val previous = _state.get_finished(task.kind).maxBy(_.id)
   855               val previous = _state.get_finished(task.kind).maxBy(_.id)
   855 
   856 
   856               for (isabelle_rev0 <- previous.isabelle_version) {
   857               for (isabelle_rev0 <- previous.isabelle_version) {
   857                 context.report.write_diff("Isabelle",
   858                 context.report.write_component_diff("Isabelle",
   858                   diff(isabelle_repository, isabelle_rev0, isabelle_rev))
   859                   diff(isabelle_repository, isabelle_rev0, isabelle_rev))
   859               }
   860               }
   860 
   861 
   861               for {
   862               for {
   862                 afp_rev0 <- previous.afp_version
   863                 afp_rev0 <- previous.afp_version
   863                 afp <- extra_components.find(_.name == Component.AFP)
   864                 afp <- extra_components.find(_.name == Component.AFP)
   864                 sync_dir <- sync_dirs.find(_.name == afp.name)
   865                 sync_dir <- sync_dirs.find(_.name == afp.name)
   865               } context.report.write_diff(afp.name, diff(sync_dir.hg, afp_rev0, afp.rev))
   866               } context.report.write_component_diff(afp.name, diff(sync_dir.hg, afp_rev0, afp.rev))
   866             }
   867             }
   867 
   868 
   868             Job(task.uuid, task.kind, id, task.build_cluster, hostnames,
   869             Job(task.uuid, task.kind, id, task.build_cluster, hostnames,
   869               Component.isabelle(isabelle_rev) :: extra_components, task.timeout, start_date)
   870               Component.isabelle(isabelle_rev) :: extra_components, task.timeout, start_date)
   870           } match {
   871           } match {
  1228 
  1229 
  1229               par(text("Start: " + Build_Log.print_date(job.start_date))) ::
  1230               par(text("Start: " + Build_Log.print_date(job.start_date))) ::
  1230               par(
  1231               par(
  1231                 if (job.cancelled) text("Cancelling ...")
  1232                 if (job.cancelled) text("Cancelling ...")
  1232                 else text("Running ...") ::: render_cancel(job.uuid)) ::
  1233                 else text("Running ...") ::: render_cancel(job.uuid)) ::
  1233               render_rev(job.components, report_data.diffs.toMap) :::
  1234               render_rev(job.components, report_data.component_diffs.toMap) :::
  1234               par(text("Log") :+ source(report_data.log)) :: Nil
  1235               par(text("Log") :+ source(report_data.build_log)) :: Nil
  1235 
  1236 
  1236             case result: Result =>
  1237             case result: Result =>
  1237               val report_data = cache.lookup(store.report(result.kind, result.id))
  1238               val report_data = cache.lookup(store.report(result.kind, result.id))
  1238 
  1239 
  1239               par(text("Start: " + Build_Log.print_date(result.start_date) +
  1240               par(text("Start: " + Build_Log.print_date(result.start_date) +
  1240                 if_proper(result.end_date,
  1241                 if_proper(result.end_date,
  1241                   ", took " + (result.end_date.get - result.start_date).message_hms))) ::
  1242                   ", took " + (result.end_date.get - result.start_date).message_hms))) ::
  1242               par(text("Status: " + result.status)) ::
  1243               par(text("Status: " + result.status)) ::
  1243               render_rev(result.components, report_data.diffs.toMap) :::
  1244               render_rev(result.components, report_data.component_diffs.toMap) :::
  1244               par(text("Log") :+ source(report_data.log)) :: Nil
  1245               par(text("Log") :+ source(report_data.build_log)) :: Nil
  1245           }
  1246           }
  1246         }
  1247         }
  1247 
  1248 
  1248       def render_cancelled: XML.Body = render_page("Build cancelled")(
  1249       def render_cancelled: XML.Body = render_page("Build cancelled")(
  1249         List(frontend_link(paths.frontend_url(Page.HOME), text("Home"))))
  1250         List(frontend_link(paths.frontend_url(Page.HOME), text("Home"))))