mack 0.3.0 → 0.4.0
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 +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
|