val default_components_base: Path = Path.explode("$ISABELLE_COMPONENTS_BASE") val dynamic_components_base: String = "${ISABELLE_COMPONENTS_BASE:-$USER_HOME/.isabelle/contrib}" val classic_components_base: Path = Path.explode("$USER_HOME/.isabelle/contrib")
val default_catalogs: List[String] = List("main") val optional_catalogs: List[String] = List("main", "optional")
def admin(dir: Path): Path = dir + Path.explode("Admin/components")
def read_components_sha1(lines: List[String] = Nil): List[SHA1_Entry] =
(proper_list(lines) getOrElse split_lines(File.read(components_sha1))).flatMap(line =>
Word.explode(line) match { case Nil => None case List(sha1, name) => Some(SHA1_Entry(SHA1.fake_digest(sha1), name)) case _ => error("Bad components.sha1 entry: " + quote(line))
})
def write_components_sha1(entries: List[SHA1_Entry]): Unit =
File.write(components_sha1, entries.sortBy(_.name).mkString)
/** manage user components **/
val components_path: Path = Path.explode("$ISABELLE_HOME_USER/etc/components")
def read_components(): List[String] = if (components_path.is_file) Library.trim_split_lines(File.read(components_path)) else Nil
def write_components(lines: List[String]): Unit = {
Isabelle_System.make_directory(components_path.dir)
File.write(components_path, terminate_lines(lines))
}
def update_components(add: Boolean, path0: Path, progress: Progress = new Progress): Unit = { val path = path0.expand.absolute if (add) Directory(path).check
val lines1 = read_components() val lines2 =
lines1.filter(line =>
line.isEmpty || line.startsWith("#") || !File.eq(Path.explode(line), path)) val lines3 = if (add) lines2 ::: List(path.implode) else lines2
if (lines1 != lines3) write_components(lines3)
val prefix = if (lines1 == lines3) "Unchanged"elseif (add) "Added"else"Removed"
progress.echo(prefix + " component " + path)
}
/* main entry point */
def main(args: Array[String]): Unit = {
Command_Line.tool { for (arg <- args) { val add = if (arg.startsWith("+")) true elseif (arg.startsWith("-")) false else error("Bad argument: " + quote(arg)) val path = Path.explode(arg.substring(1))
update_components(add, path, progress = new Console_Progress)
}
}
}
/** build and publish components **/
def components_build(
options: Options,
components: List[Path],
progress: Progress = new Progress,
publish: Boolean = false,
force: Boolean = false,
update_components_sha1: Boolean = false
): Unit = { val archives: List[Path] = for (path <- components) yield {
path.file_name match { case Archive(_) => path case name =>
Directory(path).check val component_path = path.expand val archive_dir = component_path.dir val archive_name = Archive(name)
val archive = archive_dir + Path.explode(archive_name) if (archive.is_file && !force) {
error("Component archive already exists: " + archive)
}
if ((publish && archives.nonEmpty) || update_components_sha1) { val server = options.string("isabelle_components_server") if (server.isEmpty) error("Undefined option isabelle_components_server")
using(SSH.open_session(options, server)) { ssh => val components_dir = Path.explode(options.string("isabelle_components_dir")) val contrib_dir = Path.explode(options.string("isabelle_components_contrib_dir"))
for (dir <- List(components_dir, contrib_dir) if !ssh.is_dir(dir)) {
error("Bad remote directory: " + dir)
}
if (publish) { for (archive <- archives) { val archive_name = archive.file_name val name = Archive.get_name(archive_name) val remote_component = components_dir + archive.base val remote_contrib = contrib_dir + Path.explode(name)
// local SHA1 digests
{ val new_entries = for (archive <- archives) yield { val name = archive.file_name
progress.echo("Digesting local " + name)
SHA1_Entry(SHA1.digest(archive), name)
} val new_names = new_entries.map(_.name).toSet
val isabelle_tool =
Isabelle_Tool("components_build", "build and publish Isabelle components",
Scala_Project.here,
{ args => var publish = false var update_components_sha1 = false var force = false var options = Options.init()
val getopts = Getopts("""
Usage: isabelle components_build [OPTIONS] ARCHIVES... DIRS...
Options are:
-P publish on SSH server (see options below)
-f force: overwrite existing component archives and directories
-o OPTION override Isabelle system OPTION (via NAME=VAL or NAME)
-u update all SHA1 keys in Isabelle repository Admin/components
Build and publish Isabelle components as .tar.gz archives on SSH server,
depending on system options:
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.