src/Pure/Tools/build_job.scala
changeset 76087 c8f5fec36b5c
parent 75970 b4a04fa01677
child 76088 bec8677d0e5b
equal deleted inserted replaced
76086:338adf8d423c 76087:c8f5fec36b5c
     6 
     6 
     7 package isabelle
     7 package isabelle
     8 
     8 
     9 
     9 
    10 import scala.collection.mutable
    10 import scala.collection.mutable
       
    11 import scala.util.matching.Regex
    11 
    12 
    12 
    13 
    13 object Build_Job {
    14 object Build_Job {
    14   /* theory markup/messages from session database */
    15   /* theory markup/messages from session database */
    15 
    16 
    83 
    84 
    84   def print_log(
    85   def print_log(
    85     options: Options,
    86     options: Options,
    86     session_name: String,
    87     session_name: String,
    87     theories: List[String] = Nil,
    88     theories: List[String] = Nil,
       
    89     message_head: List[Regex] = Nil,
       
    90     message_body: List[Regex] = Nil,
    88     verbose: Boolean = false,
    91     verbose: Boolean = false,
    89     progress: Progress = new Progress,
    92     progress: Progress = new Progress,
    90     margin: Double = Pretty.default_margin,
    93     margin: Double = Pretty.default_margin,
    91     breakgain: Double = Pretty.default_breakgain,
    94     breakgain: Double = Pretty.default_breakgain,
    92     metric: Pretty.Metric = Symbol.Metric,
    95     metric: Pretty.Metric = Symbol.Metric,
    93     unicode_symbols: Boolean = false
    96     unicode_symbols: Boolean = false
    94   ): Unit = {
    97   ): Unit = {
    95     val store = Sessions.store(options)
    98     val store = Sessions.store(options)
    96     val session = new Session(options, Resources.empty)
    99     val session = new Session(options, Resources.empty)
       
   100 
       
   101     def check(filter: List[Regex], make_string: => String): Boolean =
       
   102       filter.isEmpty || {
       
   103         val s = Output.clean_yxml(make_string)
       
   104         filter.forall(r => r.findFirstIn(Output.clean_yxml(s)).nonEmpty)
       
   105       }
    97 
   106 
    98     using(Export.open_session_context0(store, session_name)) { session_context =>
   107     using(Export.open_session_context0(store, session_name)) { session_context =>
    99       val result =
   108       val result =
   100         for {
   109         for {
   101           db <- session_context.session_db()
   110           db <- session_context.session_db()
   124                 val messages =
   133                 val messages =
   125                   rendering.text_messages(Text.Range.full)
   134                   rendering.text_messages(Text.Range.full)
   126                     .filter(message => verbose || Protocol.is_exported(message.info))
   135                     .filter(message => verbose || Protocol.is_exported(message.info))
   127                 if (messages.nonEmpty) {
   136                 if (messages.nonEmpty) {
   128                   val line_document = Line.Document(command.source)
   137                   val line_document = Line.Document(command.source)
   129                   progress.echo(thy_heading)
   138                   val buffer = new mutable.ListBuffer[String]
   130                   for (Text.Info(range, elem) <- messages) {
   139                   for (Text.Info(range, elem) <- messages) {
   131                     val line = line_document.position(range.start).line1
   140                     val line = line_document.position(range.start).line1
   132                     val pos = Position.Line_File(line, command.node_name.node)
   141                     val pos = Position.Line_File(line, command.node_name.node)
   133                     progress.echo(
   142                     def message_text: String =
   134                       Protocol.message_text(elem, heading = true, pos = pos,
   143                       Protocol.message_text(elem, heading = true, pos = pos,
   135                         margin = margin, breakgain = breakgain, metric = metric))
   144                         margin = margin, breakgain = breakgain, metric = metric)
       
   145                     val ok =
       
   146                       check(message_head, Protocol.message_heading(elem, pos)) &&
       
   147                       check(message_body, XML.content(Pretty.unformatted(List(elem))))
       
   148                     if (ok) buffer += message_text
       
   149                   }
       
   150                   if (buffer.nonEmpty) {
       
   151                     progress.echo(thy_heading)
       
   152                     buffer.foreach(progress.echo)
   136                   }
   153                   }
   137                 }
   154                 }
   138             }
   155             }
   139           }
   156           }
   140 
   157 
   155   val isabelle_tool = Isabelle_Tool("log", "print messages from build database",
   172   val isabelle_tool = Isabelle_Tool("log", "print messages from build database",
   156     Scala_Project.here,
   173     Scala_Project.here,
   157     { args =>
   174     { args =>
   158       /* arguments */
   175       /* arguments */
   159 
   176 
       
   177       var message_head = List.empty[Regex]
       
   178       var message_body = List.empty[Regex]
   160       var unicode_symbols = false
   179       var unicode_symbols = false
   161       var theories: List[String] = Nil
   180       var theories: List[String] = Nil
   162       var margin = Pretty.default_margin
   181       var margin = Pretty.default_margin
   163       var options = Options.init()
   182       var options = Options.init()
   164       var verbose = false
   183       var verbose = false
   165 
   184 
   166       val getopts = Getopts("""
   185       val getopts = Getopts("""
   167 Usage: isabelle log [OPTIONS] SESSION
   186 Usage: isabelle log [OPTIONS] SESSION
   168 
   187 
   169   Options are:
   188   Options are:
       
   189     -H REGEX     filter messages by matching against head
       
   190     -M REGEX     filter messages by matching against body
   170     -T NAME      restrict to given theories (multiple options possible)
   191     -T NAME      restrict to given theories (multiple options possible)
   171     -U           output Unicode symbols
   192     -U           output Unicode symbols
   172     -m MARGIN    margin for pretty printing (default: """ + margin + """)
   193     -m MARGIN    margin for pretty printing (default: """ + margin + """)
   173     -o OPTION    override Isabelle system OPTION (via NAME=VAL or NAME)
   194     -o OPTION    override Isabelle system OPTION (via NAME=VAL or NAME)
   174     -v           print all messages, including information etc.
   195     -v           print all messages, including information etc.
   175 
   196 
   176   Print messages from the build database of the given session, without any
   197   Print messages from the build database of the given session, without any
   177   checks against current sources: results from a failed build can be
   198   checks against current sources: results from a failed build can be
   178   printed as well.
   199   printed as well.
       
   200 
       
   201   Multiple options -H and -M are conjunctive: all given patterns need to
       
   202   match. Patterns match any substring, but ^ or $ may be used to match
       
   203   the start or end explicitly.
   179 """,
   204 """,
       
   205         "H:" -> (arg => message_head = message_head ::: List(arg.r)),
       
   206         "M:" -> (arg => message_body = message_body ::: List(arg.r)),
   180         "T:" -> (arg => theories = theories ::: List(arg)),
   207         "T:" -> (arg => theories = theories ::: List(arg)),
   181         "U" -> (_ => unicode_symbols = true),
   208         "U" -> (_ => unicode_symbols = true),
   182         "m:" -> (arg => margin = Value.Double.parse(arg)),
   209         "m:" -> (arg => margin = Value.Double.parse(arg)),
   183         "o:" -> (arg => options = options + arg),
   210         "o:" -> (arg => options = options + arg),
   184         "v" -> (_ => verbose = true))
   211         "v" -> (_ => verbose = true))
   190           case _ => getopts.usage()
   217           case _ => getopts.usage()
   191         }
   218         }
   192 
   219 
   193       val progress = new Console_Progress()
   220       val progress = new Console_Progress()
   194 
   221 
   195       print_log(options, session_name, theories = theories, verbose = verbose, margin = margin,
   222       print_log(options, session_name, theories = theories, message_head = message_head,
   196         progress = progress, unicode_symbols = unicode_symbols)
   223         message_body = message_body, verbose = verbose, margin = margin, progress = progress,
       
   224         unicode_symbols = unicode_symbols)
   197     })
   225     })
   198 }
   226 }
   199 
   227 
   200 class Build_Job(progress: Progress,
   228 class Build_Job(progress: Progress,
   201   session_name: String,
   229   session_name: String,