warningshot 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
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