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 |