bahuvrihi-tap 0.10.8 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -46,7 +46,7 @@ module Tap
46
46
  class FileTask < Task
47
47
  include Tap::Support::ShellUtils
48
48
 
49
- # A hash of backup (source, target) pairs, such that the
49
+ # A hash of backup [source, target] pairs, such that the
50
50
  # backed-up files are backed_up_files.keys and the actual
51
51
  # backup files are backed_up_files.values. All filepaths
52
52
  # in backed_up_files should be expanded.
@@ -1,6 +1,6 @@
1
1
  module Tap::Generator::Generators
2
2
 
3
- # Tap::Generator::Generators::CommandGenerator::generator a new tap command
3
+ # :startdoc: Tap::Generator::Generators::CommandGenerator::generator a new tap command
4
4
  #
5
5
  # Generates a new tap command under the cmd directory. The
6
6
  # new command can be run from the command line using:
@@ -18,4 +18,4 @@ module Tap::Generator::Generators
18
18
  end
19
19
 
20
20
  end
21
- end
21
+ end
@@ -16,7 +16,7 @@ OptionParser.new do |opts|
16
16
  opts.separator "options:"
17
17
 
18
18
  opts.on("-h", "--help", "Show this message") do
19
- opts.banner = Tap::Support::CommandLine.usage(__FILE__)
19
+ opts.banner = Tap::Support::Lazydoc.usage(__FILE__)
20
20
  puts opts
21
21
  exit
22
22
  end
@@ -29,4 +29,4 @@ end.parse!(ARGV)
29
29
  #
30
30
 
31
31
  puts "Received: #{ARGV.join(', ')}"
32
- puts app.info
32
+ puts app.info
@@ -1,6 +1,6 @@
1
1
  module Tap::Generator::Generators
2
2
 
3
- # Tap::Generator::Generators::ConfigGenerator::generator a config file for a task
3
+ # :startdoc: Tap::Generator::Generators::ConfigGenerator::generator a config file for a task
4
4
  #
5
5
  # Generates a new config file for a task. The configurations, defaults,
6
6
  # and documentation is determined from the task source file.
@@ -2,7 +2,7 @@ require 'tap/generator/generators/task/task_generator'
2
2
 
3
3
  module Tap::Generator::Generators
4
4
 
5
- # Tap::Generator::Generators::FileTaskGenerator::generator a file_task and test
5
+ # :startdoc: Tap::Generator::Generators::FileTaskGenerator::generator a file_task and test
6
6
  #
7
7
  # Generates a new Tap::FileTask and associated test files.
8
8
  class FileTaskGenerator < TaskGenerator
@@ -1,6 +1,6 @@
1
1
  module Tap::Generator::Generators
2
2
 
3
- # Tap::Generator::Generators::GeneratorGenerator::generator a generator task and test
3
+ # :startdoc: Tap::Generator::Generators::GeneratorGenerator::generator a generator task and test
4
4
  #
5
5
  # Generates a new generator.
6
6
  class GeneratorGenerator < Tap::Generator::Base
@@ -2,7 +2,7 @@ require 'tap/root'
2
2
 
3
3
  module Tap::Generator::Generators
4
4
 
5
- # Tap::Generator::Generators::RootGenerator::generator a basic tap directory structure
5
+ # :startdoc: Tap::Generator::Generators::RootGenerator::generator a basic tap directory structure
6
6
  #
7
7
  # Generates a tap root directory structure. Use the switches to
8
8
  # generate a Tapfile and/or a tap config file:
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
10
10
  s.test_file = "test/tap_test_suite.rb"
11
11
  #s.rubyforge_project = "<%= project_name %>"
12
12
  #s.has_rdoc = true
13
- s.add_dependency("tap", "~> <%= Tap::VERSION %>")
13
+ s.add_dependency("tap", "= <%= Tap::VERSION %>")
14
14
 
15
15
  # list extra rdoc files here.
16
16
  s.extra_rdoc_files = %W{
@@ -1,6 +1,6 @@
1
1
  module Tap::Generator::Generators
2
2
 
3
- # Tap::Generator::Generators::TaskGenerator::generator a task and test
3
+ # :startdoc: Tap::Generator::Generators::TaskGenerator::generator a task and test
4
4
  #
5
5
  # Generates a new Tap::Task and an associated test file.
6
6
  class TaskGenerator < Tap::Generator::Base
@@ -35,7 +35,8 @@ module Tap
35
35
 
36
36
  # Registers the files matching pattern under dir. Returns self.
37
37
  def register(dir, pattern)
38
- search_paths << [dir, Dir.glob(File.join(dir, pattern)).select {|file| File.file?(file) }]
38
+ paths = Dir.glob(File.join(dir, pattern)).select {|file| File.file?(file) }
39
+ search_paths << [dir, paths.sort]
39
40
  self
40
41
  end
41
42
 
@@ -112,4 +113,4 @@ module Tap
112
113
 
113
114
  end
114
115
  end
115
- end
116
+ end
@@ -276,6 +276,12 @@ module Tap
276
276
  audit
277
277
  end
278
278
 
279
+ # Calls _execute with the inputs and returns the un-audited result.
280
+ # Execute is not a batched method.
281
+ def execute(*inputs)
282
+ _execute(*inputs)._current
283
+ end
284
+
279
285
  # Raises a TerminateError if app.state == State::TERMINATE.
280
286
  # check_terminate may be called at any time to provide a
281
287
  # breakpoint in long-running processes.
@@ -21,6 +21,23 @@ module Tap
21
21
 
22
22
  attr_accessor :env
23
23
 
24
+ def enq_top_level(app)
25
+ # takes the place of rake.top_level
26
+ if options.show_tasks
27
+ display_tasks_and_comments
28
+ exit
29
+ elsif options.show_prereqs
30
+ display_prerequisites
31
+ exit
32
+ else
33
+ top_level_tasks.each do |task_string|
34
+ name, args = parse_task_string(task_string)
35
+ task = self[name]
36
+ app.mq(task, :invoke, *args)
37
+ end
38
+ end
39
+ end
40
+
24
41
  def collect_tasks(*args)
25
42
  # a little song and dance for compliance with
26
43
  # rake pre- and post-0.8.2
@@ -89,5 +106,6 @@ end
89
106
  end
90
107
 
91
108
  Rake.application.extend Tap::Support::Gems::Rake
92
- Tap::Env.manifests[:rakefiles] = Tap::Support::Gems::RakeManifest
93
-
109
+ Tap::Env.manifest(:rakefiles) do |env|
110
+ Tap::Support::Gems::RakeManifest.new(env)
111
+ end
@@ -6,61 +6,47 @@ autoload(:OptionParser, 'optparse')
6
6
 
7
7
  module Tap
8
8
 
9
- # Tasks are the basic organizational unit of Tap. Tasks provide
10
- # a standard backbone for creating the working parts of an application
11
- # by facilitating configuration, batched execution of methods, and
12
- # documentation.
13
- #
14
- # The functionality of Task is built from several base modules:
15
- # - Tap::Support::Batchable
16
- # - Tap::Support::Configurable
17
- # - Tap::Support::Executable
18
- #
19
- # Tap::Workflow is built on the same foundations; the sectons on
20
- # configuration and batching apply equally to Workflows as Tasks.
21
- #
22
9
  # === Task Definition
23
10
  #
24
- # Tasks are instantiated with a task block; when the task is run
25
- # the block gets called with the enqued inputs. As such, the block
26
- # should specify the same number of inputs as you enque (plus the
27
- # task itself, which is a standard input).
28
- #
29
- # no_inputs = Task.new {|task| }
30
- # one_input = Task.new {|task, input| }
31
- # mixed_inputs = Task.new {|task, a, b, *args| }
32
- #
33
- # no_inputs.enq
34
- # one_input.enq(:a)
35
- # mixed_inputs.enq(:a, :b)
36
- # mixed_inputs.enq(:a, :b, 1, 2, 3)
37
- #
38
- # Subclasses of Task specify executable code by overridding the process
39
- # method. In this case the number of enqued inputs should correspond to
40
- # process (passing the task would be redundant).
11
+ # Tasks specify executable code by overridding the process method in
12
+ # subclasses. The number of inputs to process corresponds to the inputs
13
+ # given to execute or enq.
41
14
  #
42
15
  # class NoInput < Tap::Task
43
- # def process() end
16
+ # def process(); []; end
44
17
  # end
45
18
  #
46
19
  # class OneInput < Tap::Task
47
- # def process(input) end
20
+ # def process(input); [input]; end
48
21
  # end
49
22
  #
50
23
  # class MixedInputs < Tap::Task
51
- # def process(a, b, *args) end
24
+ # def process(a, b, *args); [a,b,args]; end
52
25
  # end
53
26
  #
54
- # NoInput.new.enq
55
- # OneInput.new.enq(:a)
56
- # MixedInputs.new.enq(:a, :b)
57
- # MixedInputs.new.enq(:a, :b, 1, 2, 3)
27
+ # NoInput.new.execute # => []
28
+ # OneInput.new.execute(:a) # => [:a]
29
+ # MixedInputs.new.execute(:a, :b) # => [:a, :b, []]
30
+ # MixedInputs.new.execute(:a, :b, 1, 2, 3) # => [:a, :b, [1,2,3]]
31
+ #
32
+ # Tasks may be create with new, or with intern. Intern overrides
33
+ # process with a custom block that gets called with the task instance
34
+ # and the inputs.
35
+ #
36
+ # no_inputs = Task.intern {|task| [] }
37
+ # one_input = Task.intern {|task, input| [input] }
38
+ # mixed_inputs = Task.intern {|task, a, b, *args| [a, b, args] }
39
+ #
40
+ # no_inputs.execute # => []
41
+ # one_input.execute(:a) # => [:a]
42
+ # mixed_inputs.execute(:a, :b) # => [:a, :b, []]
43
+ # mixed_inputs.execute(:a, :b, 1, 2, 3) # => [:a, :b, [1,2,3]]
58
44
  #
59
45
  # === Configuration
60
46
  #
61
- # Tasks are configurable. By default each task will be configured
62
- # with the default class configurations, which can be set when the
63
- # class is defined.
47
+ # Tasks are configurable. By default each task will be configured as
48
+ # specified in the class definition. Configurations may be accessed
49
+ # through config, or through accessors.
64
50
  #
65
51
  # class ConfiguredTask < Tap::Task
66
52
  # config :one, 'one'
@@ -68,13 +54,21 @@ module Tap
68
54
  # end
69
55
  #
70
56
  # t = ConfiguredTask.new
71
- # t.name # => "configured_task"
72
- # t.config # => {:one => 'one', :two => 'two'}
57
+ # t.config # => {:one => 'one', :two => 'two'}
58
+ # t.one # => 'one'
59
+ # t.one = 'ONE'
60
+ # t.config # => {:one => 'ONE', :two => 'two'}
61
+ #
62
+ # Overrides and even unspecified configurations may be provided during
63
+ # initialization. Unspecified configurations do not have accessors.
73
64
  #
74
- # Configurations can be validated or processed using an optional
75
- # block. Tap::Support::Validation pre-packages several common
76
- # validation/processing blocks, and can be accessed through the
77
- # class method 'c':
65
+ # t = ConfiguredTask.new(:one => 'ONE', :three => 'three')
66
+ # t.config # => {:one => 'ONE', :two => 'two', :three => 'three'}
67
+ # t.respond_to?(:three) # => false
68
+ #
69
+ # Configurations can be validated/transformed using an optional block.
70
+ # Tap::Support::Validation pre-packages many common blocks which may
71
+ # be accessed through the class method 'c':
78
72
  #
79
73
  # class ValidatingTask < Tap::Task
80
74
  # # string config validated to be a string
@@ -91,42 +85,7 @@ module Tap
91
85
  # t.integer = "1"
92
86
  # t.integer == 1 # => true
93
87
  #
94
- # Tasks have a name that gets used in auditing, and as a relative
95
- # filepath to find associated files (for instance config files).
96
- # By default the task name is based on the task class, such that
97
- # Tap::Task has the default name 'tap/task'. Configurations
98
- # and custom names can be provided when a task is initialized.
99
- #
100
- # t = ConfiguredTask.new({:one => 'ONE', :three => 'three'}, "example")
101
- # t.name # => "example"
102
- # t.config # => {:one => 'ONE', :two => 'two', :three => 'three'}
103
- #
104
- # === Batches
105
- #
106
- # Tasks can be assembled into batches that enque and execute collectively.
107
- # Batched tasks are often alternatively-configured derivatives of one
108
- # parent task, although they can be manually assembled using Task.batch.
109
- #
110
- # app = Tap::App.instance
111
- # t1 = Tap::Task.intern(:key => 'one') do |task, input|
112
- # input + task.config[:key]
113
- # end
114
- # t1.batch # => [t1]
115
- #
116
- # t2 = t1.initialize_batch_obj(:key => 'two')
117
- # t1.batch # => [t1, t2]
118
- # t2.batch # => [t1, t2]
119
- #
120
- # t1.enq 't1_by_'
121
- # t2.enq 't2_by_'
122
- # app.run
123
- #
124
- # app.results(t1) # => ["t1_by_one", "t2_by_one"]
125
- # app.results(t2) # => ["t1_by_two", "t2_by_two"]
126
- #
127
- # Here the results reflects that t1 and t2 were run in succession with the
128
- # input to t1, and then the input to t2.
129
- #
88
+ #--
130
89
  # === Subclassing
131
90
  # Tasks can be subclassed normally, with one reminder related to batching.
132
91
  #
@@ -166,9 +125,10 @@ module Tap
166
125
  # Returns class dependencies
167
126
  attr_reader :dependencies
168
127
 
169
- # Returns the default name for the class: to_s.underscore
128
+ # Sets the class default_name
170
129
  attr_writer :default_name
171
130
 
131
+ # Returns the default name for the class: to_s.underscore
172
132
  def default_name
173
133
  # lazy-setting default_name like this (rather than
174
134
  # within inherited, for example) is an optimization
@@ -183,7 +143,7 @@ module Tap
183
143
  @instance ||= new
184
144
  end
185
145
 
186
- def inherited(child)
146
+ def inherited(child) # :nodoc:
187
147
  unless child.instance_variable_defined?(:@source_file)
188
148
  caller.first =~ Support::Lazydoc::CALLER_REGEXP
189
149
  child.instance_variable_set(:@source_file, File.expand_path($1))
@@ -193,7 +153,12 @@ module Tap
193
153
  super
194
154
  end
195
155
 
196
- def intern(*args, &block)
156
+ # Instantiates a new task with the input arguments and overrides
157
+ # process with the block. The block will be called with the
158
+ # instance, plus any inputs.
159
+ #
160
+ # Simply instantiates a new task if no block is given.
161
+ def intern(*args, &block) # :yields: task, inputs...
197
162
  instance = new(*args)
198
163
  if block_given?
199
164
  instance.extend Support::Intern
@@ -202,10 +167,9 @@ module Tap
202
167
  instance
203
168
  end
204
169
 
205
- # Parses the argv into an instance of self and an array of arguments (implicitly
206
- # to be enqued to the instance and run by app). Yields a help string to the
207
- # block when the argv indicates 'help'.
208
- #
170
+ # Parses the argv into an instance of self and an array of arguments
171
+ # (implicitly to be enqued to the instance). Yields a help string to
172
+ # the block when the argv indicates 'help'.
209
173
  def parse(argv=ARGV, app=Tap::App.instance, &block) # :yields: help_str
210
174
  parse!(argv.dup, &block)
211
175
  end
@@ -284,6 +248,9 @@ module Tap
284
248
  [obj, (argv + use_args)]
285
249
  end
286
250
 
251
+ # A convenience method to parse the argv and execute the instance
252
+ # with the remaining arguments. If 'help' is specified in the argv,
253
+ # execute prints the help and exits.
287
254
  def execute(argv=ARGV)
288
255
  instance, args = parse(ARGV) do |help|
289
256
  puts help
@@ -292,7 +259,8 @@ module Tap
292
259
 
293
260
  instance.execute(*args)
294
261
  end
295
-
262
+
263
+ # Returns the class lazydoc, resolving if specified.
296
264
  def lazydoc(resolve=true)
297
265
  lazydoc = super(false)
298
266
  lazydoc[self.to_s]['args'] ||= lazydoc.register_method(:process, Support::Lazydoc::Method)
@@ -312,6 +280,7 @@ module Tap
312
280
  <% end %>
313
281
 
314
282
  }
283
+ # Returns the class help.
315
284
  def help
316
285
  Tap::Support::Templater.new(DEFAULT_HELP_TEMPLATE, :task_class => self).build
317
286
  end
@@ -466,10 +435,7 @@ module Tap
466
435
  # via to_s, as does app when figuring configuration filepaths.
467
436
  attr_accessor :name
468
437
 
469
- # Initializes a new instance and associated batch objects. Batch
470
- # objects will be initialized for each configuration template
471
- # specified by app.each_config_template(config_file) where
472
- # config_file = app.config_filepath(name).
438
+ # Initializes a new Task.
473
439
  def initialize(config={}, name=nil, app=App.instance)
474
440
  super()
475
441
 
@@ -497,28 +463,19 @@ module Tap
497
463
  workflow
498
464
  end
499
465
 
500
- # Creates a new batched object and adds the object to batch. The batched object
501
- # will be a duplicate of the current object but with a new name and/or
502
- # configurations.
466
+ # Creates a new batched object and adds the object to batch. The batched
467
+ # object will be a duplicate of the current object but with a new name
468
+ # and/or configurations.
503
469
  def initialize_batch_obj(overrides={}, name=nil)
504
470
  obj = super().reconfigure(overrides)
505
471
  obj.name = name if name
506
472
  obj
507
473
  end
508
-
509
- # Executes self with the given inputs. Execute provides hooks for subclasses
510
- # to insert standard execution code: before_execute, on_execute_error,
511
- # and after_execute. Override any/all of these methods as needed.
512
- #
513
- # Execute passes the inputs to process and returns the result.
514
- def execute(*inputs)
515
- _execute(*inputs)._current
516
- end
517
474
 
518
475
  # The method for processing inputs into outputs. Override this method in
519
476
  # subclasses to provide class-specific process logic. The number of
520
477
  # arguments specified by process corresponds to the number of arguments
521
- # the task should have when enqued.
478
+ # the task should have when enqued or executed.
522
479
  #
523
480
  # class TaskWithTwoInputs < Tap::Task
524
481
  # def process(a, b)
@@ -573,7 +530,8 @@ module Tap
573
530
 
574
531
  private
575
532
 
576
- def execute_with_callbacks(*inputs)
533
+ # execute_with_callbacks is the method called by _execute
534
+ def execute_with_callbacks(*inputs) # :nodoc:
577
535
  before_execute
578
536
  begin
579
537
  result = process(*inputs)
@@ -16,33 +16,6 @@ module Tap
16
16
  # to access the rake help, and --help to access this help.
17
17
  #
18
18
  class Rake < Tap::Task
19
-
20
- # Modifies Rake::Application by adding a hook to the standard_exception_handling
21
- # method. This allows more fine-grained use of Rake::Applications by Tap.
22
- module Application
23
- def enq_top_level(app)
24
- # takes the place of rake.top_level
25
- if options.show_tasks
26
- display_tasks_and_comments
27
- exit
28
- elsif options.show_prereqs
29
- display_prerequisites
30
- exit
31
- else
32
- top_level_tasks.each do |task_string|
33
- name, args = parse_task_string(task_string)
34
- task = self[name]
35
-
36
- unless task.kind_of?(Tap::Support::Executable)
37
- Tap::Support::Executable.initialize(task, :invoke)
38
- end
39
-
40
- app.enq(task, *args)
41
- end
42
- end
43
- end
44
- end
45
-
46
19
  class << self
47
20
 
48
21
  # Overrides Tap::Support::FrameworkClass#parse! to do
@@ -55,21 +28,10 @@ module Tap
55
28
  [new({}, default_name, app), argv.collect {|arg| arg == '--rake-help' ? '--help' : arg}]
56
29
  end
57
30
  end
58
-
59
- #--
60
- # def on_complete(override=false, &block)
61
- # @rake_tasks.each do |task|
62
- # task.on_complete(override, &block)
63
- # end
64
- # end
65
- #++
66
31
 
67
32
  def enq(*argv)
68
33
  rake = ::Rake.application
69
- unless rake.kind_of?(Application)
70
- rake.extend Application
71
- end
72
-
34
+
73
35
  # run as if from command line using argv
74
36
  current_argv = ARGV.dup
75
37
  begin
@@ -89,6 +51,7 @@ module Tap
89
51
 
90
52
  nil
91
53
  end
54
+
92
55
  end
93
56
  end
94
57
  end