tap 0.19.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History +100 -45
- data/MIT-LICENSE +1 -1
- data/README +95 -51
- data/bin/tap +11 -57
- data/bin/tapexe +84 -0
- data/doc/API +91 -139
- data/doc/Configuration +93 -0
- data/doc/Examples/Command Line +10 -42
- data/doc/Examples/Tapfile +124 -0
- data/doc/Ruby to Ruby +87 -0
- data/doc/Workflow Syntax +185 -0
- data/lib/tap.rb +74 -5
- data/lib/tap/app.rb +217 -310
- data/lib/tap/app/api.rb +44 -23
- data/lib/tap/app/queue.rb +11 -12
- data/lib/tap/app/stack.rb +4 -4
- data/lib/tap/declarations.rb +200 -0
- data/lib/tap/declarations/context.rb +31 -0
- data/lib/tap/declarations/description.rb +33 -0
- data/lib/tap/env.rb +133 -779
- data/lib/tap/env/cache.rb +87 -0
- data/lib/tap/env/constant.rb +94 -39
- data/lib/tap/env/path.rb +71 -0
- data/lib/tap/join.rb +42 -78
- data/lib/tap/joins/gate.rb +85 -0
- data/lib/tap/joins/switch.rb +4 -2
- data/lib/tap/joins/sync.rb +3 -3
- data/lib/tap/middleware.rb +5 -5
- data/lib/tap/middlewares/debugger.rb +18 -58
- data/lib/tap/parser.rb +115 -183
- data/lib/tap/root.rb +162 -239
- data/lib/tap/signal.rb +72 -0
- data/lib/tap/signals.rb +20 -2
- data/lib/tap/signals/class_methods.rb +38 -43
- data/lib/tap/signals/configure.rb +19 -0
- data/lib/tap/signals/help.rb +5 -7
- data/lib/tap/signals/load.rb +49 -0
- data/lib/tap/signals/module_methods.rb +1 -0
- data/lib/tap/task.rb +46 -275
- data/lib/tap/tasks/dump.rb +21 -16
- data/lib/tap/tasks/list.rb +184 -0
- data/lib/tap/tasks/load.rb +4 -4
- data/lib/tap/tasks/prompt.rb +128 -0
- data/lib/tap/tasks/signal.rb +42 -0
- data/lib/tap/tasks/singleton.rb +35 -0
- data/lib/tap/tasks/stream.rb +64 -0
- data/lib/tap/utils.rb +83 -0
- data/lib/tap/version.rb +2 -2
- data/lib/tap/workflow.rb +124 -0
- data/tap.yml +0 -0
- metadata +59 -24
- data/cmd/console.rb +0 -43
- data/cmd/manifest.rb +0 -118
- data/cmd/run.rb +0 -145
- data/doc/Examples/Workflow +0 -40
- data/lib/tap/app/node.rb +0 -29
- data/lib/tap/env/context.rb +0 -61
- data/lib/tap/env/gems.rb +0 -63
- data/lib/tap/env/manifest.rb +0 -179
- data/lib/tap/env/minimap.rb +0 -308
- data/lib/tap/intern.rb +0 -50
- data/lib/tap/joins.rb +0 -9
- data/lib/tap/prompt.rb +0 -36
- data/lib/tap/root/utils.rb +0 -220
- data/lib/tap/root/versions.rb +0 -138
- data/lib/tap/signals/signal.rb +0 -68
@@ -0,0 +1,85 @@
|
|
1
|
+
module Tap
|
2
|
+
module Joins
|
3
|
+
|
4
|
+
# :startdoc::join collects results
|
5
|
+
#
|
6
|
+
# Similar to a synchronized merge, but collects all results regardless of
|
7
|
+
# where they come from. Gates enque themselves when called as a join, and
|
8
|
+
# won't let results pass until they get run as a task.
|
9
|
+
#
|
10
|
+
# % tap load a -- load b - inspect - gate 0,1 2
|
11
|
+
# ["a", "b"]
|
12
|
+
#
|
13
|
+
# Gates are useful in conjunction with iteration where a single task may
|
14
|
+
# feed multiple results to a single join; in this case a sync merge doesn't
|
15
|
+
# produce the desired behavior of collecting the results.
|
16
|
+
#
|
17
|
+
# % tap load/yaml "[1, 2, 3]" -:i inspect -:.gate inspect
|
18
|
+
# 1
|
19
|
+
# 2
|
20
|
+
# 3
|
21
|
+
# [1, 2, 3]
|
22
|
+
#
|
23
|
+
# % tap load/yaml "[1, 2, 3]" -:i inspect -:.sync inspect
|
24
|
+
# 1
|
25
|
+
# [1]
|
26
|
+
# 2
|
27
|
+
# [2]
|
28
|
+
# 3
|
29
|
+
# [3]
|
30
|
+
#
|
31
|
+
# When a limit is specified, the gate will collect results up to the limit
|
32
|
+
# and then pass the results. Any leftover results are still passed at the
|
33
|
+
# end.
|
34
|
+
#
|
35
|
+
# % tap load/yaml "[1, 2, 3]" -:i inspect - inspect - gate 1 2 --limit 2
|
36
|
+
# 1
|
37
|
+
# 2
|
38
|
+
# [1, 2]
|
39
|
+
# 3
|
40
|
+
# [3]
|
41
|
+
#
|
42
|
+
class Gate < Join
|
43
|
+
|
44
|
+
# An array of results collected thusfar.
|
45
|
+
attr_reader :results
|
46
|
+
|
47
|
+
config :limit, nil, :short => :l, &c.integer_or_nil # Pass results after limit
|
48
|
+
|
49
|
+
def initialize(config={}, app=Tap::App.current)
|
50
|
+
super
|
51
|
+
@results = nil
|
52
|
+
end
|
53
|
+
|
54
|
+
def call(result)
|
55
|
+
if @results
|
56
|
+
# Results are set, so self is already enqued and collecting
|
57
|
+
# results. If the input is the collection, then it's time
|
58
|
+
# to execute the results and reset. Otherwise, just
|
59
|
+
# collect the input and wait.
|
60
|
+
|
61
|
+
if result == @results
|
62
|
+
@results = nil
|
63
|
+
super(result)
|
64
|
+
else
|
65
|
+
@results << result
|
66
|
+
|
67
|
+
if limit && @results.length >= limit
|
68
|
+
super(@results.dup)
|
69
|
+
@results.clear
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
else
|
74
|
+
# No results are set, so this is a first call and self is
|
75
|
+
# not enqued. Setup the collection.
|
76
|
+
|
77
|
+
@results = [result]
|
78
|
+
app.enq(self, @results)
|
79
|
+
end
|
80
|
+
|
81
|
+
self
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/tap/joins/switch.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'tap/join'
|
2
|
+
|
1
3
|
module Tap
|
2
4
|
module Joins
|
3
5
|
|
@@ -16,7 +18,7 @@ module Tap
|
|
16
18
|
# to that receives the result.
|
17
19
|
attr_accessor :selector
|
18
20
|
|
19
|
-
def initialize(config={}, app=Tap::App.
|
21
|
+
def initialize(config={}, app=Tap::App.current, &block)
|
20
22
|
super(config, app)
|
21
23
|
@selector = block
|
22
24
|
end
|
@@ -33,7 +35,7 @@ module Tap
|
|
33
35
|
raise SwitchError, "no switch target at index: #{index}"
|
34
36
|
end
|
35
37
|
|
36
|
-
|
38
|
+
exe(output, result)
|
37
39
|
end
|
38
40
|
|
39
41
|
# Raised by a Switch join to indicate when a switch index is out of bounds.
|
data/lib/tap/joins/sync.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Tap
|
2
2
|
module Joins
|
3
3
|
|
4
|
-
# :startdoc::join
|
4
|
+
# :startdoc::join synchronized multi-way join
|
5
5
|
#
|
6
6
|
# Sync works the same as Join, but passes the collected results of the
|
7
7
|
# inputs (ie an array) to the outputs. The results will not be passed
|
@@ -17,7 +17,7 @@ module Tap
|
|
17
17
|
# An array holding results until the batch is ready to execute.
|
18
18
|
attr_reader :results
|
19
19
|
|
20
|
-
def initialize(config={}, app=Tap::App.
|
20
|
+
def initialize(config={}, app=Tap::App.current)
|
21
21
|
super
|
22
22
|
@results = nil
|
23
23
|
end
|
@@ -65,7 +65,7 @@ module Tap
|
|
65
65
|
results[index] = result
|
66
66
|
|
67
67
|
unless results.include?(NIL_VALUE)
|
68
|
-
outputs.each {|output|
|
68
|
+
outputs.each {|output| exe(output, results) }
|
69
69
|
reset
|
70
70
|
end
|
71
71
|
end
|
data/lib/tap/middleware.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require 'tap/app'
|
1
|
+
require 'tap/app/api'
|
2
2
|
|
3
3
|
module Tap
|
4
4
|
class Middleware < App::Api
|
5
5
|
class << self
|
6
|
-
def build(spec={}, app=Tap::App.
|
6
|
+
def build(spec={}, app=Tap::App.current)
|
7
7
|
new(app.stack, spec['config'] || {})
|
8
8
|
end
|
9
9
|
end
|
@@ -27,9 +27,9 @@ module Tap
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
# By default call simply calls stack with the
|
31
|
-
def call(
|
32
|
-
stack.call(
|
30
|
+
# By default call simply calls stack with the task and inputs.
|
31
|
+
def call(task, input)
|
32
|
+
stack.call(task, input)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -3,72 +3,32 @@ require 'tap/middleware'
|
|
3
3
|
module Tap
|
4
4
|
module Middlewares
|
5
5
|
|
6
|
-
# :startdoc::middleware
|
6
|
+
# :startdoc::middleware default debugger
|
7
|
+
#
|
8
|
+
# Logs the execution of tasks with their inputs. Debugger outputs the
|
9
|
+
# same information as App.exe will output when the app is set to debug. To
|
10
|
+
# avoid duplication, debugger ONLY logs execution when the app is not in
|
11
|
+
# debug mode, or when force is set.
|
12
|
+
#
|
7
13
|
class Debugger < Middleware
|
8
|
-
|
9
|
-
module_function
|
10
|
-
|
11
|
-
def arity_ok?(arity, n)
|
12
|
-
n == arity || (arity < 0 && (-1-n) <= arity)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
include Utils
|
17
|
-
|
18
|
-
config :verbose, false, &c.flag
|
19
|
-
config :output, $stderr, &c.io
|
14
|
+
config :force, false, &c.flag # Force logging
|
20
15
|
|
21
|
-
def call(
|
22
|
-
|
23
|
-
|
24
|
-
io.puts " - #{summarize(inputs)}"
|
25
|
-
end
|
16
|
+
def call(task, input)
|
17
|
+
log("#{app.var(task)} <<", "#{summarize input} (#{task.class})")
|
18
|
+
output = super
|
26
19
|
|
27
|
-
|
28
|
-
|
20
|
+
log("#{app.var(task)} >>", "#{summarize output} (#{task.class})")
|
21
|
+
output
|
29
22
|
end
|
30
23
|
|
31
|
-
def
|
32
|
-
|
33
|
-
|
34
|
-
input.class
|
35
|
-
end
|
24
|
+
def log(action, msg)
|
25
|
+
if force || !app.debug
|
26
|
+
app.log(action, msg)
|
36
27
|
end
|
37
|
-
|
38
|
-
inputs.inspect
|
39
28
|
end
|
40
29
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
-
call_arity = node.method(:call).arity
|
45
|
-
unless arity_ok?(call_arity, n)
|
46
|
-
raise InvalidSignatureError.new(node, inputs, :call, call_arity)
|
47
|
-
end
|
48
|
-
|
49
|
-
if node.kind_of?(Task)
|
50
|
-
process_arity = node.method(:process).arity
|
51
|
-
unless arity_ok?(process_arity, n)
|
52
|
-
raise InvalidSignatureError.new(node, inputs, :process, process_arity)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
if node.kind_of?(Intern)
|
57
|
-
process_block_arity = node.process_block
|
58
|
-
unless arity_ok?(process_block_arity, n)
|
59
|
-
raise InvalidSignatureError.new(node, inputs, :process_block, process_block_arity)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
end
|
64
|
-
|
65
|
-
class InvalidSignatureError < StandardError
|
66
|
-
def initialize(node, inputs, method, arity)
|
67
|
-
lines = []
|
68
|
-
lines << "Invalid input signature to: #{node.class} (#{method})"
|
69
|
-
lines << "Expected #{arity} input but was given #{inputs.length}"
|
70
|
-
super(lines.join("\n"))
|
71
|
-
end
|
30
|
+
def summarize(obj)
|
31
|
+
obj.inspect
|
72
32
|
end
|
73
33
|
end
|
74
34
|
end
|
data/lib/tap/parser.rb
CHANGED
@@ -1,74 +1,35 @@
|
|
1
|
-
require '
|
1
|
+
require 'tap/join'
|
2
|
+
require 'tap/tasks/signal'
|
2
3
|
|
3
4
|
module Tap
|
4
5
|
|
5
6
|
# A parser for workflows defined on the command line.
|
6
7
|
class Parser
|
7
|
-
class << self
|
8
|
-
def parse(argv=ARGV)
|
9
|
-
parse!(argv.dup)
|
10
|
-
end
|
11
|
-
|
12
|
-
def parse!(argv=ARGV)
|
13
|
-
argv = Shellwords.shellwords(argv) if argv.kind_of?(String)
|
14
|
-
sig, obj = argv.shift, nil
|
15
|
-
|
16
|
-
if sig =~ OBJECT
|
17
|
-
obj, sig = $1, $2
|
18
|
-
end
|
19
|
-
|
20
|
-
[obj, sig, argv]
|
21
|
-
end
|
22
|
-
end
|
23
8
|
|
24
|
-
#
|
25
|
-
|
26
|
-
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
#
|
31
|
-
|
32
|
-
|
33
|
-
#
|
34
|
-
|
35
|
-
|
36
|
-
#
|
37
|
-
|
38
|
-
|
39
|
-
#
|
40
|
-
|
41
|
-
|
42
|
-
# After the match:
|
43
|
-
#
|
44
|
-
# $1:: The string after the break, or nil
|
45
|
-
# (ex: '--' => nil, '--:' => ':', '--[1,2][3,4]' => '[1,2][3,4]')
|
46
|
-
#
|
47
|
-
BREAK = /\A--(?:\z|([\:\[\/\.@].*?)\z)/
|
48
|
-
|
49
|
-
# The node modifier.
|
50
|
-
NODE_BREAK = nil
|
51
|
-
|
52
|
-
# The join modifier.
|
53
|
-
JOIN_BREAK = "."
|
54
|
-
|
9
|
+
# Regexp to match any dash-nonword break
|
10
|
+
BREAK = /\A-(?!-?\w)/
|
11
|
+
|
12
|
+
# Matches a traditional dash-letter or double-dash-word option
|
13
|
+
OPTION = /\A--?\w/
|
14
|
+
|
15
|
+
# Delmits and sets the next object
|
16
|
+
SET = '-'
|
17
|
+
|
18
|
+
# Sets and enques the next object
|
19
|
+
ENQUE = '--'
|
20
|
+
|
21
|
+
# Sets and executes the next object
|
22
|
+
EXECUTE = '-!'
|
23
|
+
|
24
|
+
# Break to enque an existing object
|
25
|
+
SIGENQ = '-@'
|
26
|
+
|
55
27
|
# Matches a sequence break. After the match:
|
56
28
|
#
|
57
29
|
# $1:: The modifier string, or nil
|
58
30
|
# (ex: ':' => nil, ':i' => 'i')
|
59
31
|
#
|
60
|
-
|
61
|
-
|
62
|
-
# Matches a generic join break. After the match:
|
63
|
-
#
|
64
|
-
# $1:: The inputs string.
|
65
|
-
# (ex: '[1,2,3][4,5,6]' => '1,2,3')
|
66
|
-
# $2:: The outputs string.
|
67
|
-
# (ex: '[1,2,3][4,5,6]' => '4,5,6')
|
68
|
-
# $3:: The modifier string, or nil
|
69
|
-
# (ex: '[][]is' => 'is')
|
70
|
-
#
|
71
|
-
JOIN = /\A\[(.*?)\]\[(.*?)\](.+)?\z/
|
32
|
+
JOIN = /\A-:(.+)?\z/
|
72
33
|
|
73
34
|
# Matches a join modifier. After the match:
|
74
35
|
#
|
@@ -77,14 +38,7 @@ module Tap
|
|
77
38
|
# $2:: The class string.
|
78
39
|
# (ex: 'is.sync' => 'sync')
|
79
40
|
#
|
80
|
-
|
81
|
-
|
82
|
-
# Matches an enque modifier. After the match:
|
83
|
-
#
|
84
|
-
# $1:: The modifier string, or nil
|
85
|
-
# (ex: '@var' => 'var')
|
86
|
-
#
|
87
|
-
ENQUE = /\A@(.+)?\z/
|
41
|
+
MODIFIER = /\A([A-z]*)(?:\.(.*))?\z/
|
88
42
|
|
89
43
|
# Matches a signal break. After the match:
|
90
44
|
#
|
@@ -93,49 +47,39 @@ module Tap
|
|
93
47
|
# $2:: The signal string
|
94
48
|
# (ex: 'obj/sig' => 'sig')
|
95
49
|
#
|
96
|
-
SIGNAL = /\A
|
50
|
+
SIGNAL = /\A-(-)?\/(.*)\z/
|
97
51
|
|
98
|
-
#
|
99
|
-
|
100
|
-
|
101
|
-
#
|
102
|
-
|
103
|
-
|
104
|
-
#
|
105
|
-
|
106
|
-
#
|
107
|
-
OBJECT = /\A(.*)\/(.*)\z/
|
52
|
+
# The escape begin argument
|
53
|
+
ESCAPE_BEGIN = "-."
|
54
|
+
|
55
|
+
# The escape end argument
|
56
|
+
ESCAPE_END = ".-"
|
57
|
+
|
58
|
+
# The parser end flag
|
59
|
+
END_FLAG = "---"
|
108
60
|
|
109
61
|
attr_reader :specs
|
110
62
|
|
111
|
-
def initialize
|
112
|
-
@specs =
|
63
|
+
def initialize
|
64
|
+
@specs = []
|
113
65
|
end
|
114
66
|
|
115
67
|
def parse(argv)
|
116
|
-
argv
|
117
|
-
parse!(argv)
|
68
|
+
parse!(argv.dup)
|
118
69
|
end
|
119
70
|
|
120
71
|
# Same as parse, but removes parsed args from argv.
|
121
72
|
def parse!(argv)
|
122
|
-
argv = Shellwords.shellwords(argv) if argv.kind_of?(String)
|
123
73
|
return argv if argv.empty?
|
124
74
|
|
125
|
-
unless argv[0] =~ BREAK
|
126
|
-
argv.unshift("--")
|
127
|
-
end
|
128
|
-
|
129
|
-
@current_type = nil
|
130
75
|
@current_index = -1
|
131
|
-
|
76
|
+
current = argv[0] =~ BREAK ? nil : spec(:enq)
|
132
77
|
escape = false
|
133
78
|
|
134
79
|
while !argv.empty?
|
135
80
|
arg = argv.shift
|
136
81
|
|
137
|
-
#
|
138
|
-
# until an escape-end argument
|
82
|
+
# collect escaped arguments until an escape-end
|
139
83
|
if escape
|
140
84
|
if arg == ESCAPE_END
|
141
85
|
escape = false
|
@@ -144,125 +88,113 @@ module Tap
|
|
144
88
|
end
|
145
89
|
next
|
146
90
|
end
|
147
|
-
|
148
|
-
#
|
149
|
-
|
150
|
-
|
151
|
-
begin
|
152
|
-
@current_type = nil
|
153
|
-
@current_index += 1
|
154
|
-
@current = parse_break($1)
|
155
|
-
rescue
|
156
|
-
raise "invalid break: #{arg} (#{$!.message})"
|
157
|
-
end
|
158
|
-
next
|
159
|
-
|
160
|
-
when ESCAPE_BEGIN
|
161
|
-
escape = true
|
91
|
+
|
92
|
+
# collect non-option/break arguments
|
93
|
+
unless arg[0] == ?-
|
94
|
+
current << arg
|
162
95
|
next
|
163
|
-
|
164
|
-
when END_FLAG
|
165
|
-
break
|
96
|
+
end
|
166
97
|
|
167
|
-
|
98
|
+
begin
|
99
|
+
|
100
|
+
# parse option/break arguments
|
101
|
+
case arg
|
102
|
+
when SET
|
103
|
+
current = spec(:set)
|
104
|
+
when ENQUE
|
105
|
+
current = spec(:enq)
|
106
|
+
when EXECUTE
|
107
|
+
current = spec(:exe)
|
108
|
+
when OPTION
|
109
|
+
current << arg
|
110
|
+
when JOIN
|
111
|
+
current = parse_join($1)
|
112
|
+
when SIGENQ
|
113
|
+
current = parse_signal(nil, 'enq')
|
114
|
+
when SIGNAL
|
115
|
+
current = parse_signal($1, $2)
|
116
|
+
when ESCAPE_BEGIN
|
117
|
+
escape = true
|
118
|
+
when END_FLAG
|
119
|
+
break
|
120
|
+
else
|
121
|
+
raise "unknown"
|
122
|
+
end
|
123
|
+
|
124
|
+
rescue
|
125
|
+
raise "invalid break: #{arg} (#{$!.message})"
|
126
|
+
end
|
127
|
+
end
|
168
128
|
|
169
|
-
|
170
|
-
|
129
|
+
argv
|
130
|
+
end
|
131
|
+
|
132
|
+
def build_to(app)
|
133
|
+
blocks = Hash.new do |hash, type|
|
134
|
+
hash[type] = block(type, app)
|
171
135
|
end
|
172
136
|
|
173
|
-
|
174
|
-
|
175
|
-
|
137
|
+
app.scope do
|
138
|
+
specs.each do |(spec, type)|
|
139
|
+
app.call(spec, &blocks[type])
|
140
|
+
end
|
141
|
+
end
|
176
142
|
|
177
|
-
|
143
|
+
self
|
178
144
|
end
|
179
145
|
|
180
146
|
private
|
181
147
|
|
182
|
-
def
|
183
|
-
|
184
|
-
|
148
|
+
def next_args # :nodoc:
|
149
|
+
@current_index += 1
|
150
|
+
[@current_index.to_s]
|
185
151
|
end
|
186
152
|
|
187
|
-
|
188
|
-
|
189
|
-
|
153
|
+
def spec(type, args=next_args) # :nodoc:
|
154
|
+
specs << [{'sig' => 'set', 'args' => args}, type]
|
155
|
+
args
|
190
156
|
end
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
set_type(:join)
|
199
|
-
when SEQUENCE
|
200
|
-
parse_sequence($1)
|
201
|
-
when JOIN
|
202
|
-
parse_join($1, $2, $3)
|
203
|
-
when ENQUE
|
204
|
-
parse_enque($1)
|
205
|
-
when SIGNAL
|
206
|
-
parse_signal($1, $2)
|
157
|
+
|
158
|
+
def block(type, app) # :nodoc:
|
159
|
+
case type
|
160
|
+
when :enq
|
161
|
+
lambda {|obj, args| app.queue.enq(obj, args); obj }
|
162
|
+
when :exe
|
163
|
+
lambda {|obj, args| app.exe(obj, args); obj }
|
207
164
|
else
|
208
|
-
|
165
|
+
nil
|
209
166
|
end
|
210
167
|
end
|
211
|
-
|
212
|
-
#
|
213
|
-
def
|
214
|
-
@
|
215
|
-
nil
|
216
|
-
end
|
217
|
-
|
218
|
-
# parses the match of a SEQUENCE regexp
|
219
|
-
def parse_sequence(one) # :nodoc:
|
220
|
-
unless @current_index > 0
|
168
|
+
|
169
|
+
# parses the match of a JOIN regexp
|
170
|
+
def parse_join(one) # :nodoc:
|
171
|
+
if @current_index < 0
|
221
172
|
raise "no prior entry"
|
222
173
|
end
|
223
174
|
|
224
|
-
|
225
|
-
|
226
|
-
argv = current
|
227
|
-
parse_join_spec(one, "#{@current_index - 1}", @current_index.to_s)
|
228
|
-
argv
|
229
|
-
end
|
230
|
-
|
231
|
-
# parses the match of a JOIN regexp
|
232
|
-
def parse_join(one, two, three) # :nodoc:
|
233
|
-
parse_join_spec(three, one, two)
|
234
|
-
end
|
235
|
-
|
236
|
-
# parses a join modifier string into an argv.
|
237
|
-
def parse_join_spec(modifier, inputs, outputs) # :nodoc:
|
238
|
-
argv = [:join, nil, 'set', nil]
|
175
|
+
current = spec(:set)
|
176
|
+
join = spec(:set, [nil])
|
239
177
|
|
240
|
-
case
|
241
|
-
when
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
argv << ($2 || 'join')
|
247
|
-
argv << inputs
|
248
|
-
argv << outputs
|
249
|
-
$1.split("").each {|char| argv << "-#{char}"}
|
178
|
+
case one
|
179
|
+
when nil
|
180
|
+
join << Tap::Join
|
181
|
+
when MODIFIER
|
182
|
+
join << ($2 || Tap::Join)
|
183
|
+
$1.split('').each {|flag| join << "-#{flag}"}
|
250
184
|
else
|
251
185
|
raise "invalid join modifier"
|
252
186
|
end
|
253
187
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
# parses the match of an ENQUE regexp
|
259
|
-
def parse_enque(one) # :nodoc:
|
260
|
-
spec(:signal, nil, 'enque', one)
|
188
|
+
join << (@current_index - 1).to_s
|
189
|
+
join << @current_index.to_s
|
190
|
+
|
191
|
+
current
|
261
192
|
end
|
262
193
|
|
263
194
|
# parses the match of a SIGNAL regexp
|
264
195
|
def parse_signal(one, two) # :nodoc:
|
265
|
-
|
196
|
+
next_args
|
197
|
+
spec(one.nil? ? :enq : :exe, [nil, Tap::Tasks::Signal, two, '--'])
|
266
198
|
end
|
267
199
|
end
|
268
200
|
end
|