em-langrove 0.0.4.5
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/.rspec +1 -0
- data/.rvmrc +62 -0
- data/.watchr +27 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +61 -0
- data/Rakefile +24 -0
- data/bin/langrove +3 -0
- data/functional/config/boot.rb +64 -0
- data/functional/config/daemons.yml +13 -0
- data/functional/config/environment.rb +28 -0
- data/functional/config/environments/development.rb +0 -0
- data/functional/config/environments/production.rb +0 -0
- data/functional/config/environments/test.rb +0 -0
- data/functional/lib/client/socket_to_file.rb +47 -0
- data/functional/lib/daemon/datagram.rb +21 -0
- data/functional/lib/protocol/socket_to_file.rb +55 -0
- data/functional/libexec/daemon.rb +68 -0
- data/functional/tmp/README +1 -0
- data/lib/langrove/_base.rb +28 -0
- data/lib/langrove/adaptor/base.rb +2 -0
- data/lib/langrove/adaptor_base.rb +116 -0
- data/lib/langrove/client/base.rb +2 -0
- data/lib/langrove/client/datagram.rb +25 -0
- data/lib/langrove/client_base.rb +92 -0
- data/lib/langrove/daemon/base.rb +2 -0
- data/lib/langrove/daemon_base.rb +281 -0
- data/lib/langrove/ext/class_loader.rb +148 -0
- data/lib/langrove/ext/config_item.rb +34 -0
- data/lib/langrove/ext/config_loader.rb +16 -0
- data/lib/langrove/ext/fake_logger.rb +8 -0
- data/lib/langrove/ext/find.rb +90 -0
- data/lib/langrove/ext/persistable.rb +103 -0
- data/lib/langrove/ext/string.rb +35 -0
- data/lib/langrove/ext.rb +7 -0
- data/lib/langrove/handler/base.rb +2 -0
- data/lib/langrove/handler_base.rb +148 -0
- data/lib/langrove/job/base.rb +1 -0
- data/lib/langrove/job_base.rb +24 -0
- data/lib/langrove/protocol/base.rb +2 -0
- data/lib/langrove/protocol/syslog.rb +32 -0
- data/lib/langrove/protocol_base.rb +32 -0
- data/lib/langrove/version.rb +3 -0
- data/lib/langrove.rb +1 -0
- data/spec/functional/daemon/datagram_spec.rb +121 -0
- data/spec/langrove/adaptor_base_spec.rb +63 -0
- data/spec/langrove/client/datagram_spec.rb +1 -0
- data/spec/langrove/client_base_spec.rb +5 -0
- data/spec/langrove/daemon_base_spec.rb +154 -0
- data/spec/langrove/ext/class_loader_spec.rb +83 -0
- data/spec/langrove/ext/config_item_spec.rb +81 -0
- data/spec/langrove/ext/config_loader_spec.rb +5 -0
- data/spec/langrove/ext/fake_logger_spec.rb +0 -0
- data/spec/langrove/ext/find_spec.rb +53 -0
- data/spec/langrove/ext/persistable_spec.rb +117 -0
- data/spec/langrove/ext/string_spec.rb +16 -0
- data/spec/langrove/handler_base_spec.rb +103 -0
- data/spec/langrove/job_base_spec.rb +28 -0
- data/spec/langrove/protocol/syslog_spec.rb +45 -0
- data/spec/langrove/protocol_base_spec.rb +6 -0
- data/spec/todo_spec.rb +12 -0
- data/tmp/README +2 -0
- metadata +203 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'langrove'
|
3
|
+
|
4
|
+
module LanGrove
|
5
|
+
|
6
|
+
module Client
|
7
|
+
|
8
|
+
class Base < EventMachine::Connection
|
9
|
+
|
10
|
+
#
|
11
|
+
# Misnomer.
|
12
|
+
#
|
13
|
+
#
|
14
|
+
# This is not the client,
|
15
|
+
#
|
16
|
+
#
|
17
|
+
# It is the server's perspective of the client,
|
18
|
+
#
|
19
|
+
# These are generally stored in the daemon's
|
20
|
+
# handler collection,
|
21
|
+
#
|
22
|
+
# Which contains this and all similar clients,
|
23
|
+
#
|
24
|
+
# Each bonded through the daemon's connection
|
25
|
+
# adaptor to the socket that couples them to
|
26
|
+
# their actual client..
|
27
|
+
#
|
28
|
+
|
29
|
+
attr_accessor :handler
|
30
|
+
attr_accessor :protocol
|
31
|
+
attr_accessor :config
|
32
|
+
attr_accessor :logger
|
33
|
+
|
34
|
+
|
35
|
+
#
|
36
|
+
# Data arriving through the Adaptor is passed
|
37
|
+
# through the config assigned protocol and
|
38
|
+
# then arrives here in whatever format the
|
39
|
+
# <Protocol>.decode() method returned.
|
40
|
+
#
|
41
|
+
#
|
42
|
+
def receive( decoded_data )
|
43
|
+
|
44
|
+
#
|
45
|
+
# OVERRIDE
|
46
|
+
#
|
47
|
+
# - Inbound data arrived at the adaptor
|
48
|
+
#
|
49
|
+
# - It has passed through the protocol as
|
50
|
+
# defined in config.
|
51
|
+
#
|
52
|
+
# The protocol should have arranged the data
|
53
|
+
# into a Hash of:
|
54
|
+
#
|
55
|
+
# - key and value pairs
|
56
|
+
#
|
57
|
+
# - key and more_complicated_thing pairs.
|
58
|
+
#
|
59
|
+
# - The decoded data was then passed into
|
60
|
+
# this function.
|
61
|
+
#
|
62
|
+
#
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
def receive_data( data )
|
67
|
+
|
68
|
+
#
|
69
|
+
# Event machine writes into here at receiving data
|
70
|
+
# from the client.
|
71
|
+
#
|
72
|
+
|
73
|
+
receive( @protocol.decode( data ) )
|
74
|
+
|
75
|
+
#
|
76
|
+
# ?Multi-message protocol?
|
77
|
+
#
|
78
|
+
# @protocol.accumulate( multi_message_part, self )
|
79
|
+
#
|
80
|
+
# ---- With protocol responding directly to source
|
81
|
+
#
|
82
|
+
# ---- With protocol then calling receive_decoded()
|
83
|
+
# via the self being passed in.
|
84
|
+
#
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
@@ -0,0 +1,281 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
|
3
|
+
require 'langrove'
|
4
|
+
|
5
|
+
module LanGrove::Daemon class Base
|
6
|
+
|
7
|
+
def listen
|
8
|
+
|
9
|
+
#
|
10
|
+
# <Client> and <Protocol> are passed into
|
11
|
+
# the Adaptor.listen for binding onto the
|
12
|
+
# sockets at connect.
|
13
|
+
#
|
14
|
+
@adaptor.listen(
|
15
|
+
|
16
|
+
#
|
17
|
+
# pass Client, Protocol and Handler to 'listener'
|
18
|
+
#
|
19
|
+
|
20
|
+
{ :class => @client, :config => @my_config[ :client ] },
|
21
|
+
|
22
|
+
{ :class => @protocol, :config => @my_config[ :protocol ] },
|
23
|
+
|
24
|
+
@handler
|
25
|
+
|
26
|
+
)
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
def stop_daemon
|
31
|
+
|
32
|
+
#
|
33
|
+
# Handle stopping daemon
|
34
|
+
#
|
35
|
+
@logger.info "#{self} received stop_daemon"
|
36
|
+
@handler.stop_daemon
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
def reload_daemon
|
41
|
+
|
42
|
+
#
|
43
|
+
# TODO: Handle reloading daemon properly
|
44
|
+
#
|
45
|
+
# [ !!complexities abound around reloading config!! ]
|
46
|
+
#
|
47
|
+
|
48
|
+
@logger.info "#{self} received reload_daemon"
|
49
|
+
@handler.reload_daemon
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
def schedule
|
54
|
+
|
55
|
+
@logger.info "#{self} Scheduling periodic ...TODO..."
|
56
|
+
|
57
|
+
EM::add_periodic_timer( @my_config[ :periodic ] ) do
|
58
|
+
|
59
|
+
#
|
60
|
+
# TODO: This can be a lot more usefull than
|
61
|
+
# then one ticker to one function call
|
62
|
+
#
|
63
|
+
|
64
|
+
@handler.periodic
|
65
|
+
|
66
|
+
end if @my_config.has_key? :periodic
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
def run
|
71
|
+
|
72
|
+
EventMachine::run do
|
73
|
+
|
74
|
+
#
|
75
|
+
# https://github.com/eventmachine/eventmachine/wiki/Protocol-Implementations
|
76
|
+
#
|
77
|
+
|
78
|
+
schedule
|
79
|
+
|
80
|
+
listen if @server
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
def initialize( config_hash, daemon_name, logger )
|
87
|
+
|
88
|
+
@config = config_hash
|
89
|
+
@daemon_name = daemon_name
|
90
|
+
@logger = logger
|
91
|
+
@server = true
|
92
|
+
|
93
|
+
#
|
94
|
+
# A network connection.
|
95
|
+
#
|
96
|
+
@adaptor = nil
|
97
|
+
|
98
|
+
#
|
99
|
+
# The client collection class.
|
100
|
+
#
|
101
|
+
@handler = nil
|
102
|
+
|
103
|
+
#
|
104
|
+
# The client type
|
105
|
+
#
|
106
|
+
@client = nil
|
107
|
+
|
108
|
+
#
|
109
|
+
# The protocol type
|
110
|
+
#
|
111
|
+
@protocol = nil
|
112
|
+
|
113
|
+
|
114
|
+
begin
|
115
|
+
|
116
|
+
@logger.info "Starting daemon: #{@daemon_name}"
|
117
|
+
|
118
|
+
rescue
|
119
|
+
|
120
|
+
#
|
121
|
+
# you shall not pass
|
122
|
+
#
|
123
|
+
raise LanGrove::DaemonConfigException.new( "Requires a logger" )
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
begin
|
128
|
+
|
129
|
+
@my_config = @config[ :daemons ][ @daemon_name ]
|
130
|
+
|
131
|
+
@server = @my_config[ :server ] if @my_config.has_key? :server
|
132
|
+
|
133
|
+
|
134
|
+
|
135
|
+
if @my_config[ :adaptor ].has_key? :class
|
136
|
+
|
137
|
+
adaptor = @my_config[ :adaptor ][ :class ]
|
138
|
+
|
139
|
+
else
|
140
|
+
|
141
|
+
@logger.warn( "Defaulting to Adaptor::Base" )
|
142
|
+
adaptor = 'Base'
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
@logger.info "TODO: fall back to default Handler::Base"
|
149
|
+
|
150
|
+
handler = @my_config[ :handler ][ :collection ]
|
151
|
+
|
152
|
+
client = @my_config[ :client ][ :class ]
|
153
|
+
|
154
|
+
protocol = @my_config[ :protocol ][ :class ]
|
155
|
+
|
156
|
+
@logger.info "TODO: Warn instead of raise and allow nil into ClassLoader -> load default"
|
157
|
+
|
158
|
+
rescue
|
159
|
+
|
160
|
+
error = "Missing config item for daemon: #{@daemon_name}"
|
161
|
+
|
162
|
+
@logger.error "EXIT: #{error}"
|
163
|
+
|
164
|
+
raise LanGrove::DaemonConfigException.new(
|
165
|
+
|
166
|
+
"Missing config item for daemon: #{@daemon_name}"
|
167
|
+
|
168
|
+
)
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
|
173
|
+
#
|
174
|
+
# initialize the connection adaptor specified in config
|
175
|
+
#
|
176
|
+
# daemons:
|
177
|
+
# name_of_daemon:
|
178
|
+
# adaptor:
|
179
|
+
# class: MySocket <----------( optional )
|
180
|
+
# transport: tcp|udp
|
181
|
+
# iface: N.N.n.n
|
182
|
+
# port: nNn
|
183
|
+
# handler:
|
184
|
+
# collection: CollectionOfClients
|
185
|
+
#
|
186
|
+
|
187
|
+
@logger.info "CREATE: Adaptor::#{adaptor}.new( @my_config[ :adaptor ], logger )"
|
188
|
+
|
189
|
+
@adaptor = LanGrove::ClassLoader.create( {
|
190
|
+
|
191
|
+
:module => 'Adaptor',
|
192
|
+
:class => adaptor
|
193
|
+
|
194
|
+
} ).new( @my_config[ :adaptor ], logger )
|
195
|
+
|
196
|
+
|
197
|
+
#
|
198
|
+
# bind to the handler collection specified in config
|
199
|
+
#
|
200
|
+
# daemons:
|
201
|
+
# name_of_daemon:
|
202
|
+
# adaptor:
|
203
|
+
# connection: TcpServer
|
204
|
+
# handler:
|
205
|
+
# collection: CollectionOfClients <----------
|
206
|
+
#
|
207
|
+
# CollectionOfClients ---> is the handler passed into listen()
|
208
|
+
#
|
209
|
+
|
210
|
+
@logger.info "CREATE: Handler::#{handler}.new( config_hash, '#{daemon_name}', logger )"
|
211
|
+
|
212
|
+
@handler = LanGrove::ClassLoader.create( {
|
213
|
+
|
214
|
+
:module => 'Handler',
|
215
|
+
:class => handler
|
216
|
+
|
217
|
+
} ).new( @config, @daemon_name, @logger )
|
218
|
+
|
219
|
+
|
220
|
+
#
|
221
|
+
# initialize the client specified in config
|
222
|
+
#
|
223
|
+
# daemons:
|
224
|
+
# name_of_daemon:
|
225
|
+
# client:
|
226
|
+
# class: Client <---------
|
227
|
+
# adaptor:
|
228
|
+
# connection: TcpServer
|
229
|
+
# handler:
|
230
|
+
# collection: CollectionOfClients
|
231
|
+
#
|
232
|
+
#
|
233
|
+
|
234
|
+
@logger.info "DEFINE: Client::#{client}"
|
235
|
+
|
236
|
+
@client = LanGrove::ClassLoader.create( {
|
237
|
+
|
238
|
+
:module => 'Client',
|
239
|
+
:class => client
|
240
|
+
|
241
|
+
} )
|
242
|
+
|
243
|
+
|
244
|
+
#
|
245
|
+
# initialize the client specified in config
|
246
|
+
#
|
247
|
+
# daemons:
|
248
|
+
# name_of_daemon:
|
249
|
+
# protocol:
|
250
|
+
# class: Protocol <---------
|
251
|
+
# more: config
|
252
|
+
# client:
|
253
|
+
# class: Client
|
254
|
+
# adaptor:
|
255
|
+
# connection: TcpServer
|
256
|
+
# handler:
|
257
|
+
# collection: CollectionOfClients
|
258
|
+
#
|
259
|
+
#
|
260
|
+
|
261
|
+
@logger.info "DEFINE: Protocol::#{protocol}"
|
262
|
+
|
263
|
+
@protocol = LanGrove::ClassLoader.create( {
|
264
|
+
|
265
|
+
:module => 'Protocol',
|
266
|
+
:class => protocol
|
267
|
+
|
268
|
+
} )
|
269
|
+
|
270
|
+
|
271
|
+
#
|
272
|
+
# Notifiy the handler
|
273
|
+
#
|
274
|
+
# About to go to listen...
|
275
|
+
#
|
276
|
+
|
277
|
+
@handler.start_daemon
|
278
|
+
|
279
|
+
end
|
280
|
+
|
281
|
+
end; end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'langrove/ext/string'
|
2
|
+
module LanGrove
|
3
|
+
|
4
|
+
class ClassLoaderException < Exception; end
|
5
|
+
|
6
|
+
class ClassLoader
|
7
|
+
|
8
|
+
def self.create( class_config, logger = nil )
|
9
|
+
|
10
|
+
logger.info( "#{self} is loading Class with #{class_config.inspect}" ) unless logger.nil?
|
11
|
+
|
12
|
+
#
|
13
|
+
# When <config> = {
|
14
|
+
#
|
15
|
+
# :module => 'ModuleName'
|
16
|
+
# :class => 'ClassName'
|
17
|
+
#
|
18
|
+
# }
|
19
|
+
#
|
20
|
+
# Then this will return the constantized
|
21
|
+
# definition instance of ClassName as
|
22
|
+
# loaded from the F1RST found .rb file
|
23
|
+
# according to:
|
24
|
+
#
|
25
|
+
# - lib/module_name/class_name.rb
|
26
|
+
# - langrove/module_name/class_name.rb
|
27
|
+
#
|
28
|
+
# Which then facilitates the following
|
29
|
+
# construct:
|
30
|
+
#
|
31
|
+
# planet = ClassLoader.create(
|
32
|
+
#
|
33
|
+
# :module => 'Planet',
|
34
|
+
# :class => 'Mercury'
|
35
|
+
#
|
36
|
+
# ).new( *initializer_parameters )
|
37
|
+
#
|
38
|
+
|
39
|
+
raise ClassLoaderException.new(
|
40
|
+
|
41
|
+
"class_config requires :module"
|
42
|
+
|
43
|
+
) unless class_config.has_key? :module
|
44
|
+
|
45
|
+
raise ClassLoaderException.new(
|
46
|
+
|
47
|
+
"class_config requires :class"
|
48
|
+
|
49
|
+
) unless class_config.has_key? :class
|
50
|
+
|
51
|
+
|
52
|
+
module_name = class_config[:module]
|
53
|
+
class_name = class_config[:class]
|
54
|
+
|
55
|
+
|
56
|
+
#
|
57
|
+
# SIGNIFICANT DECISION
|
58
|
+
#
|
59
|
+
# - Late binding to the extent of also calling
|
60
|
+
# to require the actual class.rb file could
|
61
|
+
# potentially be avoided by
|
62
|
+
#
|
63
|
+
# << using this layer in the abstraction >>
|
64
|
+
#
|
65
|
+
# to do the necessary requiring for the specific
|
66
|
+
# daemon being spawned.
|
67
|
+
#
|
68
|
+
# - Obviously there are downsides to eval...
|
69
|
+
#
|
70
|
+
# - But there are upsides to having this layer
|
71
|
+
# totally aliteral - it leaves the window open
|
72
|
+
# to the later posibility of collecting the class
|
73
|
+
# definition itself from across the network.
|
74
|
+
#
|
75
|
+
#
|
76
|
+
# Which was the cental purpose behind daemons
|
77
|
+
# by configuration in the first place.
|
78
|
+
#
|
79
|
+
# Taking latebinding to a whole new level...
|
80
|
+
#
|
81
|
+
|
82
|
+
|
83
|
+
#
|
84
|
+
# First try local implementation root
|
85
|
+
#
|
86
|
+
|
87
|
+
exception = nil
|
88
|
+
|
89
|
+
location = nil
|
90
|
+
|
91
|
+
begin
|
92
|
+
|
93
|
+
location = "#{module_name.underscore}/#{class_name.underscore}"
|
94
|
+
|
95
|
+
eval "require '#{location}'"
|
96
|
+
|
97
|
+
return Object.const_get( module_name ).const_get( class_name )
|
98
|
+
|
99
|
+
rescue LoadError => e
|
100
|
+
|
101
|
+
exception = e
|
102
|
+
|
103
|
+
logger.error "Missing class definition in lib/#{location}.rb" unless logger.nil?
|
104
|
+
|
105
|
+
#rescue Exception => e
|
106
|
+
#
|
107
|
+
# #
|
108
|
+
# # Incase of more... (discovery phase)
|
109
|
+
# #
|
110
|
+
#
|
111
|
+
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
#
|
116
|
+
# Fall back to langrove gem lib
|
117
|
+
#
|
118
|
+
|
119
|
+
begin
|
120
|
+
|
121
|
+
path = File.expand_path('../../', __FILE__)
|
122
|
+
|
123
|
+
location = "#{path}/#{module_name.underscore}/#{class_name.underscore}"
|
124
|
+
|
125
|
+
eval "require '#{location}'"
|
126
|
+
|
127
|
+
return LanGrove.const_get( module_name ).const_get( class_name )
|
128
|
+
|
129
|
+
rescue Exception => e
|
130
|
+
|
131
|
+
#
|
132
|
+
# Raise from the original exception to
|
133
|
+
# inform the local implementation
|
134
|
+
# it is missing a module/class .rb
|
135
|
+
# "no such file 'module/class"
|
136
|
+
#
|
137
|
+
# And not confuse the issue by raising
|
138
|
+
# "no such file 'langrove/module/class"
|
139
|
+
#
|
140
|
+
raise ClassLoaderException.new "#{exception.message}.rb"
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
module LanGrove class ConfigException < Exception; end; end
|
3
|
+
|
4
|
+
module LanGrove class ConfigItem
|
5
|
+
|
6
|
+
def self.get(config_hash, key_array, mandatory = true)
|
7
|
+
|
8
|
+
# raise ConfigException.new("match")
|
9
|
+
|
10
|
+
hash = config_hash
|
11
|
+
|
12
|
+
key_array.each do |key|
|
13
|
+
|
14
|
+
if mandatory != false then
|
15
|
+
# raises a config exception if the item isnt present
|
16
|
+
raise ConfigException.new("Missing config item '#{key}'") unless hash.has_key?(key)
|
17
|
+
|
18
|
+
# raises a config exception if the nested item isnt present NEITHER NOT
|
19
|
+
# raise ConfigException.new("Missing config item '#{key}'") if hash[key].empty?
|
20
|
+
|
21
|
+
hash = hash[key]
|
22
|
+
|
23
|
+
# raises a config exception if the key isnt present BLANK NEITHER
|
24
|
+
raise ConfigException.new("Missing config item '#{key}'") if hash == ""
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
return hash
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end; end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module LanGrove
|
2
|
+
|
3
|
+
class Find
|
4
|
+
|
5
|
+
def self.with( arg_hash , &block )
|
6
|
+
|
7
|
+
type = :file
|
8
|
+
@path = '.'
|
9
|
+
|
10
|
+
#
|
11
|
+
# TODO: filter
|
12
|
+
#
|
13
|
+
|
14
|
+
@incl = nil
|
15
|
+
|
16
|
+
@relative = false
|
17
|
+
|
18
|
+
|
19
|
+
arg_hash.each do |key, value|
|
20
|
+
|
21
|
+
case key
|
22
|
+
|
23
|
+
when :type
|
24
|
+
|
25
|
+
type = value
|
26
|
+
|
27
|
+
when :path
|
28
|
+
|
29
|
+
@path = value
|
30
|
+
|
31
|
+
when :include
|
32
|
+
|
33
|
+
@incl = value
|
34
|
+
|
35
|
+
when :relative
|
36
|
+
|
37
|
+
@relative = value
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
self.send( :"find_#{type}", @path, &block )
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.find_file( path, &block )
|
49
|
+
|
50
|
+
puts "in #{path}"
|
51
|
+
|
52
|
+
Dir.entries( path ).each do | sub |
|
53
|
+
|
54
|
+
next if sub == '.'
|
55
|
+
next if sub == '..'
|
56
|
+
|
57
|
+
subdir = "#{path}/#{sub}"
|
58
|
+
|
59
|
+
begin
|
60
|
+
|
61
|
+
if @incl.nil? then
|
62
|
+
|
63
|
+
yield relative(subdir) if block
|
64
|
+
|
65
|
+
else
|
66
|
+
|
67
|
+
yield relative(subdir) unless /#{@incl}/.match( subdir ).nil?
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
next
|
72
|
+
|
73
|
+
end if File.file?( subdir ) and block
|
74
|
+
|
75
|
+
find_file( subdir, &block )
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.relative( file_path )
|
82
|
+
|
83
|
+
return file_path.gsub( "#{@path}/",'' ) if @relative
|
84
|
+
return file_path
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|