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
data/CHANGELOG ADDED
File without changes
data/CONTRIBUTORS ADDED
@@ -0,0 +1,2 @@
1
+ ==== Contributors
2
+ * Cory ODaniel (I'm lonely)
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2008 Cory ODaniel
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,101 @@
1
+ WarningShot Dependency Resolution Framework
2
+ * Additional documentation @ http://github.com/coryodaniel/warningshot/wikis/
3
+
4
+ ==== How it works
5
+ * WarningShot - Factory class that creates and runs DependencyResolver
6
+ * DependencyResolver - Locates Resolver classes, creates a dependency tree, and matches resolvers to resolution branches
7
+ * Resolver - Class that can be included to create plugins. Composed of tests and resolutions that can determine if a dependency was met, and if not, how to fix it
8
+
9
+
10
+ ==== Ruby API
11
+
12
+ - Configuring WarningShot
13
+ WarningShot::Config.use do |c|
14
+ c[:environment] = 'development'
15
+ c[:resolve] = false
16
+ c[:config_paths] = ['.' / 'config' / 'warningshot']
17
+ c[:application] = '.'
18
+ c[:log_path] = '.' / 'log' / 'warningshot.log'
19
+ c[:log_level] = :debug
20
+ c[:growl] = false
21
+ c[:verbose] = true
22
+ c[:colorize] = true
23
+ c[:]
24
+ end
25
+
26
+ - Interfacing with a DependencyResolver
27
+ dependency_resolver = WarningShot.fire!
28
+ dependency_resolver.stats # => Hash of statistics
29
+
30
+ dependency_resolver.resolvers # => Array of all executed resolvers
31
+
32
+ dependency_resolver.resolvers.first.dependencies #=> Set of all loaded dependencies
33
+
34
+ dependency_resolver.resolver.first.passed # => Array of passed dependencies
35
+ dependency_resolver.resolver.first.failed # => Array of failed dependencies
36
+ dependency_resolver.resolver.first.unresolved # => Array of unresolved dependencies
37
+ dependency_resolver.resolver.first.resolved # => Array of resolved dependencies
38
+
39
+ - Callbacks
40
+ WarningShot.before do
41
+ puts 'this would run before the DepenencyResolver was created in #fire!'
42
+ end
43
+
44
+ WarningShot.after do
45
+ puts 'this would run after the DepenencyResolver was processed in #fire!'
46
+ end
47
+
48
+ WarningShot::AnyResolverYouWant.before :test do
49
+ puts 'this would run before the #test! method on the chosen resolver'
50
+ end
51
+
52
+ WarningShot::AnotherFunResolver.after :test do
53
+ puts 'this would run after the #test! method'
54
+ end
55
+
56
+ WarningShot::AnotherResolver.before :resolution do
57
+ puts 'this would run before the #resolve! method'
58
+ end
59
+
60
+ WarningShot::AnotherResolver.after :resolution do
61
+ puts 'this would run after the #resolve! method'
62
+ end
63
+
64
+ ==== Components
65
+ * Ruby API
66
+ * Resolvers
67
+ * Config Files
68
+
69
+
70
+ ==== Using Config Files
71
+ * Coming Soon
72
+
73
+
74
+ ==== How the dependency tree works
75
+ * Coming Soon
76
+
77
+
78
+ ==== Extending WarningShot
79
+ * Writing a Resolver (Coming Soon)
80
+ * Modifying Resolvers at run-time (Coming Soon)
81
+
82
+
83
+ ==== Contributing
84
+ * Source available @:
85
+ https://github.com/coryodaniel/warningshot/tree
86
+
87
+ * Bug reports / feature requests @:
88
+ http://warningshot.lighthouseapp.com/projects/17241-warningshot/overview
89
+
90
+ * Online Documentation available @: (eventually)
91
+
92
+ * RubyForge Project @:
93
+ http://rubyforge.org/projects/warning-shot/
94
+
95
+ * All modifications should also have applicable rpsecs
96
+ http://rspec.info/
97
+
98
+ * All code should be documented using YARD
99
+ http://yard.rubyforge.org/
100
+ A template is available file://./yardoc_template.txt
101
+ Generate Yardoc with: yardoc --output-dir ./doc/yard --private --protected --readme README
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ require 'pathname'
2
+ require 'rubygems'
3
+ require 'rake'
4
+ require 'rake/clean'
5
+ require 'rake/rdoctask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/contrib/rubyforgepublisher'
8
+ require 'spec/rake/spectask'
9
+ require "rake/testtask"
10
+ require "spec"
11
+ require "spec/story"
12
+ require 'spec/story/extensions/main'
13
+ require "spec/rake/spectask"
14
+ require "fileutils"
15
+
16
+ NAME = 'warningshot'
17
+ ROOT = Pathname(__FILE__).dirname.expand_path
18
+
19
+ require 'lib/warning_shot/version'
20
+
21
+ CLEAN.include ["**/.*.sw?", "pkg", "lib/*.bundle", "*.gem", "doc/","doc/", "test/output/*", "coverage", "cache"]
22
+ Dir['tasks/*.rb'].each {|r| require r}
23
+
24
+
25
+ ##############################################################################
26
+ # ADD YOUR CUSTOM TASKS IN /lib/tasks
27
+ # NAME YOUR RAKE FILES file_name.rake
28
+ ##############################################################################
data/TODO ADDED
@@ -0,0 +1,148 @@
1
+ Additional TODOS are at:
2
+ http://warningshot.lighthouseapp.com
3
+
4
+ ====
5
+ WarningShot should have its own set of config files so it can test its self (for WS Developers)
6
+
7
+ Gems
8
+ * Minigems option, prepares gems as minigems
9
+
10
+ Binary Resolver
11
+ * Apt, Yum, Ports
12
+ * Random binaries like awk, vi, etc... (previously used `which BINARY`)
13
+
14
+ Git, Svn Resolver
15
+
16
+ ServicesResolver
17
+ * memcached, mysql, etc...
18
+
19
+ IpTableResolver
20
+ * Confirms, sets up, and saves Iptables
21
+
22
+ Connections Resolver
23
+ * test network connections
24
+ # ifconfig -a => active interfaces
25
+
26
+ Hardware Resolver
27
+ * Determines if hardware requirements are met
28
+
29
+ Script Resolver
30
+ * A scripting interface... was in old WS that enabled people to do most of this stuff
31
+ Should it just be left out since its so easy to extend?
32
+
33
+ MountResolver / NFSMount Resolver
34
+ * God knows.
35
+
36
+ QA Resolvers
37
+ * Rspec
38
+ * YSlow
39
+ * RCoverage
40
+ * Watir, etc etc
41
+
42
+ - :branch: quality
43
+ :environments:
44
+ :production:
45
+ - {attrib: "rspec", grade: ">98"}
46
+ - {attrib: "rcov", grade: ">90", rollback: "true"}
47
+
48
+
49
+ - :branch: yslow
50
+ :environments:
51
+ :production:
52
+ - {page: "http://example.com/login", grade: ">90"}
53
+ - {page: "http://example.com/index", grade: ">=99", rollback: "true"}
54
+
55
+ Interfaces for Cap, Vertebra, and Vlad
56
+
57
+ ==== Old SHit.
58
+ # This is old shit from a prototype i did of file/permissions resolver...
59
+ # http://www.workingwithrails.com/railsplugin/6146-open4-9-3
60
+ # http://codeforpeople.com/lib/ruby/open4/open4-0.9.3/README
61
+
62
+ module WarningShot
63
+ class FileSystemResource
64
+
65
+ def initialize(path_data)
66
+ @attributes = parse_params(path_data)
67
+ end
68
+
69
+ def [](key)
70
+ return @attributes[key]
71
+ end
72
+
73
+ def []=(key,val)
74
+ return @attributes[key] = val
75
+ end
76
+
77
+ def chown
78
+ status = Open4::popen4("sh") do |p,i,o,e|
79
+ command = ["chown"]
80
+ command.push "-R" if ["chown","both"].member? self[:recursive]
81
+ command.push "#{self[:user]}:#{self[:group]}"
82
+ command.push self[:target]
83
+
84
+ i.puts command.join(" ")
85
+ i.close
86
+ end
87
+
88
+ if status.exitstatus == 0
89
+ return true
90
+ else
91
+ raise Exception, "Could not chown:\n ~ #{@attributes.inspect}"
92
+ end
93
+ end
94
+
95
+ def chmod
96
+ status = Open4::popen4("sh") do |p,i,o,e|
97
+ command = ["chmod"]
98
+ command.push "-R" if ["chmod","both"].member? self[:recursive]
99
+ command.push self[:mode]
100
+ command.push self[:target]
101
+
102
+ i.puts command.join(" ")
103
+ i.close
104
+ end
105
+
106
+ if status.exitstatus == 0
107
+ return true
108
+ else
109
+ raise Exception, "Could not chmod:\n ~ #{@attributes.inspect}"
110
+ end
111
+ end
112
+
113
+ private
114
+
115
+ def parse_params(path_data)
116
+ attributes = defaults
117
+
118
+ #Make path_data a hash if it was passed as a string
119
+ path_data = {:target => path_data} if path_data.is_a? String
120
+
121
+ attributes.merge! path_data.symbolize_keys!
122
+ orig_group = attributes[:group]
123
+
124
+ #Group defaults to user
125
+ attributes[:group] = attributes[:user] if orig_group.nil? || orig_group.empty?
126
+
127
+ #Expand source and dest paths
128
+ #attributes[:source] = File.expand_path(attributes[:source]) unless attributes[:source].nil?
129
+ #attributes[:target] = File.expand_path(attributes[:target])
130
+
131
+ attributes[:recursive].downcase!
132
+
133
+ return attributes
134
+ end
135
+
136
+ def defaults
137
+ {
138
+ :target => nil,
139
+ :source => nil,
140
+ :mode => "0755",
141
+ :user => "nobody",
142
+ :group => "nobody",
143
+ :recursive => "none"
144
+ }
145
+ end
146
+
147
+ end
148
+ end
data/bin/warningshot ADDED
@@ -0,0 +1,19 @@
1
+ #! /usr/bin/env ruby
2
+ require 'warningshot'
3
+
4
+ # Parse ARGV
5
+ WarningShot::Config.parse_args
6
+
7
+ # Initialize and run a new dependency resolver
8
+ dep_resolver = WarningShot.fire!
9
+
10
+ # Get the stats from the resolver
11
+ stats = dep_resolver.stats
12
+
13
+ # Growl the results if growl is on
14
+ if WarningShot::Config[:growl]
15
+ WarningShot::Growl.say stats.to_a.join('/')
16
+ end
17
+
18
+ #Return an exit status based on number of unresolved dependencies
19
+ exit(stats[:unresolved])
data/bin/ws-stage.bat ADDED
@@ -0,0 +1,3 @@
1
+ # TODO
2
+ #This should be a prestaging file for warning shot for Windows systems
3
+ # If no ruby environment, downloads and installs latest stable environment and rubygems
data/bin/ws-stage.sh ADDED
@@ -0,0 +1,3 @@
1
+ # TODO
2
+ #This should be a prestaging file for warning shot for Unix systems
3
+ # If no ruby environment, downloads and installs latest stable environment and rubygems
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,14 @@
1
+ class Hash
2
+ def symbolize_keys!
3
+ each do |k,v|
4
+ sym = k.respond_to?(:to_sym) ? k.to_sym : k
5
+ self[sym] = Hash === v ? v.symbolize_keys! : v
6
+ self[sym] = Array === v ? v.each{|i|
7
+ i.symbolize_keys! if i.is_a? Hash
8
+ }: v
9
+
10
+ delete(k) unless k == sym
11
+ end
12
+ self
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ module Kernel
2
+ unless Kernel.respond_to?(:debugger)
3
+ #Provide a debugger method if the debugger is turned off, stops NoMethodError
4
+ def debugger
5
+ puts "=-=-=-=-=Debugger was request, but debugging is not enabled (warningshot --debugger)=-=-=-=-="
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ class Object
2
+ class << self
3
+ def is_const_defined?(const)
4
+ Object.const_get const rescue false
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ class String
2
+ def /(s)
3
+ File.join(self,s)
4
+ end
5
+ end
@@ -0,0 +1,76 @@
1
+
2
+ # Check to see if core lib packages are available
3
+ # Created due to issues with some Apt installs not installing all
4
+ # ruby core classes. This is irresolvable, but at least gives you
5
+ # a heads up.
6
+
7
+ class WarningShot::CoreLibResolver
8
+ include WarningShot::Resolver
9
+
10
+ order 10
11
+ #disable!
12
+ description 'Checks that core ruby lib packages are available'
13
+ branch :core_lib
14
+ @@do_purge = false
15
+
16
+ CoreLibResource = Struct.new(:lib)
17
+ cast do |dep|
18
+ CoreLibResource.new(dep)
19
+ end
20
+
21
+ # optionally purge CoreLIb classes in memory
22
+ # The default behavior is to just remove the
23
+ # reference to loading the class from $". Classes
24
+ # stay in memory but can be re-required without
25
+ # returning false
26
+ #
27
+ # @param do_purge [Boolean] (Default: false)
28
+ # Should classes be purged from memory.
29
+ def self.purge(do_purge=false)
30
+ @@do_purge = do_purge
31
+ end
32
+
33
+ @@original_requires = $".clone
34
+ @@original_classes = Symbol.all_symbols.clone if @@do_purge
35
+
36
+ register :test do |dep|
37
+ begin
38
+ require dep.lib
39
+ logger.debug " ~ Found core lib: #{dep.lib}"
40
+ WarningShot::CoreLibResolver.unload($" - @@original_requires)
41
+ WarningShot::CoreLibResolver.purge_classes(Symbol.all_symbols - @@original_classes) if @@do_purge
42
+ true
43
+ rescue LoadError => ex
44
+ false
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ class << self
51
+ # removes files from $" so they can be re-required
52
+ #
53
+ # @param files [Array(String)]
54
+ # files to remove
55
+ #
56
+ # @api private
57
+ def unload(files)
58
+ files.each do |req|
59
+ $".delete(req)
60
+ end
61
+ end
62
+
63
+ # Undefines classes
64
+ #
65
+ # @param classes [Array(Symbol)]
66
+ # classes to remove
67
+ #
68
+ # @api private
69
+ def purge_classes(classes)
70
+ classes.each do |klass|
71
+ Object.send(:remove_const, klass) if Object.is_const_defined? klass
72
+ end
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,31 @@
1
+ class WarningShot::DirectoryResolver
2
+ include WarningShot::Resolver
3
+ order 100
4
+ branch :directory
5
+
6
+ description 'Validates presence of directories'
7
+
8
+ DirectoryResource = Struct.new(:path)
9
+ cast do |path|
10
+ DirectoryResource.new File.expand_path(path)
11
+ end
12
+
13
+ register :test do |dep|
14
+ dir_found = File.directory? dep.path
15
+ if dir_found
16
+ logger.debug " ~ [PASSED] directory: #{dep.path}"
17
+ else
18
+ logger.warn " ~ [FAILED] directory: #{dep.path}"
19
+ end
20
+
21
+ dir_found
22
+ end
23
+
24
+ register :resolution do |dep|
25
+ begin
26
+ FileUtils.mkdir_p dep.path
27
+ rescue Exception => ex
28
+ logger.error " ~ Could not create directory #{dep.path}"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,87 @@
1
+ require 'fileutils'
2
+ require 'uri'
3
+ require 'net/http'
4
+ require 'net/https'
5
+
6
+ # Tests and Heals File Dependencies
7
+ #
8
+ # @notes
9
+ # source is were the file can be resolved FROM
10
+ # target is were the file should exist
11
+ class WarningShot::FileResolver
12
+ include WarningShot::Resolver
13
+ order 500
14
+
15
+ branch :file
16
+ description 'Validates presence of files'
17
+
18
+ # Define FileResource struct
19
+ FileResource = Struct.new(:source,:target) do
20
+ def exists?;File.exists?(target.path);end;
21
+ def remove;File.unlink(target.path);end;
22
+ end
23
+
24
+ cast String do |file|
25
+ FileResource.new URI.parse(''), URI.parse(file)
26
+ end
27
+
28
+ cast Hash do |file|
29
+ file[:source].sub!(/file:\/\//i,'') unless file[:source].nil?
30
+ FileResource.new URI.parse(file[:source] || ''), URI.parse(file[:target])
31
+ end
32
+
33
+ register :test, {:name => :file_check} do |file|
34
+ if file_found = file.exists?
35
+ logger.debug " ~ [PASSED] file: #{file.target.path}"
36
+ else
37
+ logger.warn " ~ [FAILED] file: #{file.target.path}"
38
+ end
39
+
40
+ file_found
41
+ end
42
+
43
+ # Resolve files from target sources
44
+ # @notes
45
+ # :if matches FILE_PROTOCOL or uri.scheme == nil
46
+ register(:resolution, { :name => :file_protocol,
47
+ :desc => "Resolves files from target sources",
48
+ :if => lambda { |file|
49
+ !!(file.source.scheme =~ /file/i || file.source.scheme == nil)
50
+ }
51
+ }) do |file|
52
+ begin
53
+ FileUtils.cp file.source.path, file.target.path
54
+ rescue Exception => ex
55
+ logger.error " ~ Could not restore file (#{file.target.path}) from #{file.source.path}"
56
+ end
57
+ file.exists?
58
+ end
59
+
60
+ register(:resolution, { :name => :http_protocol,
61
+ :desc => "Resolves files from HTTP sources",
62
+ :if => lambda { |file| !!(file.source.to_s =~ /http(s)?/i)}
63
+ }) do |file|
64
+ begin
65
+ http = Net::HTTP.new(file.source.host,file.source.port)
66
+ http.use_ssl = (file.source.scheme == 'https')
67
+ file.source.path = '/' if file.source.path.empty?
68
+ resp = http.get(file.source.path)
69
+
70
+ File.open(file.target.path,"w+"){ |fs| fs.puts resp.body } if resp.code == "200"
71
+ rescue Exception => ex
72
+ logger.error " ~ Could not restore file (#{file.target.path}) from #{file.source.path}"
73
+ end
74
+ file.exists?
75
+ end
76
+ =begin
77
+ register(:resolution, {:name => :scp_protocol,
78
+ :desc => "Resolves files over SSH",
79
+ :if => lambda {|file| }
80
+ }){raise Exception, ' ~ SCP is not supported yet.'}
81
+
82
+ register(:resolution, {:name => :ftp_protocol,
83
+ :desc => "Resolves files over FTP",
84
+ :if => lambda {|file| }
85
+ }){raise Exception, ' ~ FTP is not supported yet.'}
86
+ =end
87
+ end
@@ -0,0 +1,94 @@
1
+ require 'rubygems/dependency_installer'
2
+ class WarningShot::GemResolver
3
+ include WarningShot::Resolver
4
+
5
+ order 100
6
+ branch :gem
7
+ description 'Installs ruby gems and their dependencies'
8
+
9
+ # Matches >, <, >=, <=
10
+ CONDITIONAL_RGX = /[^\d]*/.freeze
11
+
12
+ # Matches digits in version
13
+ VERSION_RGX = /[\d\.]+/.freeze
14
+
15
+ # Default version to install
16
+ DEFAULT_VERSION = ">=0.0.0".freeze
17
+
18
+ cli(
19
+ :long => "--gempath",
20
+ :description => "Alternate gem path ':' separated to check. First in path is where gems will be installed",
21
+ :name => "gem_path",
22
+ :default => nil
23
+ )
24
+
25
+ cli(
26
+ :long => "--minigems",
27
+ :description => "Not supported yet.",
28
+ :name => "minigems",
29
+ :default => false
30
+ )
31
+
32
+ GemResource = Struct.new(:name,:version) do
33
+ def installed?
34
+ self.version ||= DEFAULT_VERSION
35
+ installed_versions = Gem::cache.search self.name
36
+ installed = false
37
+
38
+ required_version = Gem::Requirement.new self.version
39
+
40
+ installed_versions.each do |i_gem|
41
+ installed = case(required_version <=> Gem::Requirement.new(i_gem.version))
42
+ when 1,0
43
+ true
44
+ else
45
+ false
46
+ end
47
+
48
+ break if installed
49
+ end
50
+ installed
51
+ end
52
+ end #End GemResource
53
+
54
+ cast(String){ |yaml| GemResource.new(yaml,DEFAULT_VERSION) }
55
+ cast(Hash){ |yaml| GemResource.new yaml[:name], yaml[:version] }
56
+
57
+ register :test do |dep|
58
+ if gem_found = dep.installed?
59
+ logger.debug " ~ [PASSED] gem: #{dep.name}:#{dep.version}"
60
+ else
61
+ logger.warn " ~ [FAILED] gem: #{dep.name}:#{dep.version}"
62
+ end
63
+ gem_found
64
+ end
65
+
66
+ register :resolution do |dep|
67
+ begin
68
+ dep_inst = Gem::DependencyInstaller.new({:install_dir => Gem.path.first})
69
+ dep_inst.install(dep.name,Gem::Requirement.new(dep.version))
70
+ rescue Exception => ex
71
+ logger.error " ~ Could not install gem: #{dep.name}:#{dep.version}"
72
+ end
73
+ dep.installed?
74
+ end
75
+
76
+ class << self
77
+ # loads gem paths from WarningShot::Config
78
+ def load_paths
79
+ if WarningShot::Config.configuration.key?(:gem_path) && !WarningShot::Config.configuration[:gem_path].nil?
80
+ WarningShot::Config.configuration[:gem_path].split(":").reverse.each do |path|
81
+ Gem.path.unshift path
82
+ end
83
+
84
+ Gem::cache.class.from_gems_in WarningShot::Config.configuration[:gem_path].split(":")
85
+ Gem::cache.refresh!
86
+ end
87
+ end
88
+ end
89
+
90
+ def initialize(*params)
91
+ super
92
+ WarningShot::GemResolver.load_paths
93
+ end
94
+ end