src/Pure/System/cygwin_init.scala
changeset 53459 33f773731f0c
parent 53452 8181bc357dc4
child 53460 6015a663b889
equal deleted inserted replaced
53458:ddefd18d5ed0 53459:33f773731f0c
     1 /*  Title:      Pure/System/cygwin_init.scala
     1 /*  Title:      Pure/System/cygwin_init.scala
     2     Author:     Makarius
     2     Author:     Makarius
     3 
     3 
     4 Initialize Isabelle distribution after extracting via 7zip.
     4 Initialize raw Isabelle distribution (e.g. after extraction via 7zip).
     5 */
     5 */
     6 
     6 
     7 package isabelle
     7 package isabelle
     8 
     8 
     9 
     9 
    10 import java.io.{File => JFile, BufferedReader, InputStreamReader}
    10 import java.io.{File => JFile, BufferedReader, InputStreamReader}
    11 import java.nio.file.{Paths, Files}
    11 import java.nio.file.Files
    12 import java.awt.{GraphicsEnvironment, Point, Font}
       
    13 import javax.swing.ImageIcon
       
    14 
    12 
    15 import scala.annotation.tailrec
    13 import scala.annotation.tailrec
    16 import scala.swing.{ScrollPane, Button, FlowPanel,
       
    17   BorderPanel, MainFrame, TextArea, SwingApplication}
       
    18 import scala.swing.event.ButtonClicked
       
    19 
    14 
    20 
    15 
    21 object Cygwin_Init
    16 object Cygwin_Init
    22 {
    17 {
    23   /* main GUI entry point */
    18   def filesystem(system_dialog: System_Dialog, isabelle_home: String)
    24 
       
    25   def main_frame(isabelle_home: String, continue: Int => Unit) = new MainFrame
       
    26   {
    19   {
    27     title = "Isabelle system initialization"
    20     system_dialog.title("Isabelle system initialization")
    28     iconImage = GUI.isabelle_image()
    21     system_dialog.echo("Initializing Cygwin:")
    29 
       
    30     val layout_panel = new BorderPanel
       
    31     contents = layout_panel
       
    32 
       
    33 
       
    34     /* text area */
       
    35 
       
    36     def echo(msg: String) { text_area.append(msg + "\n") }
       
    37 
       
    38     val text_area = new TextArea {
       
    39       font = new Font("SansSerif", Font.PLAIN, GUI.resolution_scale(10) max 14)
       
    40       editable = false
       
    41       columns = 50
       
    42       rows = 15
       
    43     }
       
    44 
       
    45     layout_panel.layout(new ScrollPane(text_area)) = BorderPanel.Position.Center
       
    46 
       
    47 
       
    48     /* exit button */
       
    49 
       
    50     var _return_code: Option[Int] = None
       
    51     def maybe_exit()
       
    52     {
       
    53       _return_code match {
       
    54         case None =>
       
    55         case Some(rc) =>
       
    56           visible = false
       
    57           continue(rc)
       
    58       }
       
    59     }
       
    60 
       
    61     def return_code(rc: Int): Unit =
       
    62       Swing_Thread.later {
       
    63         _return_code = Some(rc)
       
    64         button.peer.getRootPane.setDefaultButton(button.peer)
       
    65         layout_panel.repaint
       
    66       }
       
    67 
       
    68     override def closeOperation { maybe_exit() }
       
    69 
       
    70     val button = new Button {
       
    71       text = "Done"
       
    72       reactions += { case ButtonClicked(_) => maybe_exit() }
       
    73     }
       
    74     val button_panel = new FlowPanel(FlowPanel.Alignment.Center)(button)
       
    75 
       
    76     layout_panel.layout(button_panel) = BorderPanel.Position.South
       
    77 
       
    78 
       
    79     /* show window */
       
    80 
       
    81     pack()
       
    82     val point = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint()
       
    83     location = new Point(point.x - size.width / 2, point.y - size.height / 2)
       
    84     visible = true
       
    85 
       
    86     default_thread_pool.submit(() =>
       
    87       try {
       
    88         init_filesystem(isabelle_home, echo)
       
    89         return_code(0)
       
    90       }
       
    91       catch {
       
    92         case exn: Throwable =>
       
    93           text_area.append("Error:\n" + Exn.message(exn) + "\n")
       
    94           return_code(2)
       
    95       }
       
    96     )
       
    97   }
       
    98 
       
    99 
       
   100   /* init Cygwin file-system */
       
   101 
       
   102   private def init_filesystem(isabelle_home: String, echo: String => Unit)
       
   103   {
       
   104     val cygwin_root = isabelle_home + "\\contrib\\cygwin"
       
   105 
    22 
   106     def execute(args: String*): Int =
    23     def execute(args: String*): Int =
   107     {
    24     {
   108       val cwd = new JFile(isabelle_home)
    25       val cwd = new JFile(isabelle_home)
   109       val env = Map("CYGWIN" -> "nodosfilewarning")
    26       val env = Map("CYGWIN" -> "nodosfilewarning")
   112 
    29 
   113       val stdout = new BufferedReader(new InputStreamReader(proc.getInputStream, UTF8.charset))
    30       val stdout = new BufferedReader(new InputStreamReader(proc.getInputStream, UTF8.charset))
   114       try {
    31       try {
   115         var line = stdout.readLine
    32         var line = stdout.readLine
   116         while (line != null) {
    33         while (line != null) {
   117           echo(line)
    34           system_dialog.echo(line)
   118           line = stdout.readLine
    35           line = stdout.readLine
   119         }
    36         }
   120       }
    37       }
   121       finally { stdout.close }
    38       finally { stdout.close }
   122 
    39 
   123       proc.waitFor
    40       proc.waitFor
   124     }
    41     }
   125 
    42 
   126     echo("Initializing Cygwin:")
    43     val cygwin_root = isabelle_home + "\\contrib\\cygwin"
   127 
    44 
   128     echo("symlinks ...")
    45     system_dialog.echo("symlinks ...")
   129     val symlinks =
    46     val symlinks =
   130     {
    47     {
   131       val path = (new JFile(cygwin_root + "\\isabelle\\symlinks")).toPath
    48       val path = (new JFile(cygwin_root + "\\isabelle\\symlinks")).toPath
   132       Files.readAllLines(path, UTF8.charset).toArray.toList.asInstanceOf[List[String]]
    49       Files.readAllLines(path, UTF8.charset).toArray.toList.asInstanceOf[List[String]]
   133     }
    50     }
   148         case _ => error("Unbalanced symlinks list")
    65         case _ => error("Unbalanced symlinks list")
   149       }
    66       }
   150     }
    67     }
   151     recover_symlinks(symlinks)
    68     recover_symlinks(symlinks)
   152 
    69 
   153     echo("rebaseall ...")
    70     system_dialog.echo("rebaseall ...")
   154     execute(cygwin_root + "\\bin\\dash.exe", "/isabelle/rebaseall")
    71     execute(cygwin_root + "\\bin\\dash.exe", "/isabelle/rebaseall")
   155 
    72 
   156     echo("postinstall ...")
    73     system_dialog.echo("postinstall ...")
   157     execute(cygwin_root + "\\bin\\bash.exe", "/isabelle/postinstall")
    74     execute(cygwin_root + "\\bin\\bash.exe", "/isabelle/postinstall")
   158 
    75 
   159     echo("init ...")
    76     system_dialog.echo("init ...")
   160     Isabelle_System.init()
    77     Isabelle_System.init()
   161     echo("OK")
    78     system_dialog.echo("OK")
   162   }
    79   }
   163 }
    80 }
   164 
    81