muding 0.1.1 → 0.2.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 +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
|
+
|