src/Pure/Admin/isabelle_cronjob.scala
author wenzelm
Tue Oct 11 22:24:14 2016 +0200 (2016-10-11)
changeset 64155 646c4d6a6a02
parent 64154 e5cf40a54b1e
child 64156 01716e3c3e68
permissions -rw-r--r--
tuned signature;
     1 /*  Title:      Pure/Admin/isabelle_cronjob.scala
     2     Author:     Makarius
     3 
     4 Main entry point for administrative cronjob at TUM.
     5 */
     6 
     7 package isabelle
     8 
     9 
    10 object Isabelle_Cronjob
    11 {
    12   /** file-system state: owned by main cronjob **/
    13 
    14   val main_dir = Path.explode("~/cronjob")
    15   val run_dir = main_dir + Path.explode("run")
    16   val log_dir = main_dir + Path.explode("log")
    17 
    18   val main_state_file = run_dir + Path.explode("main.state")
    19   val main_log = log_dir + Path.explode("main.log")
    20 
    21 
    22   /* managed repository clones */
    23 
    24   val isabelle_repos = main_dir + Path.explode("isabelle-build_history")
    25   val afp_repos = main_dir + Path.explode("AFP-build_history")
    26 
    27   def pull_repos(root: Path): String =
    28     using(Mercurial.open_repository(root))(hg =>
    29       {
    30         hg.pull(options = "-q")
    31         hg.identify("tip")
    32       })
    33 
    34 
    35   /** cronjob **/
    36 
    37   def cronjob(progress: Progress)
    38   {
    39     /* log */
    40 
    41     val hostname = Isabelle_System.hostname()
    42 
    43     def log(date: Date, msg: String)
    44     {
    45       val text = "[" + Build_Log.print_date(date) + " " + hostname + "]: " + msg
    46       File.append(main_log, text + "\n")
    47       progress.echo(text)
    48     }
    49 
    50 
    51     /* start */
    52 
    53     val start_date = Date.now()
    54 
    55     val still_running =
    56       try { Some(File.read(main_state_file)) }
    57       catch { case ERROR(_) => None }
    58 
    59     still_running match {
    60       case Some(running) =>
    61         error("Isabelle cronjob appears to be still running: " + running)
    62       case None =>
    63         File.write(main_state_file, start_date + " " + hostname)
    64         log(start_date, "start cronjob")
    65     }
    66 
    67 
    68     /* identify repository snapshots */
    69 
    70     {
    71       val pull_date = Date.now()
    72 
    73       val isabelle_id = pull_repos(isabelle_repos)
    74       val afp_id = pull_repos(afp_repos)
    75 
    76       val log_path = log_dir + Build_Log.log_path("isabelle_identify", pull_date)
    77       Isabelle_System.mkdirs(log_path.dir)
    78       File.write(log_path,
    79         Library.terminate_lines(
    80           List("isabelle_identify: " + Build_Log.print_date(pull_date),
    81             "",
    82             "Isabelle version: " + isabelle_id,
    83             "AFP version: " + afp_id)))
    84     }
    85 
    86 
    87     /* end */
    88 
    89     val end_date = Date.now()
    90     val elapsed_time = end_date.time - start_date.time
    91 
    92     log(end_date, "end cronjob, elapsed time " + elapsed_time.message_hms)
    93 
    94     main_state_file.file.delete
    95   }
    96 
    97 
    98 
    99   /** command line entry point **/
   100 
   101   def main(args: Array[String])
   102   {
   103     Command_Line.tool0 {
   104       var force = false
   105       var verbose = false
   106 
   107       val getopts = Getopts("""
   108 Usage: Admin/cronjob/main [OPTIONS]
   109 
   110   Options are:
   111     -f           apply force to do anything
   112     -v           verbose
   113 """,
   114         "f" -> (_ => force = true),
   115         "v" -> (_ => verbose = true))
   116 
   117       val more_args = getopts(args)
   118       if (more_args.nonEmpty) getopts.usage()
   119 
   120       val progress = if (verbose) new Console_Progress() else Ignore_Progress
   121 
   122       if (force) cronjob(progress)
   123       else error("Need to apply force to do anything")
   124     }
   125   }
   126 }