diff options
Diffstat (limited to 'railties/lib/rails')
-rw-r--r-- | railties/lib/rails/configuration.rb | 267 | ||||
-rw-r--r-- | railties/lib/rails/core.rb | 97 | ||||
-rw-r--r-- | railties/lib/rails/gem_dependency.rb | 30 | ||||
-rw-r--r-- | railties/lib/rails/paths.rb | 124 | ||||
-rw-r--r-- | railties/lib/rails/plugin/loader.rb | 4 | ||||
-rw-r--r-- | railties/lib/rails/version.rb | 6 |
6 files changed, 516 insertions, 12 deletions
diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb new file mode 100644 index 0000000000..d877915460 --- /dev/null +++ b/railties/lib/rails/configuration.rb @@ -0,0 +1,267 @@ +module Rails + class Configuration + attr_accessor :cache_classes, :load_paths, :eager_load_paths, :framework_paths, + :load_once_paths, :gems_dependencies_loaded, :after_initialize_blocks, + :frameworks, :framework_root_path, :root_path, :plugin_paths, :plugins, + :plugin_loader, :plugin_locators, :gems, :loaded_plugins, :reload_plugins, + :i18n, :gems, :whiny_nils, :consider_all_requests_local, + :action_controller, :active_record, :action_view, :active_support, + :action_mailer, :active_resource, + :log_path, :log_level, :logger, :preload_frameworks, + :database_configuration_file, :cache_store, :time_zone, + :view_path, :metals, :controller_paths, :routes_configuration_file, + :eager_load_paths, :dependency_loading, :paths + + def initialize + set_root_path! + + @framework_paths = [] + @load_once_paths = [] + @after_initialize_blocks = [] + @loaded_plugins = [] + @dependency_loading = true + @eager_load_paths = default_eager_load_paths + @load_paths = default_load_paths + @plugin_paths = default_plugin_paths + @frameworks = default_frameworks + @plugin_loader = default_plugin_loader + @plugin_locators = default_plugin_locators + @gems = default_gems + @i18n = default_i18n + @log_path = default_log_path + @log_level = default_log_level + @cache_store = default_cache_store + @view_path = default_view_path + @controller_paths = default_controller_paths + @routes_configuration_file = default_routes_configuration_file + @database_configuration_file = default_database_configuration_file + + for framework in default_frameworks + self.send("#{framework}=", Rails::OrderedOptions.new) + end + self.active_support = Rails::OrderedOptions.new + end + + def after_initialize(&blk) + @after_initialize_blocks << blk if blk + end + + def set_root_path! + raise 'RAILS_ROOT is not set' unless defined?(RAILS_ROOT) + raise 'RAILS_ROOT is not a directory' unless File.directory?(RAILS_ROOT) + + self.root_path = + # Pathname is incompatible with Windows, but Windows doesn't have + # real symlinks so File.expand_path is safe. + if RUBY_PLATFORM =~ /(:?mswin|mingw)/ + File.expand_path(RAILS_ROOT) + + # Otherwise use Pathname#realpath which respects symlinks. + else + Pathname.new(RAILS_ROOT).realpath.to_s + end + + @paths = Rails::Application::Root.new(root_path) + @paths.app = "app" + @paths.app.metals = "app/metal" + @paths.app.models = "app/models" + @paths.app.controllers = "app/controllers" + @paths.app.helpers = "app/helpers" + @paths.app.services = "app/services" + @paths.lib = "lib" + @paths.vendor = "vendor" + @paths.vendor.plugins = "vendor/plugins" + @paths.cache = "tmp/cache" + @paths.config = "config" + @paths.config.locales = "config/locales" + @paths.config.environments = "config/environments" + + @paths.app.controllers.concat builtin_directories + + @paths.app.load_path! + @paths.app.metals.load_path! + @paths.app.models.eager_load! + @paths.app.controllers.eager_load! + @paths.app.helpers.eager_load! + @paths.app.services.load_path! + @paths.app.metals.eager_load! + @paths.lib.load_path! + @paths.vendor.load_path! + + @paths.config.environments.glob = "#{RAILS_ENV}.rb" + + RAILS_ROOT.replace root_path + end + + # Enable threaded mode. Allows concurrent requests to controller actions and + # multiple database connections. Also disables automatic dependency loading + # after boot, and disables reloading code on every request, as these are + # fundamentally incompatible with thread safety. + def threadsafe! + self.preload_frameworks = true + self.cache_classes = true + self.dependency_loading = false + self.action_controller.allow_concurrency = true + self + end + + def framework_paths + paths = %w(railties railties/lib activesupport/lib) + paths << 'actionpack/lib' if frameworks.include?(:action_controller) || frameworks.include?(:action_view) + + [:active_record, :action_mailer, :active_resource, :action_web_service].each do |framework| + paths << "#{framework.to_s.gsub('_', '')}/lib" if frameworks.include?(framework) + end + + paths.map { |dir| "#{framework_root_path}/#{dir}" }.select { |dir| File.directory?(dir) } + end + + def framework_root_path + defined?(::RAILS_FRAMEWORK_ROOT) ? ::RAILS_FRAMEWORK_ROOT : "#{root_path}/vendor/rails" + end + + # TODO: Fix this when there is an application object + def middleware + ActionController::Dispatcher.middleware + end + + # Loads and returns the contents of the #database_configuration_file. The + # contents of the file are processed via ERB before being sent through + # YAML::load. + def database_configuration + require 'erb' + YAML::load(ERB.new(IO.read(database_configuration_file)).result) + end + + def default_routes_configuration_file + File.join(root_path, 'config', 'routes.rb') + end + + def default_controller_paths + paths = [File.join(root_path, 'app', 'controllers')] + paths.concat builtin_directories + paths + end + + def default_cache_store + if File.exist?("#{root_path}/tmp/cache/") + [ :file_store, "#{root_path}/tmp/cache/" ] + else + :memory_store + end + end + + def default_database_configuration_file + File.join(root_path, 'config', 'database.yml') + end + + def default_view_path + File.join(root_path, 'app', 'views') + end + + def default_eager_load_paths + %w( + app/metal + app/models + app/controllers + app/helpers + ).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) } + end + + def default_load_paths + paths = [] + + # Add the old mock paths only if the directories exists + paths.concat(Dir["#{root_path}/test/mocks/#{RAILS_ENV}"]) if File.exists?("#{root_path}/test/mocks/#{RAILS_ENV}") + + # Add the app's controller directory + paths.concat(Dir["#{root_path}/app/controllers/"]) + + # Followed by the standard includes. + paths.concat %w( + app + app/metal + app/models + app/controllers + app/helpers + app/services + lib + vendor + ).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) } + + paths.concat builtin_directories + end + + def builtin_directories + # Include builtins only in the development environment. + (RAILS_ENV == 'development') ? Dir["#{RAILTIES_PATH}/builtin/*/"] : [] + end + + def default_log_path + File.join(root_path, 'log', "#{RAILS_ENV}.log") + end + + def default_log_level + RAILS_ENV == 'production' ? :info : :debug + end + + def default_frameworks + [ :active_record, :action_controller, :action_view, :action_mailer, :active_resource ] + end + + def default_plugin_paths + ["#{root_path}/vendor/plugins"] + end + + def default_plugin_loader + require 'rails/plugin/loader' + Plugin::Loader + end + + def default_plugin_locators + require 'rails/plugin/locator' + locators = [] + locators << Plugin::GemLocator if defined? Gem + locators << Plugin::FileSystemLocator + end + + def default_i18n + i18n = Rails::OrderedOptions.new + i18n.load_path = [] + + if File.exist?(File.join(RAILS_ROOT, 'config', 'locales')) + i18n.load_path << Dir[File.join(RAILS_ROOT, 'config', 'locales', '*.{rb,yml}')] + i18n.load_path.flatten! + end + + i18n + end + + # Adds a single Gem dependency to the rails application. By default, it will require + # the library with the same name as the gem. Use :lib to specify a different name. + # + # # gem 'aws-s3', '>= 0.4.0' + # # require 'aws/s3' + # config.gem 'aws-s3', :lib => 'aws/s3', :version => '>= 0.4.0', \ + # :source => "http://code.whytheluckystiff.net" + # + # To require a library be installed, but not attempt to load it, pass :lib => false + # + # config.gem 'qrp', :version => '0.4.1', :lib => false + def gem(name, options = {}) + @gems << Rails::GemDependency.new(name, options) + end + + def default_gems + [] + end + + def environment_path + "#{root_path}/config/environments/#{RAILS_ENV}.rb" + end + + def reload_plugins? + @reload_plugins + end + end +end
\ No newline at end of file diff --git a/railties/lib/rails/core.rb b/railties/lib/rails/core.rb new file mode 100644 index 0000000000..33695a27b9 --- /dev/null +++ b/railties/lib/rails/core.rb @@ -0,0 +1,97 @@ +module Rails + # Needs to be duplicated from Active Support since its needed before Active + # Support is available. Here both Options and Hash are namespaced to prevent + # conflicts with other implementations AND with the classes residing in Active Support. + # --- + # TODO: w0t? + class << self + # The Configuration instance used to configure the Rails environment + def configuration + @@configuration + end + + def configuration=(configuration) + @@configuration = configuration + end + + def initialized? + @initialized || false + end + + def initialized=(initialized) + @initialized ||= initialized + end + + def logger + if defined?(RAILS_DEFAULT_LOGGER) + RAILS_DEFAULT_LOGGER + else + nil + end + end + + def backtrace_cleaner + @@backtrace_cleaner ||= begin + # Relies on ActiveSupport, so we have to lazy load to postpone definition until AS has been loaded + require 'rails/backtrace_cleaner' + Rails::BacktraceCleaner.new + end + end + + def root + Pathname.new(RAILS_ROOT) if defined?(RAILS_ROOT) + end + + def env + @_env ||= ActiveSupport::StringInquirer.new(RAILS_ENV) + end + + def cache + RAILS_CACHE + end + + def version + VERSION::STRING + end + + def public_path + @@public_path ||= self.root ? File.join(self.root, "public") : "public" + end + + def public_path=(path) + @@public_path = path + end + end + + class OrderedOptions < Array #:nodoc: + def []=(key, value) + key = key.to_sym + + if pair = find_pair(key) + pair.pop + pair << value + else + self << [key, value] + end + end + + def [](key) + pair = find_pair(key.to_sym) + pair ? pair.last : nil + end + + def method_missing(name, *args) + if name.to_s =~ /(.*)=$/ + self[$1.to_sym] = args.first + else + self[name] + end + end + + private + def find_pair(key) + self.each { |i| return i if i.first == key } + return false + end + end +end
\ No newline at end of file diff --git a/railties/lib/rails/gem_dependency.rb b/railties/lib/rails/gem_dependency.rb index ee3d0d81ba..06d830ba24 100644 --- a/railties/lib/rails/gem_dependency.rb +++ b/railties/lib/rails/gem_dependency.rb @@ -29,11 +29,18 @@ module Rails end end - def self.from_directory_name(directory_name) + def self.from_directory_name(directory_name, load_spec=true) directory_name_parts = File.basename(directory_name).split('-') name = directory_name_parts[0..-2].join('-') version = directory_name_parts.last - self.new(name, :version => version) + result = self.new(name, :version => version) + spec_filename = File.join(directory_name, '.specification') + if load_spec + raise "Missing specification file in #{File.dirname(spec_filename)}. Perhaps you need to do a 'rake gems:refresh_specs'?" unless File.exists?(spec_filename) + spec = YAML::load_file(spec_filename) + result.specification = spec + end + result rescue ArgumentError => e raise "Unable to determine gem name and version from '#{directory_name}'" end @@ -104,6 +111,10 @@ module Rails end end + def specification=(s) + @spec = s + end + def requirement r = version_requirements (r == Gem::Requirement.default) ? nil : r @@ -111,10 +122,14 @@ module Rails def built? return false unless frozen? - specification.extensions.each do |ext| - makefile = File.join(unpacked_gem_directory, File.dirname(ext), 'Makefile') - return false unless File.exists?(makefile) + + if vendor_gem? + specification.extensions.each do |ext| + makefile = File.join(unpacked_gem_directory, File.dirname(ext), 'Makefile') + return false unless File.exists?(makefile) + end end + true end @@ -170,13 +185,14 @@ module Rails def build(options={}) require 'rails/gem_builder' + return if specification.nil? if options[:force] || !built? return unless File.exists?(unpacked_specification_filename) spec = YAML::load_file(unpacked_specification_filename) Rails::GemBuilder.new(spec, unpacked_gem_directory).build_extensions puts "Built gem: '#{unpacked_gem_directory}'" end - dependencies.each { |dep| dep.build } + dependencies.each { |dep| dep.build(options) } end def install @@ -236,7 +252,7 @@ module Rails real_spec = Gem::Specification.load(specification.loaded_from) write_specification(real_spec) end - dependencies.each { |dep| dep.unpack } if options[:recursive] + dependencies.each { |dep| dep.unpack(options) } if options[:recursive] end def write_specification(spec) diff --git a/railties/lib/rails/paths.rb b/railties/lib/rails/paths.rb new file mode 100644 index 0000000000..d2f6d83659 --- /dev/null +++ b/railties/lib/rails/paths.rb @@ -0,0 +1,124 @@ +require 'set' + +module Rails + class Application + module PathParent + def method_missing(id, *args) + name = id.to_s + + if name =~ /^(.*)=$/ + @children[$1] = Path.new(args.first, @root) + elsif path = @children[name] + path + else + super + end + end + end + + class Root + include PathParent + + attr_reader :path + def initialize(path) + raise unless path.is_a?(String) + + @children = {} + + # TODO: Move logic from set_root_path initializer + @path = File.expand_path(path) + @root = self + @load_once, @eager_load, @all_paths = [], [], [] + end + + def load_once + @load_once.uniq! + @load_once + end + + def eager_load + @eager_load.uniq! + @eager_load + end + + def all_paths + @all_paths.uniq! + @all_paths + end + + def load_paths + all_paths.map { |path| path.paths }.flatten + end + + def add_to_load_path + load_paths.reverse_each do |path| + $LOAD_PATH.unshift(path) if File.directory?(path) + end + end + end + + class Path + include PathParent + + attr_reader :path + attr_accessor :glob + + def initialize(path, root) + @children = {} + @root = root + @paths = [path].flatten + @glob = "**/*.rb" + end + + def push(path) + @paths.push path + end + + alias << push + + def unshift(path) + @paths.unshift path + end + + def concat(paths) + @paths.concat paths + end + + def load_once! + @load_once = true + @root.load_once.push *self.paths + end + + def load_once? + @load_once + end + + def eager_load! + @eager_load = true + @root.all_paths << self + @root.eager_load.push *self.paths + end + + def eager_load? + @eager_load + end + + def load_path! + @load_path = true + @root.all_paths << self + end + + def load_path? + @load_path + end + + def paths + @paths.map do |path| + path.index('/') == 0 ? path : File.join(@root.path, path) + end + end + + alias to_a paths + end + end +end
\ No newline at end of file diff --git a/railties/lib/rails/plugin/loader.rb b/railties/lib/rails/plugin/loader.rb index bc22dfc591..7ea9c7c0f3 100644 --- a/railties/lib/rails/plugin/loader.rb +++ b/railties/lib/rails/plugin/loader.rb @@ -105,7 +105,7 @@ module Rails end def register_plugin_as_loaded(plugin) - initializer.loaded_plugins << plugin + initializer.config.loaded_plugins << plugin end def configuration @@ -174,7 +174,7 @@ module Rails end def loaded?(plugin_name) - initializer.loaded_plugins.detect { |plugin| plugin.name == plugin_name.to_s } + initializer.config.loaded_plugins.detect { |plugin| plugin.name == plugin_name.to_s } end def ensure_all_registered_plugins_are_loaded! diff --git a/railties/lib/rails/version.rb b/railties/lib/rails/version.rb index 99c7516a65..9a65096061 100644 --- a/railties/lib/rails/version.rb +++ b/railties/lib/rails/version.rb @@ -1,8 +1,8 @@ module Rails module VERSION #:nodoc: - MAJOR = 2 - MINOR = 3 - TINY = 2 + MAJOR = 3 + MINOR = 0 + TINY = "pre" STRING = [MAJOR, MINOR, TINY].join('.') end |