muding 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +17 -0
- data/MANIFEST +10 -1
- data/README +0 -9
- data/configs/boot.rb +45 -3
- data/configs/environment.rb +49 -0
- data/fresh_rakefile +5 -2
- data/helpers/test_helper.rb +2 -2
- data/lib/acts/container.rb +3 -2
- data/lib/code_statistics.rb +107 -0
- data/lib/commands/destroy.rb +3 -1
- data/lib/commands/generate.rb +1 -1
- data/lib/commands/server.rb +24 -2
- data/lib/commands/update.rb +1 -1
- data/lib/controller.rb +81 -26
- data/lib/handle.rb +8 -2
- data/lib/initializer.rb +612 -0
- data/lib/model.rb +0 -1
- data/lib/muding.rb +1 -1
- data/lib/muding_generator/base.rb +3 -3
- data/lib/muding_generator/commands.rb +7 -6
- data/lib/muding_generator/generators/applications/app/app_generator.rb +1 -0
- data/lib/muding_generator/generators/components/controller/controller_generator.rb +1 -1
- data/lib/muding_generator/generators/components/migration/migration_generator.rb +1 -1
- data/lib/muding_generator/generators/components/model/model_generator.rb +1 -1
- data/lib/muding_generator/lookup.rb +10 -10
- data/lib/muding_generator/scripts.rb +5 -5
- data/lib/tasks/databases.rake +169 -0
- data/lib/tasks/documentation.rake +55 -0
- data/lib/tasks/muding.rb +7 -0
- data/lib/tasks/statistics.rake +18 -0
- data/lib/tasks/testing.rake +102 -0
- data/lib/test_help.rb +19 -0
- data/lib/version.rb +11 -0
- metadata +12 -3
- data/lib/tasks/migrate.rake +0 -33
data/lib/handle.rb
CHANGED
@@ -8,7 +8,7 @@ class Handle
|
|
8
8
|
|
9
9
|
@@handles = [] #All of the connections.
|
10
10
|
|
11
|
-
attr_accessor :route, :session, :default_command, :peer
|
11
|
+
attr_accessor :route, :session, :default_command, :peer, :redirect, :args
|
12
12
|
|
13
13
|
def Handle.this s
|
14
14
|
@@handles << h = Handle.new(s)
|
@@ -26,7 +26,11 @@ class Handle
|
|
26
26
|
|
27
27
|
while true
|
28
28
|
update_route(response) if response
|
29
|
-
|
29
|
+
if self.redirect
|
30
|
+
response = Muding.run(self.args, self)
|
31
|
+
else
|
32
|
+
response = Muding.run(peer.gets, self) #blocks on peer.gets
|
33
|
+
end
|
30
34
|
end
|
31
35
|
|
32
36
|
rescue Errno::EPIPE
|
@@ -37,6 +41,8 @@ class Handle
|
|
37
41
|
self.route = response.new_route if response.new_route
|
38
42
|
self.default_command = nil
|
39
43
|
self.default_command = response.default_command if response.default_command
|
44
|
+
self.redirect = response.redirect
|
45
|
+
self.args = response.args
|
40
46
|
end
|
41
47
|
|
42
48
|
def message(message_string)
|
data/lib/initializer.rb
ADDED
@@ -0,0 +1,612 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'set'
|
3
|
+
MUDING_FRAMEWORK_PATH = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
4
|
+
MUDING_ENV = (ENV['MUDING_ENV'] || 'development').dup unless defined?(MUDING_ENV)
|
5
|
+
|
6
|
+
module Muding
|
7
|
+
# The Initializer is responsible for processing the Muding configuration, such
|
8
|
+
# as setting the $LOAD_PATH, requiring the right frameworks, initializing
|
9
|
+
# logging, and more. It can be run either as a single command that'll just
|
10
|
+
# use the default configuration, like this:
|
11
|
+
#
|
12
|
+
# Muding::Initializer.run
|
13
|
+
#
|
14
|
+
# But normally it's more interesting to pass in a custom configuration
|
15
|
+
# through the block running:
|
16
|
+
#
|
17
|
+
# Muding::Initializer.run do |config|
|
18
|
+
# config.frameworks -= [ :action_web_service ]
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# This will use the default configuration options from Muding::Configuration,
|
22
|
+
# but allow for overwriting on select areas.
|
23
|
+
class Initializer
|
24
|
+
# The Configuration instance used by this Initializer instance.
|
25
|
+
attr_reader :configuration
|
26
|
+
|
27
|
+
# The set of loaded plugins.
|
28
|
+
attr_reader :loaded_plugins
|
29
|
+
|
30
|
+
# Runs the initializer. By default, this will invoke the #process method,
|
31
|
+
# which simply executes all of the initialization routines. Alternately,
|
32
|
+
# you can specify explicitly which initialization routine you want:
|
33
|
+
#
|
34
|
+
# Muding::Initializer.run(:set_load_path)
|
35
|
+
#
|
36
|
+
# This is useful if you only want the load path initialized, without
|
37
|
+
# incuring the overhead of completely loading the entire environment.
|
38
|
+
def self.run(command = :process, configuration = Configuration.new)
|
39
|
+
yield configuration if block_given?
|
40
|
+
initializer = new configuration
|
41
|
+
initializer.send(command)
|
42
|
+
initializer
|
43
|
+
end
|
44
|
+
|
45
|
+
# Create a new Initializer instance that references the given Configuration
|
46
|
+
# instance.
|
47
|
+
def initialize(configuration)
|
48
|
+
@configuration = configuration
|
49
|
+
@loaded_plugins = Set.new
|
50
|
+
end
|
51
|
+
|
52
|
+
# Sequentially step through all of the available initialization routines,
|
53
|
+
# in order:
|
54
|
+
#
|
55
|
+
# * #set_load_path
|
56
|
+
# * #set_connection_adapters
|
57
|
+
# * #require_frameworks
|
58
|
+
# * #load_environment
|
59
|
+
# * #initialize_database
|
60
|
+
# * #initialize_logger
|
61
|
+
# * #initialize_framework_logging
|
62
|
+
# * #initialize_framework_views
|
63
|
+
# * #initialize_dependency_mechanism
|
64
|
+
# * #initialize_breakpoints
|
65
|
+
# * #initialize_whiny_nils
|
66
|
+
# * #initialize_framework_settings
|
67
|
+
# * #load_environment
|
68
|
+
# * #load_plugins
|
69
|
+
# * #initialize_routing
|
70
|
+
#
|
71
|
+
# (Note that #load_environment is invoked twice, once at the start and
|
72
|
+
# once at the end, to support the legacy configuration style where the
|
73
|
+
# environment could overwrite the defaults directly, instead of via the
|
74
|
+
# Configuration instance.
|
75
|
+
def process
|
76
|
+
check_ruby_version
|
77
|
+
set_load_path
|
78
|
+
set_connection_adapters
|
79
|
+
|
80
|
+
require_frameworks
|
81
|
+
#load_environment
|
82
|
+
|
83
|
+
initialize_database
|
84
|
+
initialize_logger
|
85
|
+
initialize_framework_logging
|
86
|
+
initialize_framework_views
|
87
|
+
initialize_dependency_mechanism
|
88
|
+
initialize_breakpoints
|
89
|
+
initialize_whiny_nils
|
90
|
+
initialize_temporary_directories
|
91
|
+
|
92
|
+
initialize_framework_settings
|
93
|
+
|
94
|
+
add_support_load_paths
|
95
|
+
|
96
|
+
load_plugins
|
97
|
+
|
98
|
+
# Routing must be initialized after plugins to allow the former to extend the routes
|
99
|
+
initialize_routing
|
100
|
+
|
101
|
+
# the framework is now fully initialized
|
102
|
+
after_initialize
|
103
|
+
end
|
104
|
+
|
105
|
+
# Check for valid Ruby version
|
106
|
+
# This is done in an external file, so we can use it
|
107
|
+
# from the `muding` program as well without duplication.
|
108
|
+
def check_ruby_version
|
109
|
+
require 'ruby_version_check'
|
110
|
+
end
|
111
|
+
|
112
|
+
# Set the <tt>$LOAD_PATH</tt> based on the value of
|
113
|
+
# Configuration#load_paths. Duplicates are removed.
|
114
|
+
def set_load_path
|
115
|
+
configuration.load_paths.reverse.each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) }
|
116
|
+
$LOAD_PATH.uniq!
|
117
|
+
end
|
118
|
+
|
119
|
+
# Sets the +MUDING_CONNECTION_ADAPTERS+ constant based on the value of
|
120
|
+
# Configuration#connection_adapters. This constant is used to determine
|
121
|
+
# which database adapters should be loaded (by default, all adapters are
|
122
|
+
# loaded).
|
123
|
+
def set_connection_adapters
|
124
|
+
Object.const_set("MUDING_CONNECTION_ADAPTERS", configuration.connection_adapters) if configuration.connection_adapters
|
125
|
+
end
|
126
|
+
|
127
|
+
# Requires all frameworks specified by the Configuration#frameworks
|
128
|
+
# list. By default, all frameworks (ActiveRecord, ActiveSupport,
|
129
|
+
# ActionPack, ActionMailer, and ActionWebService) are loaded.
|
130
|
+
def require_frameworks
|
131
|
+
configuration.frameworks.each { |framework| require(framework.to_s) }
|
132
|
+
end
|
133
|
+
|
134
|
+
# Add the load paths used by support functions such as the info controller
|
135
|
+
def add_support_load_paths
|
136
|
+
builtins = File.join(File.dirname(File.dirname(__FILE__)), 'builtin', '*')
|
137
|
+
$LOAD_PATH.concat(Dir[builtins])
|
138
|
+
end
|
139
|
+
|
140
|
+
# Loads all plugins in <tt>config.plugin_paths</tt>. <tt>plugin_paths</tt>
|
141
|
+
# defaults to <tt>vendor/plugins</tt> but may also be set to a list of
|
142
|
+
# paths, such as
|
143
|
+
# config.plugin_paths = ['lib/plugins', 'vendor/plugins']
|
144
|
+
#
|
145
|
+
# Each plugin discovered in <tt>plugin_paths</tt> is initialized:
|
146
|
+
# * add its +lib+ directory, if present, to the beginning of the load path
|
147
|
+
# * evaluate <tt>init.rb</tt> if present
|
148
|
+
#
|
149
|
+
# After all plugins are loaded, duplicates are removed from the load path.
|
150
|
+
# Plugins are loaded in alphabetical order.
|
151
|
+
def load_plugins
|
152
|
+
find_plugins(configuration.plugin_paths).sort.each { |path| load_plugin path }
|
153
|
+
$LOAD_PATH.uniq!
|
154
|
+
end
|
155
|
+
|
156
|
+
# Loads the environment specified by Configuration#environment_path, which
|
157
|
+
# is typically one of development, testing, or production.
|
158
|
+
def load_environment
|
159
|
+
silence_warnings do
|
160
|
+
config = configuration
|
161
|
+
constants = self.class.constants
|
162
|
+
eval(IO.read(configuration.environment_path), binding)
|
163
|
+
(self.class.constants - constants).each do |const|
|
164
|
+
Object.const_set(const, self.class.const_get(const))
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# This initialization routine does nothing unless <tt>:active_record</tt>
|
170
|
+
# is one of the frameworks to load (Configuration#frameworks). If it is,
|
171
|
+
# this sets the database configuration from Configuration#database_configuration
|
172
|
+
# and then establishes the connection.
|
173
|
+
def initialize_database
|
174
|
+
return unless configuration.frameworks.include?(:active_record)
|
175
|
+
ActiveRecord::Base.configurations = configuration.database_configuration
|
176
|
+
ActiveRecord::Base.establish_connection(MUDING_ENV)
|
177
|
+
end
|
178
|
+
|
179
|
+
# If the +MUDING_DEFAULT_LOGGER+ constant is already set, this initialization
|
180
|
+
# routine does nothing. If the constant is not set, and Configuration#logger
|
181
|
+
# is not +nil+, this also does nothing. Otherwise, a new logger instance
|
182
|
+
# is created at Configuration#log_path, with a default log level of
|
183
|
+
# Configuration#log_level.
|
184
|
+
#
|
185
|
+
# If the log could not be created, the log will be set to output to
|
186
|
+
# +STDERR+, with a log level of +WARN+.
|
187
|
+
def initialize_logger
|
188
|
+
# if the environment has explicitly defined a logger, use it
|
189
|
+
return if defined?(MUDING_DEFAULT_LOGGER)
|
190
|
+
|
191
|
+
unless logger = configuration.logger
|
192
|
+
begin
|
193
|
+
logger = Logger.new(configuration.log_path)
|
194
|
+
logger.level = Logger.const_get(configuration.log_level.to_s.upcase)
|
195
|
+
rescue StandardError
|
196
|
+
logger = Logger.new(STDERR)
|
197
|
+
logger.level = Logger::WARN
|
198
|
+
logger.warn(
|
199
|
+
"Muding Error: Unable to access log file. Please ensure that #{configuration.log_path} exists and is chmod 0666. " +
|
200
|
+
"The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
|
201
|
+
)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
silence_warnings { Object.const_set "MUDING_DEFAULT_LOGGER", logger }
|
206
|
+
end
|
207
|
+
|
208
|
+
# Sets the logger for ActiveRecord, ActionController, and ActionMailer
|
209
|
+
# (but only for those frameworks that are to be loaded). If the framework's
|
210
|
+
# logger is already set, it is not changed, otherwise it is set to use
|
211
|
+
# +MUDING_DEFAULT_LOGGER+.
|
212
|
+
def initialize_framework_logging
|
213
|
+
for framework in ([ :active_record, :action_controller, :action_mailer ] & configuration.frameworks)
|
214
|
+
framework.to_s.camelize.constantize.const_get("Base").logger ||= MUDING_DEFAULT_LOGGER
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# Sets the +template_root+ for ActionController::Base and ActionMailer::Base
|
219
|
+
# (but only for those frameworks that are to be loaded). If the framework's
|
220
|
+
# +template_root+ has already been set, it is not changed, otherwise it is
|
221
|
+
# set to use Configuration#view_path.
|
222
|
+
def initialize_framework_views
|
223
|
+
for framework in ([ :action_controller, :action_mailer ] & configuration.frameworks)
|
224
|
+
framework.to_s.camelize.constantize.const_get("Base").template_root ||= configuration.view_path
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# If ActionController is not one of the loaded frameworks (Configuration#frameworks)
|
229
|
+
# this does nothing. Otherwise, it loads the routing definitions and sets up
|
230
|
+
# loading module used to lazily load controllers (Configuration#controller_paths).
|
231
|
+
def initialize_routing
|
232
|
+
return unless configuration.frameworks.include?(:action_controller)
|
233
|
+
ActionController::Routing::Routes.reload
|
234
|
+
end
|
235
|
+
|
236
|
+
# Sets the dependency loading mechanism based on the value of
|
237
|
+
# Configuration#cache_classes.
|
238
|
+
def initialize_dependency_mechanism
|
239
|
+
Dependencies.mechanism = configuration.cache_classes ? :require : :load
|
240
|
+
end
|
241
|
+
|
242
|
+
# Sets the +BREAKPOINT_SERVER_PORT+ if Configuration#breakpoint_server
|
243
|
+
# is true.
|
244
|
+
def initialize_breakpoints
|
245
|
+
silence_warnings { Object.const_set("BREAKPOINT_SERVER_PORT", 42531) if configuration.breakpoint_server }
|
246
|
+
end
|
247
|
+
|
248
|
+
# Loads support for "whiny nil" (noisy warnings when methods are invoked
|
249
|
+
# on +nil+ values) if Configuration#whiny_nils is true.
|
250
|
+
def initialize_whiny_nils
|
251
|
+
require('active_support/whiny_nil') if configuration.whiny_nils
|
252
|
+
end
|
253
|
+
|
254
|
+
def initialize_temporary_directories
|
255
|
+
if configuration.frameworks.include?(:action_controller)
|
256
|
+
session_path = "#{MUDING_ROOT}/tmp/sessions/"
|
257
|
+
ActionController::Base.session_options[:tmpdir] = File.exist?(session_path) ? session_path : Dir::tmpdir
|
258
|
+
|
259
|
+
cache_path = "#{MUDING_ROOT}/tmp/cache/"
|
260
|
+
if File.exist?(cache_path)
|
261
|
+
ActionController::Base.fragment_cache_store = :file_store, cache_path
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
# Initializes framework-specific settings for each of the loaded frameworks
|
267
|
+
# (Configuration#frameworks). The available settings map to the accessors
|
268
|
+
# on each of the corresponding Base classes.
|
269
|
+
def initialize_framework_settings
|
270
|
+
configuration.frameworks.each do |framework|
|
271
|
+
base_class = framework.to_s.camelize.constantize.const_get("Base")
|
272
|
+
|
273
|
+
configuration.send(framework).each do |setting, value|
|
274
|
+
base_class.send("#{setting}=", value)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
# Fires the user-supplied after_initialize block (Configuration#after_initialize)
|
280
|
+
def after_initialize
|
281
|
+
configuration.after_initialize_block.call if configuration.after_initialize_block
|
282
|
+
end
|
283
|
+
|
284
|
+
|
285
|
+
protected
|
286
|
+
# Return a list of plugin paths within base_path. A plugin path is
|
287
|
+
# a directory that contains either a lib directory or an init.rb file.
|
288
|
+
# This recurses into directories which are not plugin paths, so you
|
289
|
+
# may organize your plugins within the plugin path.
|
290
|
+
def find_plugins(*base_paths)
|
291
|
+
base_paths.flatten.inject([]) do |plugins, base_path|
|
292
|
+
Dir.glob(File.join(base_path, '*')).each do |path|
|
293
|
+
if plugin_path?(path)
|
294
|
+
plugins << path
|
295
|
+
elsif File.directory?(path)
|
296
|
+
plugins += find_plugins(path)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
plugins
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
def plugin_path?(path)
|
304
|
+
File.directory?(path) and (File.directory?(File.join(path, 'lib')) or File.file?(File.join(path, 'init.rb')))
|
305
|
+
end
|
306
|
+
|
307
|
+
# Load the plugin at <tt>path</tt> unless already loaded.
|
308
|
+
#
|
309
|
+
# Each plugin is initialized:
|
310
|
+
# * add its +lib+ directory, if present, to the beginning of the load path
|
311
|
+
# * evaluate <tt>init.rb</tt> if present
|
312
|
+
#
|
313
|
+
# Returns <tt>true</tt> if the plugin is successfully loaded or
|
314
|
+
# <tt>false</tt> if it is already loaded (similar to Kernel#require).
|
315
|
+
# Raises <tt>LoadError</tt> if the plugin is not found.
|
316
|
+
def load_plugin(directory)
|
317
|
+
name = File.basename(directory)
|
318
|
+
return false if loaded_plugins.include?(name)
|
319
|
+
|
320
|
+
# Catch nonexistent and empty plugins.
|
321
|
+
raise LoadError, "No such plugin: #{directory}" unless plugin_path?(directory)
|
322
|
+
|
323
|
+
lib_path = File.join(directory, 'lib')
|
324
|
+
init_path = File.join(directory, 'init.rb')
|
325
|
+
has_lib = File.directory?(lib_path)
|
326
|
+
has_init = File.file?(init_path)
|
327
|
+
|
328
|
+
# Add lib to load path *after* the application lib, to allow
|
329
|
+
# application libraries to override plugin libraries.
|
330
|
+
if has_lib
|
331
|
+
application_lib_index = $LOAD_PATH.index(File.join(MUDING_ROOT, "lib")) || 0
|
332
|
+
$LOAD_PATH.insert(application_lib_index + 1, lib_path)
|
333
|
+
end
|
334
|
+
|
335
|
+
# Allow plugins to reference the current configuration object
|
336
|
+
config = configuration
|
337
|
+
|
338
|
+
# Add to set of loaded plugins before 'name' collapsed in eval.
|
339
|
+
loaded_plugins << name
|
340
|
+
|
341
|
+
# Evaluate init.rb.
|
342
|
+
silence_warnings { eval(IO.read(init_path), binding, init_path) } if has_init
|
343
|
+
|
344
|
+
true
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
# The Configuration class holds all the parameters for the Initializer and
|
349
|
+
# ships with defaults that suites most Muding applications. But it's possible
|
350
|
+
# to overwrite everything. Usually, you'll create an Configuration file
|
351
|
+
# implicitly through the block running on the Initializer, but it's also
|
352
|
+
# possible to create the Configuration instance in advance and pass it in
|
353
|
+
# like this:
|
354
|
+
#
|
355
|
+
# config = Muding::Configuration.new
|
356
|
+
# Muding::Initializer.run(:process, config)
|
357
|
+
class Configuration
|
358
|
+
# A stub for setting options on ActionController::Base
|
359
|
+
attr_accessor :action_controller
|
360
|
+
|
361
|
+
# A stub for setting options on ActionMailer::Base
|
362
|
+
attr_accessor :action_mailer
|
363
|
+
|
364
|
+
# A stub for setting options on ActionView::Base
|
365
|
+
attr_accessor :action_view
|
366
|
+
|
367
|
+
# A stub for setting options on ActionWebService::Base
|
368
|
+
attr_accessor :action_web_service
|
369
|
+
|
370
|
+
# A stub for setting options on ActiveRecord::Base
|
371
|
+
attr_accessor :active_record
|
372
|
+
|
373
|
+
# Whether or not to use the breakpoint server (boolean)
|
374
|
+
attr_accessor :breakpoint_server
|
375
|
+
|
376
|
+
# Whether or not classes should be cached (set to false if you want
|
377
|
+
# application classes to be reloaded on each request)
|
378
|
+
attr_accessor :cache_classes
|
379
|
+
|
380
|
+
# The list of connection adapters to load. (By default, all connection
|
381
|
+
# adapters are loaded. You can set this to be just the adapter(s) you
|
382
|
+
# will use to reduce your application's load time.)
|
383
|
+
attr_accessor :connection_adapters
|
384
|
+
|
385
|
+
# The list of paths that should be searched for controllers. (Defaults
|
386
|
+
# to <tt>app/controllers</tt> and <tt>components</tt>.)
|
387
|
+
attr_accessor :controller_paths
|
388
|
+
|
389
|
+
# The path to the database configuration file to use. (Defaults to
|
390
|
+
# <tt>config/database.yml</tt>.)
|
391
|
+
attr_accessor :database_configuration_file
|
392
|
+
|
393
|
+
# The list of muding framework components that should be loaded. (Defaults
|
394
|
+
# to <tt>:active_record</tt>, <tt>:action_controller</tt>,
|
395
|
+
# <tt>:action_view</tt>, <tt>:action_mailer</tt>, and
|
396
|
+
# <tt>:action_web_service</tt>).
|
397
|
+
attr_accessor :frameworks
|
398
|
+
|
399
|
+
# An array of additional paths to prepend to the load path. By default,
|
400
|
+
# all +app+, +lib+, +vendor+ and mock paths are included in this list.
|
401
|
+
attr_accessor :load_paths
|
402
|
+
|
403
|
+
# The log level to use for the default Muding logger. In production mode,
|
404
|
+
# this defaults to <tt>:info</tt>. In development mode, it defaults to
|
405
|
+
# <tt>:debug</tt>.
|
406
|
+
attr_accessor :log_level
|
407
|
+
|
408
|
+
# The path to the log file to use. Defaults to log/#{environment}.log
|
409
|
+
# (e.g. log/development.log or log/production.log).
|
410
|
+
attr_accessor :log_path
|
411
|
+
|
412
|
+
# The specific logger to use. By default, a logger will be created and
|
413
|
+
# initialized using #log_path and #log_level, but a programmer may
|
414
|
+
# specifically set the logger to use via this accessor and it will be
|
415
|
+
# used directly.
|
416
|
+
attr_accessor :logger
|
417
|
+
|
418
|
+
# The root of the application's views. (Defaults to <tt>app/views</tt>.)
|
419
|
+
attr_accessor :view_path
|
420
|
+
|
421
|
+
# Set to +true+ if you want to be warned (noisily) when you try to invoke
|
422
|
+
# any method of +nil+. Set to +false+ for the standard Ruby behavior.
|
423
|
+
attr_accessor :whiny_nils
|
424
|
+
|
425
|
+
# The path to the root of the plugins directory. By default, it is in
|
426
|
+
# <tt>vendor/plugins</tt>.
|
427
|
+
attr_accessor :plugin_paths
|
428
|
+
|
429
|
+
# Create a new Configuration instance, initialized with the default
|
430
|
+
# values.
|
431
|
+
def initialize
|
432
|
+
self.frameworks = default_frameworks
|
433
|
+
self.load_paths = default_load_paths
|
434
|
+
self.log_path = default_log_path
|
435
|
+
self.log_level = default_log_level
|
436
|
+
self.view_path = default_view_path
|
437
|
+
self.controller_paths = default_controller_paths
|
438
|
+
self.cache_classes = default_cache_classes
|
439
|
+
self.breakpoint_server = default_breakpoint_server
|
440
|
+
self.whiny_nils = default_whiny_nils
|
441
|
+
self.plugin_paths = default_plugin_paths
|
442
|
+
self.database_configuration_file = default_database_configuration_file
|
443
|
+
|
444
|
+
for framework in default_frameworks
|
445
|
+
self.send("#{framework}=", OrderedOptions.new)
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
# Loads and returns the contents of the #database_configuration_file. The
|
450
|
+
# contents of the file are processed via ERB before being sent through
|
451
|
+
# YAML::load.
|
452
|
+
def database_configuration
|
453
|
+
YAML::load(ERB.new(IO.read(database_configuration_file)).result)
|
454
|
+
end
|
455
|
+
|
456
|
+
# The path to the current environment's file (development.rb, etc.). By
|
457
|
+
# default the file is at <tt>config/environments/#{environment}.rb</tt>.
|
458
|
+
def environment_path
|
459
|
+
"#{root_path}/config/environments/#{environment}.rb"
|
460
|
+
end
|
461
|
+
|
462
|
+
# Return the currently selected environment. By default, it returns the
|
463
|
+
# value of the +MUDING_ENV+ constant.
|
464
|
+
def environment
|
465
|
+
::MUDING_ENV
|
466
|
+
end
|
467
|
+
|
468
|
+
# Sets a block which will be executed after muding has been fully initialized.
|
469
|
+
# Useful for per-environment configuration which depends on the framework being
|
470
|
+
# fully initialized.
|
471
|
+
def after_initialize(&after_initialize_block)
|
472
|
+
@after_initialize_block = after_initialize_block
|
473
|
+
end
|
474
|
+
|
475
|
+
# Returns the block set in Configuration#after_initialize
|
476
|
+
def after_initialize_block
|
477
|
+
@after_initialize_block
|
478
|
+
end
|
479
|
+
|
480
|
+
private
|
481
|
+
def root_path
|
482
|
+
::MUDING_ROOT
|
483
|
+
end
|
484
|
+
|
485
|
+
def framework_root_path
|
486
|
+
defined?(::MUDING_FRAMEWORK_ROOT) ? ::MUDING_FRAMEWORK_ROOT : "#{root_path}/vendor/muding"
|
487
|
+
end
|
488
|
+
|
489
|
+
def default_frameworks
|
490
|
+
[ :active_record, :action_view, :action_mailer ]
|
491
|
+
end
|
492
|
+
|
493
|
+
def default_load_paths
|
494
|
+
paths = ["#{root_path}/test/mocks/#{environment}"]
|
495
|
+
|
496
|
+
# Add the app's controller directory
|
497
|
+
paths.concat(Dir["#{root_path}/app/controllers/"])
|
498
|
+
|
499
|
+
# Then model subdirectories.
|
500
|
+
# TODO: Don't include .rb models as load paths
|
501
|
+
paths.concat(Dir["#{root_path}/app/models/[_a-z]*"])
|
502
|
+
paths.concat(Dir["#{root_path}/components/[_a-z]*"])
|
503
|
+
|
504
|
+
# Followed by the standard includes.
|
505
|
+
paths.concat %w(
|
506
|
+
mud
|
507
|
+
mud/models
|
508
|
+
mud/controllers
|
509
|
+
mud/helpers
|
510
|
+
config
|
511
|
+
lib
|
512
|
+
vendor
|
513
|
+
).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
|
514
|
+
|
515
|
+
# TODO: Don't include dirs for frameworks that are not used
|
516
|
+
paths.concat %w(
|
517
|
+
muding
|
518
|
+
muding/lib
|
519
|
+
activesupport/lib
|
520
|
+
activerecord/lib
|
521
|
+
).map { |dir| "#{framework_root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
|
522
|
+
end
|
523
|
+
|
524
|
+
def default_log_path
|
525
|
+
File.join(root_path, 'log', "#{environment}.log")
|
526
|
+
end
|
527
|
+
|
528
|
+
def default_log_level
|
529
|
+
environment == 'production' ? :info : :debug
|
530
|
+
end
|
531
|
+
|
532
|
+
def default_database_configuration_file
|
533
|
+
File.join(root_path, 'config', 'database.yml')
|
534
|
+
end
|
535
|
+
|
536
|
+
def default_view_path
|
537
|
+
File.join(root_path, 'mud', 'views')
|
538
|
+
end
|
539
|
+
|
540
|
+
def default_controller_paths
|
541
|
+
[ File.join(root_path, 'mud', 'controllers')]
|
542
|
+
end
|
543
|
+
|
544
|
+
def default_dependency_mechanism
|
545
|
+
:load
|
546
|
+
end
|
547
|
+
|
548
|
+
def default_cache_classes
|
549
|
+
false
|
550
|
+
end
|
551
|
+
|
552
|
+
def default_breakpoint_server
|
553
|
+
false
|
554
|
+
end
|
555
|
+
|
556
|
+
def default_whiny_nils
|
557
|
+
false
|
558
|
+
end
|
559
|
+
|
560
|
+
def default_plugin_paths
|
561
|
+
["#{root_path}/vendor/plugins"]
|
562
|
+
end
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
566
|
+
# Needs to be duplicated from Active Support since its needed before Active
|
567
|
+
# Support is available.
|
568
|
+
class OrderedHash < Array #:nodoc:
|
569
|
+
def []=(key, value)
|
570
|
+
if pair = find_pair(key)
|
571
|
+
pair.pop
|
572
|
+
pair << value
|
573
|
+
else
|
574
|
+
self << [key, value]
|
575
|
+
end
|
576
|
+
end
|
577
|
+
|
578
|
+
def [](key)
|
579
|
+
pair = find_pair(key)
|
580
|
+
pair ? pair.last : nil
|
581
|
+
end
|
582
|
+
|
583
|
+
def keys
|
584
|
+
self.collect { |i| i.first }
|
585
|
+
end
|
586
|
+
|
587
|
+
private
|
588
|
+
def find_pair(key)
|
589
|
+
self.each { |i| return i if i.first == key }
|
590
|
+
return false
|
591
|
+
end
|
592
|
+
end
|
593
|
+
|
594
|
+
class OrderedOptions < OrderedHash #:nodoc:
|
595
|
+
def []=(key, value)
|
596
|
+
super(key.to_sym, value)
|
597
|
+
end
|
598
|
+
|
599
|
+
def [](key)
|
600
|
+
super(key.to_sym)
|
601
|
+
end
|
602
|
+
|
603
|
+
def method_missing(name, *args)
|
604
|
+
if name.to_s =~ /(.*)=$/
|
605
|
+
self[$1.to_sym] = args.first
|
606
|
+
else
|
607
|
+
self[name]
|
608
|
+
end
|
609
|
+
end
|
610
|
+
end
|
611
|
+
|
612
|
+
|