bahuvrihi-tap 0.11.2 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/bin/rap +2 -3
  2. data/bin/tap +1 -1
  3. data/cmd/console.rb +2 -2
  4. data/cmd/manifest.rb +2 -2
  5. data/cmd/run.rb +7 -9
  6. data/cmd/server.rb +5 -5
  7. data/doc/Class Reference +17 -20
  8. data/doc/Tutorial +5 -7
  9. data/lib/tap.rb +2 -0
  10. data/lib/tap/app.rb +21 -31
  11. data/lib/tap/constants.rb +2 -2
  12. data/lib/tap/declarations.rb +85 -97
  13. data/lib/tap/declarations/declaration_task.rb +58 -0
  14. data/lib/tap/declarations/description.rb +24 -0
  15. data/lib/tap/env.rb +20 -16
  16. data/lib/tap/exe.rb +2 -2
  17. data/lib/tap/file_task.rb +224 -410
  18. data/lib/tap/generator/arguments.rb +9 -0
  19. data/lib/tap/generator/base.rb +105 -28
  20. data/lib/tap/generator/destroy.rb +29 -12
  21. data/lib/tap/generator/generate.rb +55 -39
  22. data/lib/tap/generator/generators/command/templates/command.erb +3 -3
  23. data/lib/tap/generator/generators/config/config_generator.rb +34 -3
  24. data/lib/tap/generator/generators/root/root_generator.rb +6 -9
  25. data/lib/tap/generator/generators/root/templates/Rakefile +4 -4
  26. data/lib/tap/generator/generators/task/templates/test.erb +1 -1
  27. data/lib/tap/root.rb +211 -156
  28. data/lib/tap/support/aggregator.rb +6 -9
  29. data/lib/tap/support/audit.rb +278 -357
  30. data/lib/tap/support/constant_manifest.rb +24 -21
  31. data/lib/tap/support/dependency.rb +1 -1
  32. data/lib/tap/support/executable.rb +26 -48
  33. data/lib/tap/support/join.rb +44 -19
  34. data/lib/tap/support/joins/sync_merge.rb +3 -5
  35. data/lib/tap/support/parser.rb +1 -1
  36. data/lib/tap/task.rb +195 -150
  37. data/lib/tap/tasks/dump.rb +2 -2
  38. data/lib/tap/test/extensions.rb +11 -13
  39. data/lib/tap/test/file_test.rb +71 -129
  40. data/lib/tap/test/file_test_class.rb +4 -1
  41. data/lib/tap/test/tap_test.rb +26 -154
  42. metadata +15 -22
  43. data/lib/tap/patches/optparse/summarize.rb +0 -62
  44. data/lib/tap/support/assignments.rb +0 -173
  45. data/lib/tap/support/class_configuration.rb +0 -182
  46. data/lib/tap/support/configurable.rb +0 -113
  47. data/lib/tap/support/configurable_class.rb +0 -271
  48. data/lib/tap/support/configuration.rb +0 -170
  49. data/lib/tap/support/instance_configuration.rb +0 -173
  50. data/lib/tap/support/lazydoc.rb +0 -386
  51. data/lib/tap/support/lazydoc/attributes.rb +0 -48
  52. data/lib/tap/support/lazydoc/comment.rb +0 -503
  53. data/lib/tap/support/lazydoc/config.rb +0 -17
  54. data/lib/tap/support/lazydoc/definition.rb +0 -36
  55. data/lib/tap/support/lazydoc/document.rb +0 -152
  56. data/lib/tap/support/lazydoc/method.rb +0 -24
  57. data/lib/tap/support/tdoc.rb +0 -409
  58. data/lib/tap/support/tdoc/tdoc_html_generator.rb +0 -38
  59. data/lib/tap/support/tdoc/tdoc_html_template.rb +0 -42
  60. data/lib/tap/support/validation.rb +0 -479
@@ -1,113 +0,0 @@
1
- require 'tap/support/configurable_class'
2
-
3
- module Tap
4
- module Support
5
-
6
- # Configurable enables the specification of configurations within a class definition.
7
- #
8
- # class ConfigClass
9
- # include Configurable
10
- #
11
- # config :one, 'one'
12
- # config :two, 'two'
13
- # config :three, 'three'
14
- #
15
- # def initialize(overrides={})
16
- # initialize_config(overrides)
17
- # end
18
- # end
19
- #
20
- # c = ConfigClass.new
21
- # c.config.class # => InstanceConfiguration
22
- # c.config # => {:one => 'one', :two => 'two', :three => 'three'}
23
- #
24
- # The <tt>config</tt> object acts as a forwarding hash; declared configurations
25
- # map to accessors while undeclared configurations are stored internally:
26
- #
27
- # c.config[:one] = 'ONE'
28
- # c.one # => 'ONE'
29
- #
30
- # c.one = 1
31
- # c.config # => {:one => 1, :two => 'two', :three => 'three'}
32
- #
33
- # c.config[:undeclared] = 'value'
34
- # c.config.store # => {:undeclared => 'value'}
35
- #
36
- # The writer for a configuration can be defined by providing a block to config.
37
- # The Validation module provides a number of common validation/transform
38
- # blocks which can be accessed through the class method 'c':
39
- #
40
- # class SubClass < ConfigClass
41
- # config(:one, 'one') {|v| v.upcase }
42
- # config :two, 2, &c.integer
43
- # end
44
- #
45
- # s = SubClass.new
46
- # s.config # => {:one => 'ONE', :two => 2, :three => 'three'}
47
- #
48
- # s.one = 'aNothER'
49
- # s.one # => 'ANOTHER'
50
- #
51
- # s.two = -2
52
- # s.two # => -2
53
- # s.two = "3"
54
- # s.two # => 3
55
- # s.two = nil # !> ValidationError
56
- # s.two = 'str' # !> ValidationError
57
- #
58
- # As shown above, configurations are inherited from the parent and may be
59
- # overridden in subclasses. See ConfigurableClass for more details.
60
- #
61
- module Configurable
62
-
63
- # Extends including classes with ConfigurableClass
64
- def self.included(mod) # :nodoc:
65
- mod.extend Support::ConfigurableClass if mod.kind_of?(Class)
66
- end
67
-
68
- # An InstanceConfiguration with configurations for self
69
- attr_reader :config
70
-
71
- # Reconfigures self with the given overrides. Only the specified configs
72
- # are modified. Keys are symbolized.
73
- #
74
- # Returns self.
75
- def reconfigure(overrides={})
76
- keys = (config.class_config.ordered_keys + overrides.keys) & overrides.keys
77
- keys.each do |key|
78
- config[key.to_sym] = overrides[key]
79
- end
80
-
81
- self
82
- end
83
-
84
- # Reinitializes configurations in the copy such that
85
- # the new object has it's own set of configurations,
86
- # separate from the original object.
87
- def initialize_copy(orig)
88
- super
89
- initialize_config(orig.config)
90
- end
91
-
92
- protected
93
-
94
- # Initializes config to an InstanceConfiguration. Default config values
95
- # are overridden as specified by overrides. Keys are symbolized.
96
- def initialize_config(overrides={})
97
- class_config = self.class.configurations
98
- @config = class_config.instance_config
99
-
100
- overrides.each_pair do |key, value|
101
- config[key.to_sym] = value
102
- end
103
-
104
- class_config.each_pair do |key, value|
105
- next if config.has_key?(key)
106
- config[key] = value.default
107
- end
108
-
109
- config.bind(self)
110
- end
111
- end
112
- end
113
- end
@@ -1,271 +0,0 @@
1
- require 'tap/support/class_configuration'
2
- require 'tap/support/validation'
3
- require 'tap/support/lazydoc/attributes'
4
- require 'tap/support/lazydoc/config'
5
-
6
- module Tap
7
- module Support
8
- autoload(:Templater, 'tap/support/templater')
9
-
10
- # ConfigurableClass defines class methods used by a Configurable class to
11
- # declare configurations. In addition to registering key-value pairs,
12
- # these methods generate readers and writers, much like attr_accessor.
13
- #
14
- # class ConfigurableClass
15
- # extend ConfigurableClass
16
- # config :one, 'one'
17
- # end
18
- #
19
- # ConfigurableClass.configurations.to_hash # => {:one => 'one'}
20
- #
21
- # c = ConfigurableClass.new
22
- # c.respond_to?('one') # => true
23
- # c.respond_to?('one=') # => true
24
- #
25
- module ConfigurableClass
26
- include Lazydoc::Attributes
27
-
28
- # A ClassConfiguration holding the class configurations.
29
- attr_reader :configurations
30
-
31
- # Sets the source_file for base and initializes base.configurations.
32
- def self.extended(base) # :nodoc:
33
- caller.each_with_index do |line, index|
34
- case line
35
- when /\/configurable.rb/ then next
36
- when Lazydoc::CALLER_REGEXP
37
- base.instance_variable_set(:@source_file, File.expand_path($1))
38
- break
39
- end
40
- end
41
-
42
- base.instance_variable_set(:@configurations, ClassConfiguration.new(base))
43
- end
44
-
45
- # When subclassed, the parent.configurations are duplicated and passed to
46
- # the child class where they can be extended/modified without affecting
47
- # the configurations of the parent class.
48
- def inherited(child) # :nodoc:
49
- unless child.instance_variable_defined?(:@source_file)
50
- caller.first =~ Lazydoc::CALLER_REGEXP
51
- child.instance_variable_set(:@source_file, File.expand_path($1))
52
- end
53
-
54
- child.instance_variable_set(:@configurations, ClassConfiguration.new(child, @configurations))
55
- super
56
- end
57
-
58
- # Returns the lazydoc for self.
59
- def lazydoc(resolve=true)
60
- Lazydoc.resolve_comments(configurations.code_comments) if resolve
61
- super
62
- end
63
-
64
- # Loads the contents of path as YAML. Returns an empty hash if the path
65
- # is empty, does not exist, or is not a file.
66
- def load_config(path)
67
- # the last check prevents YAML from auto-loading itself for empty files
68
- return {} if path == nil || !File.file?(path) || File.size(path) == 0
69
- YAML.load_file(path) || {}
70
- end
71
-
72
- protected
73
-
74
- # Declares a class configuration and generates the associated accessors.
75
- # If a block is given, the <tt>key=</tt> method will set <tt>@key</tt>
76
- # to the return of the block, which executes in class-context.
77
- # Configurations are inherited, and can be overridden in subclasses.
78
- #
79
- # class SampleClass
80
- # include Tap::Support::Configurable
81
- #
82
- # config :str, 'value'
83
- # config(:upcase, 'value') {|input| input.upcase }
84
- # end
85
- #
86
- # # An equivalent class to illustrate class-context
87
- # class EquivalentClass
88
- # attr_accessor :str
89
- # attr_reader :upcase
90
- #
91
- # UPCASE_BLOCK = lambda {|input| input.upcase }
92
- #
93
- # def upcase=(input)
94
- # @upcase = UPCASE_BLOCK.call(input)
95
- # end
96
- # end
97
- #
98
- def config(key, value=nil, options={}, &block)
99
- if block_given?
100
- # add arg_type implied by block, if necessary
101
- options[:arg_type] = arg_type(block) if options[:arg_type] == nil
102
- options[:arg_name] = arg_name(block) if options[:arg_name] == nil
103
-
104
- instance_variable = "@#{key}".to_sym
105
- config_attr(key, value, options) do |input|
106
- instance_variable_set(instance_variable, block.call(input))
107
- end
108
- else
109
- config_attr(key, value, options)
110
- end
111
- end
112
-
113
- # Declares a class configuration and generates the associated accessors.
114
- # If a block is given, the <tt>key=</tt> method will perform the block with
115
- # instance-context. Configurations are inherited, and can be overridden
116
- # in subclasses.
117
- #
118
- # class SampleClass
119
- # include Tap::Support::Configurable
120
- #
121
- # def initialize
122
- # initialize_config
123
- # end
124
- #
125
- # config_attr :str, 'value'
126
- # config_attr(:upcase, 'value') {|input| @upcase = input.upcase }
127
- # end
128
- #
129
- # # An equivalent class to illustrate instance-context
130
- # class EquivalentClass
131
- # attr_accessor :str
132
- # attr_reader :upcase
133
- #
134
- # def upcase=(input)
135
- # @upcase = input.upcase
136
- # end
137
- # end
138
- #
139
- # Instances of a Configurable class may set configurations through config.
140
- # The config object is an InstanceConfiguration which forwards read/write
141
- # operations to the configuration accessors. For example:
142
- #
143
- # s = SampleClass.new
144
- # s.config.class # => Tap::Support::InstanceConfiguration
145
- # s.str # => 'value'
146
- # s.config[:str] # => 'value'
147
- #
148
- # s.str = 'one'
149
- # s.config[:str] # => 'one'
150
- #
151
- # s.config[:str] = 'two'
152
- # s.str # => 'two'
153
- #
154
- # Alternative reader and writer methods may be specified as an option;
155
- # in this case config_attr assumes the methods are declared elsewhere
156
- # and will not define the associated accessors.
157
- #
158
- # class AlternativeClass
159
- # include Tap::Support::Configurable
160
- #
161
- # config_attr :sym, 'value', :reader => :get_sym, :writer => :set_sym
162
- #
163
- # def initialize
164
- # initialize_config
165
- # end
166
- #
167
- # def get_sym
168
- # @sym
169
- # end
170
- #
171
- # def set_sym(input)
172
- # @sym = input.to_sym
173
- # end
174
- # end
175
- #
176
- # alt = AlternativeClass.new
177
- # alt.respond_to?(:sym) # => false
178
- # alt.respond_to?(:sym=) # => false
179
- #
180
- # alt.config[:sym] = 'one'
181
- # alt.get_sym # => :one
182
- #
183
- # alt.set_sym('two')
184
- # alt.config[:sym] # => :two
185
- #
186
- # Idiosyncratically, true, false, and nil may also be provided as
187
- # reader/writer options. Specifying true is the same as using the
188
- # default. Specifying false or nil prevents config_attr from
189
- # defining accessors; false sets the configuration to use
190
- # the default reader/writer methods (ie <tt>key</tt> and <tt>key=</tt>,
191
- # which must be defined elsewhere) while nil prevents read/write
192
- # mapping of the config to a method.
193
- def config_attr(key, value=nil, options={}, &block)
194
-
195
- # add arg_type implied by block, if necessary
196
- options[:arg_type] = arg_type(block) if block_given? && options[:arg_type] == nil
197
- options[:arg_name] = arg_name(block) if block_given? && options[:arg_name] == nil
198
-
199
- # define the default public reader method
200
- if !options.has_key?(:reader) || options[:reader] == true
201
- attr_reader(key)
202
- public key
203
- end
204
-
205
- # define the public writer method
206
- case
207
- when options.has_key?(:writer) && options[:writer] != true
208
- raise(ArgumentError, "a block may not be specified with writer option") if block_given?
209
- when block_given?
210
- define_method("#{key}=", &block)
211
- public "#{key}="
212
- else
213
- attr_writer(key)
214
- public "#{key}="
215
- end
216
-
217
- # remove any true, false reader/writer declarations...
218
- # implicitly reverting the option to the default reader
219
- # and writer methods
220
- [:reader, :writer].each do |option|
221
- case options[option]
222
- when true, false then options.delete(option)
223
- end
224
- end
225
-
226
- # register with Lazydoc so that all extra documentation can be extracted
227
- caller.each do |line|
228
- case line
229
- when /in .config.$/ then next
230
- when Lazydoc::CALLER_REGEXP
231
- options[:desc] = Lazydoc.register($1, $3.to_i - 1, Lazydoc::Config)
232
- break
233
- end
234
- end if options[:desc] == nil
235
-
236
- configurations.add(key, value, options)
237
- end
238
-
239
- # Alias for Tap::Support::Validation
240
- def c
241
- Validation
242
- end
243
-
244
- private
245
-
246
- # Returns special argument types for standard validation
247
- # blocks, such as switch (Validation::SWITCH) and list
248
- # (Validation::LIST).
249
- def arg_type(block) # :nodoc:
250
- case
251
- when block == Validation::SWITCH then :switch
252
- when block == Validation::FLAG then :flag
253
- when block == Validation::LIST then :list
254
- else nil
255
- end
256
- end
257
-
258
- # Returns special argument names for standard validation
259
- # blocks, such as switch (Validation::ARRAY) and list
260
- # (Validation::HASH).
261
- def arg_name(block) # :nodoc:
262
- case
263
- when block == Validation::ARRAY then "'[a, b, c]'"
264
- when block == Validation::HASH then "'{one: 1, two: 2}'"
265
- else nil
266
- end
267
- end
268
-
269
- end
270
- end
271
- end
@@ -1,170 +0,0 @@
1
- module Tap
2
- module Support
3
-
4
- # Represents a configuration declared by a Configurable class.
5
- class Configuration
6
- class << self
7
-
8
- # Matches a short option
9
- SHORT_OPTION = /^-[A-z]$/
10
-
11
- # Turns the input string into a short-format option. Raises
12
- # an error if the option does not match SHORT_REGEXP.
13
- #
14
- # Configuration.shortify("-o") # => '-o'
15
- # Configuration.shortify(:o) # => '-o'
16
- #
17
- def shortify(str)
18
- str = str.to_s
19
- str = "-#{str}" unless str[0] == ?-
20
- raise "invalid short option: #{str}" unless str =~ SHORT_OPTION
21
- str
22
- end
23
-
24
- # Matches a long option
25
- LONG_OPTION = /^--(\[no-\])?([A-z][\w-]*)$/
26
-
27
- # Turns the input string into a long-format option. Raises
28
- # an error if the option does not match LONG_REGEXP.
29
- #
30
- # Configuration.longify("--opt") # => '--opt'
31
- # Configuration.longify(:opt) # => '--opt'
32
- # Configuration.longify(:opt, true) # => '--[no-]opt'
33
- # Configuration.longify(:opt_ion) # => '--opt-ion'
34
- # Configuration.longify(:opt_ion, false, false) # => '--opt_ion'
35
- #
36
- def longify(str, switch_notation=false, hyphenize=true)
37
- str = str.to_s
38
- str = "--#{str}" unless str.index("--")
39
- str.gsub!(/_/, '-') if hyphenize
40
-
41
- raise "invalid long option: #{str}" unless str =~ LONG_OPTION
42
-
43
- if switch_notation && $1.nil?
44
- str = "--[no-]#{$2}"
45
- end
46
-
47
- str
48
- end
49
- end
50
-
51
- # The name of the configuration
52
- attr_reader :name
53
-
54
- # The reader method, by default name
55
- attr_reader :reader
56
-
57
- # The writer method, by default name=
58
- attr_reader :writer
59
-
60
- # True if the default value may be duplicated
61
- attr_reader :duplicable
62
-
63
- # An array of optional metadata for self
64
- attr_reader :attributes
65
-
66
- # Initializes a new Configuration with the specified name and default
67
- # value. Options may specify an alternate reader/writer; any
68
- # additional options are set as attributes.
69
- def initialize(name, default=nil, options={})
70
- @name = name
71
- self.default = default
72
-
73
- self.reader = options.has_key?(:reader) ? options.delete(:reader) : name
74
- self.writer = options.has_key?(:writer) ? options.delete(:writer) : "#{name}="
75
- @attributes = options
76
- end
77
-
78
- # Sets the default value for self and determines if the
79
- # default is duplicable. Non-duplicable values include
80
- # nil, true, false, Symbol, Numeric, and any object that
81
- # does not respond to dup.
82
- def default=(value)
83
- @duplicable = case value
84
- when nil, true, false, Symbol, Numeric, Method then false
85
- else value.respond_to?(:dup)
86
- end
87
-
88
- @default = value.freeze
89
- end
90
-
91
- # Returns the default value, or a duplicate of the default
92
- # value if specified and the default value is duplicable.
93
- def default(duplicate=true)
94
- duplicate && duplicable ? @default.dup : @default
95
- end
96
-
97
- # Sets the reader for self. The reader is symbolized,
98
- # but may also be set to nil.
99
- def reader=(value)
100
- @reader = value == nil ? value : value.to_sym
101
- end
102
-
103
- # Sets the writer for self. The writer is symbolized,
104
- # but may also be set to nil.
105
- def writer=(value)
106
- @writer = value == nil ? value : value.to_sym
107
- end
108
-
109
- # The argument name for self: either attributes[:arg_name]
110
- # or name.to_s.upcase
111
- def arg_name
112
- attributes[:arg_name] || name.to_s.upcase
113
- end
114
-
115
- # The argument type for self: either attributes[:arg_type]
116
- # or :mandatory
117
- def arg_type
118
- attributes[:arg_type] || :mandatory
119
- end
120
-
121
- # The long version of name.
122
- def long(switch_notation=false, hyphenize=true)
123
- Configuration.longify(attributes[:long] || name.to_s, switch_notation, hyphenize)
124
- end
125
-
126
- # The short version of name.
127
- def short
128
- attributes[:short] ? Configuration.shortify(attributes[:short]) : nil
129
- end
130
-
131
- # The description for self: attributes[:desc]
132
- def desc
133
- attributes[:desc]
134
- end
135
-
136
- # True if another is a kind of Configuration with the same name,
137
- # default value, reader and writer; other attributes are NOT
138
- # taken into account.
139
- def ==(another)
140
- another.kind_of?(Configuration) &&
141
- self.name == another.name &&
142
- self.reader == another.reader &&
143
- self.writer == another.writer &&
144
- self.default(false) == another.default(false)
145
- end
146
-
147
- # Returns self as an argv that can be used to register
148
- # an option with OptionParser.
149
- def to_optparse_argv
150
- argtype = case arg_type
151
- when :optional
152
- "#{long} [#{arg_name}]"
153
- when :switch
154
- long(true)
155
- when :flag
156
- long
157
- when :list
158
- "#{long} a,b,c"
159
- when :mandatory, nil
160
- "#{long} #{arg_name}"
161
- else
162
- raise "unknown arg_type: #{arg_type}"
163
- end
164
-
165
- [short, argtype, desc].compact
166
- end
167
-
168
- end
169
- end
170
- end