src/Pure/System/isabelle_env.scala
changeset 73893 eb7655fcb090
parent 73891 6c9044f04756
child 73895 b709faa96586
equal deleted inserted replaced
73892:2847a3deedf9 73893:eb7655fcb090
     7 
     7 
     8 package isabelle
     8 package isabelle
     9 
     9 
    10 
    10 
    11 import java.io.{File => JFile}
    11 import java.io.{File => JFile}
       
    12 import java.nio.file.Files
    12 
    13 
    13 import scala.jdk.CollectionConverters._
    14 import scala.jdk.CollectionConverters._
    14 
    15 import scala.annotation.tailrec
    15 
    16 
    16 
    17 
    17 object Isabelle_Env
    18 object Isabelle_Env
    18 {
    19 {
    19   /** bootstrap information **/
    20   /** bootstrap information **/
    37       proper_string(System.getProperty(property)) getOrElse  // e.g. via JVM application boot process
    38       proper_string(System.getProperty(property)) getOrElse  // e.g. via JVM application boot process
    38       error("Unknown " + description + " directory")
    39       error("Unknown " + description + " directory")
    39 
    40 
    40     if ((new JFile(value)).isDirectory) value
    41     if ((new JFile(value)).isDirectory) value
    41     else error("Bad " + description + " directory " + quote(value))
    42     else error("Bad " + description + " directory " + quote(value))
       
    43   }
       
    44 
       
    45 
       
    46 
       
    47   /** Support for Cygwin as POSIX emulation on Windows **/
       
    48 
       
    49   /* symlink emulation */
       
    50 
       
    51   def cygwin_link(content: String, target: JFile): Unit =
       
    52   {
       
    53     val target_path = target.toPath
       
    54     Files.writeString(target_path, "!<symlink>" + content + "\u0000")
       
    55     Files.setAttribute(target_path, "dos:system", true)
       
    56   }
       
    57 
       
    58 
       
    59   /* init (e.g. after extraction via 7zip) */
       
    60 
       
    61   def cygwin_init(isabelle_root: String, cygwin_root: String): Unit =
       
    62   {
       
    63     require(Platform.is_windows, "Windows platform expected")
       
    64 
       
    65     def exec(cmdline: String*): Unit =
       
    66     {
       
    67       val cwd = new JFile(isabelle_root)
       
    68       val env = sys.env + ("CYGWIN" -> "nodosfilewarning")
       
    69       val proc = Isabelle_Env.process(cmdline.toList, cwd = cwd, env = env, redirect = true)
       
    70       val (output, rc) = Isabelle_Env.process_output(proc)
       
    71       if (rc != 0) error(output)
       
    72     }
       
    73 
       
    74     val uninitialized_file = new JFile(cygwin_root, "isabelle\\uninitialized")
       
    75     val uninitialized = uninitialized_file.isFile && uninitialized_file.delete
       
    76 
       
    77     if (uninitialized) {
       
    78       val symlinks =
       
    79       {
       
    80         val path = (new JFile(cygwin_root + "\\isabelle\\symlinks")).toPath
       
    81         Files.readAllLines(path, UTF8.charset).toArray.toList.asInstanceOf[List[String]]
       
    82       }
       
    83       @tailrec def recover_symlinks(list: List[String]): Unit =
       
    84       {
       
    85         list match {
       
    86           case Nil | List("") =>
       
    87           case target :: content :: rest =>
       
    88             cygwin_link(content, new JFile(isabelle_root, target))
       
    89             recover_symlinks(rest)
       
    90           case _ => error("Unbalanced symlinks list")
       
    91         }
       
    92       }
       
    93       recover_symlinks(symlinks)
       
    94 
       
    95       exec(cygwin_root + "\\bin\\dash.exe", "/isabelle/rebaseall")
       
    96       exec(cygwin_root + "\\bin\\bash.exe", "/isabelle/postinstall")
       
    97     }
    42   }
    98   }
    43 
    99 
    44 
   100 
    45 
   101 
    46   /** raw process **/
   102   /** raw process **/
   104       val cygwin_root1 =
   160       val cygwin_root1 =
   105         if (Platform.is_windows)
   161         if (Platform.is_windows)
   106           bootstrap_directory(cygwin_root, "CYGWIN_ROOT", "cygwin.root", "Cygwin root")
   162           bootstrap_directory(cygwin_root, "CYGWIN_ROOT", "cygwin.root", "Cygwin root")
   107         else ""
   163         else ""
   108 
   164 
   109       if (Platform.is_windows) Cygwin.init(isabelle_root1, cygwin_root1)
   165       if (Platform.is_windows) cygwin_init(isabelle_root1, cygwin_root1)
   110 
   166 
   111       def set_cygwin_root(): Unit =
   167       def set_cygwin_root(): Unit =
   112       {
   168       {
   113         if (Platform.is_windows)
   169         if (Platform.is_windows)
   114           _settings = Some(_settings.getOrElse(Map.empty) + ("CYGWIN_ROOT" -> cygwin_root1))
   170           _settings = Some(_settings.getOrElse(Map.empty) + ("CYGWIN_ROOT" -> cygwin_root1))