tap 0.18.0 → 0.19.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 +21 -0
- data/MIT-LICENSE +17 -15
- data/README +13 -30
- data/bin/tap +19 -24
- data/cmd/console.rb +1 -12
- data/cmd/manifest.rb +14 -19
- data/cmd/run.rb +96 -86
- data/doc/API +194 -54
- data/doc/Examples/Command Line +27 -1
- data/lib/tap.rb +2 -1
- data/lib/tap/app.rb +613 -166
- data/lib/tap/app/api.rb +115 -0
- data/lib/tap/app/queue.rb +36 -37
- data/lib/tap/app/state.rb +2 -1
- data/lib/tap/env.rb +454 -270
- data/lib/tap/env/constant.rb +83 -33
- data/lib/tap/env/context.rb +61 -0
- data/lib/tap/env/manifest.rb +140 -50
- data/lib/tap/env/minimap.rb +55 -39
- data/lib/tap/join.rb +71 -53
- data/lib/tap/joins/sync.rb +3 -1
- data/lib/tap/middleware.rb +4 -25
- data/lib/tap/middlewares/debugger.rb +75 -0
- data/lib/tap/parser.rb +268 -0
- data/lib/tap/prompt.rb +36 -0
- data/lib/tap/root.rb +3 -3
- data/lib/tap/signals.rb +26 -0
- data/lib/tap/signals/class_methods.rb +222 -0
- data/lib/tap/signals/help.rb +40 -0
- data/lib/tap/signals/module_methods.rb +20 -0
- data/lib/tap/signals/signal.rb +68 -0
- data/lib/tap/task.rb +28 -79
- data/lib/tap/tasks/dump.rb +6 -0
- data/lib/tap/tasks/load.rb +9 -37
- data/lib/tap/templater.rb +12 -1
- data/lib/tap/version.rb +1 -1
- metadata +22 -16
- data/doc/Class Reference +0 -330
- data/lib/tap/exe.rb +0 -130
- data/lib/tap/schema.rb +0 -374
- data/lib/tap/schema/parser.rb +0 -425
- data/lib/tap/schema/utils.rb +0 -56
data/History
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
== 0.19.0 / 2009-12-05
|
2
|
+
|
3
|
+
Significant rework of Tap internals.
|
4
|
+
|
5
|
+
* extracted task/join/middleware code to make Api base class
|
6
|
+
* some changes to semantics of Minimap; entry_to_minikey is
|
7
|
+
now entry_to_path. Likewise entries now specify their own
|
8
|
+
path using entry.path rather than entry.minikey
|
9
|
+
* added Signals implemented with the Dsl pattern
|
10
|
+
|
11
|
+
== 0.18.1
|
12
|
+
|
13
|
+
* updated API to allow nodes that do not respond to joins
|
14
|
+
* fixed bug in reassigning Sync joins
|
15
|
+
* added quick-queue option to run
|
16
|
+
* added short options to app configs
|
17
|
+
* added blocks to app.log
|
18
|
+
* added --help flag for joins, middleware
|
19
|
+
* removed recurrent loading hooks from load
|
20
|
+
(see tap-tasks:tap/tasks/stream)
|
21
|
+
|
1
22
|
== 0.18.0 / 2009-06-17
|
2
23
|
|
3
24
|
Several updates to simplify Tap. Most significantly,
|
data/MIT-LICENSE
CHANGED
@@ -1,19 +1,21 @@
|
|
1
1
|
Copyright (c) 2006-2009, Regents of the University of Colorado.
|
2
2
|
|
3
|
-
|
4
|
-
software and associated documentation files (the "Software"), to deal in the Software
|
5
|
-
without restriction, including without limitation the rights to use, copy, modify, merge,
|
6
|
-
publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
7
|
-
to whom the Software is furnished to do so, subject to the following conditions:
|
3
|
+
Copyright (c) 2009, Simon Chiang.
|
8
4
|
|
9
|
-
|
10
|
-
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README
CHANGED
@@ -14,15 +14,10 @@ Tap is the core of the
|
|
14
14
|
{Tap-Suite}[http://tap.rubyforge.org/tap-suite/index.html]
|
15
15
|
which provides a standard library of
|
16
16
|
{tasks}[http://tap.rubyforge.org/tap-tasks/index.html],
|
17
|
-
{generators}[http://tap.rubyforge.org/tap-gen/index.html],
|
18
|
-
{test utilities}[http://tap.rubyforge.org/tap-test/index.html]
|
19
|
-
and a
|
20
|
-
{server}[http://tap.rubyforge.org/tap-server/index.html]
|
21
|
-
to execute workflows via HTTP.
|
17
|
+
{generators}[http://tap.rubyforge.org/tap-gen/index.html], and
|
18
|
+
{test utilities}[http://tap.rubyforge.org/tap-test/index.html].
|
22
19
|
|
23
|
-
* {Tutorial}[http://tap.rubyforge.org/tap-suite/files/doc/Tutorial.html], {API}[link:files/doc/API.html], {Structure}[link:files/doc/Class%20Reference.html]
|
24
20
|
* Website[http://tap.rubyforge.org]
|
25
|
-
* Lighthouse[http://bahuvrihi.lighthouseapp.com/projects/9908-tap-task-application/tickets]
|
26
21
|
* Github[http://github.com/bahuvrihi/tap/tree/master]
|
27
22
|
* {Google Group}[http://groups.google.com/group/ruby-on-tap]
|
28
23
|
|
@@ -51,7 +46,7 @@ Tap automatically discovers tasks.
|
|
51
46
|
dump # the default dump task
|
52
47
|
load # the default load task
|
53
48
|
|
54
|
-
And generates documentation.
|
49
|
+
And generates command line documentation.
|
55
50
|
|
56
51
|
% tap run -- goodnight --help
|
57
52
|
Goodnight -- your basic goodnight moon task
|
@@ -65,24 +60,24 @@ And generates documentation.
|
|
65
60
|
|
66
61
|
options:
|
67
62
|
--help Print this help
|
68
|
-
--
|
63
|
+
--enque Manually enques self
|
69
64
|
--config FILE Specifies a config file
|
70
65
|
|
71
|
-
Tasks are immediately available for use in workflows
|
66
|
+
Tasks are immediately available for use in workflows, and may be configured as
|
67
|
+
if they were individual executables. This workflow joins the goodnight task to
|
68
|
+
a dump task, which prints the message to stdout.
|
72
69
|
|
73
70
|
% tap run -- goodnight moon --: dump
|
74
71
|
goodnight moon
|
75
72
|
|
76
|
-
Tasks may be configured as if they were individual executables.
|
77
|
-
|
78
73
|
% tap run -- goodnight world --message hello --: dump
|
79
74
|
hello world
|
80
75
|
|
81
76
|
=== Workflow Syntax
|
82
77
|
|
83
78
|
Workflows are specified on the command line using argument vectors separated
|
84
|
-
by option breaks. The vectors define the tasks
|
85
|
-
specify joins.
|
79
|
+
by option breaks (ie '--'). The argument vectors define the tasks while
|
80
|
+
modifications to the breaks specify joins.
|
86
81
|
|
87
82
|
A simple sequence.
|
88
83
|
|
@@ -106,30 +101,18 @@ A merge (note that dump receives the inputs in serial).
|
|
106
101
|
goodnight
|
107
102
|
moon
|
108
103
|
|
109
|
-
A synchronized merge (the printout is ['goodnight', 'moon'].to_s).
|
104
|
+
A synchronized merge (the printout is <tt>['goodnight', 'moon'].to_s</tt>).
|
110
105
|
|
111
106
|
% tap run -- load goodnight -- load moon -- dump --[0,1][2].sync
|
112
107
|
goodnightmoon
|
113
108
|
|
114
|
-
== Known Issues
|
115
|
-
|
116
|
-
Tap::Env and Tap::Schema are still in flux and have poor documentation. Neither should be treated as stable.
|
117
|
-
|
118
109
|
== Installation
|
119
110
|
|
120
|
-
Tap is available as a gem on
|
111
|
+
Tap is available as a gem on Gemcutter[http://gemcutter.org/gems/tap].
|
121
112
|
|
122
113
|
% gem install tap
|
123
114
|
|
124
|
-
Tap requires an updated version of RubyGems[http://docs.rubygems.org/]
|
125
|
-
(>= 1.2.0). To check the version and update RubyGems:
|
126
|
-
|
127
|
-
% gem --version
|
128
|
-
% gem --update system
|
129
|
-
|
130
115
|
== Info
|
131
116
|
|
132
|
-
|
133
|
-
|
134
|
-
Support:: CU Denver School of Medicine Deans Academic Enrichment Fund
|
135
|
-
License:: {MIT-Style}[link:files/MIT-LICENSE.html]
|
117
|
+
Developer:: {Simon Chiang}[http://bahuvrihi.wordpress.com]
|
118
|
+
License:: {MIT-Style}[link:files/MIT-LICENSE.html]
|
data/bin/tap
CHANGED
@@ -15,11 +15,11 @@
|
|
15
15
|
require "#{File.dirname(__FILE__)}/../lib/tap.rb"
|
16
16
|
|
17
17
|
#
|
18
|
-
# setup the
|
18
|
+
# setup the application
|
19
19
|
#
|
20
20
|
|
21
21
|
begin
|
22
|
-
|
22
|
+
app = Tap::App.setup
|
23
23
|
rescue(Tap::Env::ConfigError)
|
24
24
|
# catch errors and exit gracefully
|
25
25
|
# (errors usu from gem loading errors)
|
@@ -28,40 +28,35 @@ rescue(Tap::Env::ConfigError)
|
|
28
28
|
end
|
29
29
|
|
30
30
|
#
|
31
|
-
# launch
|
31
|
+
# launch the command
|
32
32
|
#
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
commands = app.env.manifest do |env|
|
35
|
+
env.root.glob(:cmd, "**/*.rb")
|
36
|
+
end
|
37
|
+
|
38
|
+
case command = ARGV.shift.to_s
|
39
|
+
when '', '--help'
|
40
|
+
template = %Q{<% unless minimap.empty? || count <= 1 %>
|
37
41
|
<%= env_key %>:
|
38
42
|
<% end %>
|
39
|
-
<%
|
43
|
+
<% minimap.each do |key, path| %>
|
40
44
|
<%= key.ljust(width) %>
|
41
45
|
<% end %>}
|
42
46
|
|
43
|
-
commands = exe.manifest(:command).inspect(template,
|
44
|
-
:count => 0,
|
45
|
-
:width => 10
|
46
|
-
) do |templater, globals|
|
47
|
-
entries = templater.manifest.minimap
|
48
|
-
templater.entries = entries
|
49
|
-
|
50
|
-
# determine width, count
|
51
|
-
width = globals[:width]
|
52
|
-
entries.each do |key, path|
|
53
|
-
width = key.length if width < key.length
|
54
|
-
end
|
55
|
-
globals[:width] = width
|
56
|
-
globals[:count] += 1 unless entries.empty?
|
57
|
-
end
|
58
|
-
|
59
47
|
puts Lazydoc.usage(__FILE__)
|
60
48
|
puts
|
61
49
|
puts "available commands:"
|
62
|
-
puts commands
|
50
|
+
puts commands.summarize(template)
|
63
51
|
puts
|
64
52
|
puts "version #{Tap::VERSION} -- #{Tap::WEBSITE}"
|
53
|
+
else
|
54
|
+
if path = commands.seek(command)
|
55
|
+
load path
|
56
|
+
else
|
57
|
+
puts "Unknown command: '#{command}'"
|
58
|
+
puts "Type 'tap --help' for usage information."
|
59
|
+
end
|
65
60
|
end
|
66
61
|
|
67
62
|
exit(0)
|
data/cmd/console.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
# environment through 'env'. For example:
|
6
6
|
#
|
7
7
|
# % tap console
|
8
|
-
# >> env[:
|
8
|
+
# >> app.env[:dump]
|
9
9
|
# => Tap::Tasks::Dump
|
10
10
|
# >> app.info
|
11
11
|
# => "state: 0 (READY) queue: 0"
|
@@ -29,17 +29,6 @@ def app
|
|
29
29
|
@app ||= Tap::App.instance
|
30
30
|
end
|
31
31
|
|
32
|
-
def env
|
33
|
-
@env ||= Tap::Env.instance
|
34
|
-
end
|
35
|
-
|
36
|
-
def run(cmd, reset=true)
|
37
|
-
app.reset if reset
|
38
|
-
schema = Tap::Schema.parse(cmd)
|
39
|
-
env.run(schema, app)
|
40
|
-
nil
|
41
|
-
end
|
42
|
-
|
43
32
|
IRB.start
|
44
33
|
|
45
34
|
# Handles a bug in IRB that causes exit to throw :IRB_EXIT
|
data/cmd/manifest.rb
CHANGED
@@ -24,15 +24,15 @@ template = %Q{<% unless manifests.empty? %>
|
|
24
24
|
<%= (env_key + ':').ljust(width) %> (<%= env.root.root %>)
|
25
25
|
<% manifests.each do |type, entries| %>
|
26
26
|
<%= type %>
|
27
|
-
<% entries.each do |key,
|
28
|
-
<%= key.ljust(width
|
27
|
+
<% entries.each do |key, paths| %>
|
28
|
+
<%= key.ljust(width) %> (<%= paths.join(', ') %>)
|
29
29
|
<% end %>
|
30
30
|
<% end %>
|
31
31
|
<% end %>
|
32
32
|
}
|
33
33
|
|
34
34
|
# filter envs to manifest
|
35
|
-
env = Tap::
|
35
|
+
env = Tap::App.instance.env
|
36
36
|
env_keys = env.minihash(true)
|
37
37
|
filter = if ARGV.empty?
|
38
38
|
env_keys.keys
|
@@ -43,6 +43,7 @@ else
|
|
43
43
|
end
|
44
44
|
|
45
45
|
# build the summary
|
46
|
+
constants = env.constants
|
46
47
|
summary = env.inspect(template, :width => 10) do |templater, globals|
|
47
48
|
current = templater.env
|
48
49
|
manifests = []
|
@@ -56,26 +57,20 @@ summary = env.inspect(template, :width => 10) do |templater, globals|
|
|
56
57
|
width = env_key.length if width < env_key.length
|
57
58
|
|
58
59
|
# build up the entries for each type of resource
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
types = {}
|
61
|
+
constants.entries(current).minimap.each do |key, const|
|
62
|
+
paths = const.require_paths.collect do |path|
|
63
|
+
current.root.relative_path(:root, path) || path
|
64
|
+
end.uniq
|
63
65
|
|
64
|
-
|
65
|
-
entries = entries.minimap.collect do |key, entry|
|
66
|
-
path = if entry.kind_of?(Tap::Env::Constant)
|
67
|
-
entry.require_path
|
68
|
-
else
|
69
|
-
entry
|
70
|
-
end
|
71
|
-
|
72
|
-
width = key.length if width < key.length
|
73
|
-
[key, current.root.relative_path(:root, path) || path]
|
74
|
-
end
|
66
|
+
width = key.length if width < key.length
|
75
67
|
|
76
|
-
|
68
|
+
const.types.keys.each do |type|
|
69
|
+
(types[type] ||= []) << [key, paths]
|
70
|
+
end
|
77
71
|
end
|
78
72
|
|
73
|
+
manifests.concat types.to_a.sort_by {|type, minimap| type }
|
79
74
|
globals[:width] = width
|
80
75
|
end
|
81
76
|
puts summary
|
data/cmd/run.rb
CHANGED
@@ -6,128 +6,138 @@
|
|
6
6
|
# tap run -- load hello --: dump Say hello
|
7
7
|
#
|
8
8
|
|
9
|
-
|
10
|
-
app = Tap::App.new
|
9
|
+
app = Tap::App.instance
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
# separate out argv schema
|
17
|
-
argv = []
|
18
|
-
while !ARGV.empty? && ARGV[0] !~ Tap::Schema::Parser::BREAK
|
19
|
-
argv << ARGV.shift
|
20
|
-
end
|
21
|
-
schema = ARGV.empty? ? nil : Tap::Schema.parse(ARGV)
|
22
|
-
ARGV.replace(argv)
|
23
|
-
|
24
|
-
# parse options
|
25
|
-
mode = :run
|
26
|
-
ConfigParser.new(app.config) do |opts|
|
27
|
-
opts.separator ""
|
28
|
-
opts.separator "configurations:"
|
11
|
+
opts = {}
|
12
|
+
parser = ConfigParser.bind(app.config) do |psr|
|
13
|
+
psr.separator ""
|
14
|
+
psr.separator "configurations:"
|
29
15
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
opts.separator ""
|
37
|
-
opts.separator "options:"
|
16
|
+
psr.add Tap::App.configurations
|
17
|
+
|
18
|
+
psr.separator ""
|
19
|
+
psr.separator "options:"
|
38
20
|
|
39
|
-
|
40
|
-
Tap::App.lazydoc.resolve
|
21
|
+
psr.on("-h", "--help", "Show this message") do
|
41
22
|
puts Lazydoc.usage(__FILE__)
|
42
|
-
puts
|
23
|
+
puts psr
|
43
24
|
exit(0)
|
44
25
|
end
|
45
26
|
|
46
|
-
|
47
|
-
|
48
|
-
puts "An inline schema cannot be specified with a file schema."
|
49
|
-
exit(0)
|
50
|
-
end
|
51
|
-
|
52
|
-
schema = Tap::Schema.load_file(file)
|
27
|
+
psr.on('-s', '--serialize', 'Serialize the workflow') do
|
28
|
+
opts[:serialize] = true
|
53
29
|
end
|
54
30
|
|
55
|
-
|
56
|
-
|
57
|
-
end
|
58
|
-
|
59
|
-
opts.on('-t', '--manifest', 'Print a list of available resources') do
|
60
|
-
tasks = env.manifest(:task)
|
61
|
-
tasks_found = !tasks.all_empty?
|
31
|
+
psr.on('-t', '--manifest', 'Print a list of available resources') do
|
32
|
+
constants = app.env.constants
|
62
33
|
|
63
|
-
joins =
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
34
|
+
tasks, joins, middleware = %w{task join middleware}.collect do |type|
|
35
|
+
constants.summarize do |constant|
|
36
|
+
constant.types[type]
|
37
|
+
end
|
38
|
+
end
|
68
39
|
|
69
|
-
|
70
|
-
puts "=== tasks ==="
|
71
|
-
puts tasks
|
40
|
+
unless tasks.empty?
|
41
|
+
puts "=== tasks ===" unless middleware.empty? && joins.empty?
|
42
|
+
puts tasks
|
72
43
|
end
|
73
44
|
|
74
|
-
|
75
|
-
puts "=== joins ==="
|
76
|
-
puts joins
|
45
|
+
unless joins.empty?
|
46
|
+
puts "=== joins ===" unless tasks.empty? && middleware.empty?
|
47
|
+
puts joins
|
77
48
|
end
|
78
49
|
|
79
|
-
|
80
|
-
puts "=== middleware ==="
|
81
|
-
puts middleware
|
50
|
+
unless middleware.empty?
|
51
|
+
puts "=== middleware ===" unless tasks.empty? && joins.empty?
|
52
|
+
puts middleware
|
82
53
|
end
|
83
54
|
|
84
55
|
exit(0)
|
85
56
|
end
|
86
57
|
|
87
|
-
|
88
|
-
|
58
|
+
psr.on('-T', '--tasks', 'Print a list of available tasks') do
|
59
|
+
constants = app.env.constants
|
60
|
+
tasks = constants.summarize do |constant|
|
61
|
+
constant.types['task']
|
62
|
+
end
|
63
|
+
|
64
|
+
puts tasks
|
89
65
|
exit(0)
|
90
66
|
end
|
91
67
|
|
92
|
-
|
68
|
+
psr.on('-u', '--quick-queue', 'Removes thread-safety from queue') do
|
69
|
+
mod = Module.new do
|
70
|
+
def synchronize
|
71
|
+
yield
|
72
|
+
end
|
73
|
+
end
|
74
|
+
app.queue.extend(mod)
|
75
|
+
end
|
76
|
+
end
|
93
77
|
|
94
78
|
#
|
95
79
|
# build and run
|
96
80
|
#
|
97
81
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
82
|
+
# Traps interrupt the normal flow of the program and so I assume thread safety
|
83
|
+
# is an issue (ex if the INT occurs during an enque and a signal specifies
|
84
|
+
# another enque). A safer way to go is to enque the prompt... when the prompt
|
85
|
+
# is executed the app won't be be doing anything else so thread safety
|
86
|
+
# shouldn't be an issue.
|
87
|
+
Signal.trap('INT') do
|
88
|
+
puts
|
89
|
+
puts "Interrupt! Signals from an interruption are not thread-safe."
|
90
|
+
|
91
|
+
require 'tap/prompt'
|
92
|
+
prompt = Tap::Prompt.new
|
93
|
+
call_prompt = true
|
94
|
+
3.times do
|
95
|
+
print "Wait for thread-safe break? (y/n): "
|
96
|
+
|
97
|
+
case gets.strip
|
98
|
+
when /^y(es)?$/i
|
99
|
+
puts "waiting for break..."
|
100
|
+
app.queue.unshift(prompt, [])
|
101
|
+
call_prompt = false
|
102
|
+
break
|
103
|
+
|
104
|
+
when /^no?$/i
|
105
|
+
break
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
if call_prompt
|
110
|
+
prompt.call
|
104
111
|
end
|
105
|
-
|
106
|
-
puts msg
|
107
|
-
exit(0)
|
108
112
|
end
|
109
113
|
|
110
114
|
begin
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
app.to_schema do |type, resources|
|
120
|
-
resources.each do |resource|
|
121
|
-
const_name = resource.delete(:class).to_s
|
122
|
-
resource[:id] = env.reverse_seek(type, false) do |const|
|
123
|
-
const.const_name == const_name
|
124
|
-
end
|
115
|
+
loop do
|
116
|
+
break if ARGV.empty?
|
117
|
+
parser.scan(ARGV,
|
118
|
+
:option_break => Tap::Parser::BREAK,
|
119
|
+
:keep_break => true
|
120
|
+
) do |path|
|
121
|
+
YAML.load_file(path).each do |spec|
|
122
|
+
app.call(spec)
|
125
123
|
end
|
126
|
-
end
|
124
|
+
end
|
125
|
+
|
126
|
+
break if ARGV.empty?
|
127
|
+
ARGV.replace app.call('sig' => 'parse', 'args' => ARGV)
|
127
128
|
end
|
128
129
|
|
130
|
+
if opts[:serialize]
|
131
|
+
YAML.dump(app.serialize, $stdout)
|
132
|
+
exit(0)
|
133
|
+
end
|
134
|
+
|
135
|
+
opts = nil
|
136
|
+
parser = nil
|
137
|
+
app.run
|
138
|
+
|
129
139
|
rescue
|
130
|
-
raise if
|
140
|
+
raise if app.debug?
|
131
141
|
puts $!.message
|
132
142
|
exit(1)
|
133
143
|
end
|