ape 1.0.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README +22 -8
- data/Rakefile +66 -0
- data/bin/ape_server +3 -3
- data/lib/ape.rb +131 -937
- data/lib/ape/atomURI.rb +1 -1
- data/lib/ape/authent.rb +11 -17
- data/lib/ape/categories.rb +8 -7
- data/lib/ape/collection.rb +3 -7
- data/lib/ape/crumbs.rb +1 -1
- data/lib/ape/entry.rb +1 -1
- data/lib/ape/escaper.rb +1 -1
- data/lib/ape/feed.rb +26 -14
- data/lib/ape/handler.rb +8 -3
- data/lib/ape/html.rb +1 -1
- data/lib/ape/invoker.rb +1 -1
- data/lib/ape/invokers/deleter.rb +1 -1
- data/lib/ape/invokers/getter.rb +1 -1
- data/lib/ape/invokers/poster.rb +1 -1
- data/lib/ape/invokers/putter.rb +1 -1
- data/lib/ape/names.rb +1 -1
- data/lib/ape/print_writer.rb +4 -6
- data/lib/ape/reporter.rb +156 -0
- data/lib/ape/reporters/atom_reporter.rb +51 -0
- data/lib/ape/reporters/atom_template.eruby +38 -0
- data/lib/ape/reporters/html_reporter.rb +53 -0
- data/lib/ape/reporters/html_template.eruby +62 -0
- data/lib/ape/reporters/text_reporter.rb +37 -0
- data/lib/ape/samples.rb +30 -51
- data/lib/ape/server.rb +16 -4
- data/lib/ape/service.rb +1 -1
- data/lib/ape/util.rb +67 -0
- data/lib/ape/validator.rb +85 -57
- data/lib/ape/validator_dsl.rb +40 -0
- data/lib/ape/validators/entry_posts_validator.rb +226 -0
- data/lib/ape/validators/media_linkage_validator.rb +78 -0
- data/lib/ape/validators/media_posts_validator.rb +104 -0
- data/lib/ape/validators/sanitization_validator.rb +57 -0
- data/lib/ape/validators/schema_validator.rb +57 -0
- data/lib/ape/validators/service_document_validator.rb +64 -0
- data/lib/ape/validators/sorting_validator.rb +87 -0
- data/lib/ape/version.rb +1 -1
- data/{lib/ape/samples → samples}/atom_schema.txt +0 -0
- data/{lib/ape/samples → samples}/basic_entry.eruby +4 -4
- data/{lib/ape/samples → samples}/categories_schema.txt +0 -0
- data/{lib/ape/samples → samples}/mini_entry.eruby +0 -0
- data/{lib/ape/samples → samples}/service_schema.txt +0 -0
- data/{lib/ape/samples → samples}/unclean_xhtml_entry.eruby +0 -0
- data/test/test_helper.rb +33 -1
- data/test/unit/ape_test.rb +92 -0
- data/test/unit/authent_test.rb +2 -2
- data/test/unit/reporter_test.rb +102 -0
- data/test/unit/samples_test.rb +2 -2
- data/test/unit/validators_test.rb +50 -0
- data/{lib/ape/layout → web}/ape.css +5 -1
- data/{lib/ape/layout → web}/ape_logo.png +0 -0
- data/{lib/ape/layout → web}/index.html +2 -5
- data/{lib/ape/layout → web}/info.png +0 -0
- metadata +108 -56
- data/CHANGELOG +0 -1
- data/Manifest +0 -45
- data/ape.gemspec +0 -57
- data/scripts/go.rb +0 -29
@@ -0,0 +1,51 @@
|
|
1
|
+
#
|
2
|
+
# To change this template, choose Tools | Templates
|
3
|
+
# and open the template in the editor.
|
4
|
+
|
5
|
+
|
6
|
+
module Ape
|
7
|
+
class AtomReporter < Reporter
|
8
|
+
def escape(text)
|
9
|
+
Escaper.escape(text)
|
10
|
+
end
|
11
|
+
|
12
|
+
def now
|
13
|
+
DateTime::now.strftime("%Y-%m-%dT%H:%M:%S%z").sub(/(..)$/, ':\1')
|
14
|
+
end
|
15
|
+
|
16
|
+
def id
|
17
|
+
id = ''
|
18
|
+
5.times { id += rand(1000000).to_s }
|
19
|
+
"tag:tbray.org,2005:#{id}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def content(step, dialog = nil)
|
23
|
+
xml = "<div xmlns=\"http://www.w3.org/1999/xhtml\">"
|
24
|
+
lines = step.split("\n")
|
25
|
+
lines[0 .. -2].each do |line|
|
26
|
+
xml += "#{line} <br/>"
|
27
|
+
end
|
28
|
+
xml += escape(lines[-1]) if lines[-1]
|
29
|
+
if dialog && dialogs[dialog]
|
30
|
+
xml += '<div>'
|
31
|
+
xml += 'To server:'
|
32
|
+
dialogs[dialog].grep(/^>/).each do |crumb|
|
33
|
+
xml += show_message(crumb, :to)
|
34
|
+
end
|
35
|
+
xml += '</div>'
|
36
|
+
xml += '<div>'
|
37
|
+
xml += 'From server:'
|
38
|
+
dialogs[dialog].grep(/^</).each do |crumb|
|
39
|
+
xml += show_message(crumb, :from)
|
40
|
+
end
|
41
|
+
xml += '</div>'
|
42
|
+
end
|
43
|
+
xml += '</div>'
|
44
|
+
xml
|
45
|
+
end
|
46
|
+
|
47
|
+
def report(output = STDOUT)
|
48
|
+
output.puts evaluate_template("reporters/atom_template.eruby")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<feed xmlns="http://www.w3.org/2005/Atom">
|
3
|
+
<id><%= id %></id>
|
4
|
+
<author><name>The ape</name></author>
|
5
|
+
<title>Atom Protocol Exerciser Report</title>
|
6
|
+
<updated><%= now %></updated>
|
7
|
+
<subtitle><%= errors.length == 1?"1 error":"#{errors.length} errors"%>, <%= warnings.length == 1?"1 warning":"#{warnings.length} warnings"%></subtitle>
|
8
|
+
<% steps.each do |step| %>
|
9
|
+
<% if step.kind_of?(Array) %>
|
10
|
+
<entry>
|
11
|
+
<id><%= id %></id>
|
12
|
+
<title type="html"><%= "INFO: #{step[0]}"%></title>
|
13
|
+
<updated><%= now %></updated>
|
14
|
+
<category term="info"/>
|
15
|
+
<content type="xhtml">
|
16
|
+
<% step[1..-1].each do |li| %>
|
17
|
+
<%= content(li[:message]) %>
|
18
|
+
<% end %>
|
19
|
+
</content>
|
20
|
+
</entry>
|
21
|
+
<% else %>
|
22
|
+
<% if step[:severity] == :debug %>
|
23
|
+
<% @dialog = step[:message] %>
|
24
|
+
<% else %>
|
25
|
+
<entry>
|
26
|
+
<id><%= id %></id>
|
27
|
+
<title type="html"><%= step[:severity].to_s.upcase%>: <%= step[:message] %></title>
|
28
|
+
<updated><%= now %></updated>
|
29
|
+
<category term="<%= step[:severity].to_s %>"/>
|
30
|
+
<content type="xhtml">
|
31
|
+
<%= content(step[:message], @dialog) %>
|
32
|
+
</content>
|
33
|
+
</entry>
|
34
|
+
<% @dialog = nil %>
|
35
|
+
<% end %>
|
36
|
+
<% end %>
|
37
|
+
<% end %>
|
38
|
+
</feed>
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'erubis'
|
2
|
+
module Ape
|
3
|
+
class HtmlReporter < Reporter
|
4
|
+
|
5
|
+
def static_dir
|
6
|
+
dir = (server != true)?File.expand_path(File.dirname(__FILE__) + '/../../..') : ''
|
7
|
+
dir += "/web"
|
8
|
+
dir
|
9
|
+
end
|
10
|
+
|
11
|
+
def stylesheet
|
12
|
+
static_dir + '/ape.css'
|
13
|
+
end
|
14
|
+
|
15
|
+
def mark(mark)
|
16
|
+
span = "<span class=\"#{mark.to_s}\">"
|
17
|
+
case mark
|
18
|
+
when :success
|
19
|
+
span << '✓' << '</span>'
|
20
|
+
when :warning
|
21
|
+
span << '?' << '</span>'
|
22
|
+
when :error
|
23
|
+
span << '!' << '</span>'
|
24
|
+
when :info
|
25
|
+
span = "<img class=\"info\" src=\"#{static_dir + '/info.png'}\"/>"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def report_li(step, dialog = nil, marker = nil)
|
30
|
+
html = '<li>'
|
31
|
+
if marker
|
32
|
+
html += "#{mark(marker)} "
|
33
|
+
end
|
34
|
+
# preserve line-breaks in output
|
35
|
+
lines = step.split("\n")
|
36
|
+
lines[0 .. -2].each do |line|
|
37
|
+
html += "#{line} <br/>"
|
38
|
+
end
|
39
|
+
html += lines[-1] if lines[-1]
|
40
|
+
if dialog
|
41
|
+
html += "<a class=\"diaref\" href=\"#dia-#{@dianum}\">[Dialog]</a>"
|
42
|
+
@diarefs[dialog] = @dianum
|
43
|
+
@dianum += 1
|
44
|
+
end
|
45
|
+
html += '</li>'
|
46
|
+
html
|
47
|
+
end
|
48
|
+
|
49
|
+
def report(output = STDOUT)
|
50
|
+
output.puts evaluate_template("reporters/html_template.eruby")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>Atom Protocol Exerciser Report</title>
|
4
|
+
<link rel="stylesheet" type="text/css" href="<%= stylesheet %>" />
|
5
|
+
</head>
|
6
|
+
<body>
|
7
|
+
<h2>The Ape says:</h2>
|
8
|
+
<% if header %>
|
9
|
+
<p><%= header %></p>
|
10
|
+
<p>Summary: <%= errors.length == 1?"1 error":"#{errors.length} errors"%>,
|
11
|
+
<%= warnings.length == 1?"1 warning":"#{warnings.length} warnings"%>
|
12
|
+
</p>
|
13
|
+
<% end %>
|
14
|
+
<ol id="steps">
|
15
|
+
<% steps.each do |step| %>
|
16
|
+
<% if step.kind_of?(Array) %>
|
17
|
+
<li>
|
18
|
+
<p><%= mark(:info) %> <%= step[0] %></p>
|
19
|
+
<ul>
|
20
|
+
<% step[1..-1].each do |li| %>
|
21
|
+
<%= report_li(li[:message]) %>
|
22
|
+
<% end %>
|
23
|
+
</ul>
|
24
|
+
</li>
|
25
|
+
<% else %>
|
26
|
+
<% if step[:severity] == :debug %>
|
27
|
+
<% @dialog = step[:message] %>
|
28
|
+
<% else %>
|
29
|
+
<%= report_li(step[:message], @dialog, step[:severity])%>
|
30
|
+
<% @dialog = nil %>
|
31
|
+
<% end %>
|
32
|
+
<% end %>
|
33
|
+
<% end %>
|
34
|
+
</ol>
|
35
|
+
|
36
|
+
<% if footer %>
|
37
|
+
<p><%= footer %></p>
|
38
|
+
<% end %>
|
39
|
+
|
40
|
+
<% unless dialogs.empty? %>
|
41
|
+
<h2>Recorded client/server dialogs</h2>
|
42
|
+
<% diarefs.each do |k, v| %>
|
43
|
+
<% @dialog = @dialogs[k] %>
|
44
|
+
<h3 id="<%="dia-#{v}"%>"><%= k %></h3>
|
45
|
+
<div class="dialog">
|
46
|
+
<div class="dialab">
|
47
|
+
To server:
|
48
|
+
<% @dialog.grep(/^>/).each do |crumb| %>
|
49
|
+
<%= show_message(crumb, :to) %>
|
50
|
+
<% end %>
|
51
|
+
</div>
|
52
|
+
<div class="dialab">
|
53
|
+
From server:
|
54
|
+
<% @dialog.grep(/^</).each do |crumb| %>
|
55
|
+
<%= show_message(crumb, :from) %>
|
56
|
+
<% end %>
|
57
|
+
</div>
|
58
|
+
</div>
|
59
|
+
<% end %>
|
60
|
+
<% end %>
|
61
|
+
</body>
|
62
|
+
</html>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Ape
|
2
|
+
class TextReporter < Reporter
|
3
|
+
def report(output = STDOUT)
|
4
|
+
if @header
|
5
|
+
output.puts @header
|
6
|
+
output.puts errors.length == 1?"1 error":"#{errors.length} errors"
|
7
|
+
output.puts warnings.length == 1?"1 warning":"#{warnings.length} warnings"
|
8
|
+
end
|
9
|
+
steps.each do |step|
|
10
|
+
if step.class == Crumbs
|
11
|
+
output.puts " Dialog:"
|
12
|
+
step.each { |crumb| output.puts " #{crumb}" }
|
13
|
+
else
|
14
|
+
line
|
15
|
+
if (step.kind_of?Array)
|
16
|
+
output.puts "INFO: #{step[0]}"
|
17
|
+
step[1..-1].each do |li|
|
18
|
+
lines = li[:message].split("\n")
|
19
|
+
lines[0..-2].each do |line|
|
20
|
+
output.puts("\t #{line} \n")
|
21
|
+
end
|
22
|
+
output.puts("\t #{lines[-1]}") if lines[-1]
|
23
|
+
end
|
24
|
+
else
|
25
|
+
case step[:severity]
|
26
|
+
when :warning, :error
|
27
|
+
output.puts "#{step[:severity].to_s.upcase}: #{step[:message]}"
|
28
|
+
else
|
29
|
+
output.puts step[:message]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
output.puts @footer if @footer
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/ape/samples.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright
|
1
|
+
# Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved
|
2
2
|
# Use is subject to license terms - see file "LICENSE"
|
3
3
|
require 'rexml/xpath'
|
4
4
|
require 'date'
|
@@ -6,17 +6,23 @@ require 'base64'
|
|
6
6
|
require 'erubis'
|
7
7
|
|
8
8
|
module Ape
|
9
|
+
class SamplesContext < Erubis::Context
|
10
|
+
def now
|
11
|
+
DateTime::now.strftime("%Y-%m-%dT%H:%M:%S%z").sub(/(..)$/, ':\1')
|
12
|
+
end
|
13
|
+
def id
|
14
|
+
id = ''
|
15
|
+
5.times { id += rand(1000000).to_s }
|
16
|
+
"tag:tbray.org,2005:#{id}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
9
20
|
class Samples
|
10
21
|
|
11
22
|
@@service_schema = nil
|
12
23
|
@@categories_schema = nil
|
13
24
|
@@atom_schema = nil
|
14
|
-
@@home = nil
|
15
25
|
|
16
|
-
def Samples.home=(home)
|
17
|
-
@@home = home
|
18
|
-
end
|
19
|
-
|
20
26
|
def Samples.foreign_child
|
21
27
|
'subject'
|
22
28
|
end
|
@@ -28,13 +34,7 @@ module Ape
|
|
28
34
|
end
|
29
35
|
|
30
36
|
def Samples.load_schema(file_name)
|
31
|
-
|
32
|
-
File.open(File.join(File.dirname(__FILE__), "/samples/#{file_name}_schema.txt")) do |file|
|
33
|
-
while(line = file.gets)
|
34
|
-
schema << line
|
35
|
-
end
|
36
|
-
end
|
37
|
-
schema
|
37
|
+
IO.read(File.join(File.dirname(__FILE__), "/../../samples/#{file_name}_schema.txt"))
|
38
38
|
end
|
39
39
|
|
40
40
|
def Samples.service_RNC
|
@@ -52,15 +52,7 @@ module Ape
|
|
52
52
|
@@atom_schema
|
53
53
|
end
|
54
54
|
|
55
|
-
#recipe from cap
|
56
|
-
def Samples.home_directory
|
57
|
-
ENV["HOME"] || (ENV["HOMEPATH"] && "#{ENV["HOMEDRIVE"]}#{ENV["HOMEPATH"]}") ||
|
58
|
-
"/"
|
59
|
-
end
|
60
55
|
|
61
|
-
def Samples.home
|
62
|
-
@@home || ENV["APE_HOME"] || File.join(home_directory,".ape")
|
63
|
-
end
|
64
56
|
|
65
57
|
def Samples.make_id
|
66
58
|
id = ''
|
@@ -69,57 +61,44 @@ module Ape
|
|
69
61
|
end
|
70
62
|
|
71
63
|
def Samples.entry_path(type)
|
72
|
-
File.exist?(File.join(home, "/#{type}.eruby"))?
|
73
|
-
File.join(home, "/#{type}.eruby") :
|
74
|
-
File.join(File.dirname(__FILE__), "
|
64
|
+
File.exist?(File.join(Ape.home, "/#{type}.eruby"))?
|
65
|
+
File.join(Ape.home, "/#{type}.eruby") :
|
66
|
+
File.join(File.dirname(__FILE__), "/../../samples/#{type}.eruby")
|
75
67
|
end
|
76
68
|
|
77
69
|
def Samples.load_template(type)
|
78
|
-
entry_path
|
79
|
-
input = File.read(entry_path)
|
80
|
-
eruby = Erubis::Eruby.new(input)
|
70
|
+
Erubis::FastEruby.new(IO.read(entry_path(type)))
|
81
71
|
end
|
82
72
|
|
83
73
|
|
84
74
|
def Samples.mini_entry
|
85
|
-
|
86
|
-
|
87
|
-
now = DateTime::now.strftime("%Y-%m-%dT%H:%M:%S%z").sub(/(..)$/, ':\1')
|
88
|
-
id = make_id
|
89
|
-
|
90
|
-
eruby.result(binding())
|
75
|
+
load_template('mini_entry').evaluate(SamplesContext.new)
|
91
76
|
end
|
92
77
|
|
93
78
|
def Samples.basic_entry
|
94
|
-
eruby = load_template('basic_entry')
|
79
|
+
eruby = load_template('basic_entry')
|
80
|
+
|
81
|
+
context = SamplesContext.new(
|
82
|
+
:title => Escaper.escape('From the <APE> (サル)'),
|
83
|
+
:subject => Names::DcNamespace
|
84
|
+
)
|
85
|
+
context[:summary] = "Summary from the <b>&lt;&nbsp;APE&nbsp;></b> at #{context.now}"
|
95
86
|
|
96
|
-
|
97
|
-
now = DateTime::now.strftime("%Y-%m-%dT%H:%M:%S%z").sub(/(..)$/, ':\1')
|
98
|
-
title = Escaper.escape('From the <APE> (サル)')
|
99
|
-
summary = "Summary from the <b>&lt;&nbsp;APE&nbsp;></b> at #{now}"
|
100
|
-
subject = Names::DcNamespace
|
101
|
-
|
102
|
-
eruby.result(binding())
|
87
|
+
eruby.evaluate(context)
|
103
88
|
end
|
104
89
|
|
105
90
|
def Samples.unclean_xhtml_entry
|
106
|
-
|
107
|
-
|
108
|
-
id = make_id
|
109
|
-
now = DateTime::now.strftime("%Y-%m-%dT%H:%M:%S%z").sub(/(..)$/, ':\1')
|
110
|
-
|
111
|
-
eruby.result(binding())
|
91
|
+
load_template('unclean_xhtml_entry').evaluate(SamplesContext.new)
|
112
92
|
end
|
113
93
|
|
114
94
|
def Samples.cat_test_entry
|
115
|
-
|
95
|
+
retitled_entry('Testing category posting')
|
116
96
|
end
|
117
97
|
|
118
98
|
def Samples.retitled_entry(new_title, new_id = nil)
|
119
99
|
e = basic_entry
|
120
|
-
e.gsub!(/<title>.*<\/title>/, "<title>#{new_title}</title>")
|
121
|
-
new_id
|
122
|
-
e.gsub(/<id>.*<\/id>/, "<id>#{new_id}</id>")
|
100
|
+
e.gsub!(/<title>.*<\/title>/, "<title>#{new_title}</title>")
|
101
|
+
e.gsub(/<id>.*<\/id>/, "<id>#{new_id}</id>") if new_id
|
123
102
|
end
|
124
103
|
|
125
104
|
def Samples.picture
|
data/lib/ape/server.rb
CHANGED
@@ -4,18 +4,30 @@ require 'ape/handler'
|
|
4
4
|
require 'ape/samples'
|
5
5
|
|
6
6
|
module Ape
|
7
|
+
|
8
|
+
# Manages and initializes the Mongrel handler. See run for more details.
|
7
9
|
class Server
|
10
|
+
|
11
|
+
# Starts the Mongrel handler with options given in +options+ and
|
12
|
+
# maps the <b>/</b>, <b>/ape</b> and <b>/atompub/go</b> URIs to handlers.
|
13
|
+
#
|
14
|
+
# ==== Options
|
15
|
+
# * :host - the IP address to bind to
|
16
|
+
# * :port - the port number to listen on
|
17
|
+
# * :directory - the ape home directory
|
8
18
|
def self.run(options)
|
9
|
-
|
19
|
+
Ape.home = options[:home]
|
10
20
|
|
11
21
|
mongrel = Mongrel::Configurator.new(:host => options[:host], :port => options[:port]) do
|
12
22
|
log "=> Booting mongrel"
|
13
23
|
begin
|
14
24
|
log "=> The ape starting on http://#{options[:host]}:#{options[:port]}"
|
15
25
|
listener do
|
16
|
-
redirect '/', '/
|
17
|
-
uri '/
|
18
|
-
|
26
|
+
redirect '/', '/web/index.html'
|
27
|
+
uri '/web', :handler =>
|
28
|
+
Mongrel::DirHandler.new(
|
29
|
+
File.expand_path(File.dirname(__FILE__) + '/../../web'), true)
|
30
|
+
uri '/atompub/go', :handler => Handler.new
|
19
31
|
end
|
20
32
|
rescue Errno::EADDRINUSE
|
21
33
|
log "ERROR: Address (#{options[:host]}:#{options[:port]}) is already in use"
|
data/lib/ape/service.rb
CHANGED
data/lib/ape/util.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
module Ape
|
2
|
+
module Util
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
include InstanceMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module InstanceMethods
|
9
|
+
=begin
|
10
|
+
Get a resource, optionally check its content-type
|
11
|
+
=end
|
12
|
+
def check_resource(uri, name, content_type = nil, report = true)
|
13
|
+
resource = Getter.new(uri, @authent)
|
14
|
+
|
15
|
+
# * Check the URI
|
16
|
+
if resource.last_error
|
17
|
+
reporter.error(self, "Unacceptable #{name} URI: " + resource.last_error, name) if report
|
18
|
+
return nil
|
19
|
+
end
|
20
|
+
|
21
|
+
# * Get it, make sure it has the right content-type
|
22
|
+
worked = resource.get(content_type)
|
23
|
+
reporter.save_dialog(name, resource)
|
24
|
+
|
25
|
+
reporter.security_warning(self) if (resource.security_warning)
|
26
|
+
|
27
|
+
if !worked
|
28
|
+
# oops, couldn't even get get it
|
29
|
+
reporter.error(self, "#{name} failed: " + resource.last_error, name) if report
|
30
|
+
return nil
|
31
|
+
|
32
|
+
elsif resource.last_error
|
33
|
+
# oops, media-type problem
|
34
|
+
reporter.error(self, "#{name}: #{resource.last_error}", name) if report
|
35
|
+
|
36
|
+
else
|
37
|
+
# resource fetched and is of right type
|
38
|
+
reporter.success(self, "#{name}: it exists and is served properly.", name) if report
|
39
|
+
end
|
40
|
+
|
41
|
+
return resource
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module ClassMethods
|
46
|
+
=begin
|
47
|
+
Resolve extensions into the lib directory or into the ape home directory. These extensions could be validators,
|
48
|
+
resolvers or samples.
|
49
|
+
=end
|
50
|
+
def resolve_plugin(key, dir, suffix, drop_underlines = false)
|
51
|
+
[File.dirname(__FILE__), Ape.home].each do |path|
|
52
|
+
Dir[File.join(path, "#{dir}/*.rb")].each do |file|
|
53
|
+
require file
|
54
|
+
plugin_name = file.gsub(/(.+\/#{dir}\/)(.+)(_#{suffix}.rb)/, '\2')
|
55
|
+
plugin_name.gsub!(/_/, '') if drop_underlines
|
56
|
+
plugin_class = file.gsub(/(.+\/#{dir}\/)(.+)(.rb)/, '\2').gsub(/(^|_)(.)/) { $2.upcase }
|
57
|
+
|
58
|
+
if (key.to_s.strip.downcase.include?(plugin_name))
|
59
|
+
return eval("#{plugin_class}.new", binding, __FILE__, __LINE__)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
return nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|