| author | wenzelm | 
| Thu, 06 Jun 2024 23:12:04 +0200 | |
| changeset 80275 | c631a44e9f13 | 
| parent 80232 | 99ae8c664667 | 
| child 82022 | 337d3bb65325 | 
| permissions | -rw-r--r-- | 
| 78415 
a4dee214dfcf
clarified file location: to be used by regular Isabelle/Scala tools;
 wenzelm parents: 
78158diff
changeset | 1 | /* Title: Pure/System/other_isabelle.scala | 
| 64188 | 2 | Author: Makarius | 
| 3 | ||
| 77082 | 4 | Manage other Isabelle distributions: support historic versions starting from | 
| 5 | tag "build_history_base". | |
| 64188 | 6 | */ | 
| 7 | ||
| 8 | package isabelle | |
| 9 | ||
| 10 | ||
| 75393 | 11 | object Other_Isabelle {
 | 
| 77050 | 12 | def apply( | 
| 77093 | 13 | root: Path, | 
| 77050 | 14 | isabelle_identifier: String = "", | 
| 77093 | 15 | ssh: SSH.System = SSH.Local, | 
| 77050 | 16 | progress: Progress = new Progress | 
| 17 |   ): Other_Isabelle = {
 | |
| 77093 | 18 | val (isabelle_home, url_prefix) = | 
| 19 |       ssh match {
 | |
| 20 | case session: SSH.Session => (ssh.absolute_path(root), session.rsync_prefix) | |
| 21 | case _ => | |
| 22 |           if (proper_string(System.getenv("ISABELLE_SETTINGS_PRESENT")).isDefined) {
 | |
| 23 |             error("Cannot manage other Isabelle distribution: global ISABELLE_SETTINGS_PRESENT")
 | |
| 24 | } | |
| 25 | (root.canonical, "") | |
| 26 | } | |
| 27 | val isabelle_home_url = url_prefix + isabelle_home.implode | |
| 28 | new Other_Isabelle(isabelle_home, isabelle_identifier, isabelle_home_url, ssh, progress) | |
| 77050 | 29 | } | 
| 67045 | 30 | } | 
| 31 | ||
| 77041 | 32 | final class Other_Isabelle private( | 
| 67045 | 33 | val isabelle_home: Path, | 
| 34 | val isabelle_identifier: String, | |
| 77093 | 35 | isabelle_home_url: String, | 
| 80023 | 36 | val ssh: SSH.System, | 
| 37 | val progress: Progress | |
| 75393 | 38 | ) {
 | 
| 80021 
ba06861e91f9
proper services for Setup_Tool --- avoid hardwired stuff;
 wenzelm parents: 
79681diff
changeset | 39 | other_isabelle => | 
| 
ba06861e91f9
proper services for Setup_Tool --- avoid hardwired stuff;
 wenzelm parents: 
79681diff
changeset | 40 | |
| 77093 | 41 | override def toString: String = isabelle_home_url | 
| 67046 | 42 | |
| 64188 | 43 | |
| 44 | /* static system */ | |
| 45 | ||
| 80231 | 46 | def bash_context(script: String, cwd: Path = isabelle_home): String = | 
| 80227 
af6b60c75d7d
clarified context for (remote) bash scripts: export variables are optional, support cwd;
 wenzelm parents: 
80223diff
changeset | 47 | Bash.context(script, | 
| 
af6b60c75d7d
clarified context for (remote) bash scripts: export variables are optional, support cwd;
 wenzelm parents: 
80223diff
changeset | 48 | user_home = ssh.user_home, | 
| 
af6b60c75d7d
clarified context for (remote) bash scripts: export variables are optional, support cwd;
 wenzelm parents: 
80223diff
changeset | 49 | isabelle_identifier = isabelle_identifier, | 
| 80231 | 50 | cwd = cwd) | 
| 80227 
af6b60c75d7d
clarified context for (remote) bash scripts: export variables are optional, support cwd;
 wenzelm parents: 
80223diff
changeset | 51 | |
| 65930 | 52 | def bash( | 
| 77042 | 53 | script: String, | 
| 80231 | 54 | cwd: Path = isabelle_home, | 
| 77042 | 55 | redirect: Boolean = false, | 
| 56 | echo: Boolean = false, | |
| 57 | strict: Boolean = true | |
| 58 |   ): Process_Result = {
 | |
| 80232 | 59 | ssh.bash(bash_context(script, cwd = cwd), | 
| 77093 | 60 | progress_stdout = progress.echo_if(echo, _), | 
| 61 | progress_stderr = progress.echo_if(echo, _), | |
| 62 | redirect = redirect, | |
| 63 | settings = false, | |
| 64 | strict = strict) | |
| 77042 | 65 | } | 
| 64188 | 66 | |
| 69166 | 67 | def getenv(name: String): String = | 
| 80232 | 68 |     ssh.execute(bash_context("bin/isabelle getenv -b " + Bash.string(name)),
 | 
| 69 | settings = false).check.out | |
| 69166 | 70 | |
| 77080 
7e11e96a922d
more formal Other_Isabelle.settings, with derived expand_path / bash_path;
 wenzelm parents: 
77078diff
changeset | 71 | val settings: Isabelle_System.Settings = (name: String) => getenv(name) | 
| 
7e11e96a922d
more formal Other_Isabelle.settings, with derived expand_path / bash_path;
 wenzelm parents: 
77078diff
changeset | 72 | |
| 
7e11e96a922d
more formal Other_Isabelle.settings, with derived expand_path / bash_path;
 wenzelm parents: 
77078diff
changeset | 73 | def expand_path(path: Path): Path = path.expand_env(settings) | 
| 
7e11e96a922d
more formal Other_Isabelle.settings, with derived expand_path / bash_path;
 wenzelm parents: 
77078diff
changeset | 74 | def bash_path(path: Path): String = Bash.string(expand_path(path).implode) | 
| 64188 | 75 | |
| 77085 
351eee493580
more robust locations (amending 7e11e96a922d) --- notably for cleanup() in build_release, after Admin/ been deleted;
 wenzelm parents: 
77082diff
changeset | 76 |   val isabelle_home_user: Path = expand_path(Path.explode("$ISABELLE_HOME_USER"))
 | 
| 77080 
7e11e96a922d
more formal Other_Isabelle.settings, with derived expand_path / bash_path;
 wenzelm parents: 
77078diff
changeset | 77 | |
| 77085 
351eee493580
more robust locations (amending 7e11e96a922d) --- notably for cleanup() in build_release, after Admin/ been deleted;
 wenzelm parents: 
77082diff
changeset | 78 |   def etc: Path = isabelle_home_user + Path.explode("etc")
 | 
| 77080 
7e11e96a922d
more formal Other_Isabelle.settings, with derived expand_path / bash_path;
 wenzelm parents: 
77078diff
changeset | 79 |   def etc_settings: Path = etc + Path.explode("settings")
 | 
| 
7e11e96a922d
more formal Other_Isabelle.settings, with derived expand_path / bash_path;
 wenzelm parents: 
77078diff
changeset | 80 |   def etc_preferences: Path = etc + Path.explode("preferences")
 | 
| 64188 | 81 | |
| 73625 
f8f065e20837
misc tuning and clarification: more explicit types Release_Context, Release_Archive;
 wenzelm parents: 
73522diff
changeset | 82 | |
| 69388 | 83 | /* components */ | 
| 84 | ||
| 85 | def init_components( | |
| 77128 
f40c36ab154d
clarified names to emphasize suble differences in meaning;
 wenzelm parents: 
77124diff
changeset | 86 | components_base: String = Components.dynamic_components_base, | 
| 77055 | 87 | catalogs: List[String] = Components.default_catalogs, | 
| 75393 | 88 | components: List[String] = Nil | 
| 89 |   ): List[String] = {
 | |
| 77088 
6e2c6ccc5dc0
clarified defaults: imitate "isabelle components -I" without further parameters;
 wenzelm parents: 
77087diff
changeset | 90 | val admin = Components.admin(Path.ISABELLE_HOME).implode | 
| 73240 
3e963d68d394
more robust ISABELLE_COMPONENT_REPOSITORY: use current value of managing process to avoid its fluctuation in ancient history;
 wenzelm parents: 
72375diff
changeset | 91 | |
| 77090 | 92 | catalogs.map(name => | 
| 93 | "init_components " + quote(components_base) + " " + quote(admin + "/" + name)) ::: | |
| 94 | components.map(name => | |
| 95 | "init_component " + quote(components_base) + "/" + name) | |
| 69388 | 96 | } | 
| 97 | ||
| 77097 
023273cf2651
clean components more accurately: purge other platforms or archives;
 wenzelm parents: 
77095diff
changeset | 98 | def resolve_components( | 
| 
023273cf2651
clean components more accurately: purge other platforms or archives;
 wenzelm parents: 
77095diff
changeset | 99 | echo: Boolean = false, | 
| 78610 | 100 | clean_platforms: Option[List[Platform.Family]] = None, | 
| 77124 
be90af1e3254
proper use of current ISABELLE_COMPONENT_REPOSITORY from the managing Isabelle system (amending 3e963d68d394);
 wenzelm parents: 
77123diff
changeset | 101 | clean_archives: Boolean = false, | 
| 77128 
f40c36ab154d
clarified names to emphasize suble differences in meaning;
 wenzelm parents: 
77124diff
changeset | 102 | component_repository: String = Components.static_component_repository | 
| 77097 
023273cf2651
clean components more accurately: purge other platforms or archives;
 wenzelm parents: 
77095diff
changeset | 103 |   ): Unit = {
 | 
| 77093 | 104 |     val missing = Path.split(getenv("ISABELLE_COMPONENTS_MISSING"))
 | 
| 105 |     for (path <- missing) {
 | |
| 77097 
023273cf2651
clean components more accurately: purge other platforms or archives;
 wenzelm parents: 
77095diff
changeset | 106 | Components.resolve(path.dir, path.file_name, | 
| 
023273cf2651
clean components more accurately: purge other platforms or archives;
 wenzelm parents: 
77095diff
changeset | 107 | clean_platforms = clean_platforms, | 
| 
023273cf2651
clean components more accurately: purge other platforms or archives;
 wenzelm parents: 
77095diff
changeset | 108 | clean_archives = clean_archives, | 
| 77124 
be90af1e3254
proper use of current ISABELLE_COMPONENT_REPOSITORY from the managing Isabelle system (amending 3e963d68d394);
 wenzelm parents: 
77123diff
changeset | 109 | component_repository = component_repository, | 
| 77097 
023273cf2651
clean components more accurately: purge other platforms or archives;
 wenzelm parents: 
77095diff
changeset | 110 | ssh = ssh, | 
| 77093 | 111 | progress = if (echo) progress else new Progress) | 
| 112 | } | |
| 113 | } | |
| 114 | ||
| 77094 | 115 |   def scala_build(fresh: Boolean = false, echo: Boolean = false): Unit = {
 | 
| 116 |     if (fresh) ssh.rm_tree(isabelle_home + Path.explode("lib/classes"))
 | |
| 117 | ||
| 118 |     val dummy_stty = Path.explode("~~/lib/dummy_stty/stty")
 | |
| 119 | val dummy_stty_remote = expand_path(dummy_stty) | |
| 120 |     if (!ssh.is_file(dummy_stty_remote)) {
 | |
| 121 | ssh.make_directory(dummy_stty_remote.dir) | |
| 122 | ssh.write_file(dummy_stty_remote, dummy_stty) | |
| 78158 | 123 | ssh.set_executable(dummy_stty_remote) | 
| 77094 | 124 | } | 
| 125 |     try {
 | |
| 126 | bash( | |
| 127 | "export PATH=\"" + bash_path(dummy_stty_remote.dir) + ":$PATH\"\n" + | |
| 128 |         "export CLASSPATH=" + Bash.string(getenv("ISABELLE_CLASSPATH")) + "\n" +
 | |
| 129 | "bin/isabelle jedit -b", echo = echo).check | |
| 130 | } | |
| 131 |     catch { case ERROR(msg) => cat_error("Failed to build Isabelle/Scala/Java modules:", msg) }
 | |
| 132 | } | |
| 133 | ||
| 69388 | 134 | |
| 69168 
68816d1c73a7
eliminated "isabelle makedist" -- prefer Scala over bash/perl scripting;
 wenzelm parents: 
69166diff
changeset | 135 | /* settings */ | 
| 
68816d1c73a7
eliminated "isabelle makedist" -- prefer Scala over bash/perl scripting;
 wenzelm parents: 
69166diff
changeset | 136 | |
| 
68816d1c73a7
eliminated "isabelle makedist" -- prefer Scala over bash/perl scripting;
 wenzelm parents: 
69166diff
changeset | 137 | def clean_settings(): Boolean = | 
| 77093 | 138 | if (!ssh.is_file(etc_settings)) true | 
| 139 |     else if (ssh.read(etc_settings).startsWith("# generated by Isabelle")) {
 | |
| 140 | ssh.delete(etc_settings) | |
| 77042 | 141 | true | 
| 69168 
68816d1c73a7
eliminated "isabelle makedist" -- prefer Scala over bash/perl scripting;
 wenzelm parents: 
69166diff
changeset | 142 | } | 
| 
68816d1c73a7
eliminated "isabelle makedist" -- prefer Scala over bash/perl scripting;
 wenzelm parents: 
69166diff
changeset | 143 | else false | 
| 64188 | 144 | |
| 75393 | 145 |   def init_settings(settings: List[String]): Unit = {
 | 
| 77078 | 146 |     if (clean_settings()) {
 | 
| 77093 | 147 | ssh.make_directory(etc_settings.dir) | 
| 148 | ssh.write(etc_settings, | |
| 77078 | 149 | "# generated by Isabelle " + Date.now() + "\n" + | 
| 150 | "#-*- shell-script -*- :mode=shellscript:\n" + | |
| 151 |         settings.mkString("\n", "\n", "\n"))
 | |
| 77042 | 152 | } | 
| 77078 | 153 |     else error("Cannot proceed with existing user settings file: " + etc_settings)
 | 
| 64188 | 154 | } | 
| 69168 
68816d1c73a7
eliminated "isabelle makedist" -- prefer Scala over bash/perl scripting;
 wenzelm parents: 
69166diff
changeset | 155 | |
| 79681 
df1059ea8846
propagate property "isabelle.debug", notably for Java/Scala exception trace;
 wenzelm parents: 
79633diff
changeset | 156 |   def debug_settings(): List[String] = {
 | 
| 
df1059ea8846
propagate property "isabelle.debug", notably for Java/Scala exception trace;
 wenzelm parents: 
79633diff
changeset | 157 |     val debug = System.getProperty("isabelle.debug", "") == "true"
 | 
| 
df1059ea8846
propagate property "isabelle.debug", notably for Java/Scala exception trace;
 wenzelm parents: 
79633diff
changeset | 158 |     if (debug) {
 | 
| 
df1059ea8846
propagate property "isabelle.debug", notably for Java/Scala exception trace;
 wenzelm parents: 
79633diff
changeset | 159 |       List("ISABELLE_JAVA_SYSTEM_OPTIONS=\"$ISABELLE_JAVA_SYSTEM_OPTIONS -Disabelle.debug=true\"")
 | 
| 
df1059ea8846
propagate property "isabelle.debug", notably for Java/Scala exception trace;
 wenzelm parents: 
79633diff
changeset | 160 | } | 
| 
df1059ea8846
propagate property "isabelle.debug", notably for Java/Scala exception trace;
 wenzelm parents: 
79633diff
changeset | 161 | else Nil | 
| 
df1059ea8846
propagate property "isabelle.debug", notably for Java/Scala exception trace;
 wenzelm parents: 
79633diff
changeset | 162 | } | 
| 
df1059ea8846
propagate property "isabelle.debug", notably for Java/Scala exception trace;
 wenzelm parents: 
79633diff
changeset | 163 | |
| 69168 
68816d1c73a7
eliminated "isabelle makedist" -- prefer Scala over bash/perl scripting;
 wenzelm parents: 
69166diff
changeset | 164 | |
| 77123 | 165 | /* init */ | 
| 166 | ||
| 77095 | 167 | def init( | 
| 168 | other_settings: List[String] = init_components(), | |
| 169 | fresh: Boolean = false, | |
| 77097 
023273cf2651
clean components more accurately: purge other platforms or archives;
 wenzelm parents: 
77095diff
changeset | 170 | echo: Boolean = false, | 
| 78610 | 171 | clean_platforms: Option[List[Platform.Family]] = None, | 
| 77124 
be90af1e3254
proper use of current ISABELLE_COMPONENT_REPOSITORY from the managing Isabelle system (amending 3e963d68d394);
 wenzelm parents: 
77123diff
changeset | 172 | clean_archives: Boolean = false, | 
| 77128 
f40c36ab154d
clarified names to emphasize suble differences in meaning;
 wenzelm parents: 
77124diff
changeset | 173 | component_repository: String = Components.static_component_repository | 
| 77095 | 174 |   ): Unit = {
 | 
| 175 | init_settings(other_settings) | |
| 77097 
023273cf2651
clean components more accurately: purge other platforms or archives;
 wenzelm parents: 
77095diff
changeset | 176 | resolve_components( | 
| 
023273cf2651
clean components more accurately: purge other platforms or archives;
 wenzelm parents: 
77095diff
changeset | 177 | echo = echo, | 
| 
023273cf2651
clean components more accurately: purge other platforms or archives;
 wenzelm parents: 
77095diff
changeset | 178 | clean_platforms = clean_platforms, | 
| 77124 
be90af1e3254
proper use of current ISABELLE_COMPONENT_REPOSITORY from the managing Isabelle system (amending 3e963d68d394);
 wenzelm parents: 
77123diff
changeset | 179 | clean_archives = clean_archives, | 
| 
be90af1e3254
proper use of current ISABELLE_COMPONENT_REPOSITORY from the managing Isabelle system (amending 3e963d68d394);
 wenzelm parents: 
77123diff
changeset | 180 | component_repository = component_repository) | 
| 77095 | 181 | scala_build(fresh = fresh, echo = echo) | 
| 80021 
ba06861e91f9
proper services for Setup_Tool --- avoid hardwired stuff;
 wenzelm parents: 
79681diff
changeset | 182 | Setup_Tool.init(other_isabelle) | 
| 77095 | 183 | } | 
| 184 | ||
| 185 | ||
| 69168 
68816d1c73a7
eliminated "isabelle makedist" -- prefer Scala over bash/perl scripting;
 wenzelm parents: 
69166diff
changeset | 186 | /* cleanup */ | 
| 
68816d1c73a7
eliminated "isabelle makedist" -- prefer Scala over bash/perl scripting;
 wenzelm parents: 
69166diff
changeset | 187 | |
| 75393 | 188 |   def cleanup(): Unit = {
 | 
| 69168 
68816d1c73a7
eliminated "isabelle makedist" -- prefer Scala over bash/perl scripting;
 wenzelm parents: 
69166diff
changeset | 189 | clean_settings() | 
| 80223 | 190 | ssh.delete(etc, isabelle_home_user) | 
| 69168 
68816d1c73a7
eliminated "isabelle makedist" -- prefer Scala over bash/perl scripting;
 wenzelm parents: 
69166diff
changeset | 191 | } | 
| 64188 | 192 | } |