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.
- data/Basic Overview +151 -0
- data/Command Reference +99 -0
- data/History +24 -0
- data/MIT-LICENSE +1 -1
- data/README +29 -57
- data/Rakefile +30 -37
- data/Tutorial +243 -191
- data/bin/tap +66 -35
- data/lib/tap.rb +47 -29
- data/lib/tap/app.rb +700 -342
- data/lib/tap/{script → cmd}/console.rb +0 -0
- data/lib/tap/{script → cmd}/destroy.rb +0 -0
- data/lib/tap/{script → cmd}/generate.rb +0 -0
- data/lib/tap/cmd/run.rb +156 -0
- data/lib/tap/constants.rb +4 -0
- data/lib/tap/dump.rb +57 -0
- data/lib/tap/env.rb +316 -0
- data/lib/tap/file_task.rb +106 -109
- data/lib/tap/generator.rb +4 -1
- data/lib/tap/generator/generators/command/USAGE +6 -0
- data/lib/tap/generator/generators/command/command_generator.rb +17 -0
- data/lib/tap/generator/generators/{script/templates/script.erb → command/templates/command.erb} +10 -10
- data/lib/tap/generator/generators/config/USAGE +21 -0
- data/lib/tap/generator/generators/config/config_generator.rb +17 -7
- data/lib/tap/generator/generators/file_task/USAGE +3 -0
- data/lib/tap/generator/generators/file_task/file_task_generator.rb +16 -0
- data/lib/tap/generator/generators/file_task/templates/file.txt +2 -0
- data/lib/tap/generator/generators/file_task/templates/file.yml +3 -0
- data/lib/tap/generator/generators/file_task/templates/task.erb +26 -20
- data/lib/tap/generator/generators/file_task/templates/test.erb +20 -10
- data/lib/tap/generator/generators/generator/generator_generator.rb +1 -1
- data/lib/tap/generator/generators/generator/templates/generator.erb +21 -12
- data/lib/tap/generator/generators/root/templates/Rakefile +33 -24
- data/lib/tap/generator/generators/root/templates/tap.yml +28 -31
- data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +1 -0
- data/lib/tap/generator/generators/task/USAGE +3 -0
- data/lib/tap/generator/generators/task/task_generator.rb +18 -5
- data/lib/tap/generator/generators/task/templates/task.erb +7 -12
- data/lib/tap/generator/generators/task/templates/test.erb +10 -11
- data/lib/tap/generator/generators/workflow/templates/task.erb +1 -1
- data/lib/tap/generator/generators/workflow/templates/test.erb +1 -1
- data/lib/tap/patches/rake/rake_test_loader.rb +8 -0
- data/lib/tap/patches/rake/testtask.rb +55 -0
- data/lib/tap/patches/ruby19/backtrace_filter.rb +51 -0
- data/lib/tap/patches/ruby19/parsedate.rb +16 -0
- data/lib/tap/root.rb +172 -67
- data/lib/tap/script.rb +70 -336
- data/lib/tap/support/aggregator.rb +55 -0
- data/lib/tap/support/audit.rb +281 -280
- data/lib/tap/support/batchable.rb +59 -0
- data/lib/tap/support/class_configuration.rb +279 -0
- data/lib/tap/support/configurable.rb +92 -0
- data/lib/tap/support/configurable_methods.rb +296 -0
- data/lib/tap/support/executable.rb +98 -0
- data/lib/tap/support/executable_queue.rb +82 -0
- data/lib/tap/support/logger.rb +9 -15
- data/lib/tap/support/rake.rb +43 -54
- data/lib/tap/support/run_error.rb +32 -13
- data/lib/tap/support/shell_utils.rb +47 -0
- data/lib/tap/support/tdoc.rb +9 -8
- data/lib/tap/support/tdoc/config_attr.rb +40 -16
- data/lib/tap/support/validation.rb +77 -0
- data/lib/tap/support/versions.rb +36 -36
- data/lib/tap/task.rb +276 -482
- data/lib/tap/test.rb +20 -261
- data/lib/tap/test/env_vars.rb +7 -5
- data/lib/tap/test/file_methods.rb +126 -121
- data/lib/tap/test/subset_methods.rb +86 -45
- data/lib/tap/test/tap_methods.rb +271 -0
- data/lib/tap/workflow.rb +174 -46
- data/test/app/config/another/task.yml +1 -0
- data/test/app/config/erb.yml +2 -1
- data/test/app/config/some/task.yml +1 -0
- data/test/app/config/template.yml +2 -6
- data/test/app_test.rb +1241 -1008
- data/test/env/test_configure/recurse_a.yml +2 -0
- data/test/env/test_configure/recurse_b.yml +2 -0
- data/test/env/test_configure/tap.yml +23 -0
- data/test/env/test_load_env_config/dir/tap.yml +3 -0
- data/test/env/test_load_env_config/recurse_a.yml +2 -0
- data/test/env/test_load_env_config/recurse_b.yml +2 -0
- data/test/env/test_load_env_config/tap.yml +3 -0
- data/test/env_test.rb +198 -0
- data/test/file_task_test.rb +70 -53
- data/{lib/tap/generator/generators/package/USAGE → test/root/file.txt} +0 -0
- data/test/root_test.rb +621 -454
- data/test/script_test.rb +38 -174
- data/test/support/aggregator_test.rb +99 -0
- data/test/support/audit_test.rb +409 -416
- data/test/support/batchable_test.rb +74 -0
- data/test/support/{task_configuration_test.rb → class_configuration_test.rb} +106 -47
- data/test/{task/config/overriding.yml → support/configurable/config/configured.yml} +0 -0
- data/test/support/configurable_test.rb +295 -0
- data/test/support/executable_queue_test.rb +103 -0
- data/test/support/executable_test.rb +38 -0
- data/test/support/logger_test.rb +17 -17
- data/test/support/rake_test.rb +4 -2
- data/test/support/shell_utils_test.rb +24 -0
- data/test/support/tdoc_test.rb +265 -258
- data/test/support/validation_test.rb +54 -0
- data/test/support/versions_test.rb +38 -38
- data/test/tap_test_helper.rb +19 -5
- data/test/tap_test_suite.rb +5 -2
- data/test/task_base_test.rb +13 -104
- data/test/task_syntax_test.rb +300 -0
- data/test/task_test.rb +258 -381
- data/test/test/env_vars_test.rb +40 -40
- data/test/test/file_methods/{test_assert_output_files_equal → test_assert_files}/expected/one.txt +0 -0
- data/test/test/file_methods/{test_assert_output_files_equal → test_assert_files}/expected/two.txt +0 -0
- data/test/test/file_methods/{test_assert_output_files_equal → test_assert_files}/input/one.txt +0 -0
- data/test/test/file_methods/{test_assert_output_files_equal → test_assert_files}/input/two.txt +0 -0
- data/test/test/{test_file_task_test → file_methods/test_assert_files_can_have_no_expected_files_if_specified}/input/one.txt +0 -0
- data/test/test/{test_file_task_test → file_methods/test_assert_files_can_have_no_expected_files_if_specified}/input/two.txt +0 -0
- data/test/test/file_methods/test_assert_files_fails_for_different_content/expected/one.txt +1 -0
- data/test/test/{test_file_task_test → file_methods/test_assert_files_fails_for_different_content}/expected/two.txt +0 -0
- data/test/test/file_methods/test_assert_files_fails_for_different_content/input/one.txt +1 -0
- data/test/test/file_methods/test_assert_files_fails_for_different_content/input/two.txt +1 -0
- data/test/test/{test_file_task_test → file_methods/test_assert_files_fails_for_missing_expected_file}/expected/one.txt +0 -0
- data/test/test/file_methods/test_assert_files_fails_for_missing_expected_file/input/one.txt +1 -0
- data/test/test/file_methods/test_assert_files_fails_for_missing_expected_file/input/two.txt +1 -0
- data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/expected/one.txt +1 -0
- data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/expected/two.txt +1 -0
- data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/input/one.txt +1 -0
- data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/input/two.txt +1 -0
- data/test/test/file_methods/test_assert_files_fails_for_no_expected_files/input/one.txt +1 -0
- data/test/test/file_methods/test_assert_files_fails_for_no_expected_files/input/two.txt +1 -0
- data/test/test/file_methods_doc/test_sub/expected/one.txt +1 -0
- data/test/test/file_methods_doc/test_sub/expected/two.txt +1 -0
- data/test/test/file_methods_doc/test_sub/input/one.txt +1 -0
- data/test/test/file_methods_doc/test_sub/input/two.txt +1 -0
- data/test/test/file_methods_doc_test.rb +29 -0
- data/test/test/file_methods_test.rb +214 -143
- data/test/test/subset_methods_test.rb +111 -115
- data/test/test/{test_assert_expected_result_files → tap_methods/test_assert_files}/expected/task/name/a.txt +0 -0
- data/test/test/{test_assert_expected_result_files → tap_methods/test_assert_files}/expected/task/name/b.txt +0 -0
- data/test/test/{test_assert_expected_result_files → tap_methods/test_assert_files}/input/a.txt +0 -0
- data/test/test/{test_assert_expected_result_files → tap_methods/test_assert_files}/input/b.txt +0 -0
- data/test/test/tap_methods_test.rb +399 -0
- data/test/workflow_test.rb +101 -91
- metadata +86 -70
- data/lib/tap/generator/generators/package/package_generator.rb +0 -38
- data/lib/tap/generator/generators/package/templates/package.erb +0 -186
- data/lib/tap/generator/generators/script/USAGE +0 -0
- data/lib/tap/generator/generators/script/script_generator.rb +0 -17
- data/lib/tap/script/run.rb +0 -154
- data/lib/tap/support/batch_queue.rb +0 -162
- data/lib/tap/support/combinator.rb +0 -114
- data/lib/tap/support/task_configuration.rb +0 -169
- data/lib/tap/support/template.rb +0 -81
- data/lib/tap/support/templater.rb +0 -155
- data/lib/tap/version.rb +0 -4
- data/test/app/config/addition_template.yml +0 -6
- data/test/app_class_test.rb +0 -33
- data/test/check/binding_eval.rb +0 -23
- data/test/check/define_method_check.rb +0 -22
- data/test/check/dependencies_check.rb +0 -175
- data/test/check/inheritance_check.rb +0 -22
- data/test/support/batch_queue_test.rb +0 -320
- data/test/support/combinator_test.rb +0 -249
- data/test/support/template_test.rb +0 -122
- data/test/support/templater/erb.txt +0 -2
- data/test/support/templater/erb.yml +0 -2
- data/test/support/templater/somefile.txt +0 -2
- data/test/support/templater_test.rb +0 -192
- data/test/task/config/template.yml +0 -4
- data/test/task_class_test.rb +0 -170
- data/test/task_execute_test.rb +0 -262
- data/test/test/file_methods/test_assert_expected/expected/file.txt +0 -1
- data/test/test/file_methods/test_assert_expected/expected/folder/file.txt +0 -1
- data/test/test/file_methods/test_assert_expected/input/file.txt +0 -1
- data/test/test/file_methods/test_assert_expected/input/folder/file.txt +0 -1
- data/test/test/file_methods/test_assert_files_exist/input/input_1.txt +0 -0
- data/test/test/file_methods/test_assert_files_exist/input/input_2.txt +0 -0
- data/test/test/file_methods/test_file_compare/expected/output_1.txt +0 -3
- data/test/test/file_methods/test_file_compare/expected/output_2.txt +0 -1
- data/test/test/file_methods/test_file_compare/input/input_1.txt +0 -3
- data/test/test/file_methods/test_file_compare/input/input_2.txt +0 -3
- data/test/test/file_methods/test_infer_glob/expected/file.yml +0 -0
- data/test/test/file_methods/test_infer_glob/expected/file_1.txt +0 -0
- data/test/test/file_methods/test_infer_glob/expected/file_2.txt +0 -0
- data/test/test/file_methods/test_yml_compare/expected/output_1.yml +0 -6
- data/test/test/file_methods/test_yml_compare/expected/output_2.yml +0 -6
- data/test/test/file_methods/test_yml_compare/input/input_1.yml +0 -4
- data/test/test/file_methods/test_yml_compare/input/input_2.yml +0 -4
- 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
|
data/lib/tap/script/run.rb
DELETED
|
@@ -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
|