bborn-desert 0.5.3

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.
Files changed (45) hide show
  1. data/CHANGES +50 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +316 -0
  4. data/Rakefile +77 -0
  5. data/VERSION.yml +2 -0
  6. data/generators/desert_plugin/USAGE +14 -0
  7. data/generators/desert_plugin/desert_plugin_generator.rb +73 -0
  8. data/generators/desert_plugin/templates/desert_routes.rb +4 -0
  9. data/generators/desert_plugin/templates/empty_file +0 -0
  10. data/generators/desert_plugin/templates/plugin_migration.rb +11 -0
  11. data/generators/desert_plugin/templates/spec_helper.rb +8 -0
  12. data/init.rb +0 -0
  13. data/lib/desert.rb +14 -0
  14. data/lib/desert/manager.rb +131 -0
  15. data/lib/desert/plugin.rb +74 -0
  16. data/lib/desert/plugin_migrations.rb +11 -0
  17. data/lib/desert/plugin_migrations/1.2/extensions/schema_statements.rb +34 -0
  18. data/lib/desert/plugin_migrations/1.2/migrator.rb +33 -0
  19. data/lib/desert/plugin_migrations/2.1/extensions/schema_statements.rb +39 -0
  20. data/lib/desert/plugin_migrations/2.1/migrator.rb +35 -0
  21. data/lib/desert/plugin_migrations/migrator.rb +29 -0
  22. data/lib/desert/plugin_templates.rb +13 -0
  23. data/lib/desert/plugin_templates/1.2.0/action_mailer.rb +21 -0
  24. data/lib/desert/plugin_templates/1.2.0/action_view.rb +53 -0
  25. data/lib/desert/plugin_templates/1.99.0/action_mailer.rb +25 -0
  26. data/lib/desert/plugin_templates/1.99.0/action_view.rb +38 -0
  27. data/lib/desert/plugin_templates/2.0.0/action_mailer.rb +23 -0
  28. data/lib/desert/plugin_templates/2.0.2/action_view.rb +26 -0
  29. data/lib/desert/plugin_templates/2.1.0/action_view.rb +15 -0
  30. data/lib/desert/plugin_templates/2.2.0/action_mailer.rb +23 -0
  31. data/lib/desert/plugin_templates/2.2.0/action_view.rb +10 -0
  32. data/lib/desert/plugin_templates/action_controller.rb +12 -0
  33. data/lib/desert/plugin_templates/action_view.rb +17 -0
  34. data/lib/desert/rails.rb +10 -0
  35. data/lib/desert/rails/1.2.0/initializer.rb +20 -0
  36. data/lib/desert/rails/2.0.0/plugin.rb +22 -0
  37. data/lib/desert/rails/dependencies.rb +87 -0
  38. data/lib/desert/rails/migration.rb +36 -0
  39. data/lib/desert/rails/route_set.rb +23 -0
  40. data/lib/desert/ruby.rb +2 -0
  41. data/lib/desert/ruby/object.rb +34 -0
  42. data/lib/desert/supported_rails_versions.rb +12 -0
  43. data/lib/desert/tasks.rb +4 -0
  44. data/lib/desert/version_checker.rb +34 -0
  45. metadata +105 -0
@@ -0,0 +1,35 @@
1
+ module Desert #:nodoc:
2
+ module PluginMigrations
3
+ class Migrator < ActiveRecord::Migrator
4
+ class << self
5
+ def current_version #:nodoc:
6
+ result = ActiveRecord::Base.connection.select_one("SELECT version FROM #{schema_migrations_table_name} WHERE plugin_name = '#{current_plugin.name}' order by version desc")
7
+ if result
8
+ result['version'].to_i
9
+ else
10
+ # There probably isn't an entry for this plugin in the migration info table.
11
+ 0
12
+ end
13
+ end
14
+
15
+ def get_all_versions
16
+ ActiveRecord::Base.connection.select_values("SELECT version FROM #{schema_migrations_table_name} where plugin_name='#{current_plugin.name}'").map(&:to_i).sort
17
+ end
18
+ end
19
+
20
+ def record_version_state_after_migrating(version)
21
+ sm_table = self.class.schema_migrations_table_name
22
+
23
+ if down?
24
+ ActiveRecord::Base.connection.update("DELETE FROM #{sm_table} WHERE version = '#{version}' AND plugin_name = '#{current_plugin.name}'")
25
+ else
26
+ ActiveRecord::Base.connection.insert("INSERT INTO #{sm_table} (plugin_name, version) VALUES ('#{current_plugin.name}', '#{version}')")
27
+ end
28
+ end
29
+
30
+ def migrated
31
+ self.class.get_all_versions
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,29 @@
1
+ module Desert #:nodoc:
2
+ module PluginMigrations
3
+ # Responsible for migrating plugins. PluginMigrations.Migrator.current_plugin
4
+ # indicates which plugin is currently being migrated
5
+ class Migrator < ActiveRecord::Migrator
6
+ # We need to be able to set the current plugin being migrated.
7
+ cattr_accessor :current_plugin
8
+
9
+ class << self
10
+ # Runs the migrations from a plugin, up (or down) to the version given
11
+ def migrate_plugin(plugin, version = nil)
12
+ self.current_plugin = plugin
13
+ if ActiveRecord::Base.connection.respond_to?(:initialize_schema_migrations_table)
14
+ ActiveRecord::Base.connection.initialize_schema_migrations_table
15
+ end
16
+ migrate(plugin.migration_path, version)
17
+ end
18
+
19
+ def schema_info_table_name #:nodoc:
20
+ ActiveRecord::Base.table_name_prefix + 'plugin_schema_info' + ActiveRecord::Base.table_name_suffix
21
+ end
22
+
23
+ def schema_migrations_table_name
24
+ ActiveRecord::Base.table_name_prefix + 'plugin_schema_migrations' + ActiveRecord::Base.table_name_suffix
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,13 @@
1
+ dir = File.dirname(__FILE__)
2
+ require "#{dir}/plugin_templates/action_controller"
3
+ if Desert::VersionChecker.rails_version_is_below_1990?
4
+ require "#{dir}/plugin_templates/1.2.0/action_mailer"
5
+ elsif Desert::VersionChecker.rails_version_is_below_rc2?
6
+ require "#{dir}/plugin_templates/1.99.0/action_mailer"
7
+ elsif Desert::VersionChecker.rails_version_is_below_220?
8
+ require "#{dir}/plugin_templates/2.0.0/action_mailer"
9
+ else
10
+ require "#{dir}/plugin_templates/2.2.0/action_mailer"
11
+ end
12
+
13
+ require "#{dir}/plugin_templates/action_view"
@@ -0,0 +1,21 @@
1
+ module ActionMailer #:nodoc
2
+ class Base #:nodoc:
3
+ private
4
+ def template_path_with_plugin_routing
5
+ template_paths = [template_path_without_plugin_routing]
6
+ Desert::Manager.plugins.reverse.each do |plugin|
7
+ template_paths << "#{plugin.templates_path}/#{mailer_name}"
8
+ end
9
+ "{#{template_paths * ','}}"
10
+ end
11
+ alias_method_chain :template_path, :plugin_routing
12
+
13
+ def initialize_template_class(assigns)
14
+ view_path = File.dirname(Dir["#{template_path}/#{@template}.*"].first)
15
+ returning(template = ActionView::Base.new(view_path, assigns, self)) do
16
+ template.extend ApplicationHelper
17
+ template.extend self.class.master_helper_module
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,53 @@
1
+ module ActionView
2
+ class Base
3
+ attr_reader :view_paths
4
+ def initialize_with_desert(base_path = nil, assigns_for_first_render = {}, controller = nil)
5
+ initialize_without_desert(base_path, assigns_for_first_render, controller)
6
+
7
+ @view_paths = [base_path]
8
+ Desert::Manager.plugins_and_app.reverse.each do |plugin|
9
+ @view_paths << plugin.templates_path
10
+ end
11
+ end
12
+ alias_method_chain :initialize, :desert
13
+
14
+ private
15
+ def full_path_template_exists?(path, extension)
16
+ file_path = "#{path}.#{extension}"
17
+ @@method_names.has_key?(file_path) || FileTest.exists?(file_path)
18
+ end
19
+
20
+ def find_template_extension_for(template_path)
21
+ view_paths.each do |view_path|
22
+ full_path = "#{view_path}/#{template_path}"
23
+ if match = @@template_handlers.find { |k,| full_path_template_exists?(template_path, k) }
24
+ return match.first.to_sym
25
+ elsif full_path_template_exists?(full_path, :rhtml)
26
+ return :rhtml
27
+ elsif full_path_template_exists?(full_path, :rxml)
28
+ return :rxml
29
+ elsif full_path_template_exists?(full_path, :rjs)
30
+ return :rjs
31
+ end
32
+ end
33
+ raise ActionViewError, "No rhtml, rxml, rjs or delegate template found for #{template_path} in #{@base_path}"
34
+ end
35
+
36
+ def full_template_path_with_plugin_routing(template_path, extension)
37
+ full_template_path = full_template_path_without_plugin_routing(template_path, extension)
38
+
39
+ unless File.exist?(full_template_path)
40
+ # Look through the plugins for the template
41
+ Desert::Manager.plugins.reverse.each do |plugin|
42
+ if plugin_template_path = plugin.find_template("#{template_path}.#{extension}")
43
+ full_template_path = plugin_template_path
44
+ break
45
+ end
46
+ end
47
+ end
48
+
49
+ full_template_path
50
+ end
51
+ alias_method_chain :full_template_path, :plugin_routing
52
+ end
53
+ end
@@ -0,0 +1,25 @@
1
+ module ActionMailer #:nodoc
2
+ class Base #:nodoc:
3
+ private
4
+ def template_path_with_plugin_routing
5
+ result = nil
6
+ Desert::Manager.plugins_and_app.reverse.each do |plugin|
7
+ relative_path = "#{plugin.templates_path}/#{mailer_name}"
8
+ unless Dir["#{relative_path}/#{@template}.*"].empty?
9
+ result = relative_path
10
+ break
11
+ end
12
+ end
13
+ result || template_path_without_plugin_routing
14
+ end
15
+ alias_method_chain :template_path, :plugin_routing
16
+
17
+ def initialize_template_class(assigns)
18
+ view_path = File.dirname(Dir["#{template_path}/#{@template}.*"].first)
19
+ returning(template = ActionView::Base.new([view_path], assigns, self)) do
20
+ template.extend ApplicationHelper
21
+ template.extend self.class.master_helper_module
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,38 @@
1
+ module ActionView #:nodoc:
2
+ class Base #:nodoc:
3
+ def initialize_with_desert_plugins(*args)
4
+ initialize_without_desert_plugins *args
5
+
6
+ Desert::Manager.plugins.reverse.each do |plugin|
7
+ view_paths << plugin.templates_path
8
+ end
9
+ end
10
+ alias_method_chain :initialize, :desert_plugins
11
+
12
+ def find_template_extension_from_handler(template_path, formatted = nil)
13
+ checked_template_path = formatted ? "#{template_path}.#{template_format}" : template_path
14
+
15
+ view_paths.each do |view_path|
16
+ template_handler_preferences.each do |template_type|
17
+ extensions =
18
+ case template_type
19
+ when :javascript
20
+ [:rjs]
21
+ when :delegate
22
+ @@template_handlers.keys
23
+ else
24
+ [template_type]
25
+ end
26
+
27
+ extensions.each do |extension|
28
+ file_path = File.join(view_path, "#{checked_template_path}.#{extension}")
29
+ if File.exist?(file_path)
30
+ return formatted ? "#{template_format}.#{extension}" : extension.to_s
31
+ end
32
+ end
33
+ end
34
+ end
35
+ nil
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,23 @@
1
+ module ActionMailer #:nodoc
2
+ class Base #:nodoc:
3
+ private
4
+ def template_path_with_plugin_routing
5
+ template_paths = [template_path_without_plugin_routing]
6
+ Desert::Manager.plugins.reverse.each do |plugin|
7
+ template_paths << "#{plugin.templates_path}/#{mailer_name}"
8
+ end
9
+ "{#{template_paths * ','}}"
10
+ end
11
+ alias_method_chain :template_path, :plugin_routing
12
+
13
+ def initialize_template_class(assigns)
14
+ view_paths = Dir[template_path].collect do |path|
15
+ File.dirname(path)
16
+ end
17
+ returning(template = ActionView::Base.new(view_paths, assigns, self)) do
18
+ template.extend ApplicationHelper
19
+ template.extend self.class.master_helper_module
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ module ActionView #:nodoc:
2
+ class Base #:nodoc:
3
+ def initialize_with_desert_plugins(*args)
4
+ initialize_without_desert_plugins *args
5
+
6
+ Desert::Manager.plugins.reverse.each do |plugin|
7
+ append_view_path plugin.templates_path
8
+ end
9
+ end
10
+ alias_method_chain :initialize, :desert_plugins
11
+
12
+ def find_template_extension_from_handler(template_path, formatted = nil)
13
+ checked_template_path = formatted ? "#{template_path}.#{template_format}" : template_path
14
+
15
+ view_paths.each do |view_path|
16
+ self.class.template_handler_extensions.each do |extension|
17
+ file_path = File.join(view_path, "#{checked_template_path}.#{extension}")
18
+ if File.exist?(file_path)
19
+ return formatted ? "#{template_format}.#{extension}" : extension.to_s
20
+ end
21
+ end
22
+ end
23
+ nil
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ module ActionView #:nodoc:
2
+ class TemplateFinder #:nodoc:
3
+ def initialize_with_desert_plugins(*args)
4
+ begin
5
+ initialize_without_desert_plugins *args
6
+ rescue ActionView::TemplateFinder::InvalidViewPath
7
+ # Desert will add the missing paths next
8
+ end
9
+ Desert::Manager.plugins.reverse.each do |plugin|
10
+ append_view_path plugin.templates_path
11
+ end
12
+ end
13
+ alias_method_chain :initialize, :desert_plugins
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ module ActionMailer #:nodoc
2
+ class Base #:nodoc:
3
+ private
4
+ def template_path_with_plugin_routing
5
+ template_paths = [template_path_without_plugin_routing]
6
+ Desert::Manager.plugins.reverse.each do |plugin|
7
+ template_paths << "#{plugin.templates_path}/#{mailer_name}"
8
+ end
9
+ "{#{template_paths * ','}}"
10
+ end
11
+ alias_method_chain :template_path, :plugin_routing
12
+
13
+ def initialize_template_class(assigns)
14
+ self.view_paths = Dir[template_path].collect do |path|
15
+ File.dirname(path)
16
+ end if self.view_paths.empty?
17
+ returning(template = ActionView::Base.new(view_paths, assigns, self)) do
18
+ template.extend ApplicationHelper
19
+ template.extend self.class.master_helper_module
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ ActionView::Base.class_eval do
2
+ def initialize_with_desert_plugins(*args)
3
+ initialize_without_desert_plugins *args
4
+
5
+ Desert::Manager.plugins.reverse.each do |plugin|
6
+ view_paths << plugin.templates_path
7
+ end
8
+ end
9
+ alias_method_chain :initialize, :desert_plugins
10
+ end
@@ -0,0 +1,12 @@
1
+ module ActionController #:nodoc:
2
+ module Layout #:nodoc:
3
+ module ClassMethods #:nodoc:
4
+ private
5
+ def layout_list_with_plugin_routing
6
+ plugin_layouts = Desert::Manager.layout_paths.join(",")
7
+ layout_list_without_plugin_routing + Dir["{#{plugin_layouts}}/**/*"]
8
+ end
9
+ alias_method_chain :layout_list, :plugin_routing
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ dir = File.dirname(__FILE__)
2
+
3
+ if ActionView.const_defined?(:TemplateFinder)
4
+ require "#{dir}/2.1.0/action_view"
5
+ else
6
+ if ActionView::Base.private_instance_methods.include?('find_template_extension_from_handler')
7
+ if ActionView::Base.instance_methods.include?('template_handler_preferences')
8
+ require "#{dir}/1.99.0/action_view"
9
+ else
10
+ require "#{dir}/2.0.2/action_view"
11
+ end
12
+ elsif ActionView.const_defined?(:PathSet)
13
+ require "#{dir}/2.2.0/action_view"
14
+ else
15
+ require "#{dir}/1.2.0/action_view"
16
+ end
17
+ end
@@ -0,0 +1,10 @@
1
+ dir = File.dirname(__FILE__)
2
+ if Desert::VersionChecker.rails_version_is_below_1990?
3
+ require "#{dir}/rails/1.2.0/initializer"
4
+ else
5
+ require "#{dir}/rails/2.0.0/plugin"
6
+ end
7
+ require "#{dir}/rails/dependencies"
8
+ require "#{dir}/rails/migration"
9
+
10
+ require "#{dir}/rails/route_set"
@@ -0,0 +1,20 @@
1
+ module Rails
2
+ class Initializer
3
+ def load_plugin_with_desert(directory)
4
+ return if Desert::Manager.plugin_exists?(directory)
5
+ plugin = Desert::Manager.register_plugin(directory) do
6
+ load_plugin_without_desert(directory)
7
+ end
8
+ # TODO: Can we use Initializer::Configuration#default_load_paths to do this?
9
+ configuration.controller_paths << plugin.controllers_path
10
+ end
11
+ alias_method_chain :load_plugin, :desert
12
+
13
+ def require_plugin(plugin_name)
14
+ find_plugins(configuration.plugin_paths).sort.each do |path|
15
+ return load_plugin(path) if File.basename(path) == plugin_name
16
+ end
17
+ raise "Plugin '#{plugin_name}' does not exist"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ class Rails::Plugin
2
+ attr_accessor :initializer
3
+ def require_plugin(plugin_name)
4
+ initializer.configuration.plugin_locators.each do |locator|
5
+ locator.new(initializer).each do |plugin_loader|
6
+ return plugin_loader.load(initializer) if plugin_loader.name.to_s == plugin_name.to_s
7
+ end
8
+ end
9
+ raise "Plugin '#{plugin_name}' does not exist"
10
+ end
11
+
12
+ def load_with_desert(initializer)
13
+ @initializer = initializer
14
+ return if Desert::Manager.plugin_exists?(directory)
15
+ plugin = Desert::Manager.register_plugin(directory) do
16
+ load_without_desert(initializer)
17
+ end
18
+ # TODO: Can we use Initializer::Configuration#default_load_paths to do this?
19
+ initializer.configuration.controller_paths << plugin.controllers_path
20
+ end
21
+ alias_method_chain :load, :desert
22
+ end
@@ -0,0 +1,87 @@
1
+ dependencies = ActiveSupport.const_defined?(:Dependencies) ? ActiveSupport::Dependencies : Dependencies
2
+ dependencies.module_eval do
3
+ def load_missing_constant_with_desert(from_mod, const_name)
4
+ from_mod = guard_against_anonymous_module(from_mod)
5
+ qualified_name = qualified_name_for from_mod, const_name
6
+ path_suffix = qualified_name.underscore
7
+
8
+ if define_constant_with_desert_loading(from_mod, const_name, qualified_name, path_suffix)
9
+ return from_mod.const_get(const_name)
10
+ end
11
+
12
+ if has_parent_module?(from_mod)
13
+ look_for_constant_in_parent_module(from_mod, const_name, qualified_name, path_suffix)
14
+ else
15
+ raise NameError, "Constant #{qualified_name} from #{path_suffix}.rb not found"
16
+ end
17
+ end
18
+ alias_method_chain :load_missing_constant, :desert
19
+
20
+ def load_once_path?(path)
21
+ load_once_paths.any? { |base| File.expand_path(path).starts_with? File.expand_path(base) }
22
+ end
23
+
24
+ def depend_on_with_desert(file_name, swallow_load_errors = false)
25
+ successfully_loaded_in_plugin = false
26
+ Desert::Manager.files_on_load_path(file_name).each do |file|
27
+ require_or_load(file)
28
+ successfully_loaded_in_plugin = true
29
+ end
30
+ begin
31
+ unless successfully_loaded_in_plugin
32
+ require_or_load file_name
33
+ loaded << File.expand_path(file_name)
34
+ end
35
+ rescue LoadError
36
+ if !swallow_load_errors && !successfully_loaded_in_plugin
37
+ raise
38
+ end
39
+ end
40
+ end
41
+ alias_method_chain :depend_on, :desert
42
+
43
+ protected
44
+ def define_constant_with_desert_loading(from_mod, const_name, qualified_name, path_suffix)
45
+ define_constant_from_file(from_mod, const_name, qualified_name, path_suffix) ||
46
+ define_constant_from_directory(from_mod, const_name, qualified_name, path_suffix)
47
+ end
48
+
49
+ def has_parent_module?(mod)
50
+ mod != Object
51
+ end
52
+
53
+ def look_for_constant_in_parent_module(from_mod, const_name, qualified_name, path_suffix)
54
+ return from_mod.parent.const_missing(const_name)
55
+ rescue NameError => e
56
+ raise NameError, "Constant #{qualified_name} from #{path_suffix}.rb not found\n#{e.message}"
57
+ end
58
+
59
+ def guard_against_anonymous_module(from_mod)
60
+ return Object if from_mod.name.blank?
61
+ return from_mod
62
+ end
63
+
64
+ def define_constant_from_file(from_mod, const_name, qualified_name, path_suffix)
65
+ files = Desert::Manager.files_on_load_path(path_suffix)
66
+ files.each do |file|
67
+ require_or_load file
68
+ loaded << file.gsub(/\.rb$/, '')
69
+ next if autoloaded_constants.include?(qualified_name)
70
+ next if load_once_path?(file)
71
+ autoloaded_constants << qualified_name
72
+ end
73
+ loaded << File.expand_path(path_suffix)
74
+ from_mod.const_defined?(const_name)
75
+ end
76
+
77
+ def define_constant_from_directory(from_mod, const_name, qualified_name, path_suffix)
78
+ return false unless Desert::Manager.directory_on_load_path?(path_suffix)
79
+
80
+ if autoloaded_constants.include?(qualified_name)
81
+ raise "Constant #{qualified_name} is already autoloaded but is not defined as a constant"
82
+ end
83
+ from_mod.const_set(const_name, Module.new)
84
+ autoloaded_constants << qualified_name
85
+ return true
86
+ end
87
+ end