tog-desert 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +28 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +295 -0
- data/Rakefile +100 -0
- 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/init.rb +0 -0
- data/lib/desert/manager.rb +116 -0
- data/lib/desert/plugin.rb +74 -0
- data/lib/desert/plugin_migrations/extensions/1.0/schema_statements.rb +34 -0
- data/lib/desert/plugin_migrations/extensions/2.1/schema_statements.rb +12 -0
- data/lib/desert/plugin_migrations/extensions/schema_statements.rb +6 -0
- data/lib/desert/plugin_migrations/migrator.rb +54 -0
- data/lib/desert/plugin_migrations.rb +3 -0
- data/lib/desert/plugin_templates/1.2.0/action_mailer.rb +21 -0
- data/lib/desert/plugin_templates/1.2.0/action_view.rb +53 -0
- data/lib/desert/plugin_templates/1.99.0/action_mailer.rb +25 -0
- data/lib/desert/plugin_templates/1.99.0/action_view.rb +38 -0
- data/lib/desert/plugin_templates/2.0.0/action_mailer.rb +23 -0
- data/lib/desert/plugin_templates/2.0.2/action_view.rb +26 -0
- data/lib/desert/plugin_templates/2.1.0/action_view.rb +13 -0
- data/lib/desert/plugin_templates/action_controller.rb +14 -0
- data/lib/desert/plugin_templates/action_view.rb +16 -0
- data/lib/desert/plugin_templates/edge/action_view.rb +10 -0
- data/lib/desert/plugin_templates.rb +10 -0
- data/lib/desert/rails/1.2.0/initializer.rb +20 -0
- data/lib/desert/rails/2.0.0/plugin.rb +22 -0
- data/lib/desert/rails/dependencies.rb +87 -0
- data/lib/desert/rails/migration.rb +36 -0
- data/lib/desert/rails/observer.rb +22 -0
- data/lib/desert/rails/route_set.rb +23 -0
- data/lib/desert/rails.rb +11 -0
- data/lib/desert/ruby/object.rb +34 -0
- data/lib/desert/ruby.rb +2 -0
- data/lib/desert/supported_rails_versions.rb +9 -0
- data/lib/desert/version_checker.rb +26 -0
- data/lib/desert.rb +14 -0
- metadata +95 -0
data/CHANGES
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
- Fix template loading on Edge Rails and on Rails 2.1.0
|
2
|
+
|
3
|
+
0.3.1
|
4
|
+
- Fix migration issue with Rails 2.1.0 using timestamps.
|
5
|
+
|
6
|
+
0.3.0
|
7
|
+
- Fixed script/destroy not removing the routes [From Jeff Dean]
|
8
|
+
- gem includes the Rails generator files [From Jeff Dean]
|
9
|
+
- Fixed readding the route to config/routes.rb in the script/destroy task [From Jeff Dean]
|
10
|
+
- Github now properly formats readme [From Jeff Dean]
|
11
|
+
- Updated the gemspec so rdoc includes it and updated it to add installation and setup instructions [From Jeff Dean]
|
12
|
+
- Removed sample route from generator [From Jeff Dean]
|
13
|
+
|
14
|
+
0.2.1
|
15
|
+
- Fixed ActionMailer rendering in Rails 1.99.0
|
16
|
+
|
17
|
+
0.2.0
|
18
|
+
- Works with edge Rails
|
19
|
+
- Removed Desert::Plugin#up_to_date?
|
20
|
+
- Removed Migrator#latest_version
|
21
|
+
|
22
|
+
0.1.1
|
23
|
+
- Works with edge Rails
|
24
|
+
- Fixed double loading issue with not fully expanded load_paths.
|
25
|
+
|
26
|
+
0.1.0
|
27
|
+
- Fixed [#13346] ActionController::Base.helper raises error when helper is only in plugin
|
28
|
+
- Desert does not require files that have been required before Desert was loaded
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2007 Pivotal Labs
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
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
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
require "rake"
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rake/contrib/rubyforgepublisher'
|
4
|
+
require 'rake/clean'
|
5
|
+
require 'rake/testtask'
|
6
|
+
require 'rake/rdoctask'
|
7
|
+
|
8
|
+
desc "Runs the Rspec suite"
|
9
|
+
task(:default) do
|
10
|
+
run_suite
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Runs the Rspec suite"
|
14
|
+
task(:spec) do
|
15
|
+
run_suite
|
16
|
+
end
|
17
|
+
|
18
|
+
def run_suite
|
19
|
+
dir = File.dirname(__FILE__)
|
20
|
+
system("ruby #{dir}/spec/spec_suite.rb") || raise("Example Suite failed")
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Copies the trunk to a tag with the name of the current release"
|
24
|
+
task(:tag_release) do
|
25
|
+
tag_release
|
26
|
+
end
|
27
|
+
|
28
|
+
PKG_NAME = "desert"
|
29
|
+
PKG_VERSION = "0.3.4"
|
30
|
+
PKG_FILES = FileList[
|
31
|
+
'[A-Z]*',
|
32
|
+
'*.rb',
|
33
|
+
'lib/**/*.rb',
|
34
|
+
'generators/**/*',
|
35
|
+
'generators/**/templates/*'
|
36
|
+
#'examples/**/*.rb'
|
37
|
+
]
|
38
|
+
|
39
|
+
spec = Gem::Specification.new do |s|
|
40
|
+
s.name = PKG_NAME
|
41
|
+
s.version = PKG_VERSION
|
42
|
+
s.summary = "Desert is a component framework for Rails that allows your plugins to be packaged as mini Rails apps."
|
43
|
+
#s.test_files = "examples/spec_suite.rb"
|
44
|
+
s.description = s.summary
|
45
|
+
|
46
|
+
s.files = PKG_FILES.to_a
|
47
|
+
s.require_path = 'lib'
|
48
|
+
|
49
|
+
s.has_rdoc = true
|
50
|
+
#s.extra_rdoc_files = [ "README.rdoc", "CHANGES" ]
|
51
|
+
#s.rdoc_options = ["--main", "README.rdoc", "--inline-source", "--line-numbers"]
|
52
|
+
|
53
|
+
#s.test_files = Dir.glob('spec/*_spec.rb')
|
54
|
+
#s.require_path = 'lib'
|
55
|
+
s.author = "Pivotal Labs"
|
56
|
+
s.email = "opensource@pivotallabs.com"
|
57
|
+
s.homepage = "http://pivotallabs.com"
|
58
|
+
s.rubyforge_project = "desert"
|
59
|
+
end
|
60
|
+
|
61
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
62
|
+
pkg.need_zip = true
|
63
|
+
pkg.need_tar = true
|
64
|
+
end
|
65
|
+
desc "Regenerate desert.gemspec file. This file is used by github to autobuild the gem and add it to http://gems.github.com source."
|
66
|
+
task(:gemspec) do
|
67
|
+
File.open("#{PKG_NAME}.gemspec", "w") do |gemspec|
|
68
|
+
gemspec.puts spec.to_ruby
|
69
|
+
end
|
70
|
+
puts "#{PKG_NAME}.gemspec generated."
|
71
|
+
end
|
72
|
+
|
73
|
+
def tag_release
|
74
|
+
dashed_version = PKG_VERSION.gsub('.', '-')
|
75
|
+
svn_user = "#{ENV["SVN_USER"]}@" || ""
|
76
|
+
`svn cp svn+ssh://#{svn_user}rubyforge.org/var/svn/pivotalrb/desert/trunk svn+ssh://#{svn_user}rubyforge.org/var/svn/pivotalrb/desert/tags/REL-#{dashed_version} -m 'Version #{PKG_VERSION}'`
|
77
|
+
end
|
78
|
+
|
79
|
+
desc "Install dependencies to run the build. This task uses Git."
|
80
|
+
task(:install_dependencies) do
|
81
|
+
require "lib/desert/supported_rails_versions"
|
82
|
+
system("git clone git://github.com/rails/rails.git spec/rails_root/vendor/rails_versions/edge")
|
83
|
+
Dir.chdir("spec/rails_root/vendor/rails_versions/edge") do
|
84
|
+
begin
|
85
|
+
Desert::SUPPORTED_RAILS_VERSIONS.each do |version, data|
|
86
|
+
unless version == 'edge'
|
87
|
+
system("git checkout #{data['git_tag']}")
|
88
|
+
system("cp -R ../edge ../#{version}")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
ensure
|
92
|
+
system("git checkout master")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
desc "Updates the dependencies to run the build. This task uses Git."
|
98
|
+
task(:update_dependencies) do
|
99
|
+
system "cd spec/rails_root/vendor/rails_versions/edge; git pull origin"
|
100
|
+
end
|
@@ -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/init.rb
ADDED
File without changes
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module Desert
|
2
|
+
class Manager # nodoc
|
3
|
+
class << self
|
4
|
+
def instance
|
5
|
+
@instance ||= new
|
6
|
+
end
|
7
|
+
attr_writer :instance
|
8
|
+
|
9
|
+
protected
|
10
|
+
def method_missing(method_name, *args, &block)
|
11
|
+
instance.__send__(method_name, *args, &block)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :loading_plugin, :plugins_in_registration
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@plugins = []
|
19
|
+
@plugins_in_registration = []
|
20
|
+
end
|
21
|
+
|
22
|
+
def plugins
|
23
|
+
@plugins.dup
|
24
|
+
end
|
25
|
+
|
26
|
+
def load_paths
|
27
|
+
paths = []
|
28
|
+
plugin_paths.each do |component_root|
|
29
|
+
paths << File.join(component_root, 'app')
|
30
|
+
paths << File.join(component_root, 'app','models')
|
31
|
+
paths << File.join(component_root, 'app','controllers')
|
32
|
+
paths << File.join(component_root, 'app','helpers')
|
33
|
+
paths << File.join(component_root, 'lib')
|
34
|
+
end
|
35
|
+
dependencies.load_paths.reverse.each do |path|
|
36
|
+
paths << File.expand_path(path) unless paths.include?(File.expand_path(path))
|
37
|
+
end
|
38
|
+
paths
|
39
|
+
end
|
40
|
+
|
41
|
+
def register_plugin(plugin_path)
|
42
|
+
plugin = Plugin.new(plugin_path)
|
43
|
+
@plugins_in_registration << plugin
|
44
|
+
|
45
|
+
yield if block_given?
|
46
|
+
|
47
|
+
dependencies.load_paths << plugin.models_path
|
48
|
+
dependencies.load_paths << plugin.controllers_path
|
49
|
+
dependencies.load_paths << plugin.helpers_path
|
50
|
+
|
51
|
+
@plugins_in_registration.pop
|
52
|
+
|
53
|
+
if existing_plugin = find_plugin(plugin.name)
|
54
|
+
return existing_plugin
|
55
|
+
end
|
56
|
+
|
57
|
+
@plugins << plugin
|
58
|
+
plugin
|
59
|
+
end
|
60
|
+
|
61
|
+
def find_plugin(name_or_directory)
|
62
|
+
name = File.basename(File.expand_path(name_or_directory))
|
63
|
+
plugins.find do |plugin|
|
64
|
+
plugin.name == name
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def plugin_exists?(name_or_directory)
|
69
|
+
!find_plugin(name_or_directory).nil?
|
70
|
+
end
|
71
|
+
|
72
|
+
def plugin_path(name)
|
73
|
+
plugin = find_plugin(name)
|
74
|
+
return nil unless plugin
|
75
|
+
plugin.path
|
76
|
+
end
|
77
|
+
|
78
|
+
def files_on_load_path(file)
|
79
|
+
desert_file_exists = false
|
80
|
+
files = []
|
81
|
+
load_paths.each do |path|
|
82
|
+
full_path = File.join(path, file)
|
83
|
+
full_path << '.rb' unless File.extname(full_path) == '.rb'
|
84
|
+
files << full_path if File.exists?(full_path)
|
85
|
+
end
|
86
|
+
files
|
87
|
+
end
|
88
|
+
|
89
|
+
def directory_on_load_path?(dir_suffix)
|
90
|
+
Desert::Manager.load_paths.each do |path|
|
91
|
+
return true if File.directory?(File.join(path, dir_suffix))
|
92
|
+
end
|
93
|
+
return false
|
94
|
+
end
|
95
|
+
|
96
|
+
def layout_paths
|
97
|
+
layout_paths = plugins.reverse.collect do |plugin|
|
98
|
+
plugin.layouts_path
|
99
|
+
end
|
100
|
+
layout_paths
|
101
|
+
end
|
102
|
+
|
103
|
+
protected
|
104
|
+
def dependencies
|
105
|
+
@dependencies ||= ActiveSupport.const_defined?(:Dependencies) ? ActiveSupport::Dependencies : Dependencies
|
106
|
+
end
|
107
|
+
|
108
|
+
def plugin_paths
|
109
|
+
plugins_and_app.collect { |plugin| plugin.path }
|
110
|
+
end
|
111
|
+
|
112
|
+
def plugins_and_app
|
113
|
+
plugins + @plugins_in_registration + [Plugin.new(RAILS_ROOT)]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|