desert 0.2.1 → 0.2.2

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/CHANGES CHANGED
@@ -1,3 +1,12 @@
1
+ 0.2.2
2
+ - Fixed script/destroy not removing the routes [From Jeff Dean]
3
+ - gem includes the Rails generator files [From Jeff Dean]
4
+ - Fixed readding the route to config/routes.rb in the script/destroy task [From Jeff Dean]
5
+ - Github now properly formats readme [From Jeff Dean]
6
+ - Updated the gemspec so rdoc includes it and updated it to add installation and setup instructions [From Jeff Dean]
7
+ - Removed sample route from generator [From Jeff Dean]
8
+ - Fix migration issue with Rails 2.1.0 using timestamps.
9
+
1
10
  0.2.1
2
11
  - Fixed ActionMailer rendering in Rails 1.99.0
3
12
 
data/README.rdoc ADDED
@@ -0,0 +1,295 @@
1
+ = Desert - It doesn't get any DRYer than this
2
+
3
+ Desert is a Rails plugin framework that makes it easy to share models, views,
4
+ controllers, helpers, routes, and migrations across your applications.
5
+
6
+ With Desert, reusability doesn't come at the cost of extensibility: it's trivial to extend
7
+ the functionality of a plugin - both in your application _and_ in other plugins.
8
+
9
+ Classes are automatically mixed in with your own or other plugins' classes.
10
+ This allows you to make full featured composable components.
11
+
12
+ Desert is a replacement for Appable Plugins (http://wiki.pluginaweek.org/Appable_plugins).
13
+
14
+ == Anatomy of a desert plugin
15
+
16
+ |-- app
17
+ | |-- controllers
18
+ | | |-- application.rb
19
+ | | `-- blogs_controller.rb
20
+ | |-- helpers
21
+ | | |-- application_helper.rb
22
+ | | `-- blogs_helper.rb
23
+ | |-- models
24
+ | | `-- user.rb
25
+ | `-- views
26
+ | |-- blogs
27
+ | |-- layouts
28
+ | | `-- users.html.erb
29
+ | `-- users
30
+ | |-- index.html.erb
31
+ | `-- show.html.erb
32
+ |-- db
33
+ | `-- migrate
34
+ | `-- 001_migrate_users_to_001.rb
35
+ |-- lib
36
+ | `-- current_user.rb
37
+ |-- spec
38
+ | |-- controllers
39
+ | | `-- blogs_controller_spec.rb
40
+ | |-- fixtures
41
+ | |-- models
42
+ | |-- spec_helper.rb
43
+ | `-- views
44
+ | `-- blogs
45
+ `-- vendor
46
+ `-- plugins
47
+ `-- user
48
+ |-- app
49
+ | |-- controllers
50
+ | | `-- users_controller.rb
51
+ | |-- helpers
52
+ | | `-- users_helper.rb
53
+ | |-- models
54
+ | | `-- user.rb
55
+ | `-- views
56
+ | `-- users
57
+ | |-- edit.html.erb
58
+ | |-- index.html.erb
59
+ | |-- new.html.erb
60
+ | `-- show.html.erb
61
+ |-- config
62
+ | `-- routes.rb
63
+ |-- db
64
+ | `-- migrate
65
+ | `-- 001_create_users.rb
66
+ |-- init.rb
67
+ |-- lib
68
+ | `-- current_user.rb
69
+ |-- spec
70
+ | |-- controllers
71
+ | | `-- user_controller_spec.rb
72
+ | |-- fixtures
73
+ | | `-- users.yml
74
+ | |-- models
75
+ | | `-- user.rb
76
+ | |-- spec_helper.rb
77
+ | `-- views
78
+ | `-- users
79
+ `-- tasks
80
+
81
+ == Installation and Usage
82
+
83
+ * Install the gem
84
+
85
+ sudo gem install desert
86
+
87
+ * Require 'desert' between 'boot' and Rails::Initializer.run in environment.rb
88
+
89
+ # File: config/environment.rb
90
+
91
+ require File.join(File.dirname(__FILE__), 'boot')
92
+
93
+ require 'desert'
94
+
95
+ Rails::Initializer.run do |config|
96
+ end
97
+
98
+ NOTE: you may have to require rubygems before requiring desert.
99
+
100
+ * Generate your desert plugin
101
+
102
+ script/generate desert_plugin my_plugin_app
103
+
104
+ == Manage Plugin Dependencies
105
+
106
+ By default, Rails loads plugins in alphabetical order, making it tedious to manage dependencies.
107
+ Desert will automatically load plugins in the proper order when you declare their dependencies like this:
108
+
109
+ # File: vendor/plugins/blogs/init.rb
110
+
111
+ require_plugin 'user'
112
+ require_plugin 'will_paginate'
113
+
114
+ Here <tt>user</tt> and <tt>will_paginate</tt> will always be loaded before <tt>blogs<tt>. Note that any plugin can be declared as a dependency.
115
+
116
+ == Share Routes
117
+
118
+ When you share controllers, you'll want to share their routes too.
119
+ If you look in your RAILS_ROOT/config/routes.rb file you will notice that the generator added a new line to the top:
120
+
121
+ map.routes_from_plugin(:my_plugin_app)
122
+
123
+ In the <tt>user</tt> plugin:
124
+
125
+ # File: vendor/plugins/user/config/routes.rb
126
+
127
+ resource :users
128
+
129
+ In the <tt>blogs</tt> plugin:
130
+
131
+ File: vendor/plugins/blogs/config/routes.rb
132
+
133
+ resource :blogs
134
+
135
+ In the application:
136
+
137
+ # File: config/routes.rb
138
+
139
+ ActionController::Routing::Routes.draw do |map|
140
+ map.routes_from_plugin :blogs
141
+ map.routes_from_plugin :user
142
+ end
143
+
144
+ Here the application adds the <tt>users</tt> resource from the <tt>user</tt> plugin and the <tt>blogs</tt> resource from the <tt>blogs</tt> plugin.
145
+ Notice that there is no need to call methods on map in the plugin route files, because they are instance eval'd in the map object.
146
+
147
+ All standard routing methods are available in your plugin's routes file, such as:
148
+
149
+ namespace :admin do |admin|
150
+ admin.resources :posts
151
+ end
152
+
153
+ Desert uses a separate table to manage migration version to maintain backwards compatibility with Rails 1.x.
154
+ Your plugin app's migration live in your_plugin/db/migrate. To run migrations, follow these steps:
155
+
156
+ * Create a new migration in your main app
157
+
158
+ script/generate migration migrate_my_plugin_to_045
159
+
160
+ * Add the custom `migrate_plugin` method
161
+
162
+ class MigrateMyPluginTo045 < ActiveRecord::Migration
163
+ def self.up
164
+ migrate_plugin(:my_plugin, 20080530223548)
165
+ end
166
+
167
+ def self.down
168
+ migrate_plugin(:my_plugin, 0)
169
+ end
170
+ end
171
+
172
+ * Run your migrations normally
173
+
174
+ rake db:migrate
175
+
176
+ connect "/signup", :controller => "users", :action => "signup"
177
+
178
+ == Share Migrations
179
+
180
+ Sharing models means sharing schema fragments, and that means sharing migrations:
181
+
182
+ In the <tt>user</tt> plugin:
183
+
184
+ vendor/plugins/user/db/migrate/
185
+ 001_create_user_table.rb
186
+
187
+ In the <tt>blogs</tt> plugin:
188
+
189
+ vendor/plugins/blogs/db/migrate/
190
+ 001_create_user_table.rb
191
+ 002_add_became_a_blogger_at_to_user.rb
192
+
193
+ Here the <tt>blogs</tt> plugin needs to add a column to the <tt>users</tt> table. No problem!
194
+ It just includes a migration in its <tt>db/migrate</tt> directory, just like a regular Rails application.
195
+ When the application developer installs the plugin, he migrates the plugin in his own migration:
196
+
197
+ <tt>application_root/db/migrate/009_install_user_and_blogs_plugins.rb</tt>
198
+
199
+ class InstallUserAndBlogsPlugins < ActiveRecord::Migration
200
+ def self.up
201
+ migrate_plugin 'user', 1
202
+ migrate_plugin :blogs, 2
203
+ end
204
+
205
+ def self.down
206
+ migrate_plugin 'user', 0
207
+ migrate_plugin :blogs, 0
208
+ end
209
+ end
210
+
211
+ Here the application migrates the <tt>user</tt> plugin to version 1 and the <tt>blogs</tt> plugin to version 2.
212
+ If a subsequent version of the plugin introduces new migrations, the application developer has full control over when to apply them to his schema.
213
+
214
+ == Share Views
215
+
216
+ To share views, just create templates and partials in the plugin's <tt>app/views</tt> directory, just as you would with a Rails application.
217
+
218
+ <tt>application_root/app/views/blogs/index.html.erb</tt>
219
+
220
+ <%= @blog.posts.each do |post| %>
221
+ ...
222
+ <% end %>
223
+
224
+ == Customize / extend behavior in each installation
225
+
226
+ Say you want to create a plugin named acts_as_spiffy.
227
+ Desert allows Spiffy to have a set of features that can be reused and extended in several projects.
228
+
229
+ The Spiffy project has a:
230
+
231
+ * SpiffyController
232
+ * Spiffy model
233
+ * SpiffyHelper
234
+ * spiffy.html.erb
235
+ * SpiffyLib library class
236
+
237
+ The Spiffy plugin acts as its own mini Rails application. Here is the directory structure:
238
+
239
+ RAILS_ROOT/vendor/plugins/spiffy/app/controllers/spiffy_controller.rb
240
+ RAILS_ROOT/vendor/plugins/spiffy/app/models/spiffy.rb
241
+ RAILS_ROOT/vendor/plugins/spiffy/app/helpers/spiffy_helper.rb
242
+ RAILS_ROOT/vendor/plugins/spiffy/app/views/spiffy/spiffy.rhtml
243
+ RAILS_ROOT/vendor/plugins/spiffy/lib/spiffy_lib.rb
244
+
245
+ Now, say there is a Spiffy Store rails application that uses acts_as_spiffy. The Rails app can open up any of the Spiffy classes and override any of the methods.
246
+
247
+ Say spiffy.rb in the Spiffy plugin is defined as:
248
+
249
+ class Spiffy < ActiveRecord::Base
250
+ def why?
251
+ "I just am Spiffy"
252
+ end
253
+ end
254
+
255
+ The Spiffy#why method can be overridden in RAILS_ROOT/app/models/spiffy.rb
256
+
257
+ class Spiffy < ActiveRecord::Base
258
+ def why?
259
+ "I sell Spiffy stuff"
260
+ end
261
+ end
262
+
263
+ == Running plugin tests
264
+
265
+ You can run your plugin tests/specs like so:
266
+
267
+ rake desert:testspec:plugins PLUGIN=spiffy
268
+
269
+ Leaving off the PLUGIN environment variable will cause it to run all the
270
+ test/specs for all installed plugins, which may not be what you want.
271
+
272
+ == Running Desert Specs
273
+
274
+ To run specs, you need to:
275
+
276
+ * Make sure you have the necessary gems installed (rr, rspec)
277
+ * Install git http://git.or.cz/
278
+ * Create a database named desert_test
279
+ * Update the database.yml file in <tt>spec/rails_root/config/database.yml</tt>
280
+ * Install the dependencies
281
+ * Run the specs
282
+
283
+ Desert is a library that heavily monkey patches Rails. To ensure that Desert works with
284
+ multiple versions of Rails, its tests are run against the supported versions of Rails.
285
+
286
+ To set up the different supported versions of Rails, run
287
+
288
+ rake install_dependencies
289
+
290
+ This will clone the Rails git repo and export the supported versions of rails into the
291
+ respective directories.
292
+
293
+ rake update_dependencies
294
+
295
+ will update the clones repo on your machine.
data/Rakefile CHANGED
@@ -26,13 +26,13 @@ task(:tag_release) do
26
26
  end
27
27
 
28
28
  PKG_NAME = "desert"
29
- PKG_VERSION = "0.2.1"
29
+ PKG_VERSION = "0.2.2"
30
30
  PKG_FILES = FileList[
31
31
  '[A-Z]*',
32
32
  '*.rb',
33
33
  'lib/**/*.rb',
34
- 'lib/generators/**/*',
35
- 'lib/generators/**/templates/*',
34
+ 'generators/**/*',
35
+ 'generators/**/templates/*',
36
36
  'examples/**/*.rb'
37
37
  ]
38
38
 
@@ -47,8 +47,8 @@ spec = Gem::Specification.new do |s|
47
47
  s.require_path = 'lib'
48
48
 
49
49
  s.has_rdoc = true
50
- s.extra_rdoc_files = [ "README", "CHANGES" ]
51
- s.rdoc_options = ["--main", "README", "--inline-source", "--line-numbers"]
50
+ s.extra_rdoc_files = [ "README.rdoc", "CHANGES" ]
51
+ s.rdoc_options = ["--main", "README.rdoc", "--inline-source", "--line-numbers"]
52
52
 
53
53
  s.test_files = Dir.glob('spec/*_spec.rb')
54
54
  s.require_path = 'lib'
@@ -0,0 +1,14 @@
1
+ NAME
2
+ desert_plugin - creates a directory structure and starter files for a new desert plugin
3
+
4
+ SYNOPSIS
5
+ desert_plugin [plugin name]
6
+
7
+ DESCRIPTION
8
+ |-- vendor
9
+ `-- plugins
10
+ `-- [plugin name]
11
+
12
+ EXAMPLE
13
+ ./script/generate desert_plugin spiffy
14
+
@@ -0,0 +1,73 @@
1
+ require 'rails_generator'
2
+ require 'rails_generator/commands'
3
+
4
+ class DesertPluginGenerator < Rails::Generator::NamedBase
5
+ def manifest
6
+ record do |m|
7
+ m.directory "vendor/plugins/#{file_name}"
8
+
9
+ m.directory "vendor/plugins/#{file_name}/app"
10
+ m.directory "vendor/plugins/#{file_name}/app/controllers"
11
+ m.directory "vendor/plugins/#{file_name}/app/helpers"
12
+ m.directory "vendor/plugins/#{file_name}/app/models"
13
+ m.directory "vendor/plugins/#{file_name}/app/views"
14
+
15
+ m.directory "vendor/plugins/#{file_name}/config"
16
+ m.template "routes.rb", "vendor/plugins/#{file_name}/config/routes.rb"
17
+ m.map_route_from_plugin
18
+
19
+ m.directory "vendor/plugins/#{file_name}/db"
20
+ m.directory "vendor/plugins/#{file_name}/db/migrate"
21
+ # m.template "plugin_migration.rb", "vendor/plugins/#{file_name}/db/migrate/001_init_#{file_name}_plugin.rb"
22
+
23
+ m.directory "vendor/plugins/#{file_name}/lib"
24
+
25
+ m.directory "vendor/plugins/#{file_name}/spec"
26
+ m.directory "vendor/plugins/#{file_name}/spec/controllers"
27
+ m.directory "vendor/plugins/#{file_name}/spec/fixtures"
28
+ m.directory "vendor/plugins/#{file_name}/spec/models"
29
+ m.directory "vendor/plugins/#{file_name}/spec/views"
30
+ m.file "spec_helper.rb", "vendor/plugins/#{file_name}/spec/spec_helper.rb"
31
+
32
+ m.directory "vendor/plugins/#{file_name}/tasks"
33
+
34
+ m.file "empty_file", "vendor/plugins/#{file_name}/init.rb"
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ module Desert #:nodoc:
41
+ module Generator #:nodoc:
42
+ module Commands #:nodoc:
43
+
44
+ module Create
45
+ def map_route_from_plugin
46
+ logger.route "adding map.routes_from_plugin(:#{file_name}) to top of routes.rb"
47
+ sentinel = 'ActionController::Routing::Routes.draw do |map|'
48
+ gsub_file('config/routes.rb', /(#{Regexp.escape(sentinel)})/mi) do |match|
49
+ "#{match}\n map.routes_from_plugin(:#{file_name})\n"
50
+ end
51
+ end
52
+ end
53
+
54
+ module Destroy
55
+ def map_route_from_plugin
56
+ look_for = "\n map.routes_from_plugin(:#{file_name})\n"
57
+ logger.route "removing map.routes_from_plugin(:#{file_name}) from routes.rb"
58
+ gsub_file 'config/routes.rb', /(#{Regexp.escape(look_for)})/mi, ''
59
+ end
60
+ end
61
+
62
+ module List
63
+ def map_route_from_plugin
64
+ logger.route "adding map.routes_from_plugin(:#{file_name}) to top of routes.rb"
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ Rails::Generator::Commands::Create.send :include, Desert::Generator::Commands::Create
72
+ Rails::Generator::Commands::Destroy.send :include, Desert::Generator::Commands::Destroy
73
+ Rails::Generator::Commands::List.send :include, Desert::Generator::Commands::List
File without changes
@@ -0,0 +1,11 @@
1
+ class Init<%= class_name %>Plugin < ActiveRecord::Migration
2
+ def self.up
3
+ create_table "<%= plural_name %>", :force => true do |t|
4
+ t.column "some_<%= file_name %>_column", :string
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ drop_table :<%= plural_name %>
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ # Add your custom routes here. If in config/routes.rb you would
2
+ # add <tt>map.resources</tt>, here you would add just <tt>resources</tt>
3
+
4
+ # resources :<%= plural_name %>
@@ -0,0 +1,8 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+ require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
3
+ require 'spec'
4
+ require 'spec/rails'
5
+
6
+ Spec::Runner.configure do |config|
7
+ config.fixture_path = "#{File.dirname(__FILE__)}/../spec/fixtures"
8
+ end
@@ -32,7 +32,7 @@ module Desert
32
32
  paths << File.join(component_root, 'app','helpers')
33
33
  paths << File.join(component_root, 'lib')
34
34
  end
35
- Dependencies.load_paths.reverse.each do |path|
35
+ dependencies.load_paths.reverse.each do |path|
36
36
  paths << File.expand_path(path) unless paths.include?(File.expand_path(path))
37
37
  end
38
38
  paths
@@ -44,9 +44,9 @@ module Desert
44
44
 
45
45
  yield if block_given?
46
46
 
47
- Dependencies.load_paths << plugin.models_path
48
- Dependencies.load_paths << plugin.controllers_path
49
- Dependencies.load_paths << plugin.helpers_path
47
+ dependencies.load_paths << plugin.models_path
48
+ dependencies.load_paths << plugin.controllers_path
49
+ dependencies.load_paths << plugin.helpers_path
50
50
 
51
51
  @plugins_in_registration.pop
52
52
 
@@ -101,6 +101,10 @@ module Desert
101
101
  end
102
102
 
103
103
  protected
104
+ def dependencies
105
+ @dependencies ||= ActiveSupport.const_defined?(:Dependencies) ? ActiveSupport::Dependencies : Dependencies
106
+ end
107
+
104
108
  def plugin_paths
105
109
  plugins_and_app.collect { |plugin| plugin.path }
106
110
  end
data/lib/desert/plugin.rb CHANGED
@@ -58,16 +58,16 @@ module Desert
58
58
  end
59
59
 
60
60
  def migration
61
- @migration ||= PluginAWeek::PluginMigrations::Migrator.new(:up, migration_path)
61
+ @migration ||= PluginMigrations::Migrator.new(:up, migration_path)
62
62
  end
63
63
 
64
64
  def with_current_plugin
65
- old_plugin = PluginAWeek::PluginMigrations::Migrator.current_plugin
65
+ old_plugin = PluginMigrations::Migrator.current_plugin
66
66
  begin
67
- PluginAWeek::PluginMigrations::Migrator.current_plugin = self
67
+ PluginMigrations::Migrator.current_plugin = self
68
68
  yield
69
69
  ensure
70
- PluginAWeek::PluginMigrations::Migrator.current_plugin = old_plugin
70
+ PluginMigrations::Migrator.current_plugin = old_plugin
71
71
  end
72
72
  end
73
73
  end
@@ -3,7 +3,7 @@ ActiveRecord::ConnectionAdapters::SchemaStatements.module_eval do
3
3
  initialize_schema_information_without_plugins
4
4
 
5
5
  begin
6
- execute "CREATE TABLE #{PluginAWeek::PluginMigrations::Migrator.schema_info_table_name} (plugin_name #{type_to_sql(:string)}, version #{type_to_sql(:integer)})"
6
+ execute "CREATE TABLE #{Desert::PluginMigrations::Migrator.schema_info_table_name} (plugin_name #{type_to_sql(:string)}, version #{type_to_sql(:integer)})"
7
7
  rescue ActiveRecord::StatementInvalid
8
8
  # Schema has been initialized
9
9
  end
@@ -17,11 +17,11 @@ ActiveRecord::ConnectionAdapters::SchemaStatements.module_eval do
17
17
  schema_information << dump if dump
18
18
 
19
19
  begin
20
- plugins = ActiveRecord::Base.connection.select_all("SELECT * FROM #{PluginAWeek::PluginMigrations::Migrator.schema_info_table_name}")
20
+ plugins = ActiveRecord::Base.connection.select_all("SELECT * FROM #{Desert::PluginMigrations::Migrator.schema_info_table_name}")
21
21
  plugins.each do |plugin|
22
22
  if (version = plugin['version'].to_i) > 0
23
23
  plugin_name = ActiveRecord::Base.quote_value(plugin['plugin_name'])
24
- schema_information << "INSERT INTO #{PluginAWeek::PluginMigrations::Migrator.schema_info_table_name} (plugin_name, version) VALUES (#{plugin_name}, #{version})"
24
+ schema_information << "INSERT INTO #{Desert::PluginMigrations::Migrator.schema_info_table_name} (plugin_name, version) VALUES (#{plugin_name}, #{version})"
25
25
  end
26
26
  end
27
27
  rescue ActiveRecord::StatementInvalid
@@ -3,7 +3,7 @@ ActiveRecord::ConnectionAdapters::SchemaStatements.module_eval do
3
3
  initialize_schema_migrations_table_without_plugins
4
4
 
5
5
  begin
6
- execute "CREATE TABLE #{PluginAWeek::PluginMigrations::Migrator.schema_info_table_name} (plugin_name #{type_to_sql(:string)}, version #{type_to_sql(:integer)})"
6
+ execute "CREATE TABLE #{Desert::PluginMigrations::Migrator.schema_info_table_name} (plugin_name #{type_to_sql(:string)}, version #{type_to_sql(:integer)})"
7
7
  rescue ActiveRecord::StatementInvalid
8
8
  # Schema has been initialized
9
9
  end
@@ -1,6 +1,6 @@
1
- module PluginAWeek #:nodoc:
1
+ module Desert #:nodoc:
2
2
  module PluginMigrations
3
- # Responsible for migrating plugins. PluginAWeek::PluginMigrations.Migrator.current_plugin
3
+ # Responsible for migrating plugins. PluginMigrations.Migrator.current_plugin
4
4
  # indicates which plugin is currently being migrated
5
5
  class Migrator < ActiveRecord::Migrator
6
6
  # We need to be able to set the current plugin being migrated.
@@ -43,6 +43,12 @@ module PluginAWeek #:nodoc:
43
43
  end
44
44
  end
45
45
  alias_method :record_version_state_after_migrating, :set_schema_version
46
+
47
+
48
+ def migrated
49
+ current_plugin_version = self.class.current_version
50
+ (1..current_plugin_version).to_a
51
+ end
46
52
  end
47
53
  end
48
54
  end
@@ -1,21 +1,21 @@
1
1
  module ActionMailer #:nodoc
2
2
  class Base #:nodoc:
3
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}"
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 * ','}}"
8
10
  end
9
- "{#{template_paths * ','}}"
10
- end
11
- alias_method_chain :template_path, :plugin_routing
11
+ alias_method_chain :template_path, :plugin_routing
12
12
 
13
- def initialize_template_class(assigns)
14
- base_path = Dir["#{template_path}/#{@template}.*"].first
15
- returning(template = ActionView::Base.new(File.dirname(base_path), assigns, self)) do
16
- template.extend ApplicationHelper
17
- template.extend self.class.master_helper_module
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
18
19
  end
19
- end
20
20
  end
21
21
  end
@@ -2,19 +2,21 @@ module ActionMailer #:nodoc
2
2
  class Base #:nodoc:
3
3
  private
4
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}"
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
8
12
  end
9
- "{#{template_paths * ','}}"
13
+ result || template_path_without_plugin_routing
10
14
  end
11
15
  alias_method_chain :template_path, :plugin_routing
12
16
 
13
17
  def initialize_template_class(assigns)
14
- view_paths = Dir["#{template_path}/#{@template}.*"].collect do |path|
15
- File.dirname(path)
16
- end
17
- returning(template = ActionView::Base.new(view_paths, assigns, self)) do
18
+ view_path = File.dirname(Dir["#{template_path}/#{@template}.*"].first)
19
+ returning(template = ActionView::Base.new([view_path], assigns, self)) do
18
20
  template.extend ApplicationHelper
19
21
  template.extend self.class.master_helper_module
20
22
  end
@@ -14,10 +14,98 @@ if ActionView.const_defined?(:TemplateFinder)
14
14
  else
15
15
  module ActionView #:nodoc:
16
16
  class Base #:nodoc:
17
- private
17
+ if private_instance_methods.include?('find_template_extension_from_handler')
18
+ if instance_methods.include?('template_handler_preferences')
19
+ # Rails 1.99.0
20
+ def find_template_extension_from_handler(template_path, formatted = nil)
21
+ checked_template_path = formatted ? "#{template_path}.#{template_format}" : template_path
22
+
23
+ view_paths.each do |view_path|
24
+ template_handler_preferences.each do |template_type|
25
+ extensions =
26
+ case template_type
27
+ when :javascript
28
+ [:rjs]
29
+ when :delegate
30
+ @@template_handlers.keys
31
+ else
32
+ [template_type]
33
+ end
34
+
35
+ extensions.each do |extension|
36
+ file_path = File.join(view_path, "#{checked_template_path}.#{extension}")
37
+ if File.exist?(file_path)
38
+ return formatted ? "#{template_format}.#{extension}" : extension.to_s
39
+ end
40
+ end
41
+ end
42
+ end
43
+ nil
44
+ end
45
+ else
46
+ # Rails 2.0.2
47
+ def find_template_extension_from_handler(template_path, formatted = nil)
48
+ checked_template_path = formatted ? "#{template_path}.#{template_format}" : template_path
49
+
50
+ view_paths.each do |view_path|
51
+ self.class.template_handler_extensions.each do |extension|
52
+ file_path = File.join(view_path, "#{checked_template_path}.#{extension}")
53
+ if File.exist?(file_path)
54
+ return formatted ? "#{template_format}.#{extension}" : extension.to_s
55
+ end
56
+ end
57
+ end
58
+ nil
59
+ end
60
+ end
61
+ end
62
+
63
+ if instance_methods.include?('view_paths')
64
+ def initialize_with_desert_plugins(*args)
65
+ initialize_without_desert_plugins *args
66
+
67
+ Desert::Manager.plugins.reverse.each do |plugin|
68
+ view_paths << plugin.templates_path
69
+ end
70
+ end
71
+ alias_method_chain :initialize, :desert_plugins
72
+ else
73
+ attr_reader :view_paths
74
+ def initialize_with_desert(base_path = nil, assigns_for_first_render = {}, controller = nil)
75
+ initialize_without_desert(base_path, assigns_for_first_render, controller)
76
+
77
+ @view_paths = [base_path]
78
+ Desert::Manager.plugins_and_app.reverse.each do |plugin|
79
+ @view_paths << plugin.templates_path
80
+ end
81
+ end
82
+ alias_method_chain :initialize, :desert
83
+
84
+ private
85
+ def full_path_template_exists?(path, extension)
86
+ file_path = "#{path}.#{extension}"
87
+ @@method_names.has_key?(file_path) || FileTest.exists?(file_path)
88
+ end
89
+
90
+ def find_template_extension_for(template_path)
91
+ view_paths.each do |view_path|
92
+ full_path = "#{view_path}/#{template_path}"
93
+ if match = @@template_handlers.find { |k,| full_path_template_exists?(template_path, k) }
94
+ return match.first.to_sym
95
+ elsif full_path_template_exists?(full_path, :rhtml)
96
+ return :rhtml
97
+ elsif full_path_template_exists?(full_path, :rxml)
98
+ return :rxml
99
+ elsif full_path_template_exists?(full_path, :rjs)
100
+ return :rjs
101
+ end
102
+ end
103
+ raise ActionViewError, "No rhtml, rxml, rjs or delegate template found for #{template_path} in #{@base_path}"
104
+ end
105
+
18
106
  def full_template_path_with_plugin_routing(template_path, extension)
19
107
  full_template_path = full_template_path_without_plugin_routing(template_path, extension)
20
-
108
+
21
109
  unless File.exist?(full_template_path)
22
110
  # Look through the plugins for the template
23
111
  Desert::Manager.plugins.reverse.each do |plugin|
@@ -27,10 +115,11 @@ else
27
115
  end
28
116
  end
29
117
  end
30
-
118
+
31
119
  full_template_path
32
120
  end
33
121
  alias_method_chain :full_template_path, :plugin_routing
122
+ end
34
123
  end
35
124
  end
36
125
  end
@@ -1,4 +1,5 @@
1
- module Dependencies
1
+ dependencies = ActiveSupport.const_defined?(:Dependencies) ? ActiveSupport::Dependencies : Dependencies
2
+ dependencies.module_eval do
2
3
  def load_missing_constant_with_desert(from_mod, const_name)
3
4
  from_mod = guard_against_anonymous_module(from_mod)
4
5
  qualified_name = qualified_name_for from_mod, const_name
@@ -63,9 +64,7 @@ module Dependencies
63
64
  def define_constant_from_file(from_mod, const_name, qualified_name, path_suffix)
64
65
  files = Desert::Manager.files_on_load_path(path_suffix)
65
66
  files.each do |file|
66
- # TODO: JLM/BT -- figure out why require_or_load does not work on Windows.
67
- # require_or_load file
68
- load file
67
+ require_or_load file
69
68
  loaded << file.gsub(/\.rb$/, '')
70
69
  next if autoloaded_constants.include?(qualified_name)
71
70
  next if load_once_path?(file)
@@ -2,7 +2,7 @@ class ActiveRecord::Migration
2
2
  module DesertMigration
3
3
  def migrate_plugin(plugin_name, version)
4
4
  plugin = find_plugin(plugin_name)
5
- PluginAWeek::PluginMigrations::Migrator.migrate_plugin(
5
+ Desert::PluginMigrations::Migrator.migrate_plugin(
6
6
  plugin,
7
7
  version
8
8
  )
@@ -10,13 +10,13 @@ class ActiveRecord::Migration
10
10
 
11
11
  def schema_version_equivalent_to(plugin_name, version)
12
12
  plugin = find_plugin(plugin_name)
13
- PluginAWeek::PluginMigrations::Migrator.current_plugin = plugin
14
- PluginAWeek::PluginMigrations::Migrator.allocate.set_schema_version(version)
13
+ Desert::PluginMigrations::Migrator.current_plugin = plugin
14
+ Desert::PluginMigrations::Migrator.allocate.set_schema_version(version)
15
15
  end
16
16
 
17
17
  protected
18
18
  def find_plugin(plugin_name)
19
- plugin = Desert::Manager.find_plugin(plugin_name)
19
+ plugin = Desert::Manager.find_plugin(plugin_name.to_s)
20
20
  return plugin if plugin
21
21
  raise ArgumentError, "No plugin found named #{plugin_name}"
22
22
  end
@@ -3,6 +3,7 @@ module Desert
3
3
  "1.2.5" => {'version' => '1.2.5', 'git_tag' => 'v1.2.5'},
4
4
  "1.99.0" => {'version' => '1.99.0', 'git_tag' => 'v2.0.0_RC1'},
5
5
  "2.0.2" => {'version' => '2.0.2', 'git_tag' => 'v2.0.2'},
6
+ "2.1.0" => {'version' => '2.1.0', 'git_tag' => 'v2.1.0'},
6
7
  "edge" => {'version' => 'edge', 'git_tag' => 'master'},
7
8
  }
8
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: desert
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pivotal Labs
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-05-02 00:00:00 -07:00
12
+ date: 2008-06-20 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -20,45 +20,52 @@ executables: []
20
20
  extensions: []
21
21
 
22
22
  extra_rdoc_files:
23
- - README
23
+ - README.rdoc
24
24
  - CHANGES
25
25
  files:
26
- - Rakefile
27
26
  - CHANGES
28
27
  - MIT-LICENSE
29
- - README
30
- - scratch.rb
28
+ - README.rdoc
29
+ - Rakefile
31
30
  - init.rb
32
- - lib/desert/manager.rb
33
- - lib/desert/version_checker.rb
34
- - lib/desert/plugin.rb
35
- - lib/desert/plugin_templates/1.2.0/action_mailer.rb
31
+ - lib/desert/rails/2.0.0/plugin.rb
32
+ - lib/desert/rails/1.2.0/initializer.rb
33
+ - lib/desert/rails/route_set.rb
34
+ - lib/desert/rails/migration.rb
35
+ - lib/desert/rails/dependencies.rb
36
+ - lib/desert/rails.rb
36
37
  - lib/desert/plugin_templates/action_view.rb
37
- - lib/desert/plugin_templates/2.0.0/action_mailer.rb
38
38
  - lib/desert/plugin_templates/1.99.0/action_mailer.rb
39
+ - lib/desert/plugin_templates/2.0.0/action_mailer.rb
40
+ - lib/desert/plugin_templates/1.2.0/action_mailer.rb
39
41
  - lib/desert/plugin_templates/action_controller.rb
40
- - lib/desert/rails.rb
42
+ - lib/desert/plugin_templates.rb
41
43
  - lib/desert/supported_rails_versions.rb
44
+ - lib/desert/manager.rb
42
45
  - lib/desert/plugin_migrations/migrator.rb
43
- - lib/desert/plugin_migrations/extensions/2.1/schema_statements.rb
44
46
  - lib/desert/plugin_migrations/extensions/1.0/schema_statements.rb
45
47
  - lib/desert/plugin_migrations/extensions/schema_statements.rb
46
- - lib/desert/rails/1.2.0/initializer.rb
47
- - lib/desert/rails/2.0.0/plugin.rb
48
- - lib/desert/rails/route_set.rb
49
- - lib/desert/rails/migration.rb
50
- - lib/desert/rails/dependencies.rb
51
- - lib/desert/plugin_templates.rb
52
- - lib/desert/plugin_migrations.rb
48
+ - lib/desert/plugin_migrations/extensions/2.1/schema_statements.rb
53
49
  - lib/desert/ruby.rb
50
+ - lib/desert/version_checker.rb
51
+ - lib/desert/plugin_migrations.rb
54
52
  - lib/desert/ruby/object.rb
53
+ - lib/desert/plugin.rb
55
54
  - lib/desert.rb
55
+ - generators/desert_plugin
56
+ - generators/desert_plugin/USAGE
57
+ - generators/desert_plugin/desert_plugin_generator.rb
58
+ - generators/desert_plugin/templates
59
+ - generators/desert_plugin/templates/plugin_migration.rb
60
+ - generators/desert_plugin/templates/empty_file
61
+ - generators/desert_plugin/templates/spec_helper.rb
62
+ - generators/desert_plugin/templates/routes.rb
56
63
  has_rdoc: true
57
64
  homepage: http://pivotallabs.com
58
65
  post_install_message:
59
66
  rdoc_options:
60
67
  - --main
61
- - README
68
+ - README.rdoc
62
69
  - --inline-source
63
70
  - --line-numbers
64
71
  require_paths:
@@ -78,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
85
  requirements: []
79
86
 
80
87
  rubyforge_project: pivotalrb
81
- rubygems_version: 1.1.0
88
+ rubygems_version: 1.1.1
82
89
  signing_key:
83
90
  specification_version: 2
84
91
  summary: Desert is a component framework for Rails that allows your plugins to be packaged as mini Rails apps.
data/README DELETED
@@ -1,89 +0,0 @@
1
- = Desert
2
-
3
- Desert is a component framework for Rails that allows you to seamlessly define in your plugins:
4
- * Models
5
- * Controllers
6
- * Views
7
- * Helpers
8
- * Routes
9
- * Migrations
10
- * Plugin Dependencies
11
-
12
- Classes are automatically mixed in with your own or other plugins' classes.
13
- This allows you to make full featured composable components.
14
- Desert is a replacement for Appable Plugins (http://wiki.pluginaweek.org/Appable_plugins).
15
-
16
-
17
- == Using desert
18
-
19
- To use Desert, you need to do only a few things:
20
-
21
- * require 'desert' before Rails::Initializer.run in environment.rb
22
-
23
- environment.rb
24
- require 'desert'
25
- Rails::Initializer.run do
26
- end
27
-
28
- * Install your desert plugin routes in routes.rb
29
-
30
- map.routes_from_plugin(:spiffy)
31
-
32
-
33
- == Example
34
- Say you want to create a plugin named acts_as_spiffy.
35
- Desert allows Spiffy to have a set of features that can be reused and extended in several projects.
36
-
37
- The Spiffy project has a:
38
- * SpiffyController
39
- * Spiffy model
40
- * SpiffyHelper
41
- * spiffy.rhtml
42
- * SpiffyLib library class
43
-
44
- The Spiffy plugin acts as its own mini Rails application.
45
- Here is the directory structure:
46
- RAILS_ROOT/vendor/plugins/spiffy/app/controllers/spiffy_controller.rb
47
- RAILS_ROOT/vendor/plugins/spiffy/app/models/spiffy.rb
48
- RAILS_ROOT/vendor/plugins/spiffy/app/helpers/spiffy_helper.rb
49
- RAILS_ROOT/vendor/plugins/spiffy/app/views/spiffy/spiffy.rhtml
50
- RAILS_ROOT/vendor/plugins/spiffy/lib/spiffy_lib.rb
51
-
52
- Now, say there is a Spiffy Store rails application that uses acts_as_spiffy.
53
- The Rails app can open up any of the Spiffy classes and override any of the methods.
54
-
55
- Say spiffy.rb in the Spiffy plugin is defined as:
56
- class Spiffy < ActiveRecord::Base
57
- def why?
58
- "I just am Spiffy"
59
- end
60
- end
61
-
62
- The Spiffy#why method can be overridden in RAILS_ROOT/app/models/spiffy.rb
63
- class Spiffy < ActiveRecord::Base
64
- def why?
65
- "I sell Spiffy stuff"
66
- end
67
- end
68
-
69
-
70
- == Running plugin tests
71
-
72
- You can run your plugin tests/specs like so:
73
-
74
- rake desert:testspec:plugins PLUGIN=spiffy
75
-
76
- Leaving off the PLUGIN environment variable will cause it to run all the test/specs for
77
- all installed plugins, which may not be what you want.
78
-
79
- == Running Desert tests
80
-
81
- Desert is a library that heavily monkey patches Rails. To ensure that Desert works with
82
- multiple versions of Rails, its tests are run against the supported versions of Rails.
83
-
84
- To set up the different supported versions of Rails, run `rake install_dependencies`.
85
-
86
- This will clone the Rails git repo and export the supported versions of rails into the
87
- respective directories.
88
-
89
- `rake update_dependencies` will update the clones repo on your machine.
data/scratch.rb DELETED
@@ -1,2 +0,0 @@
1
- require "rubygems"
2
- require "rr"