bahuvrihi-tap 0.10.2 → 0.10.3

Sign up to get free protection for your applications and to get access to all the features.
data/cgi/run.rb ADDED
@@ -0,0 +1,36 @@
1
+ # ::summary
2
+ # runs a task
3
+ #
4
+ # ::description
5
+ #
6
+ ############################
7
+ require 'cgi'
8
+ require "#{File.dirname(__FILE__)}/../vendor/url_encoded_pair_parser"
9
+ require "tap/support/server/parser"
10
+
11
+ cgi = CGI.new("html3") # add HTML generation methods
12
+
13
+ argh = UrlEncodedPairParser.new(cgi.params.to_a).result
14
+ queues = Tap::Env.instance.build Tap::Support::Server::Parser.new(argh)
15
+
16
+ cgi.out() do
17
+ cgi.html() do
18
+ cgi.head{ cgi.title{ "Tap::Run" } } +
19
+ cgi.body() do
20
+ cgi.pre do
21
+ if queues.empty?
22
+
23
+ "b;ah"
24
+ else
25
+
26
+ queues.each_with_index do |queue, i|
27
+ app.queue.concat(queue)
28
+ app.run
29
+ end
30
+
31
+ "Ran"
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
data/cmd/run.rb CHANGED
@@ -47,11 +47,12 @@ end.parse!(ARGV)
47
47
  #
48
48
  # handle options for each specified task
49
49
  #
50
+ require 'tap/support/parsers/command_line'
50
51
 
51
- rounds = env.parse(ARGV)
52
+ queues = Tap::Support::Parsers::CommandLine.new(ARGV).build(env, app)
52
53
  ARGV.clear
53
54
 
54
- if rounds.empty?
55
+ if queues.empty?
55
56
  puts "no task specified"
56
57
  exit
57
58
  end
@@ -99,7 +100,7 @@ end
99
100
  # enque tasks and run!
100
101
  #
101
102
 
102
- rounds.each_with_index do |queue, i|
103
+ queues.each_with_index do |queue, i|
103
104
  app.queue.concat(queue)
104
105
  app.run
105
106
  end
data/cmd/server.rb ADDED
@@ -0,0 +1,36 @@
1
+ # tap server {options}
2
+ #
3
+ # Initializes a tap server.
4
+
5
+ require 'tap'
6
+ require 'tap/support/gems/rack'
7
+
8
+ env = Tap::Env.instance
9
+
10
+ #
11
+ # handle options
12
+ #
13
+ options = {:Port => 8080}
14
+ OptionParser.new do |opts|
15
+
16
+ opts.separator ""
17
+ opts.separator "options:"
18
+
19
+ opts.on("-h", "--help", "Show this message") do
20
+ opts.banner = Tap::Support::TDoc.usage(__FILE__)
21
+ puts opts
22
+ exit
23
+ end
24
+
25
+ opts.on("-p", "--port PORT", Integer, "Specifies the port (default #{options[:Port]})") do |value|
26
+ options[:Port] = value
27
+ end
28
+
29
+ end.parse!(ARGV)
30
+
31
+ #
32
+ # cgi dir and public dir can be set in tap.yml
33
+ #
34
+
35
+ env.extend Tap::Support::Gems::Rack
36
+ Rack::Handler::WEBrick.run(env, options)
data/lib/tap/app.rb CHANGED
@@ -492,7 +492,7 @@ module Tap
492
492
  # An Executable may provided instead of a task.
493
493
  def enq(task, *inputs)
494
494
  case task
495
- when Tap::Task, Tap::Workflow
495
+ when Tap::Task
496
496
  raise "not assigned to enqueing app: #{task}" unless task.app == self
497
497
  task.enq(*inputs)
498
498
  when Support::Executable
data/lib/tap/constants.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Tap
2
2
  MAJOR = 0
3
3
  MINOR = 10
4
- TINY = 2
4
+ TINY = 3
5
5
 
6
6
  VERSION="#{MAJOR}.#{MINOR}.#{TINY}"
7
7
  WEBSITE="http://tap.rubyforge.org"
data/lib/tap/env.rb CHANGED
@@ -273,8 +273,7 @@ module Tap
273
273
  @envs = []
274
274
  @active = false
275
275
  @manifests = {}
276
- @manifested = []
277
-
276
+
278
277
  # initialize these for reset_env
279
278
  @gems = []
280
279
  @env_paths = []
@@ -553,6 +552,13 @@ module Tap
553
552
  nil
554
553
  end
555
554
 
555
+ def reset(name, &block)
556
+ each do |env|
557
+ env.manifests[name].each(&block)
558
+ env.manifests[name] = nil
559
+ end
560
+ end
561
+
556
562
  def constantize(name, *patterns)
557
563
  patterns.collect do |pattern|
558
564
  case const = search(name, pattern)
data/lib/tap/exe.rb CHANGED
@@ -1,9 +1,6 @@
1
- require 'tap/support/command_line/parser'
2
-
3
1
  module Tap
4
2
  class Exe < Env
5
- Parser = Support::CommandLine::Parser
6
-
3
+
7
4
  class << self
8
5
  def instantiate
9
6
  app = Tap::App.instance
@@ -66,58 +63,5 @@ module Tap
66
63
  end
67
64
  end
68
65
  end
69
-
70
- def parse(argv=ARGV)
71
- parser = Parser.new(argv)
72
- targets = parser.targets
73
-
74
- tasks = []
75
- rounds = parser.rounds.collect do |round|
76
- round.each do |argv|
77
- unless td = Parser.shift_arg(argv)
78
- # warn nil?
79
- next
80
- end
81
-
82
- # attempt lookup the task class
83
- const = search(:tasks, td) or raise ArgumentError, "unknown task: #{td}"
84
- task_class = const.constantize or raise ArgumentError, "unknown task: #{td}"
85
-
86
- # now let the class handle the argv
87
- task, args = task_class.instantiate(argv, app)
88
-
89
- if !targets.include?(tasks.length)
90
- task.enq(*args)
91
- elsif !args.empty?
92
- raise ArgumentError, "workflow target receives argv: [#{argv.unshift(td).join(', ')}]"
93
- end
94
-
95
- tasks << task
96
- end
97
-
98
- app.queue.clear
99
- end
100
- rounds.delete_if {|round| round.empty? }
101
-
102
- # build the workflow
103
-
104
- parser.sequences.each do |sequence|
105
- app.sequence(*sequence.collect {|s| tasks[s]})
106
- end
107
-
108
- parser.forks.each do |source, targets|
109
- app.fork(tasks[source], *targets.collect {|t| tasks[t]})
110
- end
111
-
112
- parser.merges.each do |target, sources|
113
- app.merge(tasks[target], *sources.collect {|s| tasks[s]})
114
- end
115
-
116
- parser.sync_merges.each do |target, sources|
117
- app.sync_merge(tasks[target], *sources.collect {|s| tasks[s]})
118
- end
119
-
120
- rounds
121
- end
122
66
  end
123
67
  end
@@ -16,56 +16,39 @@ module Tap
16
16
  def self.extended(base)
17
17
  set_declaration_base(base)
18
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)
19
+
20
+ def tasc(name, configs={}, &block)
21
+ declare(Tap::Task, name, configs, &block)
31
22
  end
32
23
 
33
- def file_task(name, configs={}, options={}, &block)
34
- options[:arity] = arity(block)
35
- file_tasc(nest(name), configs, options, &task_block(block)).new
24
+ def task(name, configs={}, &block)
25
+ mod_declare(Tap::Task, name, configs, &block)
36
26
  end
37
27
 
38
- def worcflow(name, configs={}, options={}, &block)
39
- Tap::Workflow.subclass(nest(name), configs, options, &block)
28
+ def file_tasc(name, configs={}, &block)
29
+ declare(Tap::FileTask, name, configs, &block)
40
30
  end
41
31
 
42
- def workflow(name, configs={}, options={}, &block)
43
- options[:arity] = arity(block)
44
- worcflow(name, configs, options, &task_block(block)).new
32
+ def file_task(name, configs={}, &block)
33
+ mod_declare(Tap::FileTask, name, configs, &block)
45
34
  end
46
-
35
+
47
36
  protected
48
37
 
49
38
  def config(key, value=nil, options={}, &block)
50
- caller.each do |line|
51
- case line
52
- when Lazydoc::CALLER_REGEXP
53
- options[:desc] = Support::Lazydoc.register($1, $3.to_i - 1)
54
- break
55
- end
56
- end if options[:desc] == nil
39
+ if options[:desc] == nil
40
+ caller[0] =~ Lazydoc::CALLER_REGEXP
41
+ options[:desc] = Support::Lazydoc.register($1, $3.to_i - 1)
42
+ end
57
43
 
58
44
  [:config, key, value, options, block]
59
45
  end
60
46
 
61
47
  def config_attr(key, value=nil, options={}, &block)
62
- caller.each do |line|
63
- case line
64
- when Lazydoc::CALLER_REGEXP
65
- options[:desc] = Support::Lazydoc.register($1, $3.to_i - 1)
66
- break
67
- end
68
- end if options[:desc] == nil
48
+ if options[:desc] == nil
49
+ caller[0] =~ Lazydoc::CALLER_REGEXP
50
+ options[:desc] = Support::Lazydoc.register($1, $3.to_i - 1)
51
+ end
69
52
 
70
53
  [:config_attr, key, value, options, block]
71
54
  end
@@ -75,12 +58,6 @@ module Tap
75
58
  end
76
59
 
77
60
  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
61
 
85
62
  def arity(block)
86
63
  arity = block.arity
@@ -92,20 +69,65 @@ module Tap
92
69
 
93
70
  arity
94
71
  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})")
72
+
73
+ def declare(klass, declaration, configs={}, options={}, &block)
74
+ # Extract name and dependencies from declaration
75
+ name, dependencies = case declaration
76
+ when Hash then declaration.to_a[0]
77
+ else [declaration, []]
78
+ end
79
+
80
+ unless dependencies.kind_of?(Array)
81
+ dependencies = [dependencies]
82
+ end
83
+
84
+ unless dependencies.empty?
85
+ dependencies.collect! do |dependency|
86
+ case dependency
87
+ when Array then dependency
88
+ when String, Symbol then [dependency, declare(Tap::Task, dependency)]
89
+ else
90
+ if dependency.kind_of?(Class) && dependency.ancestors.include?(Tap::Task)
91
+ [File.basename(dependency.default_name), dependency]
92
+ else
93
+ raise ArgumentError, "malformed dependency declaration: #{dependency}"
94
+ end
95
+ end
104
96
  end
97
+ end
98
+
99
+ # Nest the constant name
100
+ base = (self.kind_of?(Module) ? self : self.class).instance_variable_get(:@tap_declaration_base)
101
+ name = File.join(base, name.to_s)
102
+
103
+ klass.subclass(name, configs, dependencies, options, &block)
104
+ end
105
+
106
+ def mod_declare(klass, declaration, configs={}, &block)
107
+ options = {}
108
+ options[:arity] = arity(block) if block_given?
105
109
 
106
- block.call(*inputs)
110
+ subclass = declare(klass, declaration, configs, options)
111
+
112
+ if block_given?
113
+ mod = Module.new
114
+ mod.module_eval %Q{
115
+ ACTION = ObjectSpace._id2ref(#{block.object_id})
116
+ def process(*args)
117
+ results = super
118
+ case ACTION.arity
119
+ when 0 then ACTION.call
120
+ when 1 then ACTION.call(self)
121
+ else ACTION.call(self, *args)
122
+ end
123
+ results
124
+ end
125
+ }
126
+ subclass.send(:include, mod)
107
127
  end
128
+ subclass.instance
108
129
  end
130
+
109
131
  end
110
132
  end
111
133
  end
@@ -2,6 +2,7 @@ require 'tap/support/audit'
2
2
 
3
3
  module Tap
4
4
  module Support
5
+
5
6
  # Executable wraps methods to make them executable by App. Methods are
6
7
  # wrapped by extending the object that receives them; the easiest way
7
8
  # to make an object executable is to use Object#_method.
@@ -15,7 +16,9 @@ module Tap
15
16
 
16
17
  # Stores the on complete block.
17
18
  attr_reader :on_complete_block
18
-
19
+
20
+ attr_reader :dependencies
21
+
19
22
  public
20
23
 
21
24
  # Extends obj with Executable and sets up all required variables. The
@@ -25,9 +28,57 @@ module Tap
25
28
  obj.instance_variable_set(:@_method_name, method_name)
26
29
  obj.instance_variable_set(:@multithread, multithread)
27
30
  obj.instance_variable_set(:@on_complete_block, on_complete_block)
31
+ obj.instance_variable_set(:@dependencies, [])
28
32
  obj
29
33
  end
30
-
34
+
35
+ def self.clear_dependencies
36
+ @registry = []
37
+ @results = []
38
+ end
39
+
40
+ def self.registry
41
+ @registry
42
+ end
43
+
44
+ def self.results
45
+ @results
46
+ end
47
+
48
+ def self.index(instance, args)
49
+ @registry.each_with_index do |entry, index|
50
+ return index if entry[0] == instance && entry[1] == args
51
+ end
52
+ nil
53
+ end
54
+
55
+ def self.resolved?(index)
56
+ @results[index] != nil
57
+ end
58
+
59
+ def self.resolve(indicies)
60
+ indicies.each do |index|
61
+ next if @results[index]
62
+ instance, inputs = @registry[index]
63
+ @results[index] = instance._execute(*inputs)
64
+ end
65
+ end
66
+
67
+ def self.reset(indicies)
68
+ indicies.each {|index| @results[index] = nil }
69
+ end
70
+
71
+ def self.register(instance, args)
72
+ if existing = index(instance, args)
73
+ return existing
74
+ end
75
+
76
+ @registry << [instance, args]
77
+ @registry.length - 1
78
+ end
79
+
80
+ clear_dependencies
81
+
31
82
  # Sets a block to receive the results of _execute. Raises an error
32
83
  # if an on_complete block is already set. Override an existing
33
84
  # on_complete block by specifying override = true.
@@ -40,6 +91,30 @@ module Tap
40
91
  end
41
92
  @on_complete_block = block
42
93
  end
94
+
95
+ # Adds the dependency to self, making self dependent on the dependency.
96
+ # The dependency will be called with the input arguments during
97
+ # resolve_dependencies.
98
+ def depends_on(dependency, *inputs)
99
+ raise ArgumentError, "not an Executable: #{dependency}" unless dependency.kind_of?(Executable)
100
+ raise ArgumentError, "cannot depend on self" if dependency == self
101
+
102
+ index = Executable.register(dependency, inputs)
103
+ dependencies << index unless dependencies.include?(index)
104
+ index
105
+ end
106
+
107
+ # Resolves dependencies by calling dependency.resolve with
108
+ # the dependency arguments.
109
+ def resolve_dependencies
110
+ Executable.resolve(dependencies)
111
+ self
112
+ end
113
+
114
+ def reset_dependencies
115
+ Executable.reset(dependencies)
116
+ self
117
+ end
43
118
 
44
119
  # Auditing method call. Executes _method_name for self, but audits
45
120
  # the result. Sends the audited result to the on_complete_block if set.
@@ -51,7 +126,11 @@ module Tap
51
126
  # a new audit using the input
52
127
  # multiple inputs:: merges the inputs into a new Audit.
53
128
  #
129
+ # Dependencies are resolved using resolve_dependencies before
130
+ # _method_name is executed.
54
131
  def _execute(*inputs)
132
+ resolve_dependencies
133
+
55
134
  audit = case inputs.length
56
135
  when 0 then Audit.new
57
136
  when 1