36 sealed case class Key(name: String, order: Int) |
36 sealed case class Key(name: String, order: Int) |
37 { |
37 { |
38 override def toString: String = name |
38 override def toString: String = name |
39 } |
39 } |
40 |
40 |
|
41 |
|
42 /* Info */ |
|
43 |
|
44 sealed abstract class Status |
|
45 case object Pending extends Status |
|
46 case object Running extends Status |
|
47 |
41 sealed case class Info( |
48 sealed case class Info( |
42 dir: Path, |
49 dir: Path, |
43 parent: Option[String], |
50 parent: Option[String], |
44 description: String, |
51 description: String, |
45 options: Options, |
52 options: Options, |
46 theories: List[(Options, List[String])], |
53 theories: List[(Options, List[Path])], |
47 files: List[String]) |
54 files: List[Path], |
|
55 status: Status = Pending) |
|
56 |
|
57 |
|
58 /* Queue */ |
48 |
59 |
49 object Queue |
60 object Queue |
50 { |
61 { |
51 val empty: Queue = new Queue() |
62 val empty: Queue = new Queue() |
52 } |
63 } |
185 case Some(p) => Path.explode(p) |
197 case Some(p) => Path.explode(p) |
186 case None => Path.basic(entry.name) |
198 case None => Path.basic(entry.name) |
187 } |
199 } |
188 |
200 |
189 val key = Session.Key(full_name, entry.order) |
201 val key = Session.Key(full_name, entry.order) |
|
202 |
|
203 val theories = |
|
204 entry.theories.map({ case (opts, thys) => (options ++ opts, thys.map(Path.explode(_))) }) |
|
205 val files = entry.files.map(Path.explode(_)) |
190 val info = |
206 val info = |
191 Session.Info(dir + path, entry.parent, |
207 Session.Info(dir + path, entry.parent, |
192 entry.description, entry.options, entry.theories, entry.files) |
208 entry.description, options ++ entry.options, theories, files) |
193 |
209 |
194 queue1 + (key, info) |
210 queue1 + (key, info) |
195 } |
211 } |
196 catch { |
212 catch { |
197 case ERROR(msg) => |
213 case ERROR(msg) => |
198 error(msg + "\nThe error(s) above occurred in session entry " + |
214 error(msg + "\nThe error(s) above occurred in session entry " + |
199 quote(entry.name) + Position.str_of(Position.file(root))) |
215 quote(entry.name) + Position.str_of(Position.file(root))) |
200 }) |
216 }) |
201 } |
217 } |
202 |
218 |
203 private def sessions_dir(strict: Boolean, dir: Path, queue: Session.Queue): Session.Queue = |
219 private def sessions_dir(options: Options, strict: Boolean, dir: Path, queue: Session.Queue) |
|
220 : Session.Queue = |
204 { |
221 { |
205 val root = (dir + ROOT).file |
222 val root = (dir + ROOT).file |
206 if (root.isFile) sessions_root(dir, root, queue) |
223 if (root.isFile) sessions_root(options, dir, root, queue) |
207 else if (strict) error("Bad session root file: " + quote(root.toString)) |
224 else if (strict) error("Bad session root file: " + quote(root.toString)) |
208 else queue |
225 else queue |
209 } |
226 } |
210 |
227 |
211 private def sessions_catalog(dir: Path, catalog: JFile, queue: Session.Queue): Session.Queue = |
228 private def sessions_catalog(options: Options, dir: Path, catalog: JFile, queue: Session.Queue) |
|
229 : Session.Queue = |
212 { |
230 { |
213 val dirs = |
231 val dirs = |
214 split_lines(File.read(catalog)).filterNot(line => line == "" || line.startsWith("#")) |
232 split_lines(File.read(catalog)).filterNot(line => line == "" || line.startsWith("#")) |
215 (queue /: dirs)((queue1, dir1) => |
233 (queue /: dirs)((queue1, dir1) => |
216 try { |
234 try { |
217 val dir2 = dir + Path.explode(dir1) |
235 val dir2 = dir + Path.explode(dir1) |
218 if (dir2.file.isDirectory) sessions_dir(true, dir2, queue1) |
236 if (dir2.file.isDirectory) sessions_dir(options, true, dir2, queue1) |
219 else error("Bad session directory: " + dir2.toString) |
237 else error("Bad session directory: " + dir2.toString) |
220 } |
238 } |
221 catch { |
239 catch { |
222 case ERROR(msg) => |
240 case ERROR(msg) => |
223 error(msg + "\nThe error(s) above occurred in session catalog " + quote(catalog.toString)) |
241 error(msg + "\nThe error(s) above occurred in session catalog " + quote(catalog.toString)) |
224 }) |
242 }) |
225 } |
243 } |
226 |
244 |
227 def find_sessions(all_sessions: Boolean, sessions: List[String], |
245 def find_sessions(options: Options, all_sessions: Boolean, sessions: List[String], |
228 more_dirs: List[Path]): Session.Queue = |
246 more_dirs: List[Path]): Session.Queue = |
229 { |
247 { |
230 var queue = Session.Queue.empty |
248 var queue = Session.Queue.empty |
231 |
249 |
232 for (dir <- Isabelle_System.components()) { |
250 for (dir <- Isabelle_System.components()) { |
233 queue = sessions_dir(false, dir, queue) |
251 queue = sessions_dir(options, false, dir, queue) |
234 |
252 |
235 val catalog = (dir + SESSIONS).file |
253 val catalog = (dir + SESSIONS).file |
236 if (catalog.isFile) |
254 if (catalog.isFile) |
237 queue = sessions_catalog(dir, catalog, queue) |
255 queue = sessions_catalog(options, dir, catalog, queue) |
238 } |
256 } |
239 |
257 |
240 for (dir <- more_dirs) queue = sessions_dir(true, dir, queue) |
258 for (dir <- more_dirs) queue = sessions_dir(options, true, dir, queue) |
241 |
259 |
242 sessions.filter(name => !queue.defined(name)) match { |
260 sessions.filter(name => !queue.defined(name)) match { |
243 case Nil => |
261 case Nil => |
244 case bad => error("Undefined session(s): " + commas_quote(bad)) |
262 case bad => error("Undefined session(s): " + commas_quote(bad)) |
245 } |
263 } |
298 """ |
316 """ |
299 } |
317 } |
300 val args_xml = |
318 val args_xml = |
301 { |
319 { |
302 import XML.Encode._ |
320 import XML.Encode._ |
303 def symbol_string: T[String] = (s => string(Symbol.encode(s))) |
321 pair(bool, pair(string, pair(string, list(string))))( |
304 pair(bool, pair(symbol_string, pair(symbol_string, list(symbol_string))))( |
322 save, (parent, (name, info.theories.map(_._2).flatten.map(_.implode)))) |
305 save, (parent, (name, info.theories.map(_._2).flatten))) |
|
306 } |
323 } |
307 new Build_Job(cwd, env, script, YXML.string_of_body(args_xml)) |
324 new Build_Job(cwd, env, script, YXML.string_of_body(args_xml)) |
308 } |
325 } |
309 |
326 |
310 def build(all_sessions: Boolean, build_images: Boolean, list_only: Boolean, |
327 def build(all_sessions: Boolean, build_images: Boolean, list_only: Boolean, |
311 more_dirs: List[Path], more_options: List[String], sessions: List[String]): Int = |
328 more_dirs: List[Path], more_options: List[String], sessions: List[String]): Int = |
312 { |
329 { |
313 val options = (Options.init() /: more_options)(_.define_simple(_)) |
330 val options = (Options.init() /: more_options)(_.define_simple(_)) |
314 val queue = find_sessions(all_sessions, sessions, more_dirs) |
331 val queue = find_sessions(options, all_sessions, sessions, more_dirs) |
315 |
332 |
316 |
333 |
317 // prepare browser info dir |
334 // prepare browser info dir |
318 if (options.bool("browser_info") && |
335 if (options.bool("browser_info") && |
319 !Path.explode("$ISABELLE_BROWSER_INFO/index.html").file.isFile) |
336 !Path.explode("$ISABELLE_BROWSER_INFO/index.html").file.isFile) |