bahuvrihi-tap 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. data/History +69 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +119 -0
  4. data/bin/tap +114 -0
  5. data/cmd/console.rb +42 -0
  6. data/cmd/destroy.rb +16 -0
  7. data/cmd/generate.rb +16 -0
  8. data/cmd/run.rb +126 -0
  9. data/doc/Class Reference +362 -0
  10. data/doc/Command Reference +153 -0
  11. data/doc/Tutorial +237 -0
  12. data/lib/tap.rb +32 -0
  13. data/lib/tap/app.rb +720 -0
  14. data/lib/tap/constants.rb +8 -0
  15. data/lib/tap/env.rb +640 -0
  16. data/lib/tap/file_task.rb +547 -0
  17. data/lib/tap/generator/base.rb +109 -0
  18. data/lib/tap/generator/destroy.rb +37 -0
  19. data/lib/tap/generator/generate.rb +61 -0
  20. data/lib/tap/generator/generators/command/command_generator.rb +21 -0
  21. data/lib/tap/generator/generators/command/templates/command.erb +32 -0
  22. data/lib/tap/generator/generators/config/config_generator.rb +26 -0
  23. data/lib/tap/generator/generators/config/templates/doc.erb +12 -0
  24. data/lib/tap/generator/generators/config/templates/nodoc.erb +8 -0
  25. data/lib/tap/generator/generators/file_task/file_task_generator.rb +27 -0
  26. data/lib/tap/generator/generators/file_task/templates/file.txt +11 -0
  27. data/lib/tap/generator/generators/file_task/templates/result.yml +6 -0
  28. data/lib/tap/generator/generators/file_task/templates/task.erb +33 -0
  29. data/lib/tap/generator/generators/file_task/templates/test.erb +29 -0
  30. data/lib/tap/generator/generators/root/root_generator.rb +55 -0
  31. data/lib/tap/generator/generators/root/templates/Rakefile +86 -0
  32. data/lib/tap/generator/generators/root/templates/gemspec +27 -0
  33. data/lib/tap/generator/generators/root/templates/tapfile +8 -0
  34. data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +3 -0
  35. data/lib/tap/generator/generators/root/templates/test/tap_test_suite.rb +5 -0
  36. data/lib/tap/generator/generators/root/templates/test/tapfile_test.rb +15 -0
  37. data/lib/tap/generator/generators/task/task_generator.rb +27 -0
  38. data/lib/tap/generator/generators/task/templates/task.erb +14 -0
  39. data/lib/tap/generator/generators/task/templates/test.erb +21 -0
  40. data/lib/tap/generator/manifest.rb +14 -0
  41. data/lib/tap/patches/rake/rake_test_loader.rb +8 -0
  42. data/lib/tap/patches/rake/testtask.rb +55 -0
  43. data/lib/tap/patches/ruby19/backtrace_filter.rb +51 -0
  44. data/lib/tap/patches/ruby19/parsedate.rb +16 -0
  45. data/lib/tap/root.rb +581 -0
  46. data/lib/tap/support/aggregator.rb +55 -0
  47. data/lib/tap/support/assignments.rb +172 -0
  48. data/lib/tap/support/audit.rb +418 -0
  49. data/lib/tap/support/batchable.rb +47 -0
  50. data/lib/tap/support/batchable_class.rb +107 -0
  51. data/lib/tap/support/class_configuration.rb +194 -0
  52. data/lib/tap/support/command_line.rb +98 -0
  53. data/lib/tap/support/comment.rb +270 -0
  54. data/lib/tap/support/configurable.rb +114 -0
  55. data/lib/tap/support/configurable_class.rb +296 -0
  56. data/lib/tap/support/configuration.rb +122 -0
  57. data/lib/tap/support/constant.rb +70 -0
  58. data/lib/tap/support/constant_utils.rb +127 -0
  59. data/lib/tap/support/declarations.rb +111 -0
  60. data/lib/tap/support/executable.rb +111 -0
  61. data/lib/tap/support/executable_queue.rb +82 -0
  62. data/lib/tap/support/framework.rb +71 -0
  63. data/lib/tap/support/framework_class.rb +199 -0
  64. data/lib/tap/support/instance_configuration.rb +147 -0
  65. data/lib/tap/support/lazydoc.rb +428 -0
  66. data/lib/tap/support/manifest.rb +89 -0
  67. data/lib/tap/support/run_error.rb +39 -0
  68. data/lib/tap/support/shell_utils.rb +71 -0
  69. data/lib/tap/support/summary.rb +30 -0
  70. data/lib/tap/support/tdoc.rb +404 -0
  71. data/lib/tap/support/tdoc/tdoc_html_generator.rb +38 -0
  72. data/lib/tap/support/tdoc/tdoc_html_template.rb +42 -0
  73. data/lib/tap/support/templater.rb +180 -0
  74. data/lib/tap/support/validation.rb +410 -0
  75. data/lib/tap/support/versions.rb +97 -0
  76. data/lib/tap/task.rb +259 -0
  77. data/lib/tap/tasks/dump.rb +56 -0
  78. data/lib/tap/tasks/rake.rb +93 -0
  79. data/lib/tap/test.rb +37 -0
  80. data/lib/tap/test/env_vars.rb +29 -0
  81. data/lib/tap/test/file_methods.rb +377 -0
  82. data/lib/tap/test/script_methods.rb +144 -0
  83. data/lib/tap/test/subset_methods.rb +420 -0
  84. data/lib/tap/test/tap_methods.rb +237 -0
  85. data/lib/tap/workflow.rb +187 -0
  86. metadata +145 -0
data/History ADDED
@@ -0,0 +1,69 @@
1
+ == 0.10.0 / 2008-08-08
2
+
3
+ Major revision. Reworked configurations and the execution
4
+ environment. Added Lazydoc documentation. Backwards incompatible.
5
+ Development is now on GitHub.
6
+
7
+ == 0.9.1 / 2008-04-26 revision 253
8
+
9
+ Relatively minor update, but with one important refactoring that
10
+ removes the Tap::Script module. This breaks backward compatibility
11
+ but only should affect people who have made their own commands.
12
+ Simply sub Tap::Support::CommandLine for Tap::Script to fix.
13
+
14
+ * Added constants methods (ex try_constantize) to String
15
+ * Added gem discovery when no tap.yml file is present
16
+ * Cleanup and refactoring -- removal of Tap::Script
17
+ * Bug fix for JRuby 1.1.1
18
+
19
+ == 0.9.0 / 2008-04-09 revision 246
20
+
21
+ Major update to Tap. Many changes in this release ARE NOT BACKWARD COMPATIBLE.
22
+
23
+ * Reworked Task and App such that methods, are
24
+ enqued and executed. Made the Executable module
25
+ to allow any Method to be enqued and executed.
26
+ * App now aggregates results for methods that have no
27
+ on_complete block; enabled access through App#results
28
+ and App#_results.
29
+ * Removed iteration from tasks
30
+ * Task no longer templates app.config_templates. Templating code
31
+ removed from this distribution.
32
+ * Work to improve audit usability and visualization
33
+ * Removed methods forwarding from Audit to Audit#_current,
34
+ as well as ambiguous Audit methods
35
+ * Root [] now returns expanded paths unchanged. Example:
36
+ app['relative/path'] # => File.join(app.root, 'relative/path')
37
+ app['/expanded/path'] # => '/expanded/path'
38
+ * Generalized rake support; now supports version 0.8.1
39
+ * Fixes in generators
40
+ * Improvements in running of multithread tasks
41
+ * Removed condition blocks from tasks
42
+ * many other things also...
43
+
44
+ == 0.8.0 / 2007-12-08 revision 138
45
+
46
+ Major update to Tap. Many changes in this release ARE NOT BACKWARD COMPATIBLE.
47
+ Documentation is still patchy, but improving.
48
+
49
+ * Expanded/reworked application configuration, allowing specification of gems
50
+ to be loaded as task libraries.
51
+ * Default app config file is now tap.yml (from app.yml)
52
+ * Updated and improved generators
53
+ * Included rails_generators in distribution, removing rails dependency
54
+ * Reworked many classes to clean up interface
55
+ * Reworked testing methods
56
+ * Improved configuration for tasks
57
+ * Optimized loading
58
+ * Reworked threading model
59
+ * Addition of TDoc documentation
60
+ * Reworked tap command and subcommands
61
+ * Added packaging into executables
62
+ * Updated to ActiveSupport 2.0.1
63
+ * documentation, documentation, documentation
64
+ * many other things as well...
65
+
66
+ == 0.7.9 / 2007-09-14
67
+
68
+ * Initial testing release with partial documentation
69
+
data/MIT-LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2006-2008, Regents of the University of Colorado.
2
+ Developer:: Simon Chiang, Biomolecular Structure Program, Hansen Lab
3
+ Support:: CU Denver School of Medicine Deans Academic Enrichment Fund
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this
6
+ software and associated documentation files (the "Software"), to deal in the Software
7
+ without restriction, including without limitation the rights to use, copy, modify, merge,
8
+ publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
9
+ to whom the Software is furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or
12
+ substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21
+ OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,119 @@
1
+ = {Tap (Task Application)}[http://tap.rubyforge.org]
2
+
3
+ A framework for creating configurable, distributable tasks and workflows.
4
+
5
+ == Description
6
+
7
+ Tap tasks are designed to be easy to test, subclass, use in scripts, and run
8
+ from the command line. Tap provides methods to generate and utilize config
9
+ files, join tasks into workflows, as well as dump and reuse results. Task
10
+ libraries are readily shared as gems. Check out the links for tutorials,
11
+ development, and bug tracking.
12
+
13
+ * {Tutorial}[link:files/doc/Tutorial.html], {Class}[link:files/doc/Class%20Reference.html] and {Command}[link:files/doc/Command%20Reference.html] Reference
14
+ * Website[http://tap.rubyforge.org]
15
+ * Lighthouse[http://bahuvrihi.lighthouseapp.com/projects/9908-tap-task-application/overview]
16
+ * Github[http://github.com/bahuvrihi/tap/tree/master]
17
+
18
+ === Additional Notes:
19
+
20
+ - Tap and Rake[http://rake.rubyforge.org/] are targeted at different problems,
21
+ but play well together. See Tap::Tasks::Rake to use rake tasks in tap.
22
+ - Tap is tested on MRI (the standard Ruby interpreter, versions 1.8.6 and
23
+ 1.9.0) and JRuby[http://jruby.codehaus.org/].
24
+
25
+ === Usage
26
+
27
+ A simple task illustrates the usage of tap:
28
+
29
+ # Goodnight::manifest your basic goodnight moon task
30
+ # Says goodnight with a configurable message.
31
+ class Goodnight < Tap::Task
32
+
33
+ config :message, 'goodnight' # a goodnight message
34
+
35
+ def process(name)
36
+ log(message, name)
37
+ "#{message} #{name}"
38
+ end
39
+ end
40
+
41
+ Tap pulls documentation out of task classes to generate manifests:
42
+
43
+ % tap run -T
44
+ sample:
45
+ goodnight # your basic goodnight moon task
46
+ tap:
47
+ dump # the default dump task
48
+ rake # run rake tasks
49
+
50
+ And help:
51
+
52
+ % tap run -- goodnight --help
53
+ Goodnight -- your basic goodnight moon task
54
+ --------------------------------------------------------------------------------
55
+ Says goodnight with a configurable message.
56
+ --------------------------------------------------------------------------------
57
+ usage: tap run -- goodnight NAME
58
+
59
+ configurations:
60
+ --message MESSAGE a goodnight message
61
+
62
+ options:
63
+ -h, --help Print this help
64
+ --name NAME Specify a name
65
+ --use FILE Loads inputs from file
66
+
67
+
68
+ Tasks are immediately available to run:
69
+
70
+ % tap run -- goodnight moon
71
+ I[00:09:55] goodnight moon
72
+
73
+
74
+ % tap run -- goodnight moon --message hello
75
+ I[00:10:01] hello moon
76
+
77
+ Tap comes with generators and allows distribution of task libraries as gems.
78
+ This can be illustrated by installing the
79
+ {sample_tasks}[http://tap.rubyforge.org/sample_tasks] gem:
80
+
81
+ % gem install sample_tasks
82
+ % tap run -T
83
+ sample:
84
+ goodnight # your basic goodnight moon task
85
+ sample_tasks:
86
+ concat # concatenate files with formatting
87
+ copy # copies files
88
+ grep # search for lines matching a pattern
89
+ print_tree # print a directory tree
90
+ tap:
91
+ dump # the default dump task
92
+ rake # run rake tasks
93
+
94
+ === Bugs/Known Issues
95
+
96
+ - Some inconsequential tests on JRuby fail due to bugs in JRuby itself.
97
+ - Several patches are required so that Tap runs properly on MRI 1.9.0. These
98
+ will likely resolve themselves as 1.9.0 becomes stable.
99
+ - Despite the talk of workflows, the Workflow class should still be considered
100
+ in progress. Tasks themselves are stable.
101
+
102
+ == Installation
103
+
104
+ Tap is available as a gem on RubyForge[http://rubyforge.org/projects/tap]. Use:
105
+
106
+ % gem install tap
107
+
108
+ Tap requires an updated version of RubyGems[http://docs.rubygems.org/] (>= 1.2.0). To check the version and update RubyGems:
109
+
110
+ % gem --version
111
+ % gem --update system
112
+
113
+ == Info
114
+
115
+ Copyright (c) 2006-2008, Regents of the University of Colorado.
116
+ Developer:: {Simon Chiang}[http://bahuvrihi.wordpress.com], {Biomolecular Structure Program}[http://biomol.uchsc.edu/], {Hansen Lab}[http://hsc-proteomics.uchsc.edu/hansenlab/]
117
+ Support:: CU Denver School of Medicine Deans Academic Enrichment Fund
118
+ Licence:: {MIT-Style}[link:files/MIT-LICENSE.html]
119
+
data/bin/tap ADDED
@@ -0,0 +1,114 @@
1
+ #!/usr/local/bin/ruby
2
+ # usage: tap <command> {options} [args]
3
+ #
4
+ # examples:
5
+ # tap generate root . # generates a root dir
6
+ # tap run taskname --option input # runs the 'taskname' task
7
+ #
8
+ # help:
9
+ # tap help # prints this help
10
+ # tap command --help # prints help for 'command'
11
+ #
12
+
13
+ tap_root_dir = File.dirname(__FILE__) + "/.."
14
+ require "#{tap_root_dir}/lib/tap.rb"
15
+
16
+ # setup the environment
17
+ begin
18
+
19
+ $DEBUG = true if ARGV.delete('-d-')
20
+ before = nil
21
+ after = nil
22
+ aliases = nil
23
+
24
+ app = Tap::App.instance
25
+ env = Tap::Env.instantiate(app, Tap::Env.load_config(Tap::Env::GLOBAL_CONFIG_FILE), app.logger) do |unhandled_configs|
26
+ before = unhandled_configs.delete(:before)
27
+ after = unhandled_configs.delete(:after)
28
+
29
+ aliases = unhandled_configs.delete(:alias)
30
+ Tap::Support::Validation.validate(aliases, [Hash]) if aliases
31
+
32
+ unless unhandled_configs.empty?
33
+ local.log(:warn, "ignoring non-env configs: #{unhandled_configs.keys.join(',')}", Logger::DEBUG)
34
+ end
35
+ end
36
+
37
+ # add all gems if no gems are specified (Note this is VERY SLOW ~ 1/3 the overhead for tap)
38
+ if !File.exists?(Tap::Env::DEFAULT_CONFIG_FILE)
39
+ env.gems = Tap::Env.known_gems(true)
40
+ end
41
+
42
+ tap = Tap::Env.instance_for(tap_root_dir)
43
+ env.push(tap)
44
+
45
+ rescue(Tap::Env::ConfigError)
46
+ # catch errors and exit gracefully
47
+ # (errors usu from gem loading errors)
48
+ puts $!.message
49
+ exit(1)
50
+ end
51
+
52
+ #
53
+ # setup after script
54
+ #
55
+
56
+ at_exit do
57
+ begin
58
+ eval(after) if after != nil
59
+ rescue(Exception)
60
+ puts "Error in after script."
61
+ env.handle_error($!)
62
+ exit(1)
63
+ end
64
+ end
65
+
66
+ #
67
+ # run before script
68
+ #
69
+
70
+ begin
71
+ eval(before) if before != nil
72
+ rescue(Exception)
73
+ puts "Error in before script."
74
+ env.handle_error($!)
75
+ exit(1)
76
+ end
77
+
78
+ #
79
+ # run tap
80
+ #
81
+
82
+ begin
83
+ env.activate
84
+
85
+ command = ARGV.shift
86
+ if aliases && aliases.has_key?(command)
87
+ aliases[command].reverse_each {|arg| ARGV.unshift(arg)}
88
+ command = ARGV.shift
89
+ end
90
+
91
+ case command
92
+ when nil, '--help'
93
+ # give some help
94
+ require 'tap/support/command_line'
95
+
96
+ puts Tap::Support::CommandLine.usage(__FILE__)
97
+ puts
98
+ puts "available commands:"
99
+ puts env.summarize(:commands)
100
+ puts
101
+ puts "version #{Tap::VERSION} -- #{Tap::WEBSITE}"
102
+ else
103
+ if path = env.search(:commands, command)
104
+ load path # run the command, if it exists
105
+ else
106
+ puts "Unknown command: '#{command}'"
107
+ puts "Type 'tap help' for usage information."
108
+ end
109
+ end
110
+ rescue
111
+ env.handle_error($!)
112
+ end
113
+
114
+ exit(0)
data/cmd/console.rb ADDED
@@ -0,0 +1,42 @@
1
+ # tap console {options}
2
+ #
3
+ # Opens up an IRB session with Tap initialized to the configurations
4
+ # in tap.yml. Access the Tap::App.instance through 'app'.
5
+
6
+ #
7
+ # handle options
8
+ #
9
+
10
+ OptionParser.new do |opts|
11
+ opts.separator ""
12
+ opts.separator "options:"
13
+
14
+ opts.on("-h", "--help", "Show this message") do
15
+ opts.banner = Tap::Support::CommandLine.usage(__FILE__)
16
+ puts opts
17
+ exit
18
+ end
19
+ end.parse!(ARGV)
20
+
21
+ require "irb"
22
+
23
+ def app
24
+ Tap::App.instance
25
+ end
26
+
27
+ def env
28
+ Tap::Env.instance
29
+ end
30
+
31
+ IRB.start
32
+
33
+ # Handles a bug in IRB that causes exit to throw :IRB_EXIT
34
+ # and consequentially make a warning message, even on a
35
+ # clean exit. This module resets exit to the original
36
+ # aliased method.
37
+ module CleanExit # :nodoc:
38
+ def exit(ret = 0)
39
+ __exit__(ret)
40
+ end
41
+ end
42
+ IRB.CurrentContext.extend CleanExit
data/cmd/destroy.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'tap/generator/base'
2
+ require 'tap/generator/destroy'
3
+
4
+ env = Tap::Env.instance
5
+
6
+ if ARGV.empty? || ARGV == ['-T']
7
+ puts env.summarize(:generators) {|const| const.document[const.name]['generator'] }
8
+ exit
9
+ end
10
+
11
+ name = ARGV.shift
12
+ const = env.search(:generators, name) or raise "unknown generator: #{name}"
13
+
14
+ generator_class = const.constantize
15
+ generator, argv = generator_class.instantiate(ARGV)
16
+ generator.extend(Tap::Generator::Destroy).process(*argv)
data/cmd/generate.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'tap/generator/base'
2
+ require 'tap/generator/generate'
3
+
4
+ env = Tap::Env.instance
5
+
6
+ if ARGV.empty? || ARGV == ['-T']
7
+ puts env.summarize(:generators) {|const| const.document[const.name]['generator'] }
8
+ exit
9
+ end
10
+
11
+ name = ARGV.shift
12
+ const = env.search(:generators, name) or raise "unknown generator: #{name}"
13
+
14
+ generator_class = const.constantize
15
+ generator, argv = generator_class.instantiate(ARGV)
16
+ generator.extend(Tap::Generator::Generate).process(*argv)
data/cmd/run.rb ADDED
@@ -0,0 +1,126 @@
1
+ # tap run {options} -- {task options} task INPUTS...
2
+ #
3
+ # examples:
4
+ # tap run --help Prints this help
5
+ # tap run -- task --help Prints help for task
6
+ #
7
+
8
+ env = Tap::Env.instance
9
+ app = Tap::App.instance
10
+ cmdline = Tap::Support::CommandLine
11
+
12
+ #
13
+ # handle options
14
+ #
15
+
16
+ dump = false
17
+ OptionParser.new do |opts|
18
+
19
+ opts.separator ""
20
+ opts.separator "configurations:"
21
+
22
+ Tap::App.configurations.each do |receiver, key, config|
23
+ next if receiver == Tap::Root
24
+
25
+ opts.on(*cmdline.configv(config)) do |value|
26
+ app.send(configuration.writer, value)
27
+ end
28
+ end
29
+
30
+ opts.separator ""
31
+ opts.separator "options:"
32
+
33
+ opts.on("-h", "--help", "Show this message") do
34
+ opts.banner = cmdline.usage(__FILE__)
35
+ Tap::App.lazydoc.resolve
36
+ puts opts
37
+ exit
38
+ end
39
+
40
+ opts.on('-T', '--manifest', 'Print a list of available tasks') do |v|
41
+ puts env.summarize(:tasks) {|const| const.document[const.name]['manifest'] }
42
+ exit
43
+ end
44
+
45
+ end.parse!(ARGV)
46
+
47
+ #
48
+ # handle options for each specified task
49
+ #
50
+
51
+ rounds = cmdline.split(ARGV).collect do |argvs|
52
+ argvs.each do |argv|
53
+ ARGV.clear
54
+ ARGV.concat(argv)
55
+
56
+ unless td = cmdline.shift(ARGV)
57
+ # warn nil?
58
+ next
59
+ end
60
+
61
+ # attempt lookup the task class
62
+ const = env.search(:tasks, td) or raise "unknown task: #{td}"
63
+ task_class = const.constantize or raise "unknown task: #{td}"
64
+
65
+ # now let the class handle the argv
66
+ task, argv = task_class.instantiate(ARGV, app)
67
+ task.enq *argv.collect! {|str| cmdline.parse_yaml(str) }
68
+ end
69
+
70
+ app.queue.clear
71
+ end
72
+ ARGV.clear
73
+
74
+ rounds.delete_if {|round| round.empty? }
75
+ if rounds.empty?
76
+ puts "no task specified"
77
+ exit
78
+ end
79
+
80
+ #
81
+ # set signals
82
+ #
83
+
84
+ # info signal -- Note: some systems do
85
+ # not support the INFO signal
86
+ # (windows, fedora, at least)
87
+ signals = Signal.list.keys
88
+ if signals.include?("INFO")
89
+ Signal.trap("INFO") do
90
+ puts app.info
91
+ end
92
+ end
93
+
94
+ # interuption signal
95
+ if signals.include?("INT")
96
+ Signal.trap("INT") do
97
+ puts " interrupted!"
98
+ # prompt for decision
99
+ while true
100
+ print "stop, terminate, exit, or resume? (s/t/e/r):"
101
+ case gets.strip
102
+ when /s(top)?/i
103
+ app.stop
104
+ break
105
+ when /t(erminate)?/i
106
+ app.terminate
107
+ break
108
+ when /e(xit)?/i
109
+ exit
110
+ when /r(esume)?/i
111
+ break
112
+ else
113
+ puts "unexpected response..."
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ #
120
+ # enque tasks and run!
121
+ #
122
+
123
+ rounds.each_with_index do |queue, i|
124
+ app.queue.concat(queue)
125
+ app.run
126
+ end