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.
Files changed (72) hide show
  1. data/CHANGELOG +0 -0
  2. data/CONTRIBUTORS +2 -0
  3. data/LICENSE +22 -0
  4. data/README +101 -0
  5. data/Rakefile +28 -0
  6. data/TODO +148 -0
  7. data/bin/warningshot +19 -0
  8. data/bin/ws-stage.bat +3 -0
  9. data/bin/ws-stage.sh +3 -0
  10. data/images/warning_shot.png +0 -0
  11. data/images/warning_shot_sml.png +0 -0
  12. data/images/warningshot_green.png +0 -0
  13. data/images/warningshot_red.png +0 -0
  14. data/lib/core_ext/hash.rb +14 -0
  15. data/lib/core_ext/kernel.rb +8 -0
  16. data/lib/core_ext/object.rb +7 -0
  17. data/lib/core_ext/string.rb +5 -0
  18. data/lib/resolvers/core_lib_resolver.rb +76 -0
  19. data/lib/resolvers/directory_resolver.rb +31 -0
  20. data/lib/resolvers/file_resolver.rb +87 -0
  21. data/lib/resolvers/gem_resolver.rb +94 -0
  22. data/lib/resolvers/integrity_resolver.rb +69 -0
  23. data/lib/resolvers/manual_resolver.rb +19 -0
  24. data/lib/resolvers/permission_resolver.rb +72 -0
  25. data/lib/resolvers/symlink_resolver.rb +43 -0
  26. data/lib/resolvers/url_resolver.rb +76 -0
  27. data/lib/warning_shot/config.rb +132 -0
  28. data/lib/warning_shot/dependency_resolver.rb +155 -0
  29. data/lib/warning_shot/growl.rb +14 -0
  30. data/lib/warning_shot/logger.rb +27 -0
  31. data/lib/warning_shot/resolver.rb +542 -0
  32. data/lib/warning_shot/template_generator.rb +28 -0
  33. data/lib/warning_shot/version.rb +7 -0
  34. data/lib/warning_shot/warning_shot.rb +130 -0
  35. data/lib/warningshot.rb +16 -0
  36. data/tasks/gemspec.rb +48 -0
  37. data/tasks/rpsec.rb +58 -0
  38. data/tasks/yard.rb +4 -0
  39. data/templates/binaries.yml +26 -0
  40. data/templates/core_libs.yml +18 -0
  41. data/templates/directories.yml +23 -0
  42. data/templates/files.yml +18 -0
  43. data/templates/gems.yml +26 -0
  44. data/templates/manual.yml +29 -0
  45. data/templates/mounts.yml +8 -0
  46. data/templates/permissions.yml +31 -0
  47. data/templates/symlinks.yml +30 -0
  48. data/templates/urls.yml +21 -0
  49. data/test/data/mock.yaml +16 -0
  50. data/test/data/mock.yml +10 -0
  51. data/test/data/mock_resolver.rb +16 -0
  52. data/test/data/permission_test.txt +1 -0
  53. data/test/data/resolvers/file/src/that.txt +1 -0
  54. data/test/log/warningshot.log +643 -0
  55. data/test/spec/spec.opts.zoiks +0 -0
  56. data/test/spec/spec_helper.rb +11 -0
  57. data/test/spec/unit/resolvers/core_lib_resolver_spec.rb +39 -0
  58. data/test/spec/unit/resolvers/directory_resolver_spec.rb +39 -0
  59. data/test/spec/unit/resolvers/file_resolver_spec.rb +134 -0
  60. data/test/spec/unit/resolvers/gem_resolver_spec.rb +74 -0
  61. data/test/spec/unit/resolvers/integrity_resolver_spec.rb +103 -0
  62. data/test/spec/unit/resolvers/manual_resolver_spec.rb +17 -0
  63. data/test/spec/unit/resolvers/permission_resolver_spec.rb +56 -0
  64. data/test/spec/unit/resolvers/symlink_resolver_spec.rb +44 -0
  65. data/test/spec/unit/resolvers/url_resolver_spec.rb +64 -0
  66. data/test/spec/unit/warning_shot/config_spec.rb +35 -0
  67. data/test/spec/unit/warning_shot/dependency_resolver_spec.rb +43 -0
  68. data/test/spec/unit/warning_shot/resolver_spec.rb +347 -0
  69. data/test/spec/unit/warning_shot/template_generator_spec.rb +21 -0
  70. data/test/spec/unit/warning_shot/version_spec.rb +7 -0
  71. data/test/spec/unit/warning_shot/warning_shot_spec.rb +3 -0
  72. 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,7 @@
1
+ module WarningShot
2
+ MAJOR = 0
3
+ MINOR = 9
4
+ REVISION = 4
5
+
6
+ VERSION = [MAJOR,MINOR,REVISION].join('.')
7
+ 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