warningshot 0.9.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/CHANGELOG
ADDED
File without changes
|
data/CONTRIBUTORS
ADDED
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
data/bin/ws-stage.sh
ADDED
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,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
|