tap 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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