desert 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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"