warningshot 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +0 -0
- data/CONTRIBUTORS +2 -0
- data/LICENSE +22 -0
- data/README +101 -0
- data/Rakefile +28 -0
- data/TODO +148 -0
- data/bin/warningshot +19 -0
- data/bin/ws-stage.bat +3 -0
- data/bin/ws-stage.sh +3 -0
- data/images/warning_shot.png +0 -0
- data/images/warning_shot_sml.png +0 -0
- data/images/warningshot_green.png +0 -0
- data/images/warningshot_red.png +0 -0
- data/lib/core_ext/hash.rb +14 -0
- data/lib/core_ext/kernel.rb +8 -0
- data/lib/core_ext/object.rb +7 -0
- data/lib/core_ext/string.rb +5 -0
- data/lib/resolvers/core_lib_resolver.rb +76 -0
- data/lib/resolvers/directory_resolver.rb +31 -0
- data/lib/resolvers/file_resolver.rb +87 -0
- data/lib/resolvers/gem_resolver.rb +94 -0
- data/lib/resolvers/integrity_resolver.rb +69 -0
- data/lib/resolvers/manual_resolver.rb +19 -0
- data/lib/resolvers/permission_resolver.rb +72 -0
- data/lib/resolvers/symlink_resolver.rb +43 -0
- data/lib/resolvers/url_resolver.rb +76 -0
- data/lib/warning_shot/config.rb +132 -0
- data/lib/warning_shot/dependency_resolver.rb +155 -0
- data/lib/warning_shot/growl.rb +14 -0
- data/lib/warning_shot/logger.rb +27 -0
- data/lib/warning_shot/resolver.rb +542 -0
- data/lib/warning_shot/template_generator.rb +28 -0
- data/lib/warning_shot/version.rb +7 -0
- data/lib/warning_shot/warning_shot.rb +130 -0
- data/lib/warningshot.rb +16 -0
- data/tasks/gemspec.rb +48 -0
- data/tasks/rpsec.rb +58 -0
- data/tasks/yard.rb +4 -0
- data/templates/binaries.yml +26 -0
- data/templates/core_libs.yml +18 -0
- data/templates/directories.yml +23 -0
- data/templates/files.yml +18 -0
- data/templates/gems.yml +26 -0
- data/templates/manual.yml +29 -0
- data/templates/mounts.yml +8 -0
- data/templates/permissions.yml +31 -0
- data/templates/symlinks.yml +30 -0
- data/templates/urls.yml +21 -0
- data/test/data/mock.yaml +16 -0
- data/test/data/mock.yml +10 -0
- data/test/data/mock_resolver.rb +16 -0
- data/test/data/permission_test.txt +1 -0
- data/test/data/resolvers/file/src/that.txt +1 -0
- data/test/log/warningshot.log +643 -0
- data/test/spec/spec.opts.zoiks +0 -0
- data/test/spec/spec_helper.rb +11 -0
- data/test/spec/unit/resolvers/core_lib_resolver_spec.rb +39 -0
- data/test/spec/unit/resolvers/directory_resolver_spec.rb +39 -0
- data/test/spec/unit/resolvers/file_resolver_spec.rb +134 -0
- data/test/spec/unit/resolvers/gem_resolver_spec.rb +74 -0
- data/test/spec/unit/resolvers/integrity_resolver_spec.rb +103 -0
- data/test/spec/unit/resolvers/manual_resolver_spec.rb +17 -0
- data/test/spec/unit/resolvers/permission_resolver_spec.rb +56 -0
- data/test/spec/unit/resolvers/symlink_resolver_spec.rb +44 -0
- data/test/spec/unit/resolvers/url_resolver_spec.rb +64 -0
- data/test/spec/unit/warning_shot/config_spec.rb +35 -0
- data/test/spec/unit/warning_shot/dependency_resolver_spec.rb +43 -0
- data/test/spec/unit/warning_shot/resolver_spec.rb +347 -0
- data/test/spec/unit/warning_shot/template_generator_spec.rb +21 -0
- data/test/spec/unit/warning_shot/version_spec.rb +7 -0
- data/test/spec/unit/warning_shot/warning_shot_spec.rb +3 -0
- metadata +143 -0
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
|