tap 0.9.1 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History +37 -30
- data/MIT-LICENSE +1 -1
- data/README +92 -44
- data/bin/tap +62 -75
- data/cmd/console.rb +42 -0
- data/cmd/destroy.rb +16 -0
- data/cmd/generate.rb +16 -0
- data/cmd/run.rb +126 -0
- data/doc/Class Reference +362 -0
- data/doc/Command Reference +153 -0
- data/doc/Tutorial +237 -0
- data/lib/tap.rb +6 -45
- data/lib/tap/app.rb +126 -500
- data/lib/tap/constants.rb +2 -29
- data/lib/tap/env.rb +555 -250
- data/lib/tap/file_task.rb +60 -103
- data/lib/tap/generator/base.rb +109 -0
- data/lib/tap/generator/destroy.rb +37 -0
- data/lib/tap/generator/generate.rb +61 -0
- data/lib/tap/generator/generators/command/command_generator.rb +16 -12
- data/lib/tap/generator/generators/command/templates/command.erb +13 -19
- data/lib/tap/generator/generators/config/config_generator.rb +18 -27
- data/lib/tap/generator/generators/config/templates/doc.erb +12 -0
- data/lib/tap/generator/generators/config/templates/nodoc.erb +8 -0
- data/lib/tap/generator/generators/file_task/file_task_generator.rb +16 -11
- data/lib/tap/generator/generators/file_task/templates/file.txt +11 -2
- data/lib/tap/generator/generators/file_task/templates/result.yml +6 -0
- data/lib/tap/generator/generators/file_task/templates/task.erb +24 -31
- data/lib/tap/generator/generators/file_task/templates/test.erb +18 -22
- data/lib/tap/generator/generators/root/root_generator.rb +45 -31
- data/lib/tap/generator/generators/root/templates/Rakefile +64 -41
- data/lib/tap/generator/generators/root/templates/gemspec +27 -0
- data/lib/tap/generator/generators/root/templates/tapfile +8 -0
- data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +0 -0
- data/lib/tap/generator/generators/root/templates/test/tap_test_suite.rb +1 -1
- data/lib/tap/generator/generators/root/templates/test/tapfile_test.rb +15 -0
- data/lib/tap/generator/generators/task/task_generator.rb +21 -28
- data/lib/tap/generator/generators/task/templates/task.erb +13 -23
- data/lib/tap/generator/generators/task/templates/test.erb +15 -18
- data/lib/tap/generator/manifest.rb +14 -0
- data/lib/tap/patches/rake/rake_test_loader.rb +0 -0
- data/lib/tap/patches/rake/testtask.rb +0 -0
- data/lib/tap/patches/ruby19/backtrace_filter.rb +0 -0
- data/lib/tap/patches/ruby19/parsedate.rb +0 -0
- data/lib/tap/root.rb +260 -21
- data/lib/tap/support/aggregator.rb +11 -11
- data/lib/tap/support/assignments.rb +172 -0
- data/lib/tap/support/audit.rb +20 -18
- data/lib/tap/support/batchable.rb +21 -10
- data/lib/tap/support/batchable_class.rb +107 -0
- data/lib/tap/support/class_configuration.rb +154 -239
- data/lib/tap/support/command_line.rb +97 -102
- data/lib/tap/support/comment.rb +270 -0
- data/lib/tap/support/configurable.rb +86 -65
- data/lib/tap/support/configurable_class.rb +296 -0
- data/lib/tap/support/configuration.rb +122 -0
- data/lib/tap/support/constant.rb +70 -0
- data/lib/tap/support/constant_utils.rb +127 -0
- data/lib/tap/support/declarations.rb +111 -0
- data/lib/tap/support/executable.rb +30 -17
- data/lib/tap/support/executable_queue.rb +0 -0
- data/lib/tap/support/framework.rb +71 -0
- data/lib/tap/support/framework_class.rb +199 -0
- data/lib/tap/support/instance_configuration.rb +147 -0
- data/lib/tap/support/lazydoc.rb +428 -0
- data/lib/tap/support/manifest.rb +89 -0
- data/lib/tap/support/run_error.rb +0 -0
- data/lib/tap/support/shell_utils.rb +33 -9
- data/lib/tap/support/summary.rb +30 -0
- data/lib/tap/support/tdoc.rb +339 -134
- data/lib/tap/support/tdoc/tdoc_html_generator.rb +0 -0
- data/lib/tap/support/tdoc/tdoc_html_template.rb +0 -0
- data/lib/tap/support/templater.rb +180 -0
- data/lib/tap/support/validation.rb +409 -76
- data/lib/tap/support/versions.rb +5 -3
- data/lib/tap/task.rb +78 -174
- data/lib/tap/tasks/dump.rb +56 -0
- data/lib/tap/tasks/rake.rb +93 -0
- data/lib/tap/test.rb +3 -3
- data/lib/tap/test/env_vars.rb +2 -2
- data/lib/tap/test/file_methods.rb +19 -20
- data/lib/tap/test/script_methods.rb +144 -0
- data/lib/tap/test/subset_methods.rb +1 -1
- data/lib/tap/test/tap_methods.rb +28 -62
- data/lib/tap/workflow.rb +22 -39
- metadata +48 -179
- data/Basic Overview +0 -151
- data/Command Reference +0 -99
- data/Rakefile +0 -127
- data/Tutorial +0 -287
- data/lib/tap/cmd/console.rb +0 -31
- data/lib/tap/cmd/destroy.rb +0 -20
- data/lib/tap/cmd/generate.rb +0 -20
- data/lib/tap/cmd/run.rb +0 -151
- data/lib/tap/dump.rb +0 -57
- data/lib/tap/generator.rb +0 -91
- data/lib/tap/generator/generators/command/USAGE +0 -6
- data/lib/tap/generator/generators/config/USAGE +0 -21
- data/lib/tap/generator/generators/config/templates/config.erb +0 -1
- data/lib/tap/generator/generators/file_task/USAGE +0 -3
- data/lib/tap/generator/generators/file_task/templates/file.yml +0 -3
- data/lib/tap/generator/generators/generator/USAGE +0 -0
- data/lib/tap/generator/generators/generator/generator_generator.rb +0 -21
- data/lib/tap/generator/generators/generator/templates/generator.erb +0 -32
- data/lib/tap/generator/generators/generator/templates/usage.erb +0 -1
- data/lib/tap/generator/generators/root/USAGE +0 -0
- data/lib/tap/generator/generators/root/templates/ReadMe.txt +0 -0
- data/lib/tap/generator/generators/root/templates/tap.yml +0 -80
- data/lib/tap/generator/generators/task/USAGE +0 -3
- data/lib/tap/generator/generators/workflow/USAGE +0 -0
- data/lib/tap/generator/generators/workflow/templates/task.erb +0 -16
- data/lib/tap/generator/generators/workflow/templates/test.erb +0 -7
- data/lib/tap/generator/generators/workflow/workflow_generator.rb +0 -6
- data/lib/tap/generator/options.rb +0 -26
- data/lib/tap/generator/usage.rb +0 -26
- data/lib/tap/support/batchable_methods.rb +0 -34
- data/lib/tap/support/command_line_methods.rb +0 -76
- data/lib/tap/support/configurable_methods.rb +0 -224
- data/lib/tap/support/logger.rb +0 -88
- data/lib/tap/support/rake.rb +0 -43
- data/lib/tap/support/tdoc/config_attr.rb +0 -362
- data/test/app/config/another/task.yml +0 -1
- data/test/app/config/batch.yml +0 -2
- data/test/app/config/empty.yml +0 -0
- data/test/app/config/erb.yml +0 -2
- data/test/app/config/some/task.yml +0 -1
- data/test/app/config/template.yml +0 -2
- data/test/app/config/version-0.1.yml +0 -1
- data/test/app/config/version.yml +0 -1
- data/test/app/lib/app_test_task.rb +0 -3
- data/test/app_test.rb +0 -1849
- data/test/env/test_configure/recurse_a.yml +0 -2
- data/test/env/test_configure/recurse_b.yml +0 -2
- data/test/env/test_configure/tap.yml +0 -23
- data/test/env/test_load_env_config/dir/tap.yml +0 -3
- data/test/env/test_load_env_config/recurse_a.yml +0 -2
- data/test/env/test_load_env_config/recurse_b.yml +0 -2
- data/test/env/test_load_env_config/tap.yml +0 -3
- data/test/env_test.rb +0 -198
- data/test/file_task/config/batch.yml +0 -2
- data/test/file_task/config/configured.yml +0 -1
- data/test/file_task/old_file_one.txt +0 -0
- data/test/file_task/old_file_two.txt +0 -0
- data/test/file_task_test.rb +0 -1291
- data/test/root/alt_lib/alt_module.rb +0 -4
- data/test/root/file.txt +0 -0
- data/test/root/glob/one.txt +0 -0
- data/test/root/glob/two.txt +0 -0
- data/test/root/lib/absolute_alt_filepath.rb +0 -2
- data/test/root/lib/alternative_filepath.rb +0 -2
- data/test/root/lib/another_module.rb +0 -2
- data/test/root/lib/nested/some_module.rb +0 -4
- data/test/root/lib/no_module_included.rb +0 -0
- data/test/root/lib/some/module.rb +0 -4
- data/test/root/lib/some_class.rb +0 -2
- data/test/root/lib/some_module.rb +0 -3
- data/test/root/load_path/load_path_module.rb +0 -2
- data/test/root/load_path/skip_module.rb +0 -2
- data/test/root/mtime/older.txt +0 -0
- data/test/root/unload/full_path.rb +0 -2
- data/test/root/unload/loaded_by_nested.rb +0 -2
- data/test/root/unload/nested/nested_load.rb +0 -6
- data/test/root/unload/nested/nested_with_ext.rb +0 -4
- data/test/root/unload/nested/relative_path.rb +0 -4
- data/test/root/unload/older.rb +0 -2
- data/test/root/unload/unload_base.rb +0 -9
- data/test/root/versions/another.yml +0 -0
- data/test/root/versions/file-0.1.2.yml +0 -0
- data/test/root/versions/file-0.1.yml +0 -0
- data/test/root/versions/file.yml +0 -0
- data/test/root_test.rb +0 -718
- data/test/support/aggregator_test.rb +0 -99
- data/test/support/audit_test.rb +0 -445
- data/test/support/batchable_test.rb +0 -74
- data/test/support/class_configuration_test.rb +0 -331
- data/test/support/command_line_test.rb +0 -58
- data/test/support/configurable/config/configured.yml +0 -2
- data/test/support/configurable_test.rb +0 -295
- data/test/support/executable_queue_test.rb +0 -103
- data/test/support/executable_test.rb +0 -38
- data/test/support/logger_test.rb +0 -31
- data/test/support/rake_test.rb +0 -37
- data/test/support/shell_utils_test.rb +0 -24
- data/test/support/tdoc_test.rb +0 -370
- data/test/support/validation_test.rb +0 -54
- data/test/support/versions_test.rb +0 -103
- data/test/tap_test_helper.rb +0 -57
- data/test/tap_test_suite.rb +0 -7
- data/test/task/config/batch.yml +0 -2
- data/test/task/config/batched.yml +0 -2
- data/test/task/config/configured.yml +0 -1
- data/test/task/config/example.yml +0 -1
- data/test/task_base_test.rb +0 -24
- data/test/task_syntax_test.rb +0 -300
- data/test/task_test.rb +0 -320
- data/test/test/env_vars_test.rb +0 -48
- data/test/test/file_methods/test_assert_files/expected/one.txt +0 -1
- data/test/test/file_methods/test_assert_files/expected/two.txt +0 -1
- data/test/test/file_methods/test_assert_files/input/one.txt +0 -1
- data/test/test/file_methods/test_assert_files/input/two.txt +0 -1
- data/test/test/file_methods/test_assert_files_can_have_no_expected_files_if_specified/input/one.txt +0 -1
- data/test/test/file_methods/test_assert_files_can_have_no_expected_files_if_specified/input/two.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_different_content/expected/one.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_different_content/expected/two.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_different_content/input/one.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_different_content/input/two.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_missing_expected_file/expected/one.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_missing_expected_file/input/one.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_missing_expected_file/input/two.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/expected/one.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/expected/two.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/input/one.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/input/two.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_no_expected_files/input/one.txt +0 -1
- data/test/test/file_methods/test_assert_files_fails_for_no_expected_files/input/two.txt +0 -1
- data/test/test/file_methods/test_method_glob/expected/file.yml +0 -0
- data/test/test/file_methods/test_method_glob/expected/file_1.txt +0 -0
- data/test/test/file_methods/test_method_glob/expected/file_2.txt +0 -0
- data/test/test/file_methods_doc/test_sub/expected/one.txt +0 -1
- data/test/test/file_methods_doc/test_sub/expected/two.txt +0 -1
- data/test/test/file_methods_doc/test_sub/input/one.txt +0 -1
- data/test/test/file_methods_doc/test_sub/input/two.txt +0 -1
- data/test/test/file_methods_doc_test.rb +0 -29
- data/test/test/file_methods_test.rb +0 -275
- data/test/test/subset_methods_test.rb +0 -171
- data/test/test/tap_methods/test_assert_files/expected/task/name/a.txt +0 -1
- data/test/test/tap_methods/test_assert_files/expected/task/name/b.txt +0 -1
- data/test/test/tap_methods/test_assert_files/input/a.txt +0 -1
- data/test/test/tap_methods/test_assert_files/input/b.txt +0 -1
- data/test/test/tap_methods_test.rb +0 -399
- data/test/workflow_test.rb +0 -120
- data/vendor/rails_generator.rb +0 -56
- data/vendor/rails_generator/base.rb +0 -263
- data/vendor/rails_generator/commands.rb +0 -581
- data/vendor/rails_generator/generated_attribute.rb +0 -42
- data/vendor/rails_generator/lookup.rb +0 -209
- data/vendor/rails_generator/manifest.rb +0 -53
- data/vendor/rails_generator/options.rb +0 -143
- data/vendor/rails_generator/scripts.rb +0 -83
- data/vendor/rails_generator/scripts/destroy.rb +0 -7
- data/vendor/rails_generator/scripts/generate.rb +0 -7
- data/vendor/rails_generator/scripts/update.rb +0 -12
- data/vendor/rails_generator/simple_logger.rb +0 -46
- data/vendor/rails_generator/spec.rb +0 -44
@@ -0,0 +1,122 @@
|
|
1
|
+
module Tap
|
2
|
+
module Support
|
3
|
+
class Configuration
|
4
|
+
class << self
|
5
|
+
SHORT_REGEXP = /^-[A-z]$/
|
6
|
+
|
7
|
+
# Turns the input string into a short-format option. Raises
|
8
|
+
# an error if the option does not match SHORT_REGEXP.
|
9
|
+
#
|
10
|
+
# Configuration.shortify("-o") # => '-o'
|
11
|
+
# Configuration.shortify(:o) # => '-o'
|
12
|
+
#
|
13
|
+
def shortify(str)
|
14
|
+
str = str.to_s
|
15
|
+
str = "-#{str}" unless str[0] == ?-
|
16
|
+
raise "invalid short option: #{str}" unless str =~ SHORT_REGEXP
|
17
|
+
str
|
18
|
+
end
|
19
|
+
|
20
|
+
LONG_REGEXP = /^--(\[no-\])?([A-z][\w-]*)$/
|
21
|
+
|
22
|
+
# Turns the input string into a long-format option. Raises
|
23
|
+
# an error if the option does not match LONG_REGEXP.
|
24
|
+
#
|
25
|
+
# Configuration.longify("--opt") # => '--opt'
|
26
|
+
# Configuration.longify(:opt) # => '--opt'
|
27
|
+
# Configuration.longify(:opt, true) # => '--[no-]opt'
|
28
|
+
# Configuration.longify(:opt_ion) # => '--opt-ion'
|
29
|
+
# Configuration.longify(:opt_ion, false, false) # => '--opt_ion'
|
30
|
+
#
|
31
|
+
def longify(str, switch_notation=false, hyphenize=true)
|
32
|
+
str = str.to_s
|
33
|
+
str = "--#{str}" unless str.index("--")
|
34
|
+
str.gsub!(/_/, '-') if hyphenize
|
35
|
+
|
36
|
+
raise "invalid long option: #{str}" unless str =~ LONG_REGEXP
|
37
|
+
|
38
|
+
if switch_notation && $1.nil?
|
39
|
+
str = "--[no-]#{$2}"
|
40
|
+
end
|
41
|
+
|
42
|
+
str
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
attr_reader :name
|
47
|
+
attr_reader :reader
|
48
|
+
attr_reader :writer
|
49
|
+
attr_reader :duplicable
|
50
|
+
attr_reader :attributes
|
51
|
+
|
52
|
+
def initialize(name, default=nil, options={})
|
53
|
+
@name = name
|
54
|
+
self.default = default
|
55
|
+
|
56
|
+
self.reader = options.delete(:reader) || name
|
57
|
+
self.writer = options.delete(:writer) || "#{name}="
|
58
|
+
@attributes = options
|
59
|
+
end
|
60
|
+
|
61
|
+
# Sets the default value for self and determines if the
|
62
|
+
# default is duplicable (ie not nil, true, false, Symbol,
|
63
|
+
# Numeric, and responds_to?(:dup)).
|
64
|
+
def default=(value)
|
65
|
+
@duplicable = case value
|
66
|
+
when nil, true, false, Symbol, Numeric then false
|
67
|
+
else value.respond_to?(:dup)
|
68
|
+
end
|
69
|
+
|
70
|
+
@default = value.freeze
|
71
|
+
end
|
72
|
+
|
73
|
+
# Returns the default value, or a duplicate of the default
|
74
|
+
# value if specified and the default value is duplicable.
|
75
|
+
def default(duplicate=true)
|
76
|
+
duplicate && duplicable ? @default.dup : @default
|
77
|
+
end
|
78
|
+
|
79
|
+
# Sets the reader for self. The reader is symbolized.
|
80
|
+
def reader=(value)
|
81
|
+
@reader = value.to_sym
|
82
|
+
end
|
83
|
+
|
84
|
+
# Sets the writer for self. The writer is symbolized.
|
85
|
+
def writer=(value)
|
86
|
+
@writer = value.to_sym
|
87
|
+
end
|
88
|
+
|
89
|
+
def arg_name
|
90
|
+
attributes[:arg_name] || name.to_s.upcase
|
91
|
+
end
|
92
|
+
|
93
|
+
def arg_type
|
94
|
+
attributes[:arg_type] || :mandatory
|
95
|
+
end
|
96
|
+
|
97
|
+
def long(switch_notation=false, hyphenize=true)
|
98
|
+
Configuration.longify(attributes[:long] || name.to_s, switch_notation, hyphenize)
|
99
|
+
end
|
100
|
+
|
101
|
+
def short
|
102
|
+
attributes[:short] ? Configuration.shortify(attributes[:short]) : nil
|
103
|
+
end
|
104
|
+
|
105
|
+
def desc
|
106
|
+
attributes[:desc]
|
107
|
+
end
|
108
|
+
|
109
|
+
# True if another is a kind of Configuration with the same name,
|
110
|
+
# default value, reader and writer; other attributes are NOT
|
111
|
+
# taken into account.
|
112
|
+
def ==(another)
|
113
|
+
another.kind_of?(Configuration) &&
|
114
|
+
self.name == another.name &&
|
115
|
+
self.reader == another.reader &&
|
116
|
+
self.writer == another.writer &&
|
117
|
+
self.default(false) == another.default(false)
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'tap/support/constant_utils'
|
2
|
+
class String # :nodoc:
|
3
|
+
include Tap::Support::ConstantUtils
|
4
|
+
end
|
5
|
+
|
6
|
+
module Tap
|
7
|
+
module Support
|
8
|
+
class Constant
|
9
|
+
|
10
|
+
# The camelized name for self.
|
11
|
+
attr_reader :name
|
12
|
+
|
13
|
+
# The path to load to initialize the constant name.
|
14
|
+
attr_reader :require_path
|
15
|
+
|
16
|
+
def initialize(name, require_path=nil)
|
17
|
+
@name = name
|
18
|
+
@require_path = require_path
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns the underscored name.
|
22
|
+
def path
|
23
|
+
@path ||= name.underscore
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the basename of path.
|
27
|
+
def basename
|
28
|
+
@basename ||= File.basename(path)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns the path, minus the basename of path.
|
32
|
+
def dirname
|
33
|
+
@dirname ||= (dirname = File.dirname(path)) == "." ? "" : dirname
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the name of the constant, minus nesting.
|
37
|
+
def const_name
|
38
|
+
@const_name ||= (name =~ /.*::(.*)$/ ? $1 : name)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns an array of the nesting constants of name.
|
42
|
+
def nesting
|
43
|
+
@nesting ||= (name =~ /(.*)::.*$/ ? $1 : '')
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the number of constants in nesting.
|
47
|
+
def nesting_depth
|
48
|
+
@nesting_depth ||= nesting.split(/::/).length
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns the document for require_path, if set, or nil otherwise.
|
52
|
+
def document
|
53
|
+
require_path ? Support::Lazydoc[require_path] : nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def ==(another)
|
57
|
+
another.kind_of?(Constant) &&
|
58
|
+
another.name == self.name &&
|
59
|
+
another.require_path == self.require_path
|
60
|
+
end
|
61
|
+
|
62
|
+
def constantize
|
63
|
+
name.try_constantize do |const_name|
|
64
|
+
require require_path
|
65
|
+
name.constantize
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module Tap
|
2
|
+
module Support
|
3
|
+
|
4
|
+
# ConstantUtils provides methods for transforming strings into constants.
|
5
|
+
# Several methods are directly taken from or based heavily on the
|
6
|
+
# ActiveSupport {Inflections}[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
|
7
|
+
# module and should not cause conflicts if ActiveSupport is loaded
|
8
|
+
# alongside Tap.
|
9
|
+
#
|
10
|
+
# ActiveSupport is distributed with an MIT-LICENSE:
|
11
|
+
#
|
12
|
+
# Copyright (c) 2004-2008 David Heinemeier Hansson
|
13
|
+
#
|
14
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
15
|
+
# associated documentation files (the "Software"), to deal in the Software without restriction,
|
16
|
+
# including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
17
|
+
# and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
18
|
+
# subject to the following conditions:
|
19
|
+
#
|
20
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial
|
21
|
+
# portions of the Software.
|
22
|
+
#
|
23
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
24
|
+
# LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
25
|
+
# NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
26
|
+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
27
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
28
|
+
#
|
29
|
+
module ConstantUtils
|
30
|
+
|
31
|
+
# camelize converts self to UpperCamelCase. If the argument to
|
32
|
+
# camelize is set to :lower then camelize produces lowerCamelCase.
|
33
|
+
# camelize will also convert '/' to '::' which is useful for
|
34
|
+
# converting paths to namespaces.
|
35
|
+
def camelize(first_letter = :upper)
|
36
|
+
case first_letter
|
37
|
+
when :upper then self.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
38
|
+
when :lower then self.first + camelize[1..-1]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# The reverse of camelize. Makes an underscored, lowercase form
|
43
|
+
# from self. underscore will also change '::' to '/' to convert
|
44
|
+
# namespaces to paths.
|
45
|
+
def underscore
|
46
|
+
self.gsub(/::/, '/').
|
47
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
48
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
49
|
+
tr("-", "_").
|
50
|
+
downcase
|
51
|
+
end
|
52
|
+
|
53
|
+
# constantize tries to find a declared constant with the name specified
|
54
|
+
# by self. It raises a NameError when the name is not in CamelCase
|
55
|
+
# or is not initialized.
|
56
|
+
def constantize
|
57
|
+
case RUBY_VERSION
|
58
|
+
when /^1.9/
|
59
|
+
|
60
|
+
# a check is necessary to maintain the 1.8 behavior
|
61
|
+
# in 1.9, where ancestor constants may be returned
|
62
|
+
# by a direct evaluation
|
63
|
+
const_name.split("::").inject(Object) do |current, const|
|
64
|
+
const = const.to_sym
|
65
|
+
|
66
|
+
current.const_get(const).tap do |c|
|
67
|
+
unless current.const_defined?(const, false)
|
68
|
+
raise NameError.new("uninitialized constant #{const_name}")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
else
|
74
|
+
Object.module_eval("::#{const_name}", __FILE__, __LINE__)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Tries to constantize self; if a NameError is raised, try_constantize
|
79
|
+
# passes control to the block. Control is only passed if the NameError
|
80
|
+
# is for one of the constants in self.
|
81
|
+
def try_constantize
|
82
|
+
begin
|
83
|
+
constantize
|
84
|
+
rescue(NameError)
|
85
|
+
error_name = $!.name.to_s
|
86
|
+
missing_const = const_name.split(/::/).inject(Object) do |current, const|
|
87
|
+
if current.const_defined?(const)
|
88
|
+
current.const_get(const)
|
89
|
+
else
|
90
|
+
break(const)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# check that the error_name is the first missing constant
|
95
|
+
raise $! unless missing_const == error_name
|
96
|
+
yield(const_name)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def constants_split
|
101
|
+
camel_cased_word = camelize
|
102
|
+
unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ camel_cased_word
|
103
|
+
raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!"
|
104
|
+
end
|
105
|
+
|
106
|
+
constants = $1.split(/::/)
|
107
|
+
current = Object
|
108
|
+
while !constants.empty?
|
109
|
+
break unless current.const_defined?(constants[0])
|
110
|
+
current = current.const_get(constants.shift)
|
111
|
+
end
|
112
|
+
|
113
|
+
[current, constants]
|
114
|
+
end
|
115
|
+
|
116
|
+
protected
|
117
|
+
|
118
|
+
def const_name
|
119
|
+
unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ self
|
120
|
+
raise NameError, "#{inspect} is not a valid constant name!"
|
121
|
+
end
|
122
|
+
$1
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Tap
|
2
|
+
module Support
|
3
|
+
module Declarations
|
4
|
+
def self.set_declaration_base(base)
|
5
|
+
# TODO -- warn if base is Object -- conflict with Rake
|
6
|
+
declaration_base = base.to_s
|
7
|
+
declaration_base = "" if ["Object", "Tap"].include?(declaration_base)
|
8
|
+
|
9
|
+
base.instance_variable_set(:@tap_declaration_base, declaration_base.underscore)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
set_declaration_base(base)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.extended(base)
|
17
|
+
set_declaration_base(base)
|
18
|
+
end
|
19
|
+
|
20
|
+
def tasc(name, configs={}, options={}, &block)
|
21
|
+
Tap::Task.subclass(nest(name), configs, options, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def task(name, configs={}, options={}, &block)
|
25
|
+
options[:arity] = arity(block)
|
26
|
+
tasc(name, configs, options, &task_block(block)).new
|
27
|
+
end
|
28
|
+
|
29
|
+
def file_tasc(name, configs={}, options={}, &block)
|
30
|
+
Tap::FileTask.subclass(nest(name), configs, options, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def file_task(name, configs={}, options={}, &block)
|
34
|
+
options[:arity] = arity(block)
|
35
|
+
file_tasc(nest(name), configs, options, &task_block(block)).new
|
36
|
+
end
|
37
|
+
|
38
|
+
def worcflow(name, configs={}, options={}, &block)
|
39
|
+
Tap::Workflow.subclass(nest(name), configs, options, &block)
|
40
|
+
end
|
41
|
+
|
42
|
+
def workflow(name, configs={}, options={}, &block)
|
43
|
+
options[:arity] = arity(block)
|
44
|
+
worcflow(name, configs, options, &task_block(block)).new
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
def config(key, value=nil, options={}, &block)
|
50
|
+
caller.each_with_index do |line, index|
|
51
|
+
case line
|
52
|
+
when /^(([A-z]:)?[^:]+):(\d+)/
|
53
|
+
options[:desc] = Support::Lazydoc.register($1, $3.to_i - 1)
|
54
|
+
break
|
55
|
+
end
|
56
|
+
end if options[:desc] == nil
|
57
|
+
|
58
|
+
[:config, key, value, options, block]
|
59
|
+
end
|
60
|
+
|
61
|
+
def config_attr(key, value=nil, options={}, &block)
|
62
|
+
caller.each_with_index do |line, index|
|
63
|
+
case line
|
64
|
+
when /^(([A-z]:)?[^:]+):(\d+)/
|
65
|
+
options[:desc] = Support::Lazydoc.register($1, $3.to_i - 1)
|
66
|
+
break
|
67
|
+
end
|
68
|
+
end if options[:desc] == nil
|
69
|
+
|
70
|
+
[:config_attr, key, value, options, block]
|
71
|
+
end
|
72
|
+
|
73
|
+
def c
|
74
|
+
Support::Validation
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def nest(name)
|
80
|
+
# use self if self is a Module or Class,
|
81
|
+
# or self.class if self is an instance.
|
82
|
+
File.join((self.kind_of?(Module) ? self : self.class).instance_variable_get(:@tap_declaration_base), name.to_s)
|
83
|
+
end
|
84
|
+
|
85
|
+
def arity(block)
|
86
|
+
arity = block.arity
|
87
|
+
|
88
|
+
case
|
89
|
+
when arity > 0 then arity -= 1
|
90
|
+
when arity < 0 then arity += 1
|
91
|
+
end
|
92
|
+
|
93
|
+
arity
|
94
|
+
end
|
95
|
+
|
96
|
+
def task_block(block)
|
97
|
+
lambda do |*inputs|
|
98
|
+
inputs.unshift(self)
|
99
|
+
|
100
|
+
arity = block.arity
|
101
|
+
n = inputs.length
|
102
|
+
unless n == arity || (arity < 0 && (-1-n) <= arity)
|
103
|
+
raise ArgumentError.new("wrong number of arguments (#{n} for #{arity})")
|
104
|
+
end
|
105
|
+
|
106
|
+
block.call(*inputs)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -1,23 +1,25 @@
|
|
1
|
+
require 'tap/support/audit'
|
2
|
+
|
1
3
|
module Tap
|
2
4
|
module Support
|
3
|
-
# Executable wraps methods to make them executable by App.
|
5
|
+
# Executable wraps methods to make them executable by App. Methods are
|
6
|
+
# wrapped by extending the object that receives them; the easiest way
|
7
|
+
# to make an object executable is to use Object#_method.
|
4
8
|
module Executable
|
5
9
|
|
6
10
|
# The method called when an Executable is executed via _execute
|
7
11
|
attr_reader :_method_name
|
8
12
|
|
9
|
-
# Indicates whether or not to
|
13
|
+
# Indicates whether or not to execute in multithread mode.
|
10
14
|
attr_accessor :multithread
|
11
15
|
|
12
|
-
# Stores the on complete block.
|
16
|
+
# Stores the on complete block.
|
13
17
|
attr_reader :on_complete_block
|
14
18
|
|
15
|
-
protected
|
16
|
-
|
17
|
-
attr_writer :_method_name
|
18
|
-
|
19
19
|
public
|
20
|
-
|
20
|
+
|
21
|
+
# Extends obj with Executable and sets up all required variables. The
|
22
|
+
# specified method will be called on _execute.
|
21
23
|
def self.initialize(obj, method_name, multithread=false, &on_complete_block)
|
22
24
|
obj.extend Executable
|
23
25
|
obj.instance_variable_set(:@_method_name, method_name)
|
@@ -26,8 +28,9 @@ module Tap
|
|
26
28
|
obj
|
27
29
|
end
|
28
30
|
|
29
|
-
# Sets a block to receive the results of
|
30
|
-
# if
|
31
|
+
# Sets a block to receive the results of _execute. Raises an error
|
32
|
+
# if an on_complete block is already set. Override an existing
|
33
|
+
# on_complete block by specifying override = true.
|
31
34
|
#
|
32
35
|
# Note the block recieves an audited result and not
|
33
36
|
# the result itself (see Audit for more information).
|
@@ -82,15 +85,25 @@ module Tap
|
|
82
85
|
end
|
83
86
|
end
|
84
87
|
|
85
|
-
# Tap extends Object with
|
86
|
-
# that can be enqued by App and incorporated into workflows.
|
88
|
+
# Tap extends Object with <tt>_method</tt> to generate executable methods
|
89
|
+
# that can be enqued by Tap::App and incorporated into workflows.
|
90
|
+
#
|
91
|
+
# array = []
|
92
|
+
# push_to_array = array._method(:push)
|
93
|
+
#
|
94
|
+
# task = Tap::Task.new
|
95
|
+
# task.app.sequence(task, push_to_array)
|
96
|
+
#
|
97
|
+
# task.enq(1).enq(2,3)
|
98
|
+
# task.app.run
|
99
|
+
#
|
100
|
+
# array # => [[1],[2,3]]
|
101
|
+
#
|
87
102
|
class Object
|
88
103
|
|
89
|
-
#
|
90
|
-
# Object#method, setting multithread and the on_complete
|
91
|
-
# as specified.
|
92
|
-
#
|
93
|
-
# Returns nil if Object#method returns nil.
|
104
|
+
# Initializes a Tap::Support::Executable using the Method returned by
|
105
|
+
# Object#method(method_name), setting multithread and the on_complete
|
106
|
+
# block as specified. Returns nil if Object#method returns nil.
|
94
107
|
def _method(method_name, multithread=false, &on_complete_block) # :yields: _result
|
95
108
|
return nil unless m = method(method_name)
|
96
109
|
Tap::Support::Executable.initialize(m, :call, multithread, &on_complete_block)
|