tap 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. data/Basic Overview +151 -0
  2. data/Command Reference +99 -0
  3. data/History +24 -0
  4. data/MIT-LICENSE +1 -1
  5. data/README +29 -57
  6. data/Rakefile +30 -37
  7. data/Tutorial +243 -191
  8. data/bin/tap +66 -35
  9. data/lib/tap.rb +47 -29
  10. data/lib/tap/app.rb +700 -342
  11. data/lib/tap/{script → cmd}/console.rb +0 -0
  12. data/lib/tap/{script → cmd}/destroy.rb +0 -0
  13. data/lib/tap/{script → cmd}/generate.rb +0 -0
  14. data/lib/tap/cmd/run.rb +156 -0
  15. data/lib/tap/constants.rb +4 -0
  16. data/lib/tap/dump.rb +57 -0
  17. data/lib/tap/env.rb +316 -0
  18. data/lib/tap/file_task.rb +106 -109
  19. data/lib/tap/generator.rb +4 -1
  20. data/lib/tap/generator/generators/command/USAGE +6 -0
  21. data/lib/tap/generator/generators/command/command_generator.rb +17 -0
  22. data/lib/tap/generator/generators/{script/templates/script.erb → command/templates/command.erb} +10 -10
  23. data/lib/tap/generator/generators/config/USAGE +21 -0
  24. data/lib/tap/generator/generators/config/config_generator.rb +17 -7
  25. data/lib/tap/generator/generators/file_task/USAGE +3 -0
  26. data/lib/tap/generator/generators/file_task/file_task_generator.rb +16 -0
  27. data/lib/tap/generator/generators/file_task/templates/file.txt +2 -0
  28. data/lib/tap/generator/generators/file_task/templates/file.yml +3 -0
  29. data/lib/tap/generator/generators/file_task/templates/task.erb +26 -20
  30. data/lib/tap/generator/generators/file_task/templates/test.erb +20 -10
  31. data/lib/tap/generator/generators/generator/generator_generator.rb +1 -1
  32. data/lib/tap/generator/generators/generator/templates/generator.erb +21 -12
  33. data/lib/tap/generator/generators/root/templates/Rakefile +33 -24
  34. data/lib/tap/generator/generators/root/templates/tap.yml +28 -31
  35. data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +1 -0
  36. data/lib/tap/generator/generators/task/USAGE +3 -0
  37. data/lib/tap/generator/generators/task/task_generator.rb +18 -5
  38. data/lib/tap/generator/generators/task/templates/task.erb +7 -12
  39. data/lib/tap/generator/generators/task/templates/test.erb +10 -11
  40. data/lib/tap/generator/generators/workflow/templates/task.erb +1 -1
  41. data/lib/tap/generator/generators/workflow/templates/test.erb +1 -1
  42. data/lib/tap/patches/rake/rake_test_loader.rb +8 -0
  43. data/lib/tap/patches/rake/testtask.rb +55 -0
  44. data/lib/tap/patches/ruby19/backtrace_filter.rb +51 -0
  45. data/lib/tap/patches/ruby19/parsedate.rb +16 -0
  46. data/lib/tap/root.rb +172 -67
  47. data/lib/tap/script.rb +70 -336
  48. data/lib/tap/support/aggregator.rb +55 -0
  49. data/lib/tap/support/audit.rb +281 -280
  50. data/lib/tap/support/batchable.rb +59 -0
  51. data/lib/tap/support/class_configuration.rb +279 -0
  52. data/lib/tap/support/configurable.rb +92 -0
  53. data/lib/tap/support/configurable_methods.rb +296 -0
  54. data/lib/tap/support/executable.rb +98 -0
  55. data/lib/tap/support/executable_queue.rb +82 -0
  56. data/lib/tap/support/logger.rb +9 -15
  57. data/lib/tap/support/rake.rb +43 -54
  58. data/lib/tap/support/run_error.rb +32 -13
  59. data/lib/tap/support/shell_utils.rb +47 -0
  60. data/lib/tap/support/tdoc.rb +9 -8
  61. data/lib/tap/support/tdoc/config_attr.rb +40 -16
  62. data/lib/tap/support/validation.rb +77 -0
  63. data/lib/tap/support/versions.rb +36 -36
  64. data/lib/tap/task.rb +276 -482
  65. data/lib/tap/test.rb +20 -261
  66. data/lib/tap/test/env_vars.rb +7 -5
  67. data/lib/tap/test/file_methods.rb +126 -121
  68. data/lib/tap/test/subset_methods.rb +86 -45
  69. data/lib/tap/test/tap_methods.rb +271 -0
  70. data/lib/tap/workflow.rb +174 -46
  71. data/test/app/config/another/task.yml +1 -0
  72. data/test/app/config/erb.yml +2 -1
  73. data/test/app/config/some/task.yml +1 -0
  74. data/test/app/config/template.yml +2 -6
  75. data/test/app_test.rb +1241 -1008
  76. data/test/env/test_configure/recurse_a.yml +2 -0
  77. data/test/env/test_configure/recurse_b.yml +2 -0
  78. data/test/env/test_configure/tap.yml +23 -0
  79. data/test/env/test_load_env_config/dir/tap.yml +3 -0
  80. data/test/env/test_load_env_config/recurse_a.yml +2 -0
  81. data/test/env/test_load_env_config/recurse_b.yml +2 -0
  82. data/test/env/test_load_env_config/tap.yml +3 -0
  83. data/test/env_test.rb +198 -0
  84. data/test/file_task_test.rb +70 -53
  85. data/{lib/tap/generator/generators/package/USAGE → test/root/file.txt} +0 -0
  86. data/test/root_test.rb +621 -454
  87. data/test/script_test.rb +38 -174
  88. data/test/support/aggregator_test.rb +99 -0
  89. data/test/support/audit_test.rb +409 -416
  90. data/test/support/batchable_test.rb +74 -0
  91. data/test/support/{task_configuration_test.rb → class_configuration_test.rb} +106 -47
  92. data/test/{task/config/overriding.yml → support/configurable/config/configured.yml} +0 -0
  93. data/test/support/configurable_test.rb +295 -0
  94. data/test/support/executable_queue_test.rb +103 -0
  95. data/test/support/executable_test.rb +38 -0
  96. data/test/support/logger_test.rb +17 -17
  97. data/test/support/rake_test.rb +4 -2
  98. data/test/support/shell_utils_test.rb +24 -0
  99. data/test/support/tdoc_test.rb +265 -258
  100. data/test/support/validation_test.rb +54 -0
  101. data/test/support/versions_test.rb +38 -38
  102. data/test/tap_test_helper.rb +19 -5
  103. data/test/tap_test_suite.rb +5 -2
  104. data/test/task_base_test.rb +13 -104
  105. data/test/task_syntax_test.rb +300 -0
  106. data/test/task_test.rb +258 -381
  107. data/test/test/env_vars_test.rb +40 -40
  108. data/test/test/file_methods/{test_assert_output_files_equal → test_assert_files}/expected/one.txt +0 -0
  109. data/test/test/file_methods/{test_assert_output_files_equal → test_assert_files}/expected/two.txt +0 -0
  110. data/test/test/file_methods/{test_assert_output_files_equal → test_assert_files}/input/one.txt +0 -0
  111. data/test/test/file_methods/{test_assert_output_files_equal → test_assert_files}/input/two.txt +0 -0
  112. data/test/test/{test_file_task_test → file_methods/test_assert_files_can_have_no_expected_files_if_specified}/input/one.txt +0 -0
  113. data/test/test/{test_file_task_test → file_methods/test_assert_files_can_have_no_expected_files_if_specified}/input/two.txt +0 -0
  114. data/test/test/file_methods/test_assert_files_fails_for_different_content/expected/one.txt +1 -0
  115. data/test/test/{test_file_task_test → file_methods/test_assert_files_fails_for_different_content}/expected/two.txt +0 -0
  116. data/test/test/file_methods/test_assert_files_fails_for_different_content/input/one.txt +1 -0
  117. data/test/test/file_methods/test_assert_files_fails_for_different_content/input/two.txt +1 -0
  118. data/test/test/{test_file_task_test → file_methods/test_assert_files_fails_for_missing_expected_file}/expected/one.txt +0 -0
  119. data/test/test/file_methods/test_assert_files_fails_for_missing_expected_file/input/one.txt +1 -0
  120. data/test/test/file_methods/test_assert_files_fails_for_missing_expected_file/input/two.txt +1 -0
  121. data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/expected/one.txt +1 -0
  122. data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/expected/two.txt +1 -0
  123. data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/input/one.txt +1 -0
  124. data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/input/two.txt +1 -0
  125. data/test/test/file_methods/test_assert_files_fails_for_no_expected_files/input/one.txt +1 -0
  126. data/test/test/file_methods/test_assert_files_fails_for_no_expected_files/input/two.txt +1 -0
  127. data/test/test/file_methods_doc/test_sub/expected/one.txt +1 -0
  128. data/test/test/file_methods_doc/test_sub/expected/two.txt +1 -0
  129. data/test/test/file_methods_doc/test_sub/input/one.txt +1 -0
  130. data/test/test/file_methods_doc/test_sub/input/two.txt +1 -0
  131. data/test/test/file_methods_doc_test.rb +29 -0
  132. data/test/test/file_methods_test.rb +214 -143
  133. data/test/test/subset_methods_test.rb +111 -115
  134. data/test/test/{test_assert_expected_result_files → tap_methods/test_assert_files}/expected/task/name/a.txt +0 -0
  135. data/test/test/{test_assert_expected_result_files → tap_methods/test_assert_files}/expected/task/name/b.txt +0 -0
  136. data/test/test/{test_assert_expected_result_files → tap_methods/test_assert_files}/input/a.txt +0 -0
  137. data/test/test/{test_assert_expected_result_files → tap_methods/test_assert_files}/input/b.txt +0 -0
  138. data/test/test/tap_methods_test.rb +399 -0
  139. data/test/workflow_test.rb +101 -91
  140. metadata +86 -70
  141. data/lib/tap/generator/generators/package/package_generator.rb +0 -38
  142. data/lib/tap/generator/generators/package/templates/package.erb +0 -186
  143. data/lib/tap/generator/generators/script/USAGE +0 -0
  144. data/lib/tap/generator/generators/script/script_generator.rb +0 -17
  145. data/lib/tap/script/run.rb +0 -154
  146. data/lib/tap/support/batch_queue.rb +0 -162
  147. data/lib/tap/support/combinator.rb +0 -114
  148. data/lib/tap/support/task_configuration.rb +0 -169
  149. data/lib/tap/support/template.rb +0 -81
  150. data/lib/tap/support/templater.rb +0 -155
  151. data/lib/tap/version.rb +0 -4
  152. data/test/app/config/addition_template.yml +0 -6
  153. data/test/app_class_test.rb +0 -33
  154. data/test/check/binding_eval.rb +0 -23
  155. data/test/check/define_method_check.rb +0 -22
  156. data/test/check/dependencies_check.rb +0 -175
  157. data/test/check/inheritance_check.rb +0 -22
  158. data/test/support/batch_queue_test.rb +0 -320
  159. data/test/support/combinator_test.rb +0 -249
  160. data/test/support/template_test.rb +0 -122
  161. data/test/support/templater/erb.txt +0 -2
  162. data/test/support/templater/erb.yml +0 -2
  163. data/test/support/templater/somefile.txt +0 -2
  164. data/test/support/templater_test.rb +0 -192
  165. data/test/task/config/template.yml +0 -4
  166. data/test/task_class_test.rb +0 -170
  167. data/test/task_execute_test.rb +0 -262
  168. data/test/test/file_methods/test_assert_expected/expected/file.txt +0 -1
  169. data/test/test/file_methods/test_assert_expected/expected/folder/file.txt +0 -1
  170. data/test/test/file_methods/test_assert_expected/input/file.txt +0 -1
  171. data/test/test/file_methods/test_assert_expected/input/folder/file.txt +0 -1
  172. data/test/test/file_methods/test_assert_files_exist/input/input_1.txt +0 -0
  173. data/test/test/file_methods/test_assert_files_exist/input/input_2.txt +0 -0
  174. data/test/test/file_methods/test_file_compare/expected/output_1.txt +0 -3
  175. data/test/test/file_methods/test_file_compare/expected/output_2.txt +0 -1
  176. data/test/test/file_methods/test_file_compare/input/input_1.txt +0 -3
  177. data/test/test/file_methods/test_file_compare/input/input_2.txt +0 -3
  178. data/test/test/file_methods/test_infer_glob/expected/file.yml +0 -0
  179. data/test/test/file_methods/test_infer_glob/expected/file_1.txt +0 -0
  180. data/test/test/file_methods/test_infer_glob/expected/file_2.txt +0 -0
  181. data/test/test/file_methods/test_yml_compare/expected/output_1.yml +0 -6
  182. data/test/test/file_methods/test_yml_compare/expected/output_2.yml +0 -6
  183. data/test/test/file_methods/test_yml_compare/input/input_1.yml +0 -4
  184. data/test/test/file_methods/test_yml_compare/input/input_2.yml +0 -4
  185. data/test/test_test.rb +0 -373
@@ -1,38 +0,0 @@
1
- require 'shellwords'
2
- require 'pp'
3
-
4
- module Tap::Generator::Generators
5
- class PackageGenerator < Rails::Generator::NamedBase # :nodoc:
6
- include Shellwords
7
-
8
- attr_accessor :config, :argv, :package_file
9
-
10
- def initialize(*args)
11
- super(*args)
12
- @destination_root = Tap::App.instance[:root]
13
- @app = Tap::App.instance
14
- end
15
-
16
- def manifest
17
- record do |m|
18
- # read the config for the current root
19
- @config = File.read Tap::Script.config_filepath(@app[:root])
20
-
21
- # at this point ARGV still includes the package name,
22
- # ie the commands should be argument 1
23
- # Note: it's important to setup argv this way, from a single argument,
24
- # so that options can be included in the packaged arguments:
25
- # generate package raw_to_mgf "run --debug some/task"
26
- # vs
27
- # generate package raw_to_mgf run --debug some/task
28
- # where '--debug' is applied to generate rather than run
29
- @argv = PP.singleline_pp(shellwords(ARGV[1].to_s), '')
30
-
31
- @package_file = class_path.empty? ? file_name : File.join(class_path, file_name)
32
- filepath = "pkg/#{@package_file}.rb"
33
- m.directory File.dirname(filepath)
34
- m.template "package.erb", filepath
35
- end
36
- end
37
- end
38
- end
@@ -1,186 +0,0 @@
1
- #############################################
2
- # HOW TO PACKAGE YOUR SCRIPT:
3
- # 1. Attend to the parts marked TODO
4
- # 2. Run rubyscript2exe as described below:
5
- #
6
- # % rubyscript2exe <%= package_file %>.rb
7
- #
8
- # NOTES:
9
- # The 'rubyscript2exe' gem is required for packaging -- install using:
10
- # % gem install rubyscript2exe
11
- #
12
- # The inputs you used when creating this script will supplied before
13
- # the inputs you provide to the executable. Hence if you used:
14
- # % tap generate package "run --quiet some/task"
15
- #
16
- # These will be equivalent commands:
17
- # % tap run --quiet some/task INPUT1 INPUT2
18
- # % <%= package_file %>.exe INPUT1 INPUT2
19
- #
20
- # Feel free to adjust this script to behave as you like -- whatever this
21
- # script does will be packaged into the executable.
22
- #
23
- #############################################
24
- #
25
- # = Prompt Instructions
26
- # Enter an empty line to continue.
27
-
28
- require "tap"
29
- require "tap/script"
30
-
31
- # = TODO: add script requires
32
- #
33
- # Only what this script does will be packaged into the executable.
34
- # You MUST specify tasks and other files that are not loaded during
35
- # the 'rubyscript2exe' execution of this script. Usually this means
36
- # require-ing any tasks that may get used.
37
- #
38
- # require 'some/task'
39
-
40
- app = Tap::App.instance
41
- script = Tap::Script.instance
42
-
43
- # = TODO: check arguments
44
- # Make sure these are what you want later in this script they're unshifted
45
- # onto ARGV, ie they'll be hard-coded into the executable.
46
- script_argv = <%= argv %>
47
-
48
- # = TODO: check configurations
49
- #
50
- # This configures the packaged app the same as the current tap.yml
51
- # Check that the configurations look the way you want them to, or
52
- # set the executable to load it's own configurations, as by:
53
- # config_file = Tap::Script.config_filepath(Dir.pwd)
54
- # config = Tap::Script.read_config(config_file)
55
- #
56
- app_config = %Q{<%= config.gsub(/^\s*$|^#.*$/m, '') %>}
57
-
58
- # = TODO: decide if you want to prompt when you get no inputs
59
- # This can be handy if you want to be able to interact with the
60
- # packaged script.
61
- if ARGV.select {|arg| arg !~ /^-|^--/ }.empty?
62
- puts Tap::Script.usage(__FILE__, "Prompt Instructions", :keep_headers => false)
63
-
64
- while true
65
- print "glob: "
66
- line = gets.strip
67
- break if line.empty?
68
-
69
- line = line[1..-2] if line =~ /^".*"$/
70
- ARGV << line
71
- end
72
- puts
73
- end
74
-
75
- # nice give the user a second before you exit, especially if you have a prompt
76
- def exit(*args)
77
- puts
78
- puts "Hit enter to exit."
79
- ARGV.clear
80
- gets
81
- super
82
- end
83
-
84
- #############################################
85
- # These sections generally needs far less customization
86
- #############################################
87
-
88
- #
89
- # configure the app
90
- #
91
- begin
92
- config = YAML.load(app_config)
93
- config = {} if config == false
94
- script.configure_app(config)
95
- rescue(Exception)
96
- # catch errors and exit gracefully
97
- # (errors usu from gem loading errors)
98
- puts "Configuration error: #{$!.message}"
99
- exit(1)
100
- end
101
-
102
- #
103
- # add modifications for rubyscript2exe
104
- #
105
- require "rubyscript2exe"
106
- if RUBYSCRIPT2EXE.is_compiling?
107
- module Kernel
108
- def exit_with_load_path_rewriting
109
- [$", REQUIRE2LIB::LOADED].each do |loaded_files|
110
- loaded_files.collect! do |load_path|
111
- if File.expand_path(load_path) == load_path
112
- $:.each do |root|
113
- relative_load_path = Tap::Root.relative_filepath(File.expand_path(root), load_path, false)
114
- unless relative_load_path == load_path
115
- load_path = relative_load_path
116
- break
117
- end
118
- end
119
- end
120
-
121
- load_path
122
- end
123
- end
124
- exit_without_load_path_rewriting
125
- end
126
-
127
- alias exit_without_load_path_rewriting exit
128
- alias exit exit_with_load_path_rewriting
129
- end
130
-
131
- else
132
- script.config.script_paths.unshift RUBYSCRIPT2EXE.appdir("../lib/script")
133
- Dependencies.load_paths.unshift RUBYSCRIPT2EXE.appdir("../lib")
134
- Dir.chdir(RUBYSCRIPT2EXE.exedir)
135
- end
136
-
137
- #
138
- # run before script
139
- #
140
- begin
141
- eval(script.config.before.to_s)
142
- rescue
143
- puts "Error in before script."
144
- if app.options.debug
145
- raise
146
- else
147
- puts $!.message
148
- exit(1)
149
- end
150
- end
151
-
152
- # This is where the inputs used to create this script are unshifted
153
- # onto ARGV, ahead of the user inputs.
154
- script_argv.reverse_each {|arg| ARGV.unshift arg}
155
-
156
- #
157
- # run the script -- note that the first argument
158
- # to ARGV is the script that gets run.
159
- #
160
- begin
161
- load script.config.scripts[ARGV.shift]
162
- rescue
163
- if app.options.debug
164
- raise
165
- else
166
- puts "Error."
167
- puts $!.message
168
- end
169
- end
170
-
171
- #
172
- # run after script
173
- #
174
- begin
175
- eval(script.config.after.to_s)
176
- rescue
177
- puts "Error in after script."
178
- if app.options.debug
179
- raise
180
- else
181
- puts $!.message
182
- exit(1)
183
- end
184
- end
185
-
186
- exit(0)
File without changes
@@ -1,17 +0,0 @@
1
- module Tap::Generator::Generators
2
- class ScriptGenerator < Rails::Generator::NamedBase # :nodoc:
3
- def initialize(*args)
4
- super(*args)
5
- @destination_root = Tap::App.instance[:root]
6
- @app = Tap::App.instance
7
- end
8
-
9
- def manifest
10
- record do |m|
11
- script_path = @app.relative_filepath(:root, @app[:script])
12
- m.directory class_path.empty? ? script_path : File.join(script_path, class_path)
13
- m.template "script.erb", File.join(script_path, class_name.underscore + ".rb")
14
- end
15
- end
16
- end
17
- end
@@ -1,154 +0,0 @@
1
- # = Usage
2
- # tap run {options} -- {task options} task INPUTS...
3
- #
4
- # examples:
5
- # tap run --help Prints this help
6
- # tap run -- task --help Prints help for task
7
- #
8
-
9
- require 'tap/script'
10
-
11
- app = Tap::App.instance
12
- script = Tap::Script.instance
13
-
14
- #
15
- # handle options
16
- #
17
-
18
- opts = [
19
- ['--help', '-h', GetoptLong::NO_ARGUMENT, "Print this help"],
20
- ['--debug', '-d', GetoptLong::NO_ARGUMENT, "Trace execution and debug"],
21
- ['--force', '-f', GetoptLong::NO_ARGUMENT, "Force execution at checkpoints"],
22
- ['--quiet', '-q', GetoptLong::NO_ARGUMENT, "Suppress logging"]]
23
-
24
- Tap::Script.handle_options(*opts) do |opt, value|
25
- case opt
26
- when '--help'
27
- puts Tap::Script.usage(__FILE__, "Usage", :keep_headers => false)
28
- puts
29
- puts Tap::Script.usage_options(opts)
30
- exit
31
-
32
- when '--quiet', '--force', '--debug'
33
- # simply track these have been set
34
- opt =~ /^-+(\w+)/
35
- app.options.send("#{$1}=", true)
36
-
37
- end
38
- end
39
-
40
- #
41
- # handle options for each specified task
42
- #
43
- argv = Tap::Script.split_arguments(ARGV)
44
- if argv.empty?
45
- puts "no task specified"
46
- exit
47
- end
48
-
49
- argv.each do |args|
50
- ARGV.clear
51
- ARGV.concat(args)
52
-
53
- td = Tap::Script.next_arg(ARGV)
54
- if td == 'rake'
55
- # interpret 'rake' tds as specifications for
56
- # rake tasks and/or inputs:
57
- # tap run rake -T
58
- # tap run rake test
59
- #
60
- app.extend Tap::Support::Rake
61
-
62
- rake = Rake.application
63
- options = rake.options
64
-
65
- # merge options down from app
66
- app.options.marshal_dump.each_pair do |key, value|
67
- options.send("#{key}=", value)
68
- end
69
- options.silent = true
70
-
71
- # now follow the same protocol as
72
- # in run, handling options
73
- rake.init
74
- rake.load_rakefile
75
-
76
- # takes the place of rake.top_level
77
- if options.show_tasks
78
- rake.display_tasks_and_comments
79
- exit
80
- elsif options.show_prereqs
81
- rake.display_prerequisites
82
- exit
83
- else
84
- rake.top_level_tasks.each do |task_name|
85
- task = app.task(task_name)
86
- app.queue.enq(task)
87
- end
88
- end
89
-
90
- next
91
- end
92
-
93
- # lookup the task
94
- begin
95
- task = (td.nil? ? nil : app.task(td))
96
- rescue(Tap::App::LookupError)
97
- end
98
-
99
- # unless a Tap::Task was found, treat the
100
- # args as a specification for Rake.
101
- unless task.kind_of?(Tap::Task)
102
- args.unshift(td) unless task == nil
103
- args.unshift('rake')
104
- redo
105
- end
106
-
107
- # handle task configuration options
108
- Tap::Script.handle_task_options(task)
109
-
110
- # queue the task with the remaining inputs
111
- args = ARGV.collect! {|arg| Tap::App.parse_yaml(arg) }
112
- app.queue.enq(task, *args)
113
- end
114
- ARGV.clear
115
-
116
- #
117
- # set signals and run!
118
- #
119
-
120
- # info signal -- Note: windows does
121
- # not support the INFO signal
122
- if RUBY_PLATFORM.index('mswin').nil?
123
- Signal.trap("INFO") do
124
- puts app.info
125
- end
126
-
127
- puts "ctl-i prints information"
128
- end
129
-
130
- # interuption signal
131
- Signal.trap("INT") do
132
- puts " interrupted!"
133
- # prompt for decision
134
- while true
135
- print "stop, terminate, or resume? (s/t/r):"
136
- case gets.strip
137
- when /s(top)?/i
138
- app.stop
139
- break
140
- when /t(erminate)?/i
141
- app.terminate
142
- break
143
- when /r(esume)?/i
144
- break
145
- else
146
- puts "unexpected response..."
147
- end
148
- end
149
- end
150
-
151
- puts "ctl-c interupts execution"
152
- puts "beginning run..."
153
-
154
- app.run
@@ -1,162 +0,0 @@
1
- module Tap
2
- module Support
3
-
4
- # BatchQueue allows thread-safe enqueing and dequeing of tasks and inputs for
5
- # execution. Until the task is dequeued, additional enqueuements will aggregate
6
- # the inputs into a batch. The queue order is determined solely by the task;
7
- # all accumulated inputs are dequeued at once.
8
- #
9
- # # given tasks t1 and t2:
10
- # q = BatchQueue.new
11
- # q.enq t1, 1
12
- # q.enq t2, :a,:b,:c
13
- # q.enq t1, 2,3
14
- #
15
- # q.deq # => [t1, [1,2,3]]
16
- # q.deq # => [t2, [:a,:b,:c]]
17
- # q.deq # => nil
18
- #
19
- # All BatchQueue methods are monitored such that they may only be accessed
20
- # by one thread at a time, in order to ensure that transactions are atomic.
21
- class BatchQueue
22
- include MonitorMixin
23
-
24
- # creates a new BatchQueue
25
- def initialize
26
- super
27
- self.clear
28
- end
29
-
30
- # Clears the BatchQueue of all tasks and inputs.
31
- def clear
32
- synchronize do
33
- self.inputs = {}
34
- self.tasks = []
35
- end
36
- end
37
-
38
- # Returns the number of enqueued tasks (same as length)
39
- def size
40
- tasks.length
41
- end
42
-
43
- # Returns the number of enqueued tasks (same as size)
44
- def length
45
- size
46
- end
47
-
48
- # True if no tasks are enqueued
49
- def empty?
50
- tasks.empty?
51
- end
52
-
53
- # Enqueues the inputs to the task. If the task has not already been added to the
54
- # queue, then the task will be pushed onto the queue and the inputs registered.
55
- # Otherwise, the inputs will be added to the registered inputs; the task will
56
- # not be added to the queue twice. If the task is batched, then each task in the
57
- # batch will be enqueued in order, with the same inputs (Audit inputs will be forked
58
- # for each task).
59
- def enq(task, *inputs)
60
- synchronize do
61
- batch = task.batch
62
- batch.each do |t|
63
- tasks << t unless tasks.include?(t)
64
-
65
- inputs = inputs.collect do |result|
66
- result.kind_of?(Support::Audit) ? result._fork : result
67
- end if batch.length > 1
68
-
69
- self.inputs[t] = [] unless self.inputs[t]
70
- self.inputs[t].concat(inputs)
71
- end
72
- end
73
- end
74
-
75
- # Enqueues the task and input, then prioritizes the task to the front of the queue.
76
- def priority_enq(task, *inputs)
77
- synchronize do
78
- enq(task, *inputs)
79
- prioritize(task)
80
- end
81
- end
82
-
83
- # Moves the task to the front of the queue. Does not queue a task if the task is not
84
- # already in the queue. If the task is batched, then each task in the batch will be
85
- # prioritized in order.
86
- def prioritize(task)
87
- synchronize do
88
- task.batch.reverse_each do |t|
89
- tasks.unshift(t) if tasks.delete(t)
90
- end
91
- end
92
- end
93
-
94
- # Moves the task to the back of the queue. Does not queue a task if the task is not
95
- # already in the queue. If the task is batched, then each task in the batch will be
96
- # marginalized in order.
97
- def marginalize(task)
98
- synchronize do
99
- task.batch.each do |t|
100
- tasks.push(t) if tasks.delete(t)
101
- end
102
- end
103
- end
104
-
105
- # Returns true if the task is executable with the currently registered inputs
106
- # (as determined by task.executable?).
107
- def executable?(task)
108
- synchronize do
109
- task.executable?(inputs[task])
110
- end
111
- end
112
-
113
- # Dequeues the next executable task, or the specified task (even if it is not
114
- # executable). The task and the current inputs for the task are returned in
115
- # an array like: [task, inputs]. Returns nil if the task is not in the queue.
116
- def deq(task=nil)
117
- synchronize do
118
- task = peek if task.nil?
119
-
120
- if tasks.include?(task)
121
- [tasks.delete(task), inputs.delete(task)]
122
- else
123
- nil
124
- end
125
- end
126
- end
127
-
128
- # Returns the next executable task, or nil if no queued tasks are executable.
129
- # The task is not dequeued.
130
- def peek
131
- synchronize do
132
- tasks.each do |task|
133
- next unless executable?(task)
134
- return task
135
- end
136
- nil
137
- end
138
- end
139
-
140
- # Returns the number of executable tasks in the queue.
141
- def num_executable
142
- synchronize do
143
- tasks.inject(0) do |count, task|
144
- executable?(task) ? count + 1 : count
145
- end
146
- end
147
- end
148
-
149
- # Returns the number of non-executable tasks in the queue.
150
- def num_not_executable
151
- synchronize do
152
- size - num_executable
153
- end
154
- end
155
-
156
- protected
157
-
158
- attr_accessor :inputs, :tasks
159
-
160
- end
161
- end
162
- end