stratagem 0.2.3 → 0.2.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/Manifest +16 -6
- data/Rakefile +8 -1
- data/lib/generators/stratagem/install/install_base.rb +13 -3
- data/lib/generators/stratagem/install/install_generator.rb +1 -1
- data/lib/stratagem.rb +42 -18
- data/lib/stratagem/authentication.rb +2 -5
- data/lib/stratagem/auto_mock.rb +1 -0
- data/lib/stratagem/auto_mock/aquifer.rb +49 -26
- data/lib/stratagem/auto_mock/factory.rb +1 -6
- data/lib/stratagem/auto_mock/user_loader.rb +38 -0
- data/lib/stratagem/client.rb +15 -4
- data/lib/stratagem/configuration/auth_auth.rb +19 -0
- data/lib/stratagem/configuration/core.rb +20 -0
- data/lib/stratagem/crawler/authentication.rb +17 -12
- data/lib/stratagem/crawler/authentication/automated.rb +40 -0
- data/lib/stratagem/crawler/authentication/base.rb +140 -0
- data/lib/stratagem/crawler/authentication/configured.rb +27 -0
- data/lib/stratagem/crawler/parameter_resolver.rb +12 -8
- data/lib/stratagem/crawler/route_invoker.rb +10 -13
- data/lib/stratagem/crawler/session.rb +14 -2
- data/lib/stratagem/crawler/site_model.rb +4 -173
- data/lib/stratagem/crawler/site_model/edge.rb +20 -0
- data/lib/stratagem/crawler/site_model/page.rb +121 -0
- data/lib/stratagem/crawler/site_model/page_set.rb +58 -0
- data/lib/stratagem/instrumentation/models.rb +3 -14
- data/lib/stratagem/instrumentation/models/annotations.rb +39 -5
- data/lib/stratagem/instrumentation/models/authentication.rb +0 -1
- data/lib/stratagem/instrumentation/models/authentication/authlogic/detect.rb +1 -0
- data/lib/stratagem/instrumentation/models/authentication/devise/detect.rb +1 -1
- data/lib/stratagem/instrumentation/models/authentication/devise/instrumentation.rb +0 -4
- data/lib/stratagem/instrumentation/models/metadata.rb +23 -1
- data/lib/stratagem/instrumentation/models/persistence.rb +3 -4
- data/lib/stratagem/instrumentation/models/persistence/active_record/metadata.rb +2 -2
- data/lib/stratagem/interface/browser.rb +9 -3
- data/lib/stratagem/interface/public/javascripts/stratagem.js +14 -12
- data/lib/stratagem/interface/views/index.haml +3 -3
- data/lib/stratagem/logger.rb +28 -2
- data/lib/stratagem/model.rb +6 -0
- data/lib/stratagem/model/application.rb +21 -134
- data/lib/stratagem/model/components/base.rb +1 -4
- data/lib/stratagem/model/components/controller.rb +1 -2
- data/lib/stratagem/model/components/model.rb +15 -15
- data/lib/stratagem/model/components/route.rb +3 -2
- data/lib/stratagem/model/components/view.rb +0 -1
- data/lib/stratagem/model/containers/base.rb +60 -0
- data/lib/stratagem/model/containers/gem.rb +25 -0
- data/lib/stratagem/model/containers/plugin.rb +11 -0
- data/lib/stratagem/model/containers/route.rb +19 -0
- data/lib/stratagem/model/parse_util.rb +3 -3
- data/lib/stratagem/model_builder.rb +1 -4
- data/lib/stratagem/rack_hack.rb +15 -0
- data/lib/stratagem/site_crawler.rb +5 -4
- data/lib/stratagem/snapshot.rb +5 -7
- data/spec/stratagem/configuration_spec.rb +32 -0
- data/stratagem.gemspec +5 -8
- data/templates/install/environments/stratagem.rb.erb +31 -2
- data/templates/install/script/stratagem +16 -0
- data/templates/install/tasks/stratagem.rake +2 -2
- metadata +36 -65
- data/bin/stratagem +0 -58
- data/lib/stratagem/scan.rb +0 -19
- data/lib/stratagem/scan/checks/email_address.rb +0 -15
- data/lib/stratagem/scan/checks/error_pages.rb +0 -25
- data/lib/stratagem/scan/result.rb +0 -45
- data/lib/stratagem/scanner.rb +0 -32
@@ -1,25 +1,14 @@
|
|
1
1
|
module Stratagem::Instrumentation::Models; end
|
2
2
|
module Stratagem::Instrumentation::Models::Adapters; end
|
3
3
|
|
4
|
+
require 'stratagem/instrumentation/models/association'
|
5
|
+
|
4
6
|
require 'stratagem/instrumentation/models/mocking'
|
5
7
|
require 'stratagem/instrumentation/models/metadata'
|
6
8
|
require 'stratagem/instrumentation/models/tracing'
|
7
9
|
require 'stratagem/instrumentation/models/annotations'
|
8
10
|
require 'stratagem/instrumentation/models/detect'
|
9
11
|
|
10
|
-
require 'stratagem/instrumentation/models/persistence'
|
11
12
|
require 'stratagem/instrumentation/models/authentication'
|
13
|
+
require 'stratagem/instrumentation/models/persistence'
|
12
14
|
require 'stratagem/instrumentation/models/support_libraries'
|
13
|
-
|
14
|
-
# base = File.join(File.dirname(__FILE__), 'models', 'persistence', 'util')
|
15
|
-
# Dir.entries(base).select {|s| s =~ /\.rb$/}.each {|helper|
|
16
|
-
# require File.join(base, helper.gsub(/\.rb/, ''))
|
17
|
-
# }
|
18
|
-
#
|
19
|
-
# base = File.join(File.dirname(__FILE__), 'models', 'persistence')
|
20
|
-
# Dir.entries(base).select {|s| s !~ /^\./ && s != 'util' }.each {|adapter_dir|
|
21
|
-
# require File.join(base, adapter_dir, 'detect')
|
22
|
-
# require File.join(base, adapter_dir, 'tracing')
|
23
|
-
# require File.join(base, adapter_dir, 'metadata')
|
24
|
-
# require File.join(base, adapter_dir, 'extensions')
|
25
|
-
# }
|
@@ -12,6 +12,36 @@ module Stratagem::Instrumentation::Models
|
|
12
12
|
def method_missing(method, *args, &block)
|
13
13
|
@object.class.stratagem.send(method, *args, &block)
|
14
14
|
end
|
15
|
+
|
16
|
+
# objects that are related to this object
|
17
|
+
def related_objects(collection_size_limit=5000)
|
18
|
+
traverse_objects(collection_size_limit)
|
19
|
+
end
|
20
|
+
|
21
|
+
def traverse_objects(collection_size_limit, collection=[], class_chain=[])
|
22
|
+
return if collection.size >= collection_size_limit
|
23
|
+
|
24
|
+
unless collection.include?(@object)
|
25
|
+
collection << @object
|
26
|
+
relations(:has_many).each do |relation|
|
27
|
+
puts "relation #{relation.name} - #{collection.size} - #{relation.klass}"
|
28
|
+
if (relation.klass && !class_chain.include?(relation.klass))
|
29
|
+
class_chain << relation.klass
|
30
|
+
begin
|
31
|
+
related = @object.send(relation.name)
|
32
|
+
if (related.kind_of?(Array))
|
33
|
+
related.each {|r| r.stratagem.traverse_objects(collection_size_limit, collection, class_chain) }
|
34
|
+
elsif (!related.nil?)
|
35
|
+
related.stratagem.traverse_objects(collection_size_limit, collection, class_chain)
|
36
|
+
end
|
37
|
+
rescue
|
38
|
+
Stratagem.logger.error($!)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
collection
|
44
|
+
end
|
15
45
|
end
|
16
46
|
|
17
47
|
class Annotations
|
@@ -43,8 +73,12 @@ module Stratagem::Instrumentation::Models
|
|
43
73
|
# connect the adapters
|
44
74
|
detect_adapters(model).each {|adapter|
|
45
75
|
if adapter.detector.supports?(model)
|
46
|
-
|
47
|
-
|
76
|
+
begin
|
77
|
+
puts "#{model.name} supports #{adapter.tracing.name}"
|
78
|
+
model.send(:include, adapter.tracing)
|
79
|
+
rescue
|
80
|
+
Rails.logger.error($!)
|
81
|
+
end
|
48
82
|
end
|
49
83
|
}
|
50
84
|
end
|
@@ -75,14 +109,14 @@ module Stratagem::Instrumentation::Models
|
|
75
109
|
end
|
76
110
|
|
77
111
|
def initialize(model)
|
78
|
-
puts "initializing stratagem for #{model.name}
|
112
|
+
puts "initializing stratagem for #{model.name}"
|
79
113
|
@model = model
|
80
114
|
self.class.detect_adapters(model).each do |adapter|
|
81
115
|
if adapter.detector.supports?(model)
|
82
116
|
# puts "\t#{model.name} supports #{adapter.detector.name}"
|
83
117
|
instrument_model(adapter)
|
84
|
-
|
85
|
-
|
118
|
+
else
|
119
|
+
# puts "#{model.name} does not support #{adapter.detector.name}"
|
86
120
|
end
|
87
121
|
end
|
88
122
|
rescue
|
@@ -2,6 +2,7 @@ module Stratagem::Instrumentation::Models::Authentication::Authlogic
|
|
2
2
|
class Detect < Stratagem::Instrumentation::Models::Detect
|
3
3
|
def self.supports?(model)
|
4
4
|
begin
|
5
|
+
# puts "AUTHLOGIC MODEL #{model.name} - #{model.ancestors.include?(::Authlogic::ActsAsAuthentic::MagicColumns::Methods)}"
|
5
6
|
model.ancestors.include?(::Authlogic::ActsAsAuthentic::MagicColumns::Methods)
|
6
7
|
rescue
|
7
8
|
false
|
@@ -2,7 +2,7 @@ module Stratagem::Instrumentation::Models::Authentication::Devise
|
|
2
2
|
class Detect < Stratagem::Instrumentation::Models::Detect
|
3
3
|
def self.supports?(model)
|
4
4
|
begin
|
5
|
-
model.ancestors.find {|a| a.name.include?
|
5
|
+
model.ancestors.find {|a| a.name && a.name.include?('Devise::Models') } != nil
|
6
6
|
rescue
|
7
7
|
false
|
8
8
|
end
|
@@ -25,6 +25,10 @@ module Stratagem::Instrumentation::Models
|
|
25
25
|
|
26
26
|
# Convenience methods
|
27
27
|
|
28
|
+
def connected_classes
|
29
|
+
traverse_graph(model) - [model]
|
30
|
+
end
|
31
|
+
|
28
32
|
def subclasses?
|
29
33
|
model.sg_subclasses().size > 0
|
30
34
|
end
|
@@ -61,7 +65,9 @@ module Stratagem::Instrumentation::Models
|
|
61
65
|
end
|
62
66
|
|
63
67
|
def callbacks
|
64
|
-
adapters.select {|a|
|
68
|
+
adapters.select {|a|
|
69
|
+
a.detector.supports?(model)
|
70
|
+
}.map {|a| a.metadata }
|
65
71
|
end
|
66
72
|
|
67
73
|
def validators
|
@@ -71,6 +77,7 @@ module Stratagem::Instrumentation::Models
|
|
71
77
|
private
|
72
78
|
|
73
79
|
def run_callbacks(method, *args)
|
80
|
+
puts "#{self.class.name} model" if (method == :attribute_names)
|
74
81
|
results = callbacks.inject([]) {|memory,callback|
|
75
82
|
begin
|
76
83
|
memory << callback.send(method, *args) if callback.methods_include?(method)
|
@@ -82,5 +89,20 @@ module Stratagem::Instrumentation::Models
|
|
82
89
|
results.flatten.compact.uniq
|
83
90
|
end
|
84
91
|
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
# see connected_classes
|
96
|
+
def traverse_graph(application_class, class_chain=[])
|
97
|
+
class_chain << application_class
|
98
|
+
application_class.stratagem.relations.each do |relation|
|
99
|
+
traverse_graph(relation.from_class, class_chain) unless class_chain.include?(relation.from_class)
|
100
|
+
traverse_graph(relation.klass, class_chain) unless class_chain.include?(relation.klass)
|
101
|
+
end
|
102
|
+
puts class_chain.map {|c| c.name }.join(" -> ")
|
103
|
+
class_chain
|
104
|
+
end
|
105
|
+
|
106
|
+
|
85
107
|
end
|
86
108
|
end
|
@@ -2,8 +2,7 @@ module Stratagem::Instrumentation::Models::Persistence; end
|
|
2
2
|
|
3
3
|
base = File.join(File.dirname(__FILE__), 'persistence')
|
4
4
|
Dir.entries(base).select {|s| s !~ /^\./ && s != 'util' }.each {|adapter_dir|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
require File.join(base, adapter_dir, 'extensions')
|
5
|
+
['detect', 'tracing', 'metadata', 'extensions'].each do |extension|
|
6
|
+
require File.join(base, adapter_dir, extension) if File.exists?(File.join(base, adapter_dir, extension+'.rb'))
|
7
|
+
end
|
9
8
|
}
|
@@ -7,7 +7,7 @@ module Stratagem::Instrumentation::Models::Persistence::ActiveRecord
|
|
7
7
|
begin
|
8
8
|
@instance = @model.new unless (@model == ActiveRecord::Base)
|
9
9
|
rescue
|
10
|
-
puts "ERROR: #{@model
|
10
|
+
puts "ERROR: #{@model} could not be instantiated: #{$!.message}"
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -23,7 +23,7 @@ module Stratagem::Instrumentation::Models::Persistence::ActiveRecord
|
|
23
23
|
begin
|
24
24
|
Stratagem::Instrumentation::Models::Association.new(model, a.name.to_sym, a.association_foreign_key.to_sym, klass, a.macro, a.options)
|
25
25
|
rescue
|
26
|
-
puts "ERROR: #{$!.message}"
|
26
|
+
puts "METADATA ERROR: #{$!.message}"
|
27
27
|
end
|
28
28
|
}.compact
|
29
29
|
end
|
@@ -18,7 +18,7 @@ get '/' do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
get '/credentials' do
|
21
|
-
Stratagem::Authentication.instance.store_credentials(params[:
|
21
|
+
Stratagem::Authentication.instance.store_credentials(params[:api_key], params[:project])
|
22
22
|
redirect '/'
|
23
23
|
end
|
24
24
|
|
@@ -27,9 +27,15 @@ get '/logs' do
|
|
27
27
|
logger = Stratagem.logger
|
28
28
|
logs = [logger.pop]
|
29
29
|
logs << logger.pop until logger.empty?
|
30
|
-
logs.
|
30
|
+
logs.map {|log|
|
31
|
+
{
|
32
|
+
:phase => log.phase,
|
33
|
+
:details => log.details,
|
34
|
+
:level => log.level
|
35
|
+
}
|
36
|
+
}.to_json
|
31
37
|
else
|
32
|
-
|
38
|
+
null
|
33
39
|
end
|
34
40
|
end
|
35
41
|
|
@@ -2,24 +2,26 @@ $(document).ready(function() {
|
|
2
2
|
var currentPhase = null,
|
3
3
|
$phases = $("li");
|
4
4
|
|
5
|
+
function changePhase(name) {
|
6
|
+
$phases.removeClass("active");
|
7
|
+
$("#"+name).addClass("active");
|
8
|
+
if (name == "complete") {
|
9
|
+
window.setTimeout(function() { window.location = $("#completeUrl").attr("href"); }, 1000);
|
10
|
+
}
|
11
|
+
};
|
12
|
+
|
5
13
|
window.setInterval(function() {
|
6
14
|
$.getJSON('/logs', function(data) {
|
7
15
|
var logs = $("#logs .modeling_application ul");
|
8
|
-
if (data == null)
|
9
|
-
|
16
|
+
if (data == null) {
|
17
|
+
changePhase("complete");
|
18
|
+
}
|
10
19
|
|
11
20
|
$.each(data, function(idx, val) {
|
12
|
-
var phase = val[
|
13
|
-
|
14
|
-
|
21
|
+
var phase = val['phase'];
|
22
|
+
|
15
23
|
if (phase != currentPhase) {
|
16
|
-
|
17
|
-
$("#"+phase).addClass("active");
|
18
|
-
|
19
|
-
if (phase == "complete")
|
20
|
-
window.setTimeout(function() {
|
21
|
-
window.location = $("#completeUrl").attr("href");
|
22
|
-
}, 1000);
|
24
|
+
changePhase(phase);
|
23
25
|
}
|
24
26
|
});
|
25
27
|
});
|
@@ -1,4 +1,4 @@
|
|
1
|
-
- phases = ['modeling application', 'mocking models', 'traversing site', '
|
1
|
+
- phases = ['modeling application', 'mocking models', 'traversing site', 'exporting']
|
2
2
|
|
3
3
|
%html
|
4
4
|
%head
|
@@ -26,9 +26,9 @@
|
|
26
26
|
%li{:id => "#{phases[2].gsub(/\s/, '_')}"}
|
27
27
|
crawling your website
|
28
28
|
%li{:id => "#{phases[3].gsub(/\s/, '_')}"}
|
29
|
-
|
29
|
+
exporting security snapshot
|
30
30
|
%li#complete
|
31
|
-
|
31
|
+
complete
|
32
32
|
%li{:style => "display:none"}
|
33
33
|
%a{:id => "completeUrl", :href => Stratagem::Authentication.instance.project_url}
|
34
34
|
|
data/lib/stratagem/logger.rb
CHANGED
@@ -7,9 +7,15 @@ module Stratagem
|
|
7
7
|
|
8
8
|
MESSAGE_QUEUE = []
|
9
9
|
|
10
|
-
Message = Struct.new(:phase, :timestamp, :details)
|
10
|
+
Message = Struct.new(:phase, :timestamp, :details, :level)
|
11
11
|
@@blocker = Blocker.new()
|
12
12
|
|
13
|
+
attr_reader :errors
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@errors = []
|
17
|
+
end
|
18
|
+
|
13
19
|
def phase(phase)
|
14
20
|
@phase = phase
|
15
21
|
end
|
@@ -18,8 +24,17 @@ module Stratagem
|
|
18
24
|
add(Message.new(@phase, Time.now, message))
|
19
25
|
end
|
20
26
|
|
27
|
+
def error(exception)
|
28
|
+
puts exception.message
|
29
|
+
puts exception.backtrace
|
30
|
+
@errors << create_error(exception)
|
31
|
+
end
|
32
|
+
|
21
33
|
def fatal(exception)
|
22
|
-
|
34
|
+
puts exception.message
|
35
|
+
puts exception.backtrace
|
36
|
+
@errors << create_error(exception)
|
37
|
+
# add(Message.new(@phase, Time.now, $!.message))
|
23
38
|
end
|
24
39
|
|
25
40
|
def pop
|
@@ -33,6 +48,17 @@ module Stratagem
|
|
33
48
|
|
34
49
|
private
|
35
50
|
|
51
|
+
def create_error(exception)
|
52
|
+
if (exception.kind_of?(Exception))
|
53
|
+
{ :message => exception.message, :backtrace => exception.backtrace.slice(0,50) }
|
54
|
+
elsif (e.kind_of?(String))
|
55
|
+
{ :message => exception, :backtrace => [] }
|
56
|
+
else
|
57
|
+
puts "ERROR: unknown error type #{e.class.name}"
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
36
62
|
def add(obj)
|
37
63
|
puts obj.details
|
38
64
|
MESSAGE_QUEUE << obj
|
data/lib/stratagem/model.rb
CHANGED
@@ -3,6 +3,12 @@ end
|
|
3
3
|
|
4
4
|
require 'stratagem/model/application'
|
5
5
|
require 'stratagem/model/parse_util'
|
6
|
+
|
7
|
+
require 'stratagem/model/containers/base'
|
8
|
+
require 'stratagem/model/containers/gem'
|
9
|
+
require 'stratagem/model/containers/route'
|
10
|
+
require 'stratagem/model/containers/plugin'
|
11
|
+
|
6
12
|
require 'stratagem/model/components/base'
|
7
13
|
require 'stratagem/model/components/reference'
|
8
14
|
require 'stratagem/model/components/model'
|
@@ -16,13 +16,13 @@ module Stratagem::Model
|
|
16
16
|
|
17
17
|
def initialize
|
18
18
|
log "initializing application model"
|
19
|
-
@models =
|
20
|
-
@controllers =
|
21
|
-
@routes =
|
22
|
-
@views =
|
23
|
-
@static_files =
|
24
|
-
@gems =
|
25
|
-
@plugins =
|
19
|
+
@models = Stratagem::Model::Containers::Base.new self
|
20
|
+
@controllers = Stratagem::Model::Containers::Base.new self
|
21
|
+
@routes = Stratagem::Model::Containers::Route.new self
|
22
|
+
@views = Stratagem::Model::Containers::Base.new self
|
23
|
+
@static_files = Stratagem::Model::Containers::Base.new self
|
24
|
+
@gems = Stratagem::Model::Containers::Gem.new self
|
25
|
+
@plugins = Stratagem::Model::Containers::Plugin.new self
|
26
26
|
end
|
27
27
|
|
28
28
|
def log(msg)
|
@@ -31,7 +31,7 @@ module Stratagem::Model
|
|
31
31
|
|
32
32
|
def export
|
33
33
|
puts "exporting site model"
|
34
|
-
puts "references
|
34
|
+
puts "\tmapping #{Stratagem::Instrumentation::Models::Tracing.invocations_audit.size} references"
|
35
35
|
references = []
|
36
36
|
begin
|
37
37
|
references = Stratagem::Instrumentation::Models::Tracing.invocations_audit.uniq.map {|ia| ia.to_reference.export }.uniq
|
@@ -39,28 +39,30 @@ module Stratagem::Model
|
|
39
39
|
puts $!.message
|
40
40
|
puts $!.backtrace
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
|
+
puts "\tmapping #{Stratagem.logger.errors.size} errors"
|
44
|
+
errors = Stratagem.logger.errors.compact.uniq
|
43
45
|
begin
|
44
|
-
# references = @controllers.map {|c| c.references }.flatten.map {|r| r.export }.uniq
|
45
46
|
h = {
|
46
47
|
:rails_version => rails_version,
|
47
48
|
:rails_environment => Rails.env,
|
48
49
|
:rails_root => Rails.root.to_s,
|
49
|
-
:models => @models.export,
|
50
|
-
:controllers => @controllers.export,
|
51
|
-
:routes => @routes.export,
|
52
|
-
:views => @views.export,
|
53
|
-
:gems => @gems.export,
|
54
50
|
:plugins => @plugins.export,
|
55
|
-
:
|
56
|
-
|
51
|
+
:scanning_exceptions_attributes => errors,
|
52
|
+
|
53
|
+
:models_attributes => @models.export,
|
54
|
+
:controllers_attributes => @controllers.export,
|
55
|
+
:routes_attributes => @routes.export,
|
56
|
+
:views_attributes => @views.export,
|
57
|
+
:gems => @gems.export,
|
58
|
+
:references_attributes => references,
|
59
|
+
:site_attributes => crawler ? crawler.export : {},
|
57
60
|
}
|
58
61
|
rescue
|
59
62
|
puts $!.message
|
60
63
|
puts $!.backtrace
|
61
64
|
end
|
62
|
-
puts "
|
63
|
-
puts h.to_json
|
65
|
+
puts "Sending snapshot of #{h.to_json.size} bytes"
|
64
66
|
h
|
65
67
|
end
|
66
68
|
|
@@ -69,120 +71,5 @@ module Stratagem::Model
|
|
69
71
|
end
|
70
72
|
end
|
71
73
|
|
72
|
-
protected
|
73
|
-
|
74
|
-
class GemContainer
|
75
|
-
include Enumerable
|
76
|
-
|
77
|
-
def initialize(app_model)
|
78
|
-
@app_model = app_model
|
79
|
-
@gems = Gem.loaded_specs
|
80
|
-
end
|
81
|
-
|
82
|
-
def names
|
83
|
-
@gems.map {|g| g[0] }
|
84
|
-
end
|
85
|
-
|
86
|
-
def export(options=nil)
|
87
|
-
@gems.map {|g|
|
88
|
-
name, spec = g
|
89
|
-
[name, {:version => spec.version.version}]
|
90
|
-
}
|
91
|
-
end
|
92
|
-
|
93
|
-
def each
|
94
|
-
@gems.each {|spec| yield spec }
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
class ComponentContainer
|
99
|
-
include Enumerable
|
100
|
-
|
101
|
-
attr_reader :invalid, :missing, :parse_trees, :components, :errors
|
102
|
-
|
103
|
-
def initialize(app_model)
|
104
|
-
@app_model = app_model
|
105
|
-
@components = Set.new()
|
106
|
-
@parse_trees = {}
|
107
|
-
@invalid = []
|
108
|
-
@missing = {}
|
109
|
-
end
|
110
|
-
|
111
|
-
def export(options=nil)
|
112
|
-
{
|
113
|
-
:components => @components.to_a.map {|c| c.export }.compact,
|
114
|
-
:invalid => @invalid.map {|c| c.export }.compact
|
115
|
-
}
|
116
|
-
end
|
117
|
-
|
118
|
-
def find
|
119
|
-
@components.find{|component| yield component }
|
120
|
-
end
|
121
|
-
|
122
|
-
def clear
|
123
|
-
@components.clear
|
124
|
-
end
|
125
|
-
|
126
|
-
def size
|
127
|
-
@components.size
|
128
|
-
end
|
129
|
-
|
130
|
-
def -(other)
|
131
|
-
@components-other
|
132
|
-
end
|
133
|
-
|
134
|
-
def each
|
135
|
-
@components.each {|e| yield e }
|
136
|
-
end
|
137
|
-
|
138
|
-
def map
|
139
|
-
@components.map {|e| yield e }
|
140
|
-
end
|
141
|
-
|
142
|
-
def << (component)
|
143
|
-
if (component.kind_of?(Array))
|
144
|
-
component.each {|e|
|
145
|
-
@components << e
|
146
|
-
e.app_model = @app_model if e.methods_include?(:app_model=)
|
147
|
-
}
|
148
|
-
elsif (component.kind_of?(Exception))
|
149
|
-
errors << component
|
150
|
-
else
|
151
|
-
@components << component
|
152
|
-
component.app_model = @app_model if component.methods_include?(:app_model=)
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
class RouteContainer < ComponentContainer
|
158
|
-
def recognize(page, method = :get)
|
159
|
-
path = nil
|
160
|
-
if (page.kind_of?(Stratagem::Crawler::Page))
|
161
|
-
method = page.method
|
162
|
-
path = page.path
|
163
|
-
else
|
164
|
-
path = page
|
165
|
-
end
|
166
|
-
|
167
|
-
unless path.nil?
|
168
|
-
# path = path.gsub('http://www.example.com', '')
|
169
|
-
route = self.find {|r| r.responds_to?(path, method) }
|
170
|
-
puts "route: #{route.path}" if route
|
171
|
-
route
|
172
|
-
else
|
173
|
-
nil
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
class PluginContainer < ComponentContainer
|
179
|
-
def names
|
180
|
-
components.map {|plugin| plugin.name }
|
181
|
-
end
|
182
|
-
|
183
|
-
def export(options=nil)
|
184
|
-
names
|
185
|
-
end
|
186
|
-
end
|
187
74
|
end
|
188
75
|
|