gat 0.2.8
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.txt +84 -0
- data/PostInstall.txt +22 -0
- data/README.txt +49 -0
- data/Rakefile +12 -0
- data/bin/gat +15 -0
- data/lib/gat.rb +323 -0
- data/lib/gat/action/base.rb +197 -0
- data/lib/gat/action/ruby_method.rb +35 -0
- data/lib/gat/action/shell_command.rb +185 -0
- data/lib/gat/boot.rb +63 -0
- data/lib/gat/checks.rb +136 -0
- data/lib/gat/debug.rb +29 -0
- data/lib/gat/dependence/argument.rb +62 -0
- data/lib/gat/dependence/base.rb +54 -0
- data/lib/gat/dependence/folder.rb +104 -0
- data/lib/gat/dependence/program.rb +36 -0
- data/lib/gat/email.rb +80 -0
- data/lib/gat/exceptions.rb +163 -0
- data/lib/gat/extends.rb +102 -0
- data/lib/gat/help.rb +79 -0
- data/lib/gat/interpreter.rb +93 -0
- data/lib/gat/launcher.rb +100 -0
- data/lib/gat/logger.rb +331 -0
- data/lib/gat/operation.rb +253 -0
- data/lib/gat/version.rb +20 -0
- data/lib/gatgets/dar_backup/dar_backup.rb +367 -0
- data/lib/gatgets/dar_backup/dar_backup.yml +387 -0
- data/lib/gatgets/dar_backup/launcher.rb +44 -0
- data/lib/gatgets/dar_backup/templates/list_backups.erb +31 -0
- data/lib/gatgets/dar_backup/templates/search.erb +33 -0
- data/lib/gatgets/gatgets_manager/gatgets_manager.rb +65 -0
- data/lib/gatgets/gatgets_manager/gatgets_manager.yml +71 -0
- data/lib/gatgets/gatgets_manager/templates/list.erb +9 -0
- data/lib/gatgets/synchronization/README +26 -0
- data/lib/gatgets/synchronization/launcher.rb +20 -0
- data/lib/gatgets/synchronization/launcher_cron.sh +69 -0
- data/lib/gatgets/synchronization/synchronization.rb +123 -0
- data/lib/gatgets/synchronization/synchronization.yml +144 -0
- data/test/test_gat.rb +36 -0
- data/test/test_helper.rb +3 -0
- metadata +131 -0
@@ -0,0 +1,197 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
:file => action/base.rb
|
4
|
+
:author => (c) 2008-2009 A.C. Gnoxys info@gnoxys.net
|
5
|
+
|
6
|
+
######################################################################################
|
7
|
+
## This file is part of GAT: http://gat.rubyforge.org ##
|
8
|
+
## ##
|
9
|
+
## GAT (Gnoxys Administration Tools) is released under the GPL License 3 or higher. ##
|
10
|
+
## You can get a copy of the license easily at http://www.gnu.org/licenses/gpl.html.##
|
11
|
+
######################################################################################
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
14
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
15
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
16
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
17
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
18
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
19
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
|
21
|
+
=end
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
module Gat
|
26
|
+
|
27
|
+
|
28
|
+
# Gat::Action::Base
|
29
|
+
#
|
30
|
+
# Action are pieces of operations. Actions are the objetives of dependences
|
31
|
+
# Actions have the next config options at YML definition
|
32
|
+
#
|
33
|
+
# <action_name> *must be uniq*
|
34
|
+
# type: <shell_command> || <ruby_method>
|
35
|
+
# Type of the action. It can be
|
36
|
+
# - shell_command: Action will execute a shell command
|
37
|
+
# - ruby_method: Action will call a ruby_method called by action.name
|
38
|
+
# flags: [ <action flags> ]
|
39
|
+
# Conditional flags have to been passed to execute action. Action is skipped if only one flag failed
|
40
|
+
# Flags can be marked as negative. For example, [ '!file_doesnt_exist' ]. In this case, flags must be marked as false
|
41
|
+
# to result in action execution
|
42
|
+
#
|
43
|
+
# syntax: "<shell_command_syntax">
|
44
|
+
# Only in Shell Commands types, syntax is the command line form to be executed by Ruby Terminal.
|
45
|
+
#
|
46
|
+
# multiple: ["<n multiple parameters>"]
|
47
|
+
# Only in shell commands types.
|
48
|
+
# If multiple isnt empty, Action will interprete multiple parameters as multiple values. That means, that gat expect
|
49
|
+
# that multiple paramters return an array of values. Gat::Action will loop and execute each shell_command with these parameters substitions
|
50
|
+
# For example, that is usefull to exec one command peer each File in one Dir.
|
51
|
+
#
|
52
|
+
# onfail: "<continue> || <abort>"
|
53
|
+
# What happens is action end with non 0 status
|
54
|
+
#
|
55
|
+
# onfail_message: "<onfail_message>"
|
56
|
+
# Custom message to be logged at error
|
57
|
+
#
|
58
|
+
# onfail_callback: "<on_fail_callback>"
|
59
|
+
# Custom ruby method that is executed if action fails
|
60
|
+
|
61
|
+
module Action
|
62
|
+
|
63
|
+
class Base
|
64
|
+
|
65
|
+
include Gat::Interpreter
|
66
|
+
|
67
|
+
attr_reader :operation
|
68
|
+
attr_reader :config
|
69
|
+
attr_reader :name
|
70
|
+
attr_reader :argument
|
71
|
+
attr_reader :description
|
72
|
+
attr_reader :flags
|
73
|
+
attr_accessor :error
|
74
|
+
|
75
|
+
|
76
|
+
attr_accessor :times
|
77
|
+
attr_accessor :output
|
78
|
+
attr_accessor :errors
|
79
|
+
attr_accessor :exit_level
|
80
|
+
|
81
|
+
attr_accessor :status
|
82
|
+
|
83
|
+
attr_accessor :parsed_syntax
|
84
|
+
|
85
|
+
attr_accessor :onfail
|
86
|
+
attr_accessor :onfail_message
|
87
|
+
attr_accessor :onfail_callback
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
# Get the current action
|
92
|
+
def self.get_current_action
|
93
|
+
@@current_action
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
def initialize(name, config, operation)
|
98
|
+
|
99
|
+
operation.gatget.logger.log("trace", "action", "Initialize action #{ self.class } @#{ name }")
|
100
|
+
|
101
|
+
@times = Hash.new
|
102
|
+
@times['init'] = Time.now
|
103
|
+
@operation = operation
|
104
|
+
@config = config
|
105
|
+
@name = name
|
106
|
+
@description = config['description'] || "Another Action named #{ name }"
|
107
|
+
@flags = config['flags'] || [ ]
|
108
|
+
@output = ''
|
109
|
+
@error = nil
|
110
|
+
|
111
|
+
@onfail = config['onfail'] || 'abort'
|
112
|
+
@onfail_message = config['onfail_message']
|
113
|
+
@onfail_callback = config['onfail_callback']
|
114
|
+
|
115
|
+
@@current_action = self
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
def execute
|
120
|
+
|
121
|
+
if self.execute?
|
122
|
+
|
123
|
+
self.run
|
124
|
+
|
125
|
+
#self.set_outputs
|
126
|
+
|
127
|
+
unless self.exit_level == 0
|
128
|
+
self.operation.gatget.logger.log("warning", "action_error", "#{self.error}")
|
129
|
+
self.operation.gatget.logger.log("warning", "action_error", "Action #{ self.name } finished with status #{self.exit_level}")
|
130
|
+
|
131
|
+
if self.onfail_callback
|
132
|
+
self.operation.gatget.send(self.onfail_callback)
|
133
|
+
end
|
134
|
+
|
135
|
+
if self.onfail == 'abort'
|
136
|
+
self.operation.gatget.logger.log('error', 'action_execute', "Action #{ self.name } abort Gatget")
|
137
|
+
self.operation.status = 'fail'
|
138
|
+
|
139
|
+
raise GatgetProcessException.new(self.error, "execute_action", self.onfail_message ? {:message => self.onfail_message} : {} )
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
@times['end'] = Time.now
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
# Execute? Method check if action must be executed. It test the follow conditions
|
150
|
+
# If flags is set, check that all flags are true
|
151
|
+
# If operation state is to abort or skip actions, skip actions
|
152
|
+
def execute?
|
153
|
+
flags_ok? and status_ok?
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
private
|
158
|
+
# Check if action flags are ok...
|
159
|
+
def flags_ok?
|
160
|
+
flags_ok = true
|
161
|
+
marker_flag = nil
|
162
|
+
|
163
|
+
if @flags and @flags.any?
|
164
|
+
@flags.each do |flag|
|
165
|
+
|
166
|
+
if flag[0..0] == '!'
|
167
|
+
compare_with = false
|
168
|
+
flag = flag.gsub(/^!/,'')
|
169
|
+
else
|
170
|
+
compare_with = true
|
171
|
+
end
|
172
|
+
|
173
|
+
unless self.operation.gatget.get_flag(flag) == compare_with
|
174
|
+
flags_ok = false
|
175
|
+
marker_flag = flag
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
unless flags_ok
|
181
|
+
self.operation.gatget.logger.log("message", "action", "Action #{ self.class } @#{ self.name } not mark to exec by flag: #{ marker_flag }")
|
182
|
+
end
|
183
|
+
flags_ok
|
184
|
+
end
|
185
|
+
|
186
|
+
def status_ok?
|
187
|
+
status_ok = self.operation.status == 'ok'
|
188
|
+
unless status_ok
|
189
|
+
self.operation.gatget.logger.log("message", "action", "Operation #{ self.operation.name } is not marked as OK. Actions are skipped")
|
190
|
+
end
|
191
|
+
status_ok
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
|
2
|
+
module Gat
|
3
|
+
module Action
|
4
|
+
class RubyMethod < Base
|
5
|
+
|
6
|
+
attr_accessor :status
|
7
|
+
|
8
|
+
def run
|
9
|
+
|
10
|
+
self.exec
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
def exec
|
16
|
+
self.operation.gatget.logger.log("trace", "action_syntax", "Action #{ self.name } exec ruby method." )
|
17
|
+
self.times['init'] ||= Time.now
|
18
|
+
|
19
|
+
begin
|
20
|
+
self.operation.gatget.send(self.name)
|
21
|
+
self.status = 'ok'
|
22
|
+
self.exit_level = 0
|
23
|
+
rescue => e
|
24
|
+
self.error = e
|
25
|
+
self.status = 'failed'
|
26
|
+
self.exit_level = 1
|
27
|
+
end
|
28
|
+
|
29
|
+
self.times['end'] ||= Time.now
|
30
|
+
self.exit_level
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
module Gat
|
2
|
+
module Action
|
3
|
+
|
4
|
+
class ShellCommand < Base
|
5
|
+
|
6
|
+
attr_reader :syntax
|
7
|
+
attr_reader :childs
|
8
|
+
attr_accessor :arguments
|
9
|
+
|
10
|
+
attr_accessor :pid
|
11
|
+
attr_accessor :status
|
12
|
+
|
13
|
+
def initialize(name, config, operation)
|
14
|
+
super(name, config, operation)
|
15
|
+
|
16
|
+
@syntax = config['syntax'] || raise(GatgetConfigException.new("Shell Command Action #{ name } has not a syntax attribute", "initialize_shell_command"))
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
def run
|
21
|
+
ret = nil
|
22
|
+
# Shell Command can be multiple, that means the command will be execute over a foreach variable subtitutions.
|
23
|
+
# That is usefull, for example, when you need to do the same actions with some variable subtition, like
|
24
|
+
# a multiple files compression.
|
25
|
+
@childs = (@config['multiple'] and @config['multiple'].any?) ? set_multiple_childs(@config['multiple']) : [ ]
|
26
|
+
|
27
|
+
# If ShellCommand is multiple, then, we exec all of its childs
|
28
|
+
# If not, we just execute ShellCommand instance
|
29
|
+
if @childs.any?
|
30
|
+
@childs.each { |child|
|
31
|
+
if not child.exec
|
32
|
+
ret = false
|
33
|
+
end
|
34
|
+
}
|
35
|
+
else
|
36
|
+
self.parsed_syntax = interpreter_parameters(self.syntax, self.operation.gatget)
|
37
|
+
ret = exec(self.parsed_syntax)
|
38
|
+
end
|
39
|
+
|
40
|
+
if self.config['output']
|
41
|
+
self.operation.gatget.logger.log("direct", "action_output", self.output)
|
42
|
+
end
|
43
|
+
ret
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
# Execute shell command with Open4
|
48
|
+
#
|
49
|
+
# Open4 module is the next generation Ruby module for executing shell commands.
|
50
|
+
# Open4 works better thant the standard Open3 module, and has built inside the feature
|
51
|
+
# to return exit status through Process.status Class.
|
52
|
+
# Even it has some problems too. Open4 module has big problems when the stdout or the stderr comes
|
53
|
+
# with tons of information. For example, with a mysqldump output.
|
54
|
+
#
|
55
|
+
# The solution presented here is a wapper through Process.fork. We create a new fork, making
|
56
|
+
# and the output is not managed by the ruby script itself but by the fork process.
|
57
|
+
# IO.pipes are created to pass the stdout, stderr and stdin data through Gat proccess and Fork process
|
58
|
+
#
|
59
|
+
# Some disccusion about this can be readed here: http://stackoverflow.com/questions/1076257/returning-data-from-forked-processes
|
60
|
+
#
|
61
|
+
# Maybe, we could use Theread.new, and maybe it would be better, but... =)
|
62
|
+
#
|
63
|
+
def exec(shell_command, multiple_name = '')
|
64
|
+
|
65
|
+
trap_save = trap( 0, "IGNORE" )
|
66
|
+
|
67
|
+
self.operation.gatget.logger.log("trace", "action_syntax", "Action #{ self.name }#{ multiple_name } exec command syntax : #{ shell_command }" )
|
68
|
+
|
69
|
+
self.times['init'] ||= Time.now
|
70
|
+
|
71
|
+
read_stdout, write_stdout = IO.pipe
|
72
|
+
read_stderr, write_stderr = IO.pipe
|
73
|
+
|
74
|
+
pid = fork do
|
75
|
+
trap( 0, "IGNORE" )
|
76
|
+
read_stdout.close
|
77
|
+
read_stderr.close
|
78
|
+
|
79
|
+
pid_open4, stdin, stdout, stderr = Open4::popen4 "#{ shell_command }"
|
80
|
+
|
81
|
+
write_stdout.puts stdout.read
|
82
|
+
write_stderr.puts stderr.read
|
83
|
+
|
84
|
+
ignored, status_open4 = Process::waitpid2 pid_open4
|
85
|
+
exit status_open4.exitstatus
|
86
|
+
end
|
87
|
+
trap( 0, trap_save )
|
88
|
+
|
89
|
+
write_stdout.close
|
90
|
+
write_stderr.close
|
91
|
+
|
92
|
+
result_stdout = read_stdout.read
|
93
|
+
result_stderr = read_stderr.read
|
94
|
+
|
95
|
+
pid, status = Process.wait2(pid)
|
96
|
+
|
97
|
+
self.output, self.error, self.exit_level = reinterpret_output_and_error(result_stdout, result_stderr, status.exitstatus)
|
98
|
+
|
99
|
+
self.pid = pid
|
100
|
+
self.status = status
|
101
|
+
self.times['end'] = Time.now
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
def set_multiple_childs(multiples_parameters)
|
106
|
+
# get multiples values
|
107
|
+
multiples_values = {}
|
108
|
+
multiples_parameters.each do |parameter|
|
109
|
+
values = interpreter_parameter(parameter, self.operation.gatget)
|
110
|
+
multiples_values[parameter] = values
|
111
|
+
end
|
112
|
+
|
113
|
+
# all multiple values must have the same size for substitution
|
114
|
+
last_multiple_vales_size = multiples_values.values.first.size
|
115
|
+
multiples_values.values.each do |values|
|
116
|
+
unless values.size == last_multiple_vales_size
|
117
|
+
raise GatgetConfigException.new("Multiples values at Action #{ self.name } doesnt have the same size. Substitution cannot be interpreted", "set_multiple_chids")
|
118
|
+
end
|
119
|
+
last_multiple_vales_size == values.size
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
unless last_multiple_vales_size > 0
|
124
|
+
raise GatgetConfigException.new("Multiples values at Action #{ self.name } are empty", "set_multiple_chids")
|
125
|
+
end
|
126
|
+
|
127
|
+
# create childs objects
|
128
|
+
childs = []
|
129
|
+
i = 0
|
130
|
+
last_multiple_vales_size.times do
|
131
|
+
child_multiple_parameters = {}
|
132
|
+
multiples_values.each_pair do |parameter, values|
|
133
|
+
child_multiple_parameters[parameter] = values[i]
|
134
|
+
end
|
135
|
+
childs << ShellCommandChild.new(self, child_multiple_parameters)
|
136
|
+
i += 1
|
137
|
+
end
|
138
|
+
|
139
|
+
# return child
|
140
|
+
childs
|
141
|
+
end
|
142
|
+
|
143
|
+
# Redefine this two methods in your class to clean or reinterpret the output and error
|
144
|
+
def reinterpret_output_and_error(output, error, status)
|
145
|
+
return output == "\n" ? "" : output,
|
146
|
+
error == "\n" ? "" : error, status
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
class ShellCommandChild
|
153
|
+
include Gat::Interpreter
|
154
|
+
|
155
|
+
attr_reader :parent
|
156
|
+
attr_reader :syntax
|
157
|
+
attr_reader :values
|
158
|
+
attr_reader :name
|
159
|
+
|
160
|
+
attr_accessor :syntax
|
161
|
+
attr_accessor :arguments
|
162
|
+
|
163
|
+
|
164
|
+
def initialize(parent, values)
|
165
|
+
@parent = parent
|
166
|
+
@values = values
|
167
|
+
|
168
|
+
|
169
|
+
@syntax = parent.syntax
|
170
|
+
@name = "#{ parent.name }*over* #{ values.values.join("_") }"
|
171
|
+
end
|
172
|
+
|
173
|
+
def exec
|
174
|
+
# make the substitution of each parameter and exec like other action
|
175
|
+
values.each_pair do |parameter_key, parameter_value |
|
176
|
+
self.syntax = self.syntax.gsub(/\{\{#{ parameter_key }\}\}/, parameter_value)
|
177
|
+
end
|
178
|
+
|
179
|
+
parse_syntax = interpreter_parameters(self.syntax, self.parent.operation.gatget)
|
180
|
+
self.parent.exec(parse_syntax, " *over* #{ values.values.join("_") }")
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
data/lib/gat/boot.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
:file => boot.rb
|
4
|
+
:author => (c) 2008-2009 A.C. Gnoxys info@gnoxys.net
|
5
|
+
|
6
|
+
######################################################################################
|
7
|
+
## This file is part of GAT: http://gat.rubyforge.org ##
|
8
|
+
## ##
|
9
|
+
## GAT (Gnoxys Administration Tools) is released under the GPL License 3 or higher. ##
|
10
|
+
## You can get a copy of the license easily at http://www.gnu.org/licenses/gpl.html.##
|
11
|
+
######################################################################################
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
14
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
15
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
16
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
17
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
18
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
19
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
|
21
|
+
=end
|
22
|
+
|
23
|
+
|
24
|
+
# Boot File provides the starting point to execute gatget based script.
|
25
|
+
#
|
26
|
+
# Boot load required modules && classes for Gat::Base and other gems.
|
27
|
+
# Differents exit levels are launched if requires files fails.
|
28
|
+
#
|
29
|
+
# Gat constants
|
30
|
+
GAT_GATGETS = GAT_ROOT + '/gatgets'
|
31
|
+
GAT_TEMPLATES = GAT_ROOT + '/templates'
|
32
|
+
|
33
|
+
# External gems
|
34
|
+
gems = [ 'ftools', 'rubygems', 'open4', 'yaml', 'erb', 'rdoc/usage', 'rdoc/code_objects',
|
35
|
+
'rdoc/markup/simple_markup', 'rdoc/markup/simple_markup/to_flow', 'rdoc/ri/ri_formatter',
|
36
|
+
'rdoc/ri/ri_options', 'net/smtp', 'tmail', 'erb' ]
|
37
|
+
|
38
|
+
# Gat Modules
|
39
|
+
modules = [ 'debug', 'help', 'interpreter', 'extends', 'version', 'launcher', 'checks', 'email' ]
|
40
|
+
|
41
|
+
# Gat Classes
|
42
|
+
classes = [ 'exceptions', 'operation', 'dependence/base', 'dependence/program', 'dependence/argument', 'dependence/folder',
|
43
|
+
'action/base.rb', 'action/shell_command.rb', 'action/ruby_method.rb', 'logger' ]
|
44
|
+
|
45
|
+
|
46
|
+
# Build required hash
|
47
|
+
load_data = { 'gems' => { 'data' => gems, 'path' => '', 'exit' => 9 },
|
48
|
+
'modules' => { 'data' => modules, 'path' => "#{ GAT_ROOT + '/lib/gat/' }", 'exit' => 10 },
|
49
|
+
'classes' => { 'data' => classes, 'path' => "#{ GAT_ROOT + '/lib/gat/' }", 'exit' => 11 } }
|
50
|
+
|
51
|
+
# Require all data
|
52
|
+
load_data.each_pair do |key, value|
|
53
|
+
value['data'].each do |dependency|
|
54
|
+
begin
|
55
|
+
require value['path'] + dependency
|
56
|
+
rescue LoadError => msg
|
57
|
+
$stderr.puts "Error while loading #{ key }: #{ msg }"
|
58
|
+
$stderr.puts "[ ERROR ] Backtrace \n" + msg.backtrace.join("\n")
|
59
|
+
$stderr.puts "\nexit level #{ value['exit'] }"
|
60
|
+
exit value['exit']
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|