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")))) |