class Results private( val store: Store, val deps: Sessions.Deps,
results: Map[String, Process_Result],
other_rc: Int
) { def cache: Rich_Text.Cache = store.cache
def sessions_ok: List[String] =
List.from( for {
name <- deps.sessions_structure.build_topological_order.iterator
result <- results.get(name) if result.ok
} yield name)
val build_deps = { val deps0 =
Sessions.deps(full_sessions.selection(selection), progress = progress,
inlined_files = true, list_files = list_files).check_errors
if (soft_build && !fresh_build) { val outdated =
deps0.sessions_structure.build_topological_order.flatMap(name =>
store.try_open_database(name, server = server) match { case Some(db) =>
using(db)(store.read_build(_, name)) match { case Some(build) if build.ok => val sources_shasum = deps0.sources_shasum(name) val thorough = deps0.sessions_structure(name).build_thorough if (Sessions.eq_sources(thorough, build.sources, sources_shasum)) None else Some(name) case _ => Some(name)
} case None => Some(name)
})
val results = if (fresh) full_build() else { val results0 = test_build() if (results0.ok) results0 else full_build()
}
if (strict && !results.ok) error(build_logic_failed(logic)) else results
}
/* Isabelle tool wrappers */
val isabelle_tool1 = Isabelle_Tool("build", "build and manage Isabelle sessions",
Scala_Project.here,
{ args => var afp_root: Option[Path] = None val base_sessions = new mutable.ListBuffer[String] val select_dirs = new mutable.ListBuffer[Path] val build_hosts = new mutable.ListBuffer[Build_Cluster.Host] var numa_shuffling = false var browser_info = Browser_Info.Config.none var requirements = false var soft_build = false val exclude_session_groups = new mutable.ListBuffer[String] var all_sessions = false var build_heap = false var clean_build = false val dirs = new mutable.ListBuffer[Path] var export_files = false var fresh_build = false val session_groups = new mutable.ListBuffer[String] var max_jobs: Option[Int] = None var list_files = false var no_build = false var options = Options.init(specs = Options.Spec.ISABELLE_BUILD_OPTIONS) var verbose = false val exclude_sessions = new mutable.ListBuffer[String]
val getopts = Getopts("""
Usage: isabelle build [OPTIONS] [SESSIONS ...]
Options are:
-A ROOT include AFP with given root directory (":"for""" + AFP.BASE.implode + """)
-B NAME include session NAME and all descendants
-D DIR include session directory and select its sessions
-H HOSTS additional cluster host specifications of the form
NAMES:PARAMETERS (separated by commas)
-N cyclic shuffling of NUMA CPU nodes (performance tuning)
-P DIR enable HTML/PDF presentation in directory (":"for default)
-R refer to requirements of selected sessions
-S soft build: only observe changes of sources, not heap images
-X NAME exclude sessions from group NAME and all descendants
-a select all sessions
-b build heap images
-c clean build
-d DIR include session directory
-e export files from session specification into file-system
-f fresh build
-g NAME select session group NAME
-j INT maximum number of parallel jobs
(default: 1 for local build, 0 for build cluster)
-l list session source files
-n no build -- take existing session build databases
-o OPTION override Isabelle system OPTION (via NAME=VAL or NAME)
-v verbose
-x NAME exclude session NAME and all descendants
Build and manage Isabelle sessions: ML heaps, session databases, documents.
Parameters for cluster host specifications (-H), apart from system options: """ + Library.indent_lines(4, Build_Cluster.Host.parameters.print()) + """
Notable system options: see "isabelle options -l -t build"
def read_builds(build_database: Option[SQL.Database]): List[Build_Process.Build] =
build_database match { case None => Nil case Some(db) => Build_Process.read_builds(db)
}
def print_builds(build_database: Option[SQL.Database], builds: List[Build_Process.Build]): String =
{ val print_database =
build_database match { case None => "" case Some(db) => " (database " + db + ")"
} if (builds.isEmpty) "No build processes" + print_database else"Build processes" + print_database + builds.map(build => "\n " + build.print).mkString
}
def find_builds(
build_database: Option[SQL.Database],
build_id: String,
builds: List[Build_Process.Build]
): Build_Process.Build = {
(build_id, builds.length) match { case (UUID(_), _) if builds.exists(_.build_uuid == build_id) =>
builds.find(_.build_uuid == build_id).get case ("", 1) => builds.head case ("", 0) => error(print_builds(build_database, builds)) case _ =>
cat_error("Cannot identify build process " + quote(build_id),
print_builds(build_database, builds))
}
}
/* "isabelle build_process" */
def build_process(
options: Options,
build_cluster: Boolean = false,
list_builds: Boolean = false,
remove_builds: Boolean = false,
force: Boolean = false,
progress: Progress = new Progress
): Unit = { val engine = Engine(engine_name(options)) val store = engine.build_store(options, build_cluster = build_cluster)
using(store.open_server()) { server =>
using_optional(store.maybe_open_build_database(server = server)) { build_database => def print(builds: List[Build_Process.Build]): Unit = if (list_builds) progress.echo(print_builds(build_database, builds))
build_database match { case None => print(Nil) case Some(db) if remove_builds && force =>
db.transaction { val tables0 =
ML_Heap.private_data.tables.list :::
Store.private_data.tables.list :::
Database_Progress.private_data.tables.list :::
Build_Process.private_data.tables.list val tables = tables0.filter(t => db.exists_table(t.name)).sortBy(_.name) if (tables.nonEmpty) {
progress.echo("Removing tables " + commas_quote(tables.map(_.name)) + " ...")
db.execute_statement(SQL.MULTI(tables.map(db.destroy)))
}
} case Some(db) =>
Build_Process.private_data.transaction_lock(db, create = true, label = "build_process") { val builds = Build_Process.private_data.read_builds(db)
print(builds) if (remove_builds) { val remove = builds.flatMap(_.active_build_uuid) if (remove.nonEmpty) {
progress.echo("Removing " + commas(remove) + " ...")
Build_Process.private_data.remove_builds(db, remove)
print(Build_Process.private_data.read_builds(db))
}
}
}
}
}
}
}
val isabelle_tool2 = Isabelle_Tool("build_process", "manage session build process",
Scala_Project.here,
{ args => var build_cluster = false var force = false var list_builds = false var options =
Options.init(specs =
Options.Spec.ISABELLE_BUILD_OPTIONS ::: List(Options.Spec.make("build_database"))) var remove_builds = false
val getopts = Getopts("""
Usage: isabelle build_process [OPTIONS]
Options are:
-C build cluster mode (database server)
-f extra force for option -r
-l list build processes
-o OPTION override Isabelle system OPTION (via NAME=VAL or NAME)
-r remove data from build processes: inactive processes (default)
or all processes (option -f)
val isabelle_tool3 = Isabelle_Tool("build_worker", "start worker for session build process",
Scala_Project.here,
{ args => var build_id = "" var numa_shuffling = false val dirs = new mutable.ListBuffer[Path] var max_jobs: Option[Int] = None var options =
Options.init(specs =
Options.Spec.ISABELLE_BUILD_OPTIONS ::: List(Options.Spec.make("build_database"))) var quiet = false var verbose = false
val getopts = Getopts("""
Usage: isabelle build_worker [OPTIONS]
Options are:
-B UUID existing UUID for build process (default: from database)
-N cyclic shuffling of NUMA CPU nodes (performance tuning)
-d DIR include session directory
-j INT maximum number of parallel jobs (default 1)
-o OPTION override Isabelle system OPTION (via NAME=VAL or NAME)
-q quiet mode: no progress
-v verbose """, "B:" -> (arg => build_id = arg), "N" -> (_ => numa_shuffling = true), "d:" -> (arg => dirs += Path.explode(arg)), "j:" -> (arg => max_jobs = Some(Value.Nat.parse(arg))), "o:" -> (arg => options = options + arg), "q" -> (_ => quiet = true), "v" -> (_ => verbose = true))
val more_args = getopts(args) if (more_args.nonEmpty) getopts.usage()
val progress = if (quiet && verbose) new Progress { overridedef verbose: Boolean = true } elseif (quiet) new Progress elsenew Console_Progress(verbose = verbose)
for {
id <- theory_context.document_id()
(thy_file0, blobs_files0) <- theory_context.files(permissive = true)
} yield { val thy_file = migrate_file(thy_file0)
val blobs =
blobs_files0.map { case (command_offset, name0) => val node_name = Document.Node.Name(migrate_file(name0)) val src_path = Path.explode(name0)
val file = read_source_file(name0) val bytes = file.bytes val text = decode(bytes.text) val chunk = Symbol.Text_Chunk(text) val content = Some((file.digest, chunk))
val thy_source = decode(read_source_file(thy_file0).bytes.text) val thy_xml = read_xml(Export.MARKUP) val blobs_xml = for (i <- (1 to blobs.length).toList) yield read_xml(Export.MARKUP + i)
val markups_index = Command.Markup_Index.make(blobs.map(_._1)) val markups =
Command.Markups.make( for ((index, xml) <- markups_index.zip(thy_xml :: blobs_xml)) yield index -> Markup_Tree.from_XML(xml))
val results =
Command.Results.make( for (case elem@XML.Elem(Markup(_, Markup.Serial(i)), _) <- read_xml(Export.MESSAGES)) yield i -> elem)
val command =
Command.unparsed(thy_source, theory_commands = Some(0), id = id,
node_name = Document.Node.Name(thy_file, theory = theory_context.theory),
blobs_info = Command.Blobs_Info.make(blobs),
markups = markups, results = results)
def print(session_name: String): Unit = {
using(Export.open_session_context0(store, session_name)) { session_context => val result = for {
db <- session_context.session_db()
theories = store.read_theories(db, session_name)
errors = store.read_errors(db, session_name)
info <- store.read_build(db, session_name)
} yield (theories, errors, info.return_code)
result match { case None => store.error_database(session_name) case Some((used_theories, errors, rc)) =>
theories.filterNot(used_theories.toSet) match { case Nil => case bad => error("Unknown theories " + commas_quote(bad))
} val print_theories = if (theories.isEmpty) used_theories else used_theories.filter(theories.toSet)
for (thy <- print_theories) { val thy_heading = "\nTheory " + quote(thy) + " (in " + session_name + ")" + ":"
Build.read_theory(session_context.theory(thy), unicode_symbols = unicode_symbols) match { case None => progress.echo(thy_heading + " MISSING") case Some(snapshot) => val messages =
Rendering.text_messages(snapshot,
filter = msg => progress.verbose || Protocol.is_exported(msg)) if (messages.nonEmpty) { val line_document = Line.Document(snapshot.node.source) val buffer = new mutable.ListBuffer[String] for (Text.Info(range, elem) <- messages) { val line = line_document.position(range.start).line1 val pos = Position.Line_File(line, snapshot.node_name.node) if (print_log_check(pos, elem, message_head, message_body)) {
buffer +=
Protocol.message_text(elem, heading = true, pos = pos,
margin = margin, breakgain = breakgain, metric = metric)
}
} if (buffer.nonEmpty) {
progress.echo(thy_heading)
buffer.foreach(progress.echo(_))
}
}
}
}
if (errors.nonEmpty) { val msg = Symbol.output(unicode_symbols, cat_lines(errors))
progress.echo("\nBuild errors:\n" + Output.error_message_text(msg))
} if (rc != Process_Result.RC.ok) {
progress.echo("\n" + Process_Result.RC.print_long(rc))
}
}
}
}
val errors = new mutable.ListBuffer[String] for (session_name <- sessions) {
Exn.result(print(session_name)) match { case Exn.Res(_) => case Exn.Exn(exn) => errors += Exn.message(exn)
}
} if (errors.nonEmpty) error(cat_lines(errors.toList))
}
/* Isabelle tool wrapper */
val isabelle_tool4 = Isabelle_Tool("build_log", "print messages from session build database",
Scala_Project.here,
{ args => /* arguments */
val message_head = new mutable.ListBuffer[Regex] val message_body = new mutable.ListBuffer[Regex] var unicode_symbols = false val theories = new mutable.ListBuffer[String] var margin = Pretty.default_margin var options = Options.init() var verbose = false
val getopts = Getopts("""
Usage: isabelle build_log [OPTIONS] [SESSIONS ...]
Options are:
-H REGEX filter messages by matching against head
-M REGEX filter messages by matching against body
-T NAME restrict to given theories (multiple options possible)
-U output Unicode symbols
-m MARGIN margin for pretty printing (default: """ + margin + """)
-o OPTION override Isabelle system OPTION (via NAME=VAL or NAME)
-v print all messages, including information etc.
Print messages from the session build database of the given sessions,
without any checks against current sources nor session structure: results
from old sessions or failed builds can be printed as well.
Multiple options -H and -M are conjunctive: all given patterns need to match. Patterns match any substring, but ^ or $ may be used to match the
start or end explicitly. """, "H:" -> (arg => message_head += arg.r), "M:" -> (arg => message_body += arg.r), "T:" -> (arg => theories += arg), "U" -> (_ => unicode_symbols = true), "m:" -> (arg => margin = Value.Double.parse(arg)), "o:" -> (arg => options = options + arg), "v" -> (_ => verbose = true))
val sessions = getopts(args)
val progress = new Console_Progress(verbose = verbose)
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.22Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.