63 cycle.map(c => quote(c.toString)).mkString(" via ")))) |
64 cycle.map(c => quote(c.toString)).mkString(" via ")))) |
64 }) |
65 }) |
65 |
66 |
66 def - (name: String): Queue = new Queue(graph.del_node(name)) |
67 def - (name: String): Queue = new Queue(graph.del_node(name)) |
67 |
68 |
68 def required(names: List[String]): Queue = |
69 def required(groups: List[String], names: List[String]): Queue = |
69 new Queue(graph.restrict(graph.all_preds(names).toSet)) |
70 { |
|
71 val selected_group = groups.toSet |
|
72 val selected_name = names.toSet |
|
73 val selected = |
|
74 graph.keys.filter(name => |
|
75 selected_name(name) || apply(name).groups.exists(selected_group)).toList |
|
76 new Queue(graph.restrict(graph.all_preds(selected).toSet)) |
|
77 } |
70 |
78 |
71 def dequeue(skip: String => Boolean): Option[(String, Info)] = |
79 def dequeue(skip: String => Boolean): Option[(String, Info)] = |
72 { |
80 { |
73 val it = graph.entries.dropWhile( |
81 val it = graph.entries.dropWhile( |
74 { case (name, (_, (deps, _))) => !deps.isEmpty || skip(name) }) |
82 { case (name, (_, (deps, _))) => !deps.isEmpty || skip(name) }) |
85 /* parsing */ |
93 /* parsing */ |
86 |
94 |
87 private case class Session_Entry( |
95 private case class Session_Entry( |
88 name: String, |
96 name: String, |
89 this_name: Boolean, |
97 this_name: Boolean, |
|
98 groups: List[String], |
90 path: Option[String], |
99 path: Option[String], |
91 parent: Option[String], |
100 parent: Option[String], |
92 description: String, |
101 description: String, |
93 options: List[Options.Spec], |
102 options: List[Options.Spec], |
94 theories: List[(List[Options.Spec], List[String])], |
103 theories: List[(List[Options.Spec], List[String])], |
119 keyword(THEORIES) ~! ((options | success(Nil)) ~ rep1(theory_name)) ^^ |
128 keyword(THEORIES) ~! ((options | success(Nil)) ~ rep1(theory_name)) ^^ |
120 { case _ ~ (x ~ y) => (x, y) } |
129 { case _ ~ (x ~ y) => (x, y) } |
121 |
130 |
122 ((keyword(SESSION) ~! session_name) ^^ { case _ ~ x => x }) ~ |
131 ((keyword(SESSION) ~! session_name) ^^ { case _ ~ x => x }) ~ |
123 (keyword("!") ^^^ true | success(false)) ~ |
132 (keyword("!") ^^^ true | success(false)) ~ |
|
133 (keyword("(") ~! (rep1(name) <~ keyword(")")) ^^ { case _ ~ x => x } | success(Nil)) ~ |
124 (opt(keyword(IN) ~! string ^^ { case _ ~ x => x })) ~ |
134 (opt(keyword(IN) ~! string ^^ { case _ ~ x => x })) ~ |
125 (keyword("=") ~> opt(session_name <~ keyword("+"))) ~ |
135 (keyword("=") ~> opt(session_name <~ keyword("+"))) ~ |
126 (keyword(DESCRIPTION) ~! text ^^ { case _ ~ x => x } | success("")) ~ |
136 (keyword(DESCRIPTION) ~! text ^^ { case _ ~ x => x } | success("")) ~ |
127 (keyword(OPTIONS) ~! options ^^ { case _ ~ x => x } | success(Nil)) ~ |
137 (keyword(OPTIONS) ~! options ^^ { case _ ~ x => x } | success(Nil)) ~ |
128 rep(theories) ~ |
138 rep(theories) ~ |
129 (keyword(FILES) ~! rep1(path) ^^ { case _ ~ x => x } | success(Nil)) ^^ |
139 (keyword(FILES) ~! rep1(path) ^^ { case _ ~ x => x } | success(Nil)) ^^ |
130 { case a ~ b ~ c ~ d ~ e ~ f ~ g ~ h => Session_Entry(a, b, c, d, e, f, g, h) } |
140 { case a ~ b ~ c ~ d ~ e ~ f ~ g ~ h ~ i => Session_Entry(a, b, c, d, e, f, g, h, i) } |
131 } |
141 } |
132 |
142 |
133 def parse_entries(root: JFile): List[Session_Entry] = |
143 def parse_entries(root: JFile): List[Session_Entry] = |
134 { |
144 { |
135 val toks = syntax.scan(File.read(root)) |
145 val toks = syntax.scan(File.read(root)) |
184 (session_options ++ opts, thys.map(Path.explode(_))) }) |
194 (session_options ++ opts, thys.map(Path.explode(_))) }) |
185 val files = entry.files.map(Path.explode(_)) |
195 val files = entry.files.map(Path.explode(_)) |
186 val digest = SHA1.digest((full_name, entry.parent, entry.options, entry.theories).toString) |
196 val digest = SHA1.digest((full_name, entry.parent, entry.options, entry.theories).toString) |
187 |
197 |
188 val info = |
198 val info = |
189 Session.Info(entry.name, dir + path, entry.parent, parent_base_name, |
199 Session.Info(entry.name, entry.groups, dir + path, entry.parent, parent_base_name, |
190 entry.description, session_options, theories, files, digest) |
200 entry.description, session_options, theories, files, digest) |
191 |
201 |
192 queue1 + (full_name, info) |
202 queue1 + (full_name, info) |
193 } |
203 } |
194 catch { |
204 catch { |
222 case ERROR(msg) => |
232 case ERROR(msg) => |
223 error(msg + "\nThe error(s) above occurred in session catalog " + quote(catalog.toString)) |
233 error(msg + "\nThe error(s) above occurred in session catalog " + quote(catalog.toString)) |
224 }) |
234 }) |
225 } |
235 } |
226 |
236 |
227 def find_sessions(options: Options, all_sessions: Boolean, sessions: List[String], |
237 def find_sessions(options: Options, more_dirs: List[Path], |
228 more_dirs: List[Path]): Session.Queue = |
238 all_sessions: Boolean, session_groups: List[String], sessions: List[String]): Session.Queue = |
229 { |
239 { |
230 var queue = Session.Queue.empty |
240 var queue = Session.Queue.empty |
231 |
241 |
232 for (dir <- Isabelle_System.components()) { |
242 for (dir <- Isabelle_System.components()) { |
233 queue = sessions_dir(options, false, dir, queue) |
243 queue = sessions_dir(options, false, dir, queue) |
417 } |
427 } |
418 |
428 |
419 |
429 |
420 /* build */ |
430 /* build */ |
421 |
431 |
422 def build(all_sessions: Boolean, build_images: Boolean, max_jobs: Int, |
432 def build( |
423 no_build: Boolean, system_mode: Boolean, timing: Boolean, verbose: Boolean, |
433 all_sessions: Boolean = false, |
424 more_dirs: List[Path], more_options: List[String], sessions: List[String]): Int = |
434 build_images: Boolean = false, |
425 { |
435 more_dirs: List[Path] = Nil, |
426 val options = (Options.init() /: more_options)(_.define_simple(_)) |
436 session_groups: List[String] = Nil, |
427 val queue = find_sessions(options, all_sessions, sessions, more_dirs) |
437 max_jobs: Int = 1, |
|
438 no_build: Boolean = false, |
|
439 build_options: List[String] = Nil, |
|
440 system_mode: Boolean = false, |
|
441 timing: Boolean = false, |
|
442 verbose: Boolean = false, |
|
443 sessions: List[String] = Nil): Int = |
|
444 { |
|
445 val options = (Options.init() /: build_options)(_.define_simple(_)) |
|
446 val queue = find_sessions(options, more_dirs, all_sessions, session_groups, sessions) |
428 val deps = dependencies(verbose, queue) |
447 val deps = dependencies(verbose, queue) |
429 |
448 |
430 def make_stamp(name: String): String = |
449 def make_stamp(name: String): String = |
431 sources_stamp(queue(name).digest :: deps.sources(name)) |
450 sources_stamp(queue(name).digest :: deps.sources(name)) |
432 |
451 |
532 Properties.Value.Int(max_jobs) :: |
551 Properties.Value.Int(max_jobs) :: |
533 Properties.Value.Boolean(no_build) :: |
552 Properties.Value.Boolean(no_build) :: |
534 Properties.Value.Boolean(system_mode) :: |
553 Properties.Value.Boolean(system_mode) :: |
535 Properties.Value.Boolean(timing) :: |
554 Properties.Value.Boolean(timing) :: |
536 Properties.Value.Boolean(verbose) :: |
555 Properties.Value.Boolean(verbose) :: |
537 Command_Line.Chunks(more_dirs, options, sessions) => |
556 Command_Line.Chunks(more_dirs, session_groups, build_options, sessions) => |
538 build(all_sessions, build_images, max_jobs, no_build, system_mode, timing, |
557 build(all_sessions, build_images, more_dirs.map(Path.explode), session_groups, |
539 verbose, more_dirs.map(Path.explode), options, sessions) |
558 max_jobs, no_build, build_options, system_mode, timing, verbose, sessions) |
540 case _ => error("Bad arguments:\n" + cat_lines(args)) |
559 case _ => error("Bad arguments:\n" + cat_lines(args)) |
541 } |
560 } |
542 } |
561 } |
543 } |
562 } |
544 } |
563 } |