warningshot 0.9.4
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/CHANGELOG +0 -0
- data/CONTRIBUTORS +2 -0
- data/LICENSE +22 -0
- data/README +101 -0
- data/Rakefile +28 -0
- data/TODO +148 -0
- data/bin/warningshot +19 -0
- data/bin/ws-stage.bat +3 -0
- data/bin/ws-stage.sh +3 -0
- data/images/warning_shot.png +0 -0
- data/images/warning_shot_sml.png +0 -0
- data/images/warningshot_green.png +0 -0
- data/images/warningshot_red.png +0 -0
- data/lib/core_ext/hash.rb +14 -0
- data/lib/core_ext/kernel.rb +8 -0
- data/lib/core_ext/object.rb +7 -0
- data/lib/core_ext/string.rb +5 -0
- data/lib/resolvers/core_lib_resolver.rb +76 -0
- data/lib/resolvers/directory_resolver.rb +31 -0
- data/lib/resolvers/file_resolver.rb +87 -0
- data/lib/resolvers/gem_resolver.rb +94 -0
- data/lib/resolvers/integrity_resolver.rb +69 -0
- data/lib/resolvers/manual_resolver.rb +19 -0
- data/lib/resolvers/permission_resolver.rb +72 -0
- data/lib/resolvers/symlink_resolver.rb +43 -0
- data/lib/resolvers/url_resolver.rb +76 -0
- data/lib/warning_shot/config.rb +132 -0
- data/lib/warning_shot/dependency_resolver.rb +155 -0
- data/lib/warning_shot/growl.rb +14 -0
- data/lib/warning_shot/logger.rb +27 -0
- data/lib/warning_shot/resolver.rb +542 -0
- data/lib/warning_shot/template_generator.rb +28 -0
- data/lib/warning_shot/version.rb +7 -0
- data/lib/warning_shot/warning_shot.rb +130 -0
- data/lib/warningshot.rb +16 -0
- data/tasks/gemspec.rb +48 -0
- data/tasks/rpsec.rb +58 -0
- data/tasks/yard.rb +4 -0
- data/templates/binaries.yml +26 -0
- data/templates/core_libs.yml +18 -0
- data/templates/directories.yml +23 -0
- data/templates/files.yml +18 -0
- data/templates/gems.yml +26 -0
- data/templates/manual.yml +29 -0
- data/templates/mounts.yml +8 -0
- data/templates/permissions.yml +31 -0
- data/templates/symlinks.yml +30 -0
- data/templates/urls.yml +21 -0
- data/test/data/mock.yaml +16 -0
- data/test/data/mock.yml +10 -0
- data/test/data/mock_resolver.rb +16 -0
- data/test/data/permission_test.txt +1 -0
- data/test/data/resolvers/file/src/that.txt +1 -0
- data/test/log/warningshot.log +643 -0
- data/test/spec/spec.opts.zoiks +0 -0
- data/test/spec/spec_helper.rb +11 -0
- data/test/spec/unit/resolvers/core_lib_resolver_spec.rb +39 -0
- data/test/spec/unit/resolvers/directory_resolver_spec.rb +39 -0
- data/test/spec/unit/resolvers/file_resolver_spec.rb +134 -0
- data/test/spec/unit/resolvers/gem_resolver_spec.rb +74 -0
- data/test/spec/unit/resolvers/integrity_resolver_spec.rb +103 -0
- data/test/spec/unit/resolvers/manual_resolver_spec.rb +17 -0
- data/test/spec/unit/resolvers/permission_resolver_spec.rb +56 -0
- data/test/spec/unit/resolvers/symlink_resolver_spec.rb +44 -0
- data/test/spec/unit/resolvers/url_resolver_spec.rb +64 -0
- data/test/spec/unit/warning_shot/config_spec.rb +35 -0
- data/test/spec/unit/warning_shot/dependency_resolver_spec.rb +43 -0
- data/test/spec/unit/warning_shot/resolver_spec.rb +347 -0
- data/test/spec/unit/warning_shot/template_generator_spec.rb +21 -0
- data/test/spec/unit/warning_shot/version_spec.rb +7 -0
- data/test/spec/unit/warning_shot/warning_shot_spec.rb +3 -0
- metadata +143 -0
@@ -0,0 +1,542 @@
|
|
1
|
+
# API access for resolvers
|
2
|
+
#
|
3
|
+
# @example
|
4
|
+
# require 'warningshot'
|
5
|
+
# class MyCustomResolver
|
6
|
+
# include WarningShot::Resolver
|
7
|
+
# end
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
module WarningShot
|
11
|
+
module Resolver
|
12
|
+
module ClassMethods
|
13
|
+
attr_reader :raw_cli_ext
|
14
|
+
|
15
|
+
# extends command line interface
|
16
|
+
#
|
17
|
+
# @param opts [Hash]
|
18
|
+
# Keys and example values
|
19
|
+
# :short => "-s",
|
20
|
+
# :long => "--longflag",
|
21
|
+
# :default => "my_value",
|
22
|
+
# :description => "Command line description",
|
23
|
+
# :name => "keyname", #required
|
24
|
+
# :type => String #[:list, :of, :available, :values]
|
25
|
+
# :default_desc => "Default: my_value"
|
26
|
+
# @api public
|
27
|
+
def cli(opts)
|
28
|
+
@raw_cli_ext ||= []
|
29
|
+
#Do not extend the interface if the class is being
|
30
|
+
return if self.disabled?
|
31
|
+
|
32
|
+
##A keyname for the option is required
|
33
|
+
return if opts[:name].nil?
|
34
|
+
@raw_cli_ext << opts
|
35
|
+
|
36
|
+
clean_opts = [
|
37
|
+
opts[:short],
|
38
|
+
opts[:long],
|
39
|
+
opts[:type],
|
40
|
+
opts[:description],
|
41
|
+
opts[:default_desc]
|
42
|
+
]
|
43
|
+
clean_opts.delete(nil)
|
44
|
+
|
45
|
+
#Set the default value if it was given
|
46
|
+
opt_name = opts[:name].intern
|
47
|
+
WarningShot::Config[opt_name] = opts[:default]
|
48
|
+
|
49
|
+
WarningShot.parser.on_tail(*clean_opts) do |val|
|
50
|
+
WarningShot::Config[opt_name] = val
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
# Setter/Getter for resolver branch,
|
56
|
+
# used in outputting info and for determine which yaml to apply
|
57
|
+
#
|
58
|
+
# @param b [~to_s]
|
59
|
+
# branch in dependency tree to use
|
60
|
+
#
|
61
|
+
# @return [String]
|
62
|
+
# Resolver's branch
|
63
|
+
#
|
64
|
+
# @example
|
65
|
+
# class MyResolver
|
66
|
+
# include WarningShot::Resolver
|
67
|
+
# branch :mock
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# @api public
|
71
|
+
def branch(b=nil)
|
72
|
+
@branch = b unless b.nil?
|
73
|
+
@branch
|
74
|
+
end
|
75
|
+
|
76
|
+
# Setter/Getter for resolver description,
|
77
|
+
#
|
78
|
+
# @param d [~to_s]
|
79
|
+
# Resolver's description
|
80
|
+
#
|
81
|
+
# @return [String]
|
82
|
+
# Resolver's description
|
83
|
+
#
|
84
|
+
# @example
|
85
|
+
# class MyResolver
|
86
|
+
# include WarningShot::Resolver
|
87
|
+
# description 'Mock resolver for rspec testing'
|
88
|
+
# end
|
89
|
+
#
|
90
|
+
# @api public
|
91
|
+
def description(d=nil)
|
92
|
+
@description = d unless d.nil?
|
93
|
+
@description
|
94
|
+
end
|
95
|
+
|
96
|
+
# Setter/Getter for resolver order,
|
97
|
+
# determines order in which resolver is checked
|
98
|
+
#
|
99
|
+
# @param p [Fixnum] (optional; default 100)
|
100
|
+
# Resolver's order, lower the earlier it is run
|
101
|
+
#
|
102
|
+
# @return [Fixnum]
|
103
|
+
# Resolver's order
|
104
|
+
#
|
105
|
+
# @example
|
106
|
+
# class MyResolver
|
107
|
+
# include WarningShot::Resolver
|
108
|
+
# order 1 # Would attempt to run this resolver check first
|
109
|
+
# #order 1000
|
110
|
+
# end
|
111
|
+
#
|
112
|
+
# @api public
|
113
|
+
def order(p=nil)
|
114
|
+
@order = p unless p.nil?
|
115
|
+
@order || 100
|
116
|
+
end
|
117
|
+
|
118
|
+
# Sets a resolver to disabled mode, won't be processed
|
119
|
+
#
|
120
|
+
# @example
|
121
|
+
# class MyResolver
|
122
|
+
# include WarningShot::Resolver
|
123
|
+
# disable!
|
124
|
+
# end
|
125
|
+
#
|
126
|
+
# @api public
|
127
|
+
def disable!
|
128
|
+
@disabled = true
|
129
|
+
end
|
130
|
+
|
131
|
+
# Determines if resolver is disabled
|
132
|
+
#
|
133
|
+
# @return [Boolean]
|
134
|
+
# is it disabled
|
135
|
+
#
|
136
|
+
# @api public
|
137
|
+
def disabled?
|
138
|
+
@disabled ||=false
|
139
|
+
end
|
140
|
+
|
141
|
+
# Provides resolver access to logger
|
142
|
+
#
|
143
|
+
# @return [~Logger]
|
144
|
+
# WarningShots logger
|
145
|
+
#
|
146
|
+
# @api public
|
147
|
+
def logger
|
148
|
+
@logger || Logger.new(STDOUT)
|
149
|
+
end
|
150
|
+
|
151
|
+
# Sets
|
152
|
+
def logger=(log)
|
153
|
+
@logger = log
|
154
|
+
end
|
155
|
+
|
156
|
+
# Defines how to cast YAML parsed data to an object
|
157
|
+
# the resolver can work with
|
158
|
+
#
|
159
|
+
# @param klass [Class]
|
160
|
+
# Type of class to perform casting against,
|
161
|
+
# if nil, the method is used on all types not matched
|
162
|
+
#
|
163
|
+
# @param block [lambda]
|
164
|
+
# How to cast the data to an object
|
165
|
+
#
|
166
|
+
# @api public
|
167
|
+
def cast(klass=nil,&block)
|
168
|
+
if klass.nil?
|
169
|
+
klass = :default
|
170
|
+
else
|
171
|
+
klass = klass.name.to_sym
|
172
|
+
end
|
173
|
+
(@yaml_to_object_methods||={})[klass] = block
|
174
|
+
end
|
175
|
+
|
176
|
+
# calls the block defined by Resolver#cast to convert
|
177
|
+
# the yaml data to an object
|
178
|
+
#
|
179
|
+
# @param data [~YAML::load]
|
180
|
+
# The data parsed from YAML::load
|
181
|
+
#
|
182
|
+
# @return [Object]
|
183
|
+
# The casted objects
|
184
|
+
#
|
185
|
+
# @notes
|
186
|
+
# if Resolver#cast was not called, it will just return
|
187
|
+
# the YAML parsed data
|
188
|
+
#
|
189
|
+
# @api private
|
190
|
+
def yaml_to_object(data)
|
191
|
+
@yaml_to_object_methods||={}
|
192
|
+
klass = data.class.name.to_sym
|
193
|
+
|
194
|
+
# if klass has a registered casting method, do it
|
195
|
+
if @yaml_to_object_methods.key? klass
|
196
|
+
return @yaml_to_object_methods[klass].call(data)
|
197
|
+
# elsif there is a regsitered default method, do it.
|
198
|
+
elsif @yaml_to_object_methods.key? :default
|
199
|
+
return @yaml_to_object_methods[:default].call(data)
|
200
|
+
else
|
201
|
+
# else return original data
|
202
|
+
return data
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# Registers a test or resolution block
|
207
|
+
#
|
208
|
+
# @param type [Symbol]
|
209
|
+
# The type of block being registered :test | :resolution
|
210
|
+
#
|
211
|
+
# @param meta [Hash]
|
212
|
+
# :name [String] (Optional)
|
213
|
+
# Name of the test
|
214
|
+
# :desc [String] (Optional)
|
215
|
+
# Description of the test
|
216
|
+
# :if|:unless [lambda] (Optional)
|
217
|
+
# Block that returns ~boolean determining if the test applies
|
218
|
+
# The block will be passed the current item from config file
|
219
|
+
#
|
220
|
+
# @param block [lambda]
|
221
|
+
# block should return ~boolean result of resolution attempt
|
222
|
+
# The block will be passed the current item from config file
|
223
|
+
#
|
224
|
+
# @example
|
225
|
+
# register :test, :name => :awesome_test, :desc => "this is my awesome test" do |dependency|
|
226
|
+
# your_logic_that_tests dependency
|
227
|
+
# end
|
228
|
+
#
|
229
|
+
# register :test, :if => lambda { |dependency|
|
230
|
+
# #This condition would determine if test should be run
|
231
|
+
# logic_that_determines_if_test_applies dependency
|
232
|
+
# } do |dependency|
|
233
|
+
# your_logic_that_tests dependency
|
234
|
+
# end
|
235
|
+
|
236
|
+
# register :resolution do |dependency|
|
237
|
+
# #Access to current dependency via dependency
|
238
|
+
# my_method_that_would_resolve dependency
|
239
|
+
# end
|
240
|
+
#
|
241
|
+
# register :resolution, :if => lambda{|dependency|
|
242
|
+
# #This will determin if resolution should be attempted
|
243
|
+
# # this would only resolve in production
|
244
|
+
# WarningShot.environment == 'production'
|
245
|
+
# } do |dependency|
|
246
|
+
# my_method_that_would_resolve dependency
|
247
|
+
# end
|
248
|
+
#
|
249
|
+
# @api public
|
250
|
+
def register(type, meta={}, &block)
|
251
|
+
if meta[:if] && meta[:unless]
|
252
|
+
raise Exception, ":if and :unless cannot be specified on the same resolution"
|
253
|
+
end
|
254
|
+
|
255
|
+
@registered_blocks ||= {:test => [], :resolution => []}
|
256
|
+
meta[type] = block
|
257
|
+
|
258
|
+
# If a condition is given add to begining of array, if no condition
|
259
|
+
# add it to end. This makes it so we dont have to sort later on :if|:unless
|
260
|
+
# to get non-condition resolutions to run last
|
261
|
+
|
262
|
+
if meta[:if] || meta[:unless]
|
263
|
+
@registered_blocks[type].unshift meta
|
264
|
+
else
|
265
|
+
@registered_blocks[type] << meta
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
# Lists current resolver tests
|
270
|
+
#
|
271
|
+
# @param test_name [Symbol]
|
272
|
+
# find a test by name (if a name was given)
|
273
|
+
#
|
274
|
+
# @return [Hash|Array]
|
275
|
+
# When name given, returns test Hash
|
276
|
+
# When name not give, returns all test Hashes in an array
|
277
|
+
#
|
278
|
+
# @api private
|
279
|
+
def tests(test_name=nil)
|
280
|
+
unless test_name
|
281
|
+
@registered_blocks[:test] ||= []
|
282
|
+
else
|
283
|
+
return @registered_blocks[:test].find do |registered_test|
|
284
|
+
registered_test[:name] == test_name
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
# Lists current resolver resolutions
|
290
|
+
#
|
291
|
+
# @param resolution_name [Symbol]
|
292
|
+
# find a test by name (if a name was given)
|
293
|
+
#
|
294
|
+
# @api private
|
295
|
+
def resolutions(resolution_name=nil)
|
296
|
+
unless resolution_name
|
297
|
+
@registered_blocks[:resolution] ||= []
|
298
|
+
else
|
299
|
+
return @registered_blocks[:resolution].find do |registered_resolution|
|
300
|
+
registered_resolution[:name] == resolution_name
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
# Removes all tests from a resolver
|
306
|
+
#
|
307
|
+
# @api public
|
308
|
+
def flush_tests!
|
309
|
+
@registered_blocks[:test] = []
|
310
|
+
end
|
311
|
+
|
312
|
+
# Removes all resolutions from a resolver
|
313
|
+
#
|
314
|
+
# @api public
|
315
|
+
def flush_resolutions!
|
316
|
+
@registered_blocks[:resolution] = []
|
317
|
+
end
|
318
|
+
|
319
|
+
# add before filters to test/resolution blocks
|
320
|
+
#
|
321
|
+
# @param type Symbol
|
322
|
+
# run before :test | :resolution
|
323
|
+
# @param block [lambda]
|
324
|
+
# block to run before tests or resolutions
|
325
|
+
#
|
326
|
+
# @api public
|
327
|
+
def before(type,&block)
|
328
|
+
@before_filters ||= {:test=>[],:resolution=>[]}
|
329
|
+
@before_filters[type] << block
|
330
|
+
end
|
331
|
+
|
332
|
+
# gets before filters for type
|
333
|
+
#
|
334
|
+
# @param type [Symbol]
|
335
|
+
# Type of filters to get
|
336
|
+
# @return [Array[Proc]]
|
337
|
+
# Before filters
|
338
|
+
# @api private
|
339
|
+
def before_filters(type)
|
340
|
+
@before_filters ? @before_filters[type] : []
|
341
|
+
end
|
342
|
+
|
343
|
+
# gets after filters for type
|
344
|
+
#
|
345
|
+
# @param type [Symbol]
|
346
|
+
# Type of filters to get
|
347
|
+
# @return [Array[Proc]]
|
348
|
+
# after filters
|
349
|
+
# @api private
|
350
|
+
def after_filters(type)
|
351
|
+
@after_filters ? @after_filters[type] : []
|
352
|
+
end
|
353
|
+
|
354
|
+
# add after filters to test/resolution blocks
|
355
|
+
#
|
356
|
+
# @param type Symbol
|
357
|
+
# run after :test | :resolution
|
358
|
+
# @param block [lambda]
|
359
|
+
# block to run after tests or resolutions
|
360
|
+
#
|
361
|
+
# @api public
|
362
|
+
def after(type,&block)
|
363
|
+
@after_filters ||= {:test=>[],:resolution=>[]}
|
364
|
+
@after_filters[type] << block
|
365
|
+
end
|
366
|
+
|
367
|
+
# Outputs class static details
|
368
|
+
#
|
369
|
+
# @return [Array(Object)]
|
370
|
+
# @api private
|
371
|
+
def details
|
372
|
+
[self.name,self.description,self.order,self.disabled?]
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
module InstanceMethods
|
377
|
+
|
378
|
+
# Loops through each dependency and runs applicable tests until one passes
|
379
|
+
#
|
380
|
+
# @api private
|
381
|
+
def test!
|
382
|
+
dependencies.each do |dep|
|
383
|
+
self.class.tests.each{ |test_meta|
|
384
|
+
dep.met = process_block :test, dep, test_meta
|
385
|
+
break if dep.met
|
386
|
+
}
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
# Loops through dependencies and runs applicable resolutions until one passes
|
391
|
+
#
|
392
|
+
# @api private
|
393
|
+
def resolve!
|
394
|
+
dependencies.each do |dep|
|
395
|
+
self.class.resolutions.each{ |resolution_meta|
|
396
|
+
dep.resolved = process_block :resolution, dep, resolution_meta
|
397
|
+
break if dep.resolved
|
398
|
+
}
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
# list of unresolved dependencies
|
403
|
+
#
|
404
|
+
# @return [Array<Objects>]
|
405
|
+
# dependencies that weren't resolved
|
406
|
+
#
|
407
|
+
# @api private
|
408
|
+
def unresolved
|
409
|
+
dependencies.inject([]){ |list,dep|
|
410
|
+
if !dep.met && !dep.resolved
|
411
|
+
list << dep
|
412
|
+
else
|
413
|
+
list
|
414
|
+
end
|
415
|
+
}
|
416
|
+
end
|
417
|
+
|
418
|
+
# list of failed dependencies
|
419
|
+
#
|
420
|
+
# @return [Array<Objects>]
|
421
|
+
# failed dependencies
|
422
|
+
#
|
423
|
+
# @api private
|
424
|
+
def failed
|
425
|
+
dependencies.inject([]){ |list,dep|
|
426
|
+
unless dep.met
|
427
|
+
list << dep
|
428
|
+
else
|
429
|
+
list
|
430
|
+
end
|
431
|
+
}
|
432
|
+
end
|
433
|
+
|
434
|
+
# list of successful dependencies
|
435
|
+
#
|
436
|
+
# @return [Array<Objects>]
|
437
|
+
# @api private
|
438
|
+
def passed
|
439
|
+
dependencies.inject([]){ |list,dep|
|
440
|
+
if dep.met
|
441
|
+
list << dep
|
442
|
+
else
|
443
|
+
list
|
444
|
+
end
|
445
|
+
}
|
446
|
+
end
|
447
|
+
|
448
|
+
# list of resolved dependencies
|
449
|
+
#
|
450
|
+
# @return [Array<Objects>]
|
451
|
+
# resolved dependencies
|
452
|
+
#
|
453
|
+
# @api private
|
454
|
+
def resolved
|
455
|
+
dependencies.inject([]){ |list,dep|
|
456
|
+
if(!dep.met && dep.resolved)
|
457
|
+
list << dep
|
458
|
+
else
|
459
|
+
list
|
460
|
+
end
|
461
|
+
}
|
462
|
+
end
|
463
|
+
|
464
|
+
# loads up instance variables for new test
|
465
|
+
# @param *deps [Array]
|
466
|
+
# Dependencies from YAML file
|
467
|
+
#
|
468
|
+
# @notes
|
469
|
+
# instance_eval is because I didnt want another class just to track
|
470
|
+
# met/resolved, if you hate it, feel free to change it :)
|
471
|
+
# met [Boolean] Was the dependency met
|
472
|
+
# resolved [Boolean] Was teh dependency resolved
|
473
|
+
#
|
474
|
+
# @api semi-public
|
475
|
+
def initialize(*deps)
|
476
|
+
@dependencies = Set.new
|
477
|
+
deps.each do |dep|
|
478
|
+
# Cast YAML data as described in resolver.
|
479
|
+
dep = self.class.yaml_to_object(dep)
|
480
|
+
|
481
|
+
dep.instance_eval { self.class.send(:attr_accessor, :met, :resolved) }
|
482
|
+
@dependencies.add dep
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
486
|
+
attr_accessor :logger
|
487
|
+
attr_accessor :dependencies
|
488
|
+
|
489
|
+
protected
|
490
|
+
# processes a test or resolution block
|
491
|
+
#
|
492
|
+
# @param type <Symbol>
|
493
|
+
# The type of block being processed :test | :resolution
|
494
|
+
#
|
495
|
+
# @param dep <Hash>
|
496
|
+
# Dependency parsed from yaml configs (Currently Hash)
|
497
|
+
# TODO; once Dependencies are an object besides Hash, this may need to be changed
|
498
|
+
#
|
499
|
+
# @param block_info <Hash>
|
500
|
+
# The block details and proc
|
501
|
+
#
|
502
|
+
# @return <Boolean>
|
503
|
+
# Was the block successful; meaning conditions passed and block returned true
|
504
|
+
#
|
505
|
+
# @api private
|
506
|
+
def process_block(type, dep, block_info)
|
507
|
+
if !block_info[:if] && !block_info[:unless]
|
508
|
+
# no condition, run block
|
509
|
+
return block_info[type].call(dep)
|
510
|
+
elsif block_info[:if] && block_info[:if].call(dep)
|
511
|
+
#if Condition given and it applies, run block
|
512
|
+
return block_info[type].call(dep)
|
513
|
+
elsif block_info[:unless] && !block_info[:unless].call(dep)
|
514
|
+
#unless Condition given and it applies, run block
|
515
|
+
return block_info[type].call(dep)
|
516
|
+
end
|
517
|
+
|
518
|
+
return false
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
@@descendents = []
|
523
|
+
def self.descendents
|
524
|
+
#Filter out descendents that are disabled
|
525
|
+
temp_descendents = []
|
526
|
+
@@descendents.each do |klass|
|
527
|
+
temp_descendents.push(klass) unless klass.disabled?
|
528
|
+
end
|
529
|
+
|
530
|
+
#Sort by order
|
531
|
+
temp_descendents.sort_by{|desc| desc.order}
|
532
|
+
end
|
533
|
+
|
534
|
+
|
535
|
+
private
|
536
|
+
def self.included(subclass)
|
537
|
+
subclass.extend ClassMethods
|
538
|
+
subclass.send :include, InstanceMethods
|
539
|
+
@@descendents.push subclass
|
540
|
+
end
|
541
|
+
end
|
542
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module WarningShot
|
2
|
+
module TemplateGenerator
|
3
|
+
class << self
|
4
|
+
def create(path)
|
5
|
+
generate_configs(path)
|
6
|
+
end
|
7
|
+
|
8
|
+
def generate_configs(path)
|
9
|
+
from = WarningShot.dir_for(:templates) / WarningShot::ConfigExt
|
10
|
+
copy_templates from, path
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
def copy_templates(from,to)
|
15
|
+
FileUtils.mkdir_p to unless File.exists? to
|
16
|
+
|
17
|
+
Dir[from].each do |file|
|
18
|
+
file_dest_path = to / File.basename(file)
|
19
|
+
# Add .sample if config is already present
|
20
|
+
file_dest_path += '.sample' if File.exists? file_dest_path
|
21
|
+
FileUtils.cp file, file_dest_path
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module WarningShot
|
2
|
+
BeforeCallbacks= []
|
3
|
+
AfterCallbacks = []
|
4
|
+
|
5
|
+
PATHS = {
|
6
|
+
:templates => 'templates',
|
7
|
+
:images => 'images',
|
8
|
+
:resolvers => 'lib' / 'warning_shot' / 'resolvers'
|
9
|
+
}
|
10
|
+
|
11
|
+
ConfigExt = "*.{yml,yaml}".freeze
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def root
|
15
|
+
File.expand_path(File.dirname(__FILE__)) / ".." / ".."
|
16
|
+
end
|
17
|
+
|
18
|
+
def hostname
|
19
|
+
`hostname`.strip
|
20
|
+
end
|
21
|
+
|
22
|
+
# Gets the absolute path for a resource.
|
23
|
+
# if it is not listed in PATHS then the string is appended to
|
24
|
+
# WarningShot.root
|
25
|
+
#
|
26
|
+
# @param dir [Symbol]
|
27
|
+
# directory to look up
|
28
|
+
#
|
29
|
+
# @return [String]
|
30
|
+
# absolute path to resource
|
31
|
+
#
|
32
|
+
# @api public
|
33
|
+
def dir_for(dir)
|
34
|
+
dir = PATHS[dir.to_sym] || dir.to_s
|
35
|
+
WarningShot.root / dir
|
36
|
+
end
|
37
|
+
|
38
|
+
def platform
|
39
|
+
case ::Config::CONFIG['host_os']
|
40
|
+
when /darwin/i: :mac
|
41
|
+
when /mswin|windows/i: :windows
|
42
|
+
when /linux/i: :linux
|
43
|
+
when /sunos|solaris/i: :solaris
|
44
|
+
else
|
45
|
+
:unknown
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# the application/framework warningshot is running in
|
50
|
+
# uses constants to determine
|
51
|
+
#
|
52
|
+
# @return [String] Name of framework/application
|
53
|
+
# @api public
|
54
|
+
def framework
|
55
|
+
if defined?(RAILS_ROOT)
|
56
|
+
return "RAILS"
|
57
|
+
elsif defined?(Merb)
|
58
|
+
return "MERB"
|
59
|
+
else
|
60
|
+
return "CONSOLE"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# shortcut to current environment
|
65
|
+
#
|
66
|
+
# @return [String] name of the environment
|
67
|
+
# @api public
|
68
|
+
def environment
|
69
|
+
WarningShot::Config.configuration[:environment]
|
70
|
+
end
|
71
|
+
|
72
|
+
# Parser used to parse Config hash
|
73
|
+
#
|
74
|
+
# @api private
|
75
|
+
def parser
|
76
|
+
@opt_parser ||= OptionParser.new
|
77
|
+
end
|
78
|
+
|
79
|
+
# register a callback to be run before starting
|
80
|
+
# the dependency resolver
|
81
|
+
# @param block [Proc]
|
82
|
+
# the before filter
|
83
|
+
# @api public
|
84
|
+
def before(&block)
|
85
|
+
BeforeCallbacks << block if block_given?
|
86
|
+
end
|
87
|
+
|
88
|
+
# register a callback to be run after starting
|
89
|
+
# the dependency resolver
|
90
|
+
# @param block [Proc]
|
91
|
+
# the after filter
|
92
|
+
# @api public
|
93
|
+
def after(&block)
|
94
|
+
AfterCallbacks << block if block_given?
|
95
|
+
end
|
96
|
+
|
97
|
+
# creates and runs a new dependency resolver
|
98
|
+
#
|
99
|
+
# @return WarningShot::DependencyResolver
|
100
|
+
# a processed dependency resolver
|
101
|
+
#
|
102
|
+
# @api public
|
103
|
+
def fire!
|
104
|
+
WarningShot.load_app
|
105
|
+
WarningShot.load_addl_resolvers
|
106
|
+
ws_dr = DependencyResolver.new WarningShot::Config.configuration
|
107
|
+
BeforeCallbacks.each {|p| p.call }
|
108
|
+
ws_dr.run
|
109
|
+
AfterCallbacks.each {|p| p.call }
|
110
|
+
|
111
|
+
ws_dr
|
112
|
+
end
|
113
|
+
alias :run :fire!
|
114
|
+
|
115
|
+
# Changes the working directory to that of the application
|
116
|
+
# Default application is '.'
|
117
|
+
def load_app
|
118
|
+
Dir.chdir(WarningShot::Config[:application])
|
119
|
+
end
|
120
|
+
|
121
|
+
# Loads any additional resolvers specified by --resolvers= or WarningShot::Config[:resolvers]
|
122
|
+
# defaults to ~/.warningshot/*.rb
|
123
|
+
def load_addl_resolvers
|
124
|
+
WarningShot::Config[:resolvers].each do |resolver_path|
|
125
|
+
Dir[File.expand_path(resolver_path)].each {|r| load r}
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
end
|