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 +9 -0
- data/README.rdoc +295 -0
- data/Rakefile +5 -5
- data/generators/desert_plugin/USAGE +14 -0
- data/generators/desert_plugin/desert_plugin_generator.rb +73 -0
- data/generators/desert_plugin/templates/empty_file +0 -0
- data/generators/desert_plugin/templates/plugin_migration.rb +11 -0
- data/generators/desert_plugin/templates/routes.rb +4 -0
- data/generators/desert_plugin/templates/spec_helper.rb +8 -0
- data/lib/desert/manager.rb +8 -4
- data/lib/desert/plugin.rb +4 -4
- data/lib/desert/plugin_migrations/extensions/1.0/schema_statements.rb +3 -3
- data/lib/desert/plugin_migrations/extensions/2.1/schema_statements.rb +1 -1
- data/lib/desert/plugin_migrations/migrator.rb +8 -2
- data/lib/desert/plugin_templates/1.2.0/action_mailer.rb +13 -13
- data/lib/desert/plugin_templates/1.99.0/action_mailer.rb +10 -8
- data/lib/desert/plugin_templates/action_view.rb +92 -3
- data/lib/desert/rails/dependencies.rb +3 -4
- data/lib/desert/rails/migration.rb +4 -4
- data/lib/desert/supported_rails_versions.rb +1 -0
- metadata +29 -22
- data/README +0 -89
- data/scratch.rb +0 -2
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.
|
29
|
+
PKG_VERSION = "0.2.2"
|
30
30
|
PKG_FILES = FileList[
|
31
31
|
'[A-Z]*',
|
32
32
|
'*.rb',
|
33
33
|
'lib/**/*.rb',
|
34
|
-
'
|
35
|
-
'
|
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,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
|
data/lib/desert/manager.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
48
|
-
|
49
|
-
|
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 ||=
|
61
|
+
@migration ||= PluginMigrations::Migrator.new(:up, migration_path)
|
62
62
|
end
|
63
63
|
|
64
64
|
def with_current_plugin
|
65
|
-
old_plugin =
|
65
|
+
old_plugin = PluginMigrations::Migrator.current_plugin
|
66
66
|
begin
|
67
|
-
|
67
|
+
PluginMigrations::Migrator.current_plugin = self
|
68
68
|
yield
|
69
69
|
ensure
|
70
|
-
|
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 #{
|
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 #{
|
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 #{
|
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 #{
|
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
|
1
|
+
module Desert #:nodoc:
|
2
2
|
module PluginMigrations
|
3
|
-
# Responsible for migrating plugins.
|
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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
10
|
-
end
|
11
|
-
alias_method_chain :template_path, :plugin_routing
|
11
|
+
alias_method_chain :template_path, :plugin_routing
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
6
|
-
Desert::Manager.
|
7
|
-
|
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
|
-
|
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
|
-
|
15
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
14
|
-
|
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.
|
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-
|
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
|
-
-
|
28
|
+
- README.rdoc
|
29
|
+
- Rakefile
|
31
30
|
- init.rb
|
32
|
-
- lib/desert/
|
33
|
-
- lib/desert/
|
34
|
-
- lib/desert/
|
35
|
-
- lib/desert/
|
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/
|
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/
|
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.
|
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