tap 0.9.1 → 0.10.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/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)
|