mack 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +6 -1
- data/lib/core_extensions/string.rb +0 -35
- data/lib/distributed/errors/errors.rb +27 -0
- data/lib/distributed/routing/url_cache.rb +10 -0
- data/lib/distributed/routing/urls.rb +48 -0
- data/lib/generators/generator_base.rb +1 -3
- data/lib/initialization/configuration.rb +29 -38
- data/lib/initialization/console.rb +1 -1
- data/lib/initialization/initializer.rb +3 -2
- data/lib/rendering/base.rb +2 -4
- data/lib/rendering/classes/url.rb +1 -1
- data/lib/routing/route_map.rb +27 -9
- data/lib/routing/urls.rb +37 -1
- data/lib/sea_level/controller_base.rb +3 -3
- data/lib/sea_level/request.rb +2 -2
- data/lib/tasks/mack_dump_tasks.rake +50 -0
- data/lib/tasks/mack_server_tasks.rake +48 -0
- data/lib/tasks/mack_tasks.rake +20 -29
- data/lib/test_extensions/test_helpers.rb +6 -0
- data/lib/utils/crypt/keeper.rb +1 -1
- data/lib/utils/html.rb +1 -1
- data/tasks/gem_helper.rb +48 -0
- data/tasks/gem_tasks.rake +93 -0
- metadata +13 -13
- data/lib/core_extensions/hash.rb +0 -39
- data/lib/core_extensions/module.rb +0 -29
- data/lib/core_extensions/nil.rb +0 -8
- data/lib/core_extensions/object.rb +0 -9
- data/lib/tasks/script_tasks.rake +0 -44
- data/lib/utils/inflections.rb +0 -62
- data/lib/utils/inflector.rb +0 -129
data/CHANGELOG
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
===0.4.0
|
2
|
+
* Added Distributed Routes!
|
3
|
+
* gem: mack_ruby_core_extensions 0.1.3
|
4
|
+
* removed gem: ruby_extensions
|
5
|
+
|
1
6
|
===0.3.0
|
2
7
|
* Ticket: #8 Xml Builder Support
|
3
8
|
* Ticket: #7 Ability to drive certain content based on 'format'
|
@@ -37,4 +42,4 @@
|
|
37
42
|
|
38
43
|
===0.0.4
|
39
44
|
* gem: rack 0.3.0
|
40
|
-
* gem: ruby_extensions 1.0.11
|
45
|
+
* gem: ruby_extensions 1.0.11
|
@@ -1,40 +1,5 @@
|
|
1
1
|
class String
|
2
2
|
|
3
|
-
# Camel cases the string.
|
4
|
-
#
|
5
|
-
# Examples:
|
6
|
-
# "user".camelcase # => User
|
7
|
-
# "my_blog".camelcase # => MyBlog
|
8
|
-
# "my/blog".camelcase # => My::Blog
|
9
|
-
def camelcase
|
10
|
-
self.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
11
|
-
end
|
12
|
-
|
13
|
-
# Returns a constant of the string.
|
14
|
-
#
|
15
|
-
# Examples:
|
16
|
-
# "User".constantize # => User
|
17
|
-
# "HomeController".constantize # => HomeController
|
18
|
-
# "Mack::Configuration" # => Mack::Configuration
|
19
|
-
def constantize
|
20
|
-
Module.instance_eval("::#{self}")
|
21
|
-
end
|
22
|
-
|
23
|
-
# If the string is empty, this will return true.
|
24
|
-
def blank?
|
25
|
-
self == ""
|
26
|
-
end
|
27
|
-
|
28
|
-
# Maps to Mack::Utils::Inflector.instance.pluralize
|
29
|
-
def plural
|
30
|
-
Mack::Utils::Inflector.instance.pluralize(self)
|
31
|
-
end
|
32
|
-
|
33
|
-
# Maps to Mack::Utils::Inflector.instance.singularize
|
34
|
-
def singular
|
35
|
-
Mack::Utils::Inflector.instance.singularize(self)
|
36
|
-
end
|
37
|
-
|
38
3
|
# Maps to Kernel _encrypt
|
39
4
|
#
|
40
5
|
# Examples:
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Mack
|
2
|
+
module Distributed # :nodoc:
|
3
|
+
module Errors # :nodoc:
|
4
|
+
|
5
|
+
# Raised when an unknown distributed application is referenced.
|
6
|
+
class UnknownApplication < StandardError
|
7
|
+
# Takes the application name.
|
8
|
+
def initialize(app_name)
|
9
|
+
super("APPLICATION: #{app_name} is not a known/registered distributed application.")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Raised when an unknown distributed route name for a distributed application is referenced.
|
14
|
+
class UnknownRouteName < StandardError
|
15
|
+
# Takes the application name and the route name.
|
16
|
+
def initialize(app_name, route_name)
|
17
|
+
super("ROUTE_NAME: #{route_name}, is not a known/registered distributed route name for application: #{app_name}.")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Raised when an application doesn't declare it's application name for use in a distributed system.
|
22
|
+
class ApplicationNameUndefined < StandardError
|
23
|
+
end
|
24
|
+
|
25
|
+
end # Errors
|
26
|
+
end # Distributed
|
27
|
+
end # Mack
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Mack
|
2
|
+
module Distributed
|
3
|
+
module Routes # :nodoc:
|
4
|
+
# Used to house the Mack::Distributed::Routes::Urls object for each distributed application.
|
5
|
+
class UrlCache < Cachetastic::Caches::Base
|
6
|
+
|
7
|
+
end # UrlCache
|
8
|
+
end # Routes
|
9
|
+
end # Distributed
|
10
|
+
end # Mack
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Mack
|
2
|
+
module Distributed
|
3
|
+
module Routes
|
4
|
+
# A class used to house the Mack::Routes::Url module for distributed applications.
|
5
|
+
# Functionally this class does nothing, but since you can't cache a module, a class is needed.
|
6
|
+
class Urls
|
7
|
+
|
8
|
+
def initialize(dsd) # :nodoc:
|
9
|
+
@dsd = dsd
|
10
|
+
@url_method_list = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
# def add_url_method(key, meth)
|
14
|
+
# @url_method_list[key.to_sym] = meth
|
15
|
+
# end
|
16
|
+
|
17
|
+
def []=(key, method)
|
18
|
+
@url_method_list[key.to_sym] = method
|
19
|
+
@runner = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def run
|
23
|
+
if @runner.nil?
|
24
|
+
klass_name = String.randomize(40).downcase.camelcase
|
25
|
+
meths = ""
|
26
|
+
@url_method_list.each_pair {|k,v| meths += v + "\n\n"}
|
27
|
+
eval %{
|
28
|
+
class Mack::Distributed::Routes::Temp::M#{klass_name}
|
29
|
+
include Mack::Routes::Urls
|
30
|
+
def initialize(dsd)
|
31
|
+
@dsd = dsd
|
32
|
+
end
|
33
|
+
#{meths}
|
34
|
+
end
|
35
|
+
}
|
36
|
+
@runner = "Mack::Distributed::Routes::Temp::M#{klass_name}".constantize.new(@dsd)
|
37
|
+
end
|
38
|
+
@runner
|
39
|
+
end
|
40
|
+
|
41
|
+
end # Urls
|
42
|
+
|
43
|
+
module Temp # :nodoc:
|
44
|
+
end # Temp
|
45
|
+
|
46
|
+
end # Routes
|
47
|
+
end # Distributed
|
48
|
+
end # Mack
|
@@ -49,9 +49,7 @@ module Mack
|
|
49
49
|
end
|
50
50
|
|
51
51
|
# Needs to be implemented by the subclass.
|
52
|
-
|
53
|
-
raise MethodNotImplemented.new("generate")
|
54
|
-
end
|
52
|
+
needs_method :generate
|
55
53
|
|
56
54
|
# Takes an input_file runs it through ERB and
|
57
55
|
# saves it to the specified output_file. If the output_file exists it will
|
@@ -11,17 +11,6 @@ module Mack
|
|
11
11
|
"mack::show_exceptions" => false,
|
12
12
|
"log::level" => "info",
|
13
13
|
"log::detailed_requests" => false,
|
14
|
-
"cachetastic_default_options" => {
|
15
|
-
"debug" => false,
|
16
|
-
"adapter" => "local_memory",
|
17
|
-
"expiry_time" => 86400,
|
18
|
-
"logging" => {
|
19
|
-
"logger_1" => {
|
20
|
-
"type" => "file",
|
21
|
-
"file" => File.join(MACK_ROOT, "log", "cachetastic.log")
|
22
|
-
}
|
23
|
-
}
|
24
|
-
},
|
25
14
|
"cachetastic_caches_mack_session_cache_options" => {
|
26
15
|
"debug" => false,
|
27
16
|
"adapter" => "file",
|
@@ -31,7 +20,7 @@ module Mack
|
|
31
20
|
"logging" => {
|
32
21
|
"logger_1" => {
|
33
22
|
"type" => "file",
|
34
|
-
"file" => File.join(MACK_ROOT, "log", "
|
23
|
+
"file" => File.join(MACK_ROOT, "log", "cachetastic_caches_mack_session_cache.log")
|
35
24
|
}
|
36
25
|
}
|
37
26
|
}
|
@@ -40,39 +29,14 @@ module Mack
|
|
40
29
|
# use local memory and store stuff for 5 minutes:
|
41
30
|
DEFAULTS_DEVELOPMENT = {
|
42
31
|
"mack::cache_classes" => false,
|
43
|
-
"mack::default_domain" => "http://localhost:3000",
|
44
32
|
"log::level" => "debug",
|
45
33
|
"log::console" => true,
|
46
|
-
"cachetastic_default_options" => {
|
47
|
-
"debug" => false,
|
48
|
-
"adapter" => "local_memory",
|
49
|
-
"expiry_time" => 300,
|
50
|
-
"logging" => {
|
51
|
-
"logger_1" => {
|
52
|
-
"type" => "file",
|
53
|
-
"file" => File.join(MACK_ROOT, "log", "cachetastic.log")
|
54
|
-
}
|
55
|
-
}
|
56
|
-
}
|
57
34
|
} unless self.const_defined?("DEFAULTS_DEVELOPMENT")
|
58
35
|
|
59
36
|
# use local memory and store stuff for 1 hour:
|
60
37
|
DEFAULTS_TEST = {
|
61
|
-
"mack::default_domain" => "http://localhost",
|
62
|
-
"mack::default_domain_port" => 6666,
|
63
38
|
"log::level" => "error",
|
64
39
|
"run_remote_tests" => true,
|
65
|
-
"cachetastic_default_options" => {
|
66
|
-
"debug" => false,
|
67
|
-
"adapter" => "local_memory",
|
68
|
-
"expiry_time" => 3600,
|
69
|
-
"logging" => {
|
70
|
-
"logger_1" => {
|
71
|
-
"type" => "file",
|
72
|
-
"file" => File.join(MACK_ROOT, "log", "cachetastic.log")
|
73
|
-
}
|
74
|
-
}
|
75
|
-
}
|
76
40
|
} unless self.const_defined?("DEFAULTS_TEST")
|
77
41
|
|
78
42
|
unless self.const_defined?("DEFAULTS")
|
@@ -86,7 +50,34 @@ module Mack
|
|
86
50
|
"mack::cookie_values" => {
|
87
51
|
"path" => "/"
|
88
52
|
},
|
89
|
-
|
53
|
+
"cachetastic_default_options" => {
|
54
|
+
"debug" => false,
|
55
|
+
"adapter" => "local_memory",
|
56
|
+
"expiry_time" => 300,
|
57
|
+
"logging" => {
|
58
|
+
"logger_1" => {
|
59
|
+
"type" => "file",
|
60
|
+
"file" => File.join(MACK_ROOT, "log", "cachetastic.log")
|
61
|
+
}
|
62
|
+
}
|
63
|
+
},
|
64
|
+
"mack_distributed_routes_url_cache_options" => {
|
65
|
+
"debug" => false,
|
66
|
+
"adapter" => "drb",
|
67
|
+
"store_options" => {
|
68
|
+
"host" => "druby://127.0.0.1:61676"
|
69
|
+
},
|
70
|
+
"logging" => {
|
71
|
+
"logger_1" => {
|
72
|
+
"type" => "file",
|
73
|
+
"file" => File.join(MACK_ROOT, "log", "mack_distributed_routes_url_cache.log")
|
74
|
+
}
|
75
|
+
}
|
76
|
+
},
|
77
|
+
"mack::site_domain" => "http://localhost:3000",
|
78
|
+
"mack::use_distributed_routes" => false,
|
79
|
+
"mack::distributed_app_name" => nil,
|
80
|
+
"mack::distributed_site_domain" => "http://localhost:3000",
|
90
81
|
"log::detailed_requests" => true,
|
91
82
|
"log::level" => "info",
|
92
83
|
"log::console" => false,
|
@@ -1,13 +1,14 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rack'
|
3
3
|
require 'digest'
|
4
|
-
require '
|
4
|
+
require 'mack_ruby_core_extensions'
|
5
5
|
require 'application_configuration'
|
6
6
|
require 'cachetastic'
|
7
7
|
require 'fileutils'
|
8
8
|
require 'log4r'
|
9
9
|
require 'crypt/rijndael'
|
10
10
|
require 'singleton'
|
11
|
+
require 'uri'
|
11
12
|
|
12
13
|
# Set up Mack constants, if they haven't already been set up.
|
13
14
|
unless Object.const_defined?("MACK_ENV")
|
@@ -42,7 +43,7 @@ unless Object.const_defined?("MACK_INITIALIZED")
|
|
42
43
|
fl = File.join(File.dirname(__FILE__), "..")
|
43
44
|
|
44
45
|
# Require all the necessary files to make Mack actually work!
|
45
|
-
["errors", "core_extensions", "utils", "test_extensions", "routing", "rendering", "sea_level", "tasks", "initialization/server", "generators"].each do |dir|
|
46
|
+
["distributed", "errors", "core_extensions", "utils", "test_extensions", "routing", "rendering", "sea_level", "tasks", "initialization/server", "generators"].each do |dir|
|
46
47
|
dir_globs = Dir.glob(File.join(fl, dir, "**/*.rb"))
|
47
48
|
dir_globs.each do |d|
|
48
49
|
require d
|
data/lib/rendering/base.rb
CHANGED
@@ -26,14 +26,12 @@ module Mack
|
|
26
26
|
|
27
27
|
def initialize(view_binder, options)
|
28
28
|
self.view_binder = view_binder
|
29
|
-
self.options = options
|
29
|
+
self.options = {:parameters => {}}.merge(options)
|
30
30
|
end
|
31
31
|
|
32
32
|
# This is the only method that needs to be implemented by a rendering system.
|
33
33
|
# It should return a String.
|
34
|
-
|
35
|
-
raise MethodNotImplemented.new("render")
|
36
|
-
end
|
34
|
+
needs_method :render
|
37
35
|
|
38
36
|
# Maps to the view_binder's param method. See also Mack::ViewBinder params.
|
39
37
|
def params(key)
|
@@ -5,7 +5,7 @@ module Mack
|
|
5
5
|
class Url < Base
|
6
6
|
|
7
7
|
def render
|
8
|
-
options = {:method => :get, :domain => app_config.mack.
|
8
|
+
options = {:method => :get, :domain => app_config.mack.site_domain, :raise_exception => false}.merge(self.options)
|
9
9
|
case options[:method]
|
10
10
|
when :get
|
11
11
|
do_render_url(options) do |uri, options|
|
data/lib/routing/route_map.rb
CHANGED
@@ -7,8 +7,13 @@ module Mack
|
|
7
7
|
#
|
8
8
|
# See Mack::Routes::RouteMap for more information.
|
9
9
|
def self.build
|
10
|
+
$distributed_urls = Mack::Distributed::Routes::Urls.new(app_config.mack.distributed_site_domain) if $distributed_urls.nil?
|
10
11
|
yield Mack::Routes::RouteMap.instance
|
11
12
|
Mack::Routes::Urls.include_safely_into(Mack::Controller::Base, Mack::ViewBinder, Test::Unit::TestCase)
|
13
|
+
if app_config.mack.use_distributed_routes
|
14
|
+
raise Mack::Distributed::Errors::ApplicationNameUndefined.new if app_config.mack.distributed_app_name.nil?
|
15
|
+
Mack::Distributed::Routes::UrlCache.set(app_config.mack.distributed_app_name.to_sym, $distributed_urls)
|
16
|
+
end
|
12
17
|
# puts "Finished compiling routes: #{Mack::Routes::RouteMap.instance.routes_list.inspect}"
|
13
18
|
end
|
14
19
|
|
@@ -193,21 +198,34 @@ module Mack
|
|
193
198
|
raise Mack::Errors::UndefinedRoute.new(req)
|
194
199
|
end # get
|
195
200
|
|
196
|
-
private
|
197
201
|
attr_reader :routes_list # :nodoc:
|
198
202
|
|
203
|
+
private
|
199
204
|
def connect_with_named_route(n_route, pattern, options = {})
|
200
205
|
route = connect(pattern, options)
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
206
|
+
|
207
|
+
url = %{
|
208
|
+
def #{n_route}_url(options = {})
|
209
|
+
url_for_pattern("#{route.original_pattern}", options)
|
210
|
+
end
|
211
|
+
|
212
|
+
def #{n_route}_full_url(options = {})
|
213
|
+
u = #{n_route}_url(options)
|
214
|
+
"\#{@request.full_host}\#{u}"
|
215
|
+
end
|
216
|
+
}
|
217
|
+
|
218
|
+
Mack::Routes::Urls.class_eval(url)
|
219
|
+
|
220
|
+
if app_config.mack.use_distributed_routes
|
221
|
+
$distributed_urls["#{n_route}_url"] = url
|
222
|
+
|
223
|
+
$distributed_urls["#{n_route}_distributed_url"] = %{
|
224
|
+
def #{n_route}_distributed_url(options = {})
|
225
|
+
(@dsd || app_config.mack.distributed_site_domain) + #{n_route}_url(options)
|
209
226
|
end
|
210
227
|
}
|
228
|
+
end
|
211
229
|
end
|
212
230
|
|
213
231
|
def regex_from_pattern(pattern)
|
data/lib/routing/urls.rb
CHANGED
@@ -56,7 +56,43 @@ module Mack
|
|
56
56
|
</html>
|
57
57
|
}
|
58
58
|
end
|
59
|
+
|
60
|
+
# Retrieves a distributed route from a DRb server.
|
61
|
+
#
|
62
|
+
# Example:
|
63
|
+
# droute_url(:app_1, :home_page_url)
|
64
|
+
# droute_url(:registration_app, :signup_url, {:from => :google})
|
65
|
+
def droute_url(app_name, route_name, options = {})
|
66
|
+
if app_config.mack.use_distributed_routes
|
67
|
+
ivar_cache("droute_url_hash") do
|
68
|
+
{}
|
69
|
+
end
|
70
|
+
d_urls = @droute_url_hash[app_name.to_sym]
|
71
|
+
if d_urls.nil?
|
72
|
+
d_urls = Mack::Distributed::Routes::UrlCache.get(app_name.to_sym)
|
73
|
+
@droute_url_hash[app_name.to_sym] = d_urls
|
74
|
+
if d_urls.nil?
|
75
|
+
raise Mack::Distributed::Errors::UnknownApplication.new(app_name)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
route_name = route_name.to_s
|
79
|
+
if route_name.match(/_url$/)
|
80
|
+
unless route_name.match(/_distributed_url$/)
|
81
|
+
route_name.gsub!("_url", "_distributed_url")
|
82
|
+
end
|
83
|
+
else
|
84
|
+
route_name << "_distributed_url"
|
85
|
+
end
|
86
|
+
if d_urls.run.respond_to?(route_name)
|
87
|
+
return d_urls.run.send(route_name, options)
|
88
|
+
else
|
89
|
+
raise Mack::Distributed::Errors::UnknownRouteName.new(app_name, route_name)
|
90
|
+
end
|
91
|
+
else
|
92
|
+
return nil
|
93
|
+
end
|
94
|
+
end # droute_url
|
59
95
|
|
60
96
|
end # Urls
|
61
97
|
end # Routes
|
62
|
-
end # Mack
|
98
|
+
end # Mack
|
@@ -170,7 +170,7 @@ module Mack
|
|
170
170
|
# end
|
171
171
|
#
|
172
172
|
# # This will render a 'local' url. If a domain is not present render url will
|
173
|
-
# # reach out for the config parameter "mack::
|
173
|
+
# # reach out for the config parameter "mack::site_domain" and prepend that
|
174
174
|
# # to the url. This can be overridden locally with the :domain option.
|
175
175
|
# def get_index
|
176
176
|
# render(:url => "/")
|
@@ -287,12 +287,12 @@ module Mack
|
|
287
287
|
begin
|
288
288
|
# try action.html.erb
|
289
289
|
return Mack::ViewBinder.new(self).render({:action => self.action_name})
|
290
|
-
rescue
|
290
|
+
rescue Errno::ENOENT => e
|
291
291
|
if @result_of_action_called.is_a?(String)
|
292
292
|
@render_options[:text] = @result_of_action_called
|
293
293
|
return Mack::ViewBinder.new(self).render(@render_options)
|
294
294
|
end
|
295
|
-
|
295
|
+
|
296
296
|
end
|
297
297
|
end
|
298
298
|
end # complete_action_render
|
data/lib/sea_level/request.rb
CHANGED
@@ -57,9 +57,9 @@ module Mack
|
|
57
57
|
unless p.nil?
|
58
58
|
p = p.to_s if p.is_a?(Symbol)
|
59
59
|
if p.is_a?(String)
|
60
|
-
p =
|
60
|
+
p = p.to_s.uri_unescape
|
61
61
|
elsif p.is_a?(Hash)
|
62
|
-
p.each_pair {|k,v| p[k] =
|
62
|
+
p.each_pair {|k,v| p[k] = v.to_s.uri_unescape}
|
63
63
|
end
|
64
64
|
end
|
65
65
|
p
|
@@ -0,0 +1,50 @@
|
|
1
|
+
namespace :mack do
|
2
|
+
|
3
|
+
namespace :dump do
|
4
|
+
|
5
|
+
desc "Dumps out the configuration for the specified environment."
|
6
|
+
task :config => :environment do
|
7
|
+
fcs = app_config.instance.instance_variable_get("@final_configuration_settings")
|
8
|
+
conf = {}
|
9
|
+
fcs.each_pair do |k, v|
|
10
|
+
unless v.is_a?(Application::Configuration::Namespace)
|
11
|
+
conf[k.to_s] = v unless k.to_s.match("__")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
pp conf
|
15
|
+
end # config
|
16
|
+
|
17
|
+
desc "Show all the routes available"
|
18
|
+
task :routes => :environment do
|
19
|
+
include Mack::Routes::Urls
|
20
|
+
puts ""
|
21
|
+
puts "Routes:"
|
22
|
+
|
23
|
+
routes = Mack::Routes::RouteMap.instance.routes_list
|
24
|
+
routes.each do |r|
|
25
|
+
# pp r.inspect
|
26
|
+
pat = r.original_pattern.blank? ? '/' : r.original_pattern
|
27
|
+
pat << "(.:format)"
|
28
|
+
opts = r.options.dup
|
29
|
+
meth = opts[:method]
|
30
|
+
opts.delete(:method)
|
31
|
+
puts "#{pat.rjust(50)}\t#{meth.to_s.upcase}\t#{opts.inspect.ljust(0)}"
|
32
|
+
end
|
33
|
+
puts ""
|
34
|
+
puts "-" * 125
|
35
|
+
puts "Route helper methods:"
|
36
|
+
|
37
|
+
url_methods = Mack::Routes::Urls.protected_instance_methods.collect {|x| x if x.match(/_url$/)}.compact
|
38
|
+
url_methods.sort.each do |meth|
|
39
|
+
unless meth.match(/(full|droute)_url$/)
|
40
|
+
puts "#{meth.rjust(50)}\t#{self.send(meth)}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
puts ""
|
44
|
+
end # routes
|
45
|
+
|
46
|
+
end # dump
|
47
|
+
|
48
|
+
end # mack
|
49
|
+
|
50
|
+
alias_task :routes, "mack:dump:routes"
|
@@ -0,0 +1,48 @@
|
|
1
|
+
namespace :mack do
|
2
|
+
|
3
|
+
namespace :server do
|
4
|
+
|
5
|
+
desc "Starts the webserver."
|
6
|
+
task :start do |t|
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'optparse'
|
10
|
+
require 'optparse/time'
|
11
|
+
require 'ostruct'
|
12
|
+
require 'fileutils'
|
13
|
+
|
14
|
+
d_handler = "WEBrick"
|
15
|
+
begin
|
16
|
+
require 'mongrel'
|
17
|
+
d_handler = "mongrel"
|
18
|
+
rescue Exception => e
|
19
|
+
end
|
20
|
+
begin
|
21
|
+
require 'thin'
|
22
|
+
d_handler = "thin"
|
23
|
+
rescue Exception => e
|
24
|
+
end
|
25
|
+
|
26
|
+
MACK_ROOT = FileUtils.pwd unless Object.const_defined?("MACK_ROOT")
|
27
|
+
|
28
|
+
options = OpenStruct.new
|
29
|
+
options.port = (ENV["PORT"] ||= "3000") # Does NOT work with Thin!! You must edit the thin.yml file!
|
30
|
+
options.handler = (ENV["HANDLER"] ||= d_handler)
|
31
|
+
|
32
|
+
|
33
|
+
require File.join(MACK_ROOT, "config", "boot.rb")
|
34
|
+
|
35
|
+
if options.handler == "thin"
|
36
|
+
# thin_opts = ["start", "-r", "config/thin.ru"]
|
37
|
+
thin_opts = ["start", "-C", "config/thin.yml"]
|
38
|
+
Thin::Runner.new(thin_opts.flatten).run!
|
39
|
+
else
|
40
|
+
Mack::SimpleServer.run(options)
|
41
|
+
end
|
42
|
+
end # start
|
43
|
+
|
44
|
+
end # server
|
45
|
+
|
46
|
+
end # mack
|
47
|
+
|
48
|
+
alias_task :server, "log:clear", "mack:server:start"
|
data/lib/tasks/mack_tasks.rake
CHANGED
@@ -1,31 +1,22 @@
|
|
1
|
-
|
2
|
-
task :environment do
|
3
|
-
MACK_ENV = ENV["MACK_ENV"] ||= "development" unless Object.const_defined?("MACK_ENV")
|
4
|
-
MACK_ROOT = FileUtils.pwd unless Object.const_defined?("MACK_ROOT")
|
5
|
-
require File.join(MACK_ROOT, "config", "boot.rb")
|
6
|
-
end
|
7
|
-
|
8
|
-
desc "Loads an irb console allow you full access to the application w/o a browser."
|
9
|
-
task :console do
|
10
|
-
libs = []
|
11
|
-
libs << "-r irb/completion"
|
12
|
-
libs << "-r #{File.join(File.dirname(__FILE__), '..', 'mack')}"
|
13
|
-
libs << "-r #{File.join(File.dirname(__FILE__), '..', 'initialization', 'console')}"
|
14
|
-
exec "irb #{libs.join(" ")} --simple-prompt"
|
15
|
-
end
|
16
|
-
|
17
|
-
namespace :dump do
|
1
|
+
namespace :mack do
|
18
2
|
|
19
|
-
desc "
|
20
|
-
task :
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
3
|
+
desc "Loads the Mack environment. Default is development."
|
4
|
+
task :environment do
|
5
|
+
MACK_ENV = ENV["MACK_ENV"] ||= "development" unless Object.const_defined?("MACK_ENV")
|
6
|
+
MACK_ROOT = FileUtils.pwd unless Object.const_defined?("MACK_ROOT")
|
7
|
+
require File.join(MACK_ROOT, "config", "boot.rb")
|
8
|
+
end # environment
|
9
|
+
|
10
|
+
desc "Loads an irb console allow you full access to the application w/o a browser."
|
11
|
+
task :console do
|
12
|
+
libs = []
|
13
|
+
libs << "-r irb/completion"
|
14
|
+
libs << "-r #{File.join(File.dirname(__FILE__), '..', 'mack')}"
|
15
|
+
libs << "-r #{File.join(File.dirname(__FILE__), '..', 'initialization', 'console')}"
|
16
|
+
exec "irb #{libs.join(" ")} --simple-prompt"
|
17
|
+
end # console
|
30
18
|
|
31
|
-
end
|
19
|
+
end # mack
|
20
|
+
|
21
|
+
alias_task :console, "mack:console"
|
22
|
+
alias_task :environment, "mack:environment"
|
data/lib/utils/crypt/keeper.rb
CHANGED
@@ -31,7 +31,7 @@ module Mack
|
|
31
31
|
if worker.nil?
|
32
32
|
worker_klass = key.to_s.camelcase + "Worker"
|
33
33
|
if Mack::Utils::Crypt.const_defined?(worker_klass)
|
34
|
-
worker = "Mack::Utils::Crypt::#{worker_klass}".
|
34
|
+
worker = "Mack::Utils::Crypt::#{worker_klass}".to_instance
|
35
35
|
else
|
36
36
|
worker = Mack::Utils::Crypt::DefaultWorker.new
|
37
37
|
end
|
data/lib/utils/html.rb
CHANGED
@@ -60,7 +60,7 @@ module Mack
|
|
60
60
|
# Mack::Utils::Html.b("hello") # => <b>hello</b>
|
61
61
|
# Mack::Utils::Html.div("hello world!", :class => :foo)) # => <div class="foo">hello world!</div>
|
62
62
|
def method_missing(sym, *args)
|
63
|
-
ags = args.
|
63
|
+
ags = args.parse_splat_args
|
64
64
|
|
65
65
|
tag = sym
|
66
66
|
content = nil
|
data/tasks/gem_helper.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
class GemHelper # :nodoc:
|
2
|
+
include Singleton
|
3
|
+
|
4
|
+
attr_accessor :project
|
5
|
+
attr_accessor :package
|
6
|
+
attr_accessor :gem_name
|
7
|
+
attr_accessor :version
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
self.project = "magrathea"
|
11
|
+
self.package = "mack"
|
12
|
+
self.gem_name = "mack"
|
13
|
+
self.version = "0.4.0"
|
14
|
+
end
|
15
|
+
|
16
|
+
def gem_name_with_version
|
17
|
+
"#{self.gem_name}-#{self.version}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def full_gem_name
|
21
|
+
"#{self.gem_name_with_version}.gem"
|
22
|
+
end
|
23
|
+
|
24
|
+
def release
|
25
|
+
begin
|
26
|
+
rf = RubyForge.new
|
27
|
+
rf.login
|
28
|
+
begin
|
29
|
+
rf.add_release(self.project, self.package, self.version, File.join("pkg", full_gem_name))
|
30
|
+
rescue Exception => e
|
31
|
+
if e.message.match("Invalid package_id") || e.message.match("no <package_id> configured for")
|
32
|
+
puts "You need to create the package!"
|
33
|
+
rf.create_package(self.project, self.package)
|
34
|
+
rf.add_release(self.project, self.package, self.version, File.join("pkg", full_gem_name))
|
35
|
+
else
|
36
|
+
raise e
|
37
|
+
end
|
38
|
+
end
|
39
|
+
rescue Exception => e
|
40
|
+
puts e
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def install
|
45
|
+
puts `sudo gem install #{File.join("pkg", full_gem_name)}`
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'find'
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
require 'rubyforge'
|
9
|
+
require 'rubygems'
|
10
|
+
require 'rubygems/gem_runner'
|
11
|
+
require 'singleton'
|
12
|
+
|
13
|
+
require 'tasks/gem_helper'
|
14
|
+
|
15
|
+
namespace :gem do
|
16
|
+
|
17
|
+
namespace :package do
|
18
|
+
|
19
|
+
desc "Package up the mack gem."
|
20
|
+
task :mack do |t|
|
21
|
+
pwd = FileUtils.pwd
|
22
|
+
gh = GemHelper.instance
|
23
|
+
FileUtils.rm_rf("#{pwd}/pkg", :verbose => true)
|
24
|
+
gem_spec = Gem::Specification.new do |s|
|
25
|
+
s.name = gh.gem_name
|
26
|
+
s.version = gh.version
|
27
|
+
s.summary = "Mack is a powerful, yet simple, web application framework."
|
28
|
+
s.description = %{
|
29
|
+
Mack is a powerful, yet simple, web application framework.
|
30
|
+
It takes some cues from the likes of Rails and Merb, so it's not entirely unfamiliar.
|
31
|
+
Mack hopes to provide developers a great framework for building, and deploying, portal and
|
32
|
+
distributed applications.
|
33
|
+
}
|
34
|
+
s.author = "markbates"
|
35
|
+
s.email = "mark@mackframework.com"
|
36
|
+
s.homepage = "http://www.mackframework.com"
|
37
|
+
s.has_rdoc = true
|
38
|
+
s.extra_rdoc_files = ["README", "CHANGELOG"]
|
39
|
+
s.files = FileList["README", "**/*.*"].exclude("pkg/").exclude("test/").exclude("tasks/private").exclude("doc")
|
40
|
+
s.require_paths << '.'
|
41
|
+
s.require_paths << 'bin'
|
42
|
+
s.require_paths << 'lib'
|
43
|
+
|
44
|
+
s.bindir = "bin"
|
45
|
+
s.executables << "mack"
|
46
|
+
|
47
|
+
s.rdoc_options << '--title' << 'Mack' << '--main' << 'README' << '--line-numbers' << "--inline-source"
|
48
|
+
|
49
|
+
s.add_dependency("rack", "0.3.0")
|
50
|
+
s.add_dependency("mack_ruby_core_extensions", "0.1.3")
|
51
|
+
s.add_dependency("application_configuration", "1.2.1")
|
52
|
+
s.add_dependency("cachetastic", "1.4.1")
|
53
|
+
s.add_dependency("log4r", "1.0.5")
|
54
|
+
s.add_dependency("thin", "0.7.0")
|
55
|
+
s.add_dependency("builder", "2.1.2")
|
56
|
+
s.add_dependency("crypt", "1.1.4")
|
57
|
+
|
58
|
+
|
59
|
+
s.rubyforge_project = gh.project
|
60
|
+
end
|
61
|
+
Rake::GemPackageTask.new(gem_spec) do |pkg|
|
62
|
+
pkg.package_dir = "#{pwd}/pkg"
|
63
|
+
pkg.need_zip = false
|
64
|
+
pkg.need_tar = false
|
65
|
+
end
|
66
|
+
Rake::Task["package"].invoke
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
namespace :install do
|
72
|
+
|
73
|
+
desc "Package up and install the mack gem."
|
74
|
+
task :mack => "gem:package:mack" do |t|
|
75
|
+
GemHelper.instance.install
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
namespace :release do
|
81
|
+
|
82
|
+
desc "Package up, install, and release the mack gem."
|
83
|
+
task :mack => ["gem:install:mack"] do |t|
|
84
|
+
GemHelper.instance.release
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
alias_task :pack, "gem:package:mack"
|
92
|
+
alias_task :install, "gem:install:mack"
|
93
|
+
alias_task :release, "gem:release:mack"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- markbates
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-03-
|
12
|
+
date: 2008-03-26 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -22,13 +22,13 @@ dependencies:
|
|
22
22
|
version: 0.3.0
|
23
23
|
version:
|
24
24
|
- !ruby/object:Gem::Dependency
|
25
|
-
name:
|
25
|
+
name: mack_ruby_core_extensions
|
26
26
|
version_requirement:
|
27
27
|
version_requirements: !ruby/object:Gem::Requirement
|
28
28
|
requirements:
|
29
29
|
- - "="
|
30
30
|
- !ruby/object:Gem::Version
|
31
|
-
version: 1.
|
31
|
+
version: 0.1.3
|
32
32
|
version:
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: application_configuration
|
@@ -84,7 +84,7 @@ dependencies:
|
|
84
84
|
- !ruby/object:Gem::Version
|
85
85
|
version: 1.1.4
|
86
86
|
version:
|
87
|
-
description:
|
87
|
+
description: Mack is a powerful, yet simple, web application framework. It takes some cues from the likes of Rails and Merb, so it's not entirely unfamiliar. Mack hopes to provide developers a great framework for building, and deploying, portal and distributed applications.
|
88
88
|
email: mark@mackframework.com
|
89
89
|
executables:
|
90
90
|
- mack
|
@@ -111,12 +111,11 @@ files:
|
|
111
111
|
- bin/templates/public/favicon.ico
|
112
112
|
- bin/templates/public/stylesheets/scaffold.css.template
|
113
113
|
- bin/templates/Rakefile.template
|
114
|
-
- lib/core_extensions/hash.rb
|
115
114
|
- lib/core_extensions/kernel.rb
|
116
|
-
- lib/core_extensions/module.rb
|
117
|
-
- lib/core_extensions/nil.rb
|
118
|
-
- lib/core_extensions/object.rb
|
119
115
|
- lib/core_extensions/string.rb
|
116
|
+
- lib/distributed/errors/errors.rb
|
117
|
+
- lib/distributed/routing/url_cache.rb
|
118
|
+
- lib/distributed/routing/urls.rb
|
120
119
|
- lib/errors/errors.rb
|
121
120
|
- lib/generators/generator_base.rb
|
122
121
|
- lib/generators/plugin_generator/plugin_generator.rb
|
@@ -161,19 +160,20 @@ files:
|
|
161
160
|
- lib/sea_level/view_binder.rb
|
162
161
|
- lib/tasks/cachetastic_tasks.rake
|
163
162
|
- lib/tasks/log_tasks.rake
|
163
|
+
- lib/tasks/mack_dump_tasks.rake
|
164
|
+
- lib/tasks/mack_server_tasks.rake
|
164
165
|
- lib/tasks/mack_tasks.rake
|
165
166
|
- lib/tasks/rake_helpers.rb
|
166
167
|
- lib/tasks/rake_rules.rake
|
167
|
-
- lib/tasks/script_tasks.rake
|
168
168
|
- lib/tasks/test_tasks.rake
|
169
169
|
- lib/test_extensions/test_assertions.rb
|
170
170
|
- lib/test_extensions/test_helpers.rb
|
171
171
|
- lib/utils/crypt/default_worker.rb
|
172
172
|
- lib/utils/crypt/keeper.rb
|
173
173
|
- lib/utils/html.rb
|
174
|
-
- lib/utils/inflections.rb
|
175
|
-
- lib/utils/inflector.rb
|
176
174
|
- lib/utils/server.rb
|
175
|
+
- tasks/gem_helper.rb
|
176
|
+
- tasks/gem_tasks.rake
|
177
177
|
- CHANGELOG
|
178
178
|
has_rdoc: true
|
179
179
|
homepage: http://www.mackframework.com
|
@@ -208,6 +208,6 @@ rubyforge_project: magrathea
|
|
208
208
|
rubygems_version: 1.0.1
|
209
209
|
signing_key:
|
210
210
|
specification_version: 2
|
211
|
-
summary:
|
211
|
+
summary: Mack is a powerful, yet simple, web application framework.
|
212
212
|
test_files: []
|
213
213
|
|
data/lib/core_extensions/hash.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
class Hash
|
2
|
-
|
3
|
-
# Deletes the key(s) passed in from the hash.
|
4
|
-
def -(ars)
|
5
|
-
[ars].flatten.each {|a| self.delete(a)}
|
6
|
-
self
|
7
|
-
end
|
8
|
-
|
9
|
-
# Converts a hash to query string parameters.
|
10
|
-
# An optional boolean escapes the values if true, which is the default.
|
11
|
-
def to_params(escape = true)
|
12
|
-
params = ''
|
13
|
-
stack = []
|
14
|
-
|
15
|
-
each do |k, v|
|
16
|
-
if v.is_a?(Hash)
|
17
|
-
stack << [k,v]
|
18
|
-
else
|
19
|
-
v = Rack::Utils.escape(v) if escape
|
20
|
-
params << "#{k}=#{v}&"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
stack.each do |parent, hash|
|
25
|
-
hash.each do |k, v|
|
26
|
-
if v.is_a?(Hash)
|
27
|
-
stack << ["#{parent}[#{k}]", v]
|
28
|
-
else
|
29
|
-
v = Rack::Utils.escape(v) if escape
|
30
|
-
params << "#{parent}[#{k}]=#{v}&"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
params.chop! # trailing &
|
36
|
-
params
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
class Module
|
2
|
-
|
3
|
-
# Bulk converts the security level of methods in this Module from one level to another.
|
4
|
-
def convert_security_of_methods(old_level = :public, new_level = :protected)
|
5
|
-
eval("#{old_level}_instance_methods").each{ |meth| self.send(new_level, meth) }
|
6
|
-
self
|
7
|
-
end
|
8
|
-
|
9
|
-
# Includes this module into an Object, and changes all public methods to protected.
|
10
|
-
#
|
11
|
-
# Examples:
|
12
|
-
# module MyCoolUtils
|
13
|
-
# def some_meth
|
14
|
-
# "hi"
|
15
|
-
# end
|
16
|
-
# self.include_safely_into(FooController)
|
17
|
-
# end
|
18
|
-
# or:
|
19
|
-
# MyCoolUtils.include_safely_into(FooController, SomeOtherClass)
|
20
|
-
def include_safely_into(*args)
|
21
|
-
[args].flatten.each do |a|
|
22
|
-
if a.is_a?(String) || a.is_a?(Symbol)
|
23
|
-
a = a.to_s.constantize
|
24
|
-
end
|
25
|
-
a.send(:include, self.convert_security_of_methods)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
data/lib/core_extensions/nil.rb
DELETED
data/lib/tasks/script_tasks.rake
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
namespace :server do
|
2
|
-
|
3
|
-
desc "Starts the webserver."
|
4
|
-
task :start do |t|
|
5
|
-
|
6
|
-
require 'rubygems'
|
7
|
-
require 'optparse'
|
8
|
-
require 'optparse/time'
|
9
|
-
require 'ostruct'
|
10
|
-
require 'fileutils'
|
11
|
-
|
12
|
-
d_handler = "WEBrick"
|
13
|
-
begin
|
14
|
-
require 'mongrel'
|
15
|
-
d_handler = "mongrel"
|
16
|
-
rescue Exception => e
|
17
|
-
end
|
18
|
-
begin
|
19
|
-
require 'thin'
|
20
|
-
d_handler = "thin"
|
21
|
-
rescue Exception => e
|
22
|
-
end
|
23
|
-
|
24
|
-
MACK_ROOT = FileUtils.pwd unless Object.const_defined?("MACK_ROOT")
|
25
|
-
|
26
|
-
options = OpenStruct.new
|
27
|
-
options.port = (ENV["PORT"] ||= "3000") # Does NOT work with Thin!! You must edit the thin.yml file!
|
28
|
-
options.handler = (ENV["HANDLER"] ||= d_handler)
|
29
|
-
|
30
|
-
|
31
|
-
require File.join(MACK_ROOT, "config", "boot.rb")
|
32
|
-
|
33
|
-
if options.handler == "thin"
|
34
|
-
# thin_opts = ["start", "-r", "config/thin.ru"]
|
35
|
-
thin_opts = ["start", "-C", "config/thin.yml"]
|
36
|
-
Thin::Runner.new(thin_opts.flatten).run!
|
37
|
-
else
|
38
|
-
Mack::SimpleServer.run(options)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
alias_task :server, "log:clear", "server:start"
|
data/lib/utils/inflections.rb
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "inflector")
|
2
|
-
# Default inflections. This is taken from Jeremy McAnally's great Rails plugin, acts_as_good_speeler. Thanks Jeremy! http://www.jeremymcanally.com/
|
3
|
-
Mack::Utils::Inflector.inflections do |inflect|
|
4
|
-
inflect.plural(/$/, 's')
|
5
|
-
inflect.plural(/s$/i, 's')
|
6
|
-
inflect.plural(/(bu)s$/i, '\1ses')
|
7
|
-
inflect.plural(/(stimul|hippopotam|octop|vir|syllab|foc|alumn|fung|radi)us$/i, '\1i')
|
8
|
-
inflect.plural(/(ax|test)is$/i, '\1es')
|
9
|
-
inflect.plural(/(alias|status)$/i, '\1es')
|
10
|
-
inflect.plural(/(buffal|tomat|torped)o$/i, '\1oes')
|
11
|
-
inflect.plural(/([dti])um$/i, '\1a')
|
12
|
-
inflect.plural(/sis$/i, 'ses')
|
13
|
-
inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
|
14
|
-
inflect.plural(/(hive)$/i, '\1s')
|
15
|
-
inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
|
16
|
-
inflect.plural(/(x|ch|ss|sh)$/i, '\1es')
|
17
|
-
inflect.plural(/(matr|append|vert|ind)ix|ex$/i, '\1ices')
|
18
|
-
inflect.plural(/([m|l])ouse$/i, '\1ice')
|
19
|
-
inflect.plural(/^(ox)$/i, '\1en')
|
20
|
-
inflect.plural(/(quiz)$/i, '\1zes')
|
21
|
-
inflect.plural(/(phenomen|criteri)on$/i, '\1a')
|
22
|
-
inflect.plural(/^(?!(.*hu|.*ger|.*sha))(.*)(wom|m)an$/i, '\2\3en')
|
23
|
-
inflect.plural(/(curricul|bacteri|medi)um$/i, '\1a')
|
24
|
-
inflect.plural(/(nebul|formul|vit|vertebr|alg|alumn)a$/i, '\1ae')
|
25
|
-
|
26
|
-
inflect.singular(/s$/i, '')
|
27
|
-
inflect.singular(/(n)ews$/i, '\1ews')
|
28
|
-
inflect.singular(/([dti])a$/i, '\1um')
|
29
|
-
inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis')
|
30
|
-
inflect.singular(/(^analy|cri|empha)ses$/i, '\1sis')
|
31
|
-
inflect.singular(/([^f])ves$/i, '\1fe')
|
32
|
-
inflect.singular(/(hive)s$/i, '\1')
|
33
|
-
inflect.singular(/(tive)s$/i, '\1')
|
34
|
-
inflect.singular(/(bus)es$/i, '\1')
|
35
|
-
inflect.singular(/(o)es$/i, '\1')
|
36
|
-
inflect.singular(/(shoe)s$/i, '\1')
|
37
|
-
inflect.singular(/(test|ax)es$/i, '\1is')
|
38
|
-
inflect.singular(/(stimul|hippopotam|octop|vir|syllab|foc|alumn|fung|radi)i$/i, '\1us')
|
39
|
-
inflect.singular(/(alias|status)es$/i, '\1')
|
40
|
-
inflect.singular(/^(ox)en$/i, '\1')
|
41
|
-
inflect.singular(/(vert|ind)ices$/i, '\1ex')
|
42
|
-
inflect.singular(/(matr|append)ices$/i, '\1ix')
|
43
|
-
inflect.singular(/(quiz)zes$/i, '\1')
|
44
|
-
inflect.singular(/(phenomen|criteri)a$/i, '\1on')
|
45
|
-
inflect.singular(/(.*)(wo|m)en$/i, '\1\2an')
|
46
|
-
inflect.singular(/(medi|curricul|bacteri)a$/i, '\1um')
|
47
|
-
inflect.singular(/(nebula|formula|vita|vertebra|alga|alumna)e$/i, '\1')
|
48
|
-
inflect.singular(/^(.*)ookies$/, '\1ookie')
|
49
|
-
inflect.singular(/(.*)ss$/, '\1ss')
|
50
|
-
inflect.singular(/(.*)ies$/, '\1y')
|
51
|
-
|
52
|
-
inflect.irregular('person', 'people')
|
53
|
-
inflect.irregular('child', 'children')
|
54
|
-
inflect.irregular('sex', 'sexes')
|
55
|
-
inflect.irregular('move', 'moves')
|
56
|
-
inflect.irregular('tooth', 'teeth')
|
57
|
-
inflect.irregular('die', 'dice')
|
58
|
-
inflect.irregular('talisman', 'talismans')
|
59
|
-
inflect.irregular('penis', 'penises')
|
60
|
-
|
61
|
-
inflect.uncountable(%w(pokemon pokémon equipment information rice money species series fish sheep deer offspring))
|
62
|
-
end
|
data/lib/utils/inflector.rb
DELETED
@@ -1,129 +0,0 @@
|
|
1
|
-
require 'singleton'
|
2
|
-
module Mack
|
3
|
-
module Utils
|
4
|
-
# This class is used to deal with inflection strings. This means taken a string and make it plural, or singular, etc...
|
5
|
-
# Inflection rules can be added very easy, and are checked from the bottom up. This means that the last rule is the first
|
6
|
-
# rule to be matched. The exception to this, kind of, is 'irregular' and 'uncountable' rules. The 'uncountable' rules are
|
7
|
-
# always checked first, then the 'irregular' rules, and finally either the 'singular' or 'plural' rules, depending on what
|
8
|
-
# you're trying to do. Within each of these sets of rules, the last rule in is the first rule matched.
|
9
|
-
#
|
10
|
-
# Example:
|
11
|
-
# Mack::Utils::Inflector.inflections do |inflect|
|
12
|
-
# inflect.plural(/$/, 's')
|
13
|
-
# inflect.plural(/^(ox)$/i, '\1en')
|
14
|
-
# inflect.plural(/(phenomen|criteri)on$/i, '\1a')
|
15
|
-
#
|
16
|
-
# inflect.singular(/s$/i, '')
|
17
|
-
# inflect.singular(/(n)ews$/i, '\1ews')
|
18
|
-
# inflect.singular(/^(.*)ookies$/, '\1ookie')
|
19
|
-
#
|
20
|
-
# inflect.irregular('person', 'people')
|
21
|
-
# inflect.irregular('child', 'children')
|
22
|
-
#
|
23
|
-
# inflect.uncountable(%w(fish sheep deer offspring))
|
24
|
-
# end
|
25
|
-
class Inflector
|
26
|
-
include Singleton
|
27
|
-
|
28
|
-
def initialize # :nodoc:
|
29
|
-
@plural_rules = []
|
30
|
-
@singular_rules = []
|
31
|
-
@irregular_rules = []
|
32
|
-
@uncountable_rules = []
|
33
|
-
end
|
34
|
-
|
35
|
-
# Adds a plural rule to the system.
|
36
|
-
#
|
37
|
-
# Example:
|
38
|
-
# Mack::Utils::Inflector.inflections do |inflect|
|
39
|
-
# inflect.plural(/$/, 's')
|
40
|
-
# inflect.plural(/^(ox)$/i, '\1en')
|
41
|
-
# inflect.plural(/(phenomen|criteri)on$/i, '\1a')
|
42
|
-
# end
|
43
|
-
def plural(rule, replacement)
|
44
|
-
@plural_rules << {:rule => rule, :replacement => replacement}
|
45
|
-
end
|
46
|
-
|
47
|
-
# Adds a singular rule to the system.
|
48
|
-
#
|
49
|
-
# Example:
|
50
|
-
# Mack::Utils::Inflector.inflections do |inflect|
|
51
|
-
# inflect.singular(/s$/i, '')
|
52
|
-
# inflect.singular(/(n)ews$/i, '\1ews')
|
53
|
-
# inflect.singular(/^(.*)ookies$/, '\1ookie')
|
54
|
-
# end
|
55
|
-
def singular(rule, replacement)
|
56
|
-
@singular_rules << {:rule => rule, :replacement => replacement}
|
57
|
-
end
|
58
|
-
|
59
|
-
# Adds a irregular rule to the system.
|
60
|
-
#
|
61
|
-
# Example:
|
62
|
-
# Mack::Utils::Inflector.inflections do |inflect|
|
63
|
-
# inflect.irregular('person', 'people')
|
64
|
-
# inflect.irregular('child', 'children')
|
65
|
-
# end
|
66
|
-
def irregular(rule, replacement)
|
67
|
-
@irregular_rules << {:rule => rule, :replacement => replacement}
|
68
|
-
# do the reverse so you get:
|
69
|
-
# person => people
|
70
|
-
# people => person
|
71
|
-
@irregular_rules << {:rule => replacement, :replacement => rule}
|
72
|
-
end
|
73
|
-
|
74
|
-
# Adds a uncountable word, or words, to the system.
|
75
|
-
#
|
76
|
-
# Example:
|
77
|
-
# Mack::Utils::Inflector.inflections do |inflect|
|
78
|
-
# inflect.uncountable(%w(fish sheep deer offspring))
|
79
|
-
# end
|
80
|
-
def uncountable(*args)
|
81
|
-
[args].flatten.each do |word|
|
82
|
-
@uncountable_rules << word.downcase
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
# Returns the singular version of the word, if possible.
|
87
|
-
#
|
88
|
-
# Examples:
|
89
|
-
# Mack::Utils::Inflector.instance.singularize("armies") # => "army"
|
90
|
-
# Mack::Utils::Inflector.instance.singularize("people") # => "person"
|
91
|
-
# Mack::Utils::Inflector.instance.singularize("boats") # => "boat"
|
92
|
-
def singularize(word)
|
93
|
-
do_work(word, @singular_rules)
|
94
|
-
end
|
95
|
-
|
96
|
-
# Returns the singular version of the word, if possible.
|
97
|
-
#
|
98
|
-
# Examples:
|
99
|
-
# Mack::Utils::Inflector.instance.pluralize("army") # => "armies"
|
100
|
-
# Mack::Utils::Inflector.instance.pluralize("person") # => "people"
|
101
|
-
# Mack::Utils::Inflector.instance.pluralize("boat") # => "boats"
|
102
|
-
def pluralize(word)
|
103
|
-
do_work(word, @plural_rules)
|
104
|
-
end
|
105
|
-
|
106
|
-
private
|
107
|
-
def do_work(word, specific_rules)
|
108
|
-
return word if @uncountable_rules.include?(word.downcase)
|
109
|
-
w = word.dup
|
110
|
-
[specific_rules, @irregular_rules].flatten.reverse.each do |rule_hash|
|
111
|
-
return w if w.gsub!(rule_hash[:rule], rule_hash[:replacement])
|
112
|
-
end
|
113
|
-
# if all else fails, return the word:
|
114
|
-
return word
|
115
|
-
end
|
116
|
-
|
117
|
-
public
|
118
|
-
class << self
|
119
|
-
|
120
|
-
# Yields up Mack::Utils::Inflector.instance
|
121
|
-
def inflections
|
122
|
-
yield Mack::Utils::Inflector.instance
|
123
|
-
end
|
124
|
-
|
125
|
-
end
|
126
|
-
|
127
|
-
end # Inflection
|
128
|
-
end # Utils
|
129
|
-
end # Mack
|