desert 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +7 -0
- data/MIT-LICENSE +20 -0
- data/README +77 -0
- data/Rakefile +71 -0
- data/init.rb +0 -0
- data/lib/desert.rb +32 -0
- data/lib/desert/manager.rb +112 -0
- data/lib/desert/plugin.rb +80 -0
- data/lib/desert/plugin_migrations/extensions/schema_statements.rb +38 -0
- data/lib/desert/plugin_migrations/migrator.rb +43 -0
- data/lib/desert/plugin_templates/1.x/action_mailer.rb +21 -0
- data/lib/desert/plugin_templates/2.x/action_mailer.rb +23 -0
- data/lib/desert/plugin_templates/action_controller.rb +12 -0
- data/lib/desert/plugin_templates/action_view.rb +36 -0
- data/lib/desert/rails/1.x/initializer.rb +20 -0
- data/lib/desert/rails/2.x/plugin.rb +22 -0
- data/lib/desert/rails/dependencies.rb +88 -0
- data/lib/desert/rails/migration.rb +42 -0
- data/lib/desert/rails/migrator.rb +14 -0
- data/lib/desert/rails/route_set.rb +23 -0
- data/lib/desert/ruby/object.rb +34 -0
- data/lib/desert/version_checker.rb +26 -0
- data/lib/generators/desert_plugin/USAGE +14 -0
- data/lib/generators/desert_plugin/desert_plugin_generator.rb +40 -0
- data/lib/generators/desert_plugin/templates/empty_file +0 -0
- data/lib/generators/desert_plugin/templates/plugin_migration.rb +11 -0
- data/lib/generators/desert_plugin/templates/routes.rb +1 -0
- data/lib/generators/desert_plugin/templates/spec_helper.rb +8 -0
- metadata +79 -0
data/CHANGES
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
0.1.1
|
|
2
|
+
- Works with edge Rails
|
|
3
|
+
- Fixed double loading issue with not fully expanded load_paths.
|
|
4
|
+
|
|
5
|
+
0.1.0
|
|
6
|
+
- Fixed [#13346] ActionController::Base.helper raises error when helper is only in plugin
|
|
7
|
+
- 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
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
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.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
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.1.1"
|
|
30
|
+
PKG_FILES = FileList[
|
|
31
|
+
'[A-Z]*',
|
|
32
|
+
'*.rb',
|
|
33
|
+
'lib/**/*.rb',
|
|
34
|
+
'lib/generators/**/*',
|
|
35
|
+
'lib/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", "CHANGES" ]
|
|
51
|
+
s.rdoc_options = ["--main", "README", "--inline-source", "--line-numbers"]
|
|
52
|
+
|
|
53
|
+
s.test_files = Dir.glob('spec/*_spec.rb')
|
|
54
|
+
s.require_path = 'lib'
|
|
55
|
+
s.autorequire = 'desert'
|
|
56
|
+
s.author = "Pivotal Labs"
|
|
57
|
+
s.email = "opensource@pivotallabs.com"
|
|
58
|
+
s.homepage = "http://pivotallabs.com"
|
|
59
|
+
s.rubyforge_project = "pivotalrb"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
|
63
|
+
pkg.need_zip = true
|
|
64
|
+
pkg.need_tar = true
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def tag_release
|
|
68
|
+
dashed_version = PKG_VERSION.gsub('.', '-')
|
|
69
|
+
svn_user = "#{ENV["SVN_USER"]}@" || ""
|
|
70
|
+
`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}'`
|
|
71
|
+
end
|
data/init.rb
ADDED
|
File without changes
|
data/lib/desert.rb
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require "active_support"
|
|
2
|
+
require "active_record"
|
|
3
|
+
require "action_controller"
|
|
4
|
+
require "action_mailer"
|
|
5
|
+
|
|
6
|
+
dir = File.dirname(__FILE__)
|
|
7
|
+
require "#{dir}/desert/plugin"
|
|
8
|
+
require "#{dir}/desert/manager"
|
|
9
|
+
require "#{dir}/desert/version_checker"
|
|
10
|
+
|
|
11
|
+
if Desert::VersionChecker.rails_version_is_below_1990?
|
|
12
|
+
require "#{dir}/desert/rails/1.x/initializer"
|
|
13
|
+
else
|
|
14
|
+
require "#{dir}/desert/rails/2.x/plugin"
|
|
15
|
+
end
|
|
16
|
+
require "#{dir}/desert/rails/dependencies"
|
|
17
|
+
require "#{dir}/desert/rails/migration"
|
|
18
|
+
require "#{dir}/desert/rails/migrator"
|
|
19
|
+
require "#{dir}/desert/ruby/object"
|
|
20
|
+
|
|
21
|
+
require "#{dir}/desert/rails/route_set"
|
|
22
|
+
|
|
23
|
+
require "#{dir}/desert/plugin_migrations/migrator"
|
|
24
|
+
require "#{dir}/desert/plugin_migrations/extensions/schema_statements"
|
|
25
|
+
|
|
26
|
+
require "#{dir}/desert/plugin_templates/action_controller"
|
|
27
|
+
if Desert::VersionChecker.rails_version_is_below_rc2?
|
|
28
|
+
require "#{dir}/desert/plugin_templates/1.x/action_mailer"
|
|
29
|
+
else
|
|
30
|
+
require "#{dir}/desert/plugin_templates/2.x/action_mailer"
|
|
31
|
+
end
|
|
32
|
+
require "#{dir}/desert/plugin_templates/action_view"
|
|
@@ -0,0 +1,112 @@
|
|
|
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 plugin_paths
|
|
105
|
+
plugins_and_app.collect { |plugin| plugin.path }
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def plugins_and_app
|
|
109
|
+
plugins + @plugins_in_registration + [Plugin.new(RAILS_ROOT)]
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
module Desert
|
|
2
|
+
class Plugin # nodoc
|
|
3
|
+
attr_reader :name, :path
|
|
4
|
+
def initialize(path)
|
|
5
|
+
@path = File.expand_path(path)
|
|
6
|
+
@name = File.basename(@path)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def migration_path
|
|
10
|
+
"#{@path}/db/migrate"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# The path to the views for this plugin
|
|
14
|
+
def templates_path
|
|
15
|
+
"#{@path}/app/views"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def controllers_path
|
|
19
|
+
"#{@path}/app/controllers"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# TODO: Test me
|
|
23
|
+
def models_path
|
|
24
|
+
"#{@path}/app/models"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# TODO: Test me
|
|
28
|
+
def helpers_path
|
|
29
|
+
"#{@path}/app/helpers"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# The path to the layout for this plugin
|
|
33
|
+
def layouts_path
|
|
34
|
+
"#{templates_path}/layouts"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Finds a template with the specified path
|
|
38
|
+
def find_template(template)
|
|
39
|
+
template_path = "#{templates_path}/#{template}"
|
|
40
|
+
File.exists?(template_path) ? template_path : nil
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def framework_paths
|
|
44
|
+
# TODO: Don't include dirs for frameworks that are not used
|
|
45
|
+
%w(
|
|
46
|
+
railties
|
|
47
|
+
railties/lib
|
|
48
|
+
actionpack/lib
|
|
49
|
+
activesupport/lib
|
|
50
|
+
activerecord/lib
|
|
51
|
+
actionmailer/lib
|
|
52
|
+
actionwebservice/lib
|
|
53
|
+
).map { |dir| "#{framework_root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def ==(other)
|
|
57
|
+
self.path == other.path
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def migration
|
|
61
|
+
@migration ||= PluginAWeek::PluginMigrations::Migrator.new(:up, migration_path)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def up_to_date?
|
|
65
|
+
with_current_plugin do
|
|
66
|
+
migration.latest_version <= migration.current_version
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def with_current_plugin
|
|
71
|
+
old_plugin = PluginAWeek::PluginMigrations::Migrator.current_plugin
|
|
72
|
+
begin
|
|
73
|
+
PluginAWeek::PluginMigrations::Migrator.current_plugin = self
|
|
74
|
+
yield
|
|
75
|
+
ensure
|
|
76
|
+
PluginAWeek::PluginMigrations::Migrator.current_plugin = old_plugin
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module ActiveRecord #:nodoc:
|
|
2
|
+
module ConnectionAdapters #:nodoc:
|
|
3
|
+
module SchemaStatements #:nodoc:
|
|
4
|
+
def initialize_schema_information_with_plugins
|
|
5
|
+
initialize_schema_information_without_plugins
|
|
6
|
+
|
|
7
|
+
begin
|
|
8
|
+
execute "CREATE TABLE #{PluginAWeek::PluginMigrations::Migrator.schema_info_table_name} (plugin_name #{type_to_sql(:string)}, version #{type_to_sql(:integer)})"
|
|
9
|
+
rescue ActiveRecord::StatementInvalid
|
|
10
|
+
# Schema has been initialized
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
alias_method_chain :initialize_schema_information, :plugins
|
|
14
|
+
|
|
15
|
+
def dump_schema_information_with_plugins
|
|
16
|
+
schema_information = []
|
|
17
|
+
|
|
18
|
+
dump = dump_schema_information_without_plugins
|
|
19
|
+
schema_information << dump if dump
|
|
20
|
+
|
|
21
|
+
begin
|
|
22
|
+
plugins = ActiveRecord::Base.connection.select_all("SELECT * FROM #{PluginAWeek::PluginMigrations::Migrator.schema_info_table_name}")
|
|
23
|
+
plugins.each do |plugin|
|
|
24
|
+
if (version = plugin['version'].to_i) > 0
|
|
25
|
+
plugin_name = ActiveRecord::Base.quote_value(plugin['plugin_name'])
|
|
26
|
+
schema_information << "INSERT INTO #{PluginAWeek::PluginMigrations::Migrator.schema_info_table_name} (plugin_name, version) VALUES (#{plugin_name}, #{version})"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
rescue ActiveRecord::StatementInvalid
|
|
30
|
+
# No Schema Info
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
schema_information.join(";\n")
|
|
34
|
+
end
|
|
35
|
+
alias_method_chain :dump_schema_information, :plugins
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module PluginAWeek #:nodoc:
|
|
2
|
+
module PluginMigrations
|
|
3
|
+
# Responsible for migrating plugins. PluginAWeek::PluginMigrations.Migrator.current_plugin
|
|
4
|
+
# indicates which plugin is currently being migrated
|
|
5
|
+
class Migrator < ActiveRecord::Migrator
|
|
6
|
+
# We need to be able to set the current plugin being migrated.
|
|
7
|
+
cattr_accessor :current_plugin
|
|
8
|
+
|
|
9
|
+
class << self
|
|
10
|
+
# Runs the migrations from a plugin, up (or down) to the version given
|
|
11
|
+
def migrate_plugin(plugin, version = nil)
|
|
12
|
+
self.current_plugin = plugin
|
|
13
|
+
migrate(plugin.migration_path, version)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def schema_info_table_name #:nodoc:
|
|
17
|
+
ActiveRecord::Base.table_name_prefix + 'plugin_schema_info' + ActiveRecord::Base.table_name_suffix
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def current_version #:nodoc:
|
|
21
|
+
result = ActiveRecord::Base.connection.select_one("SELECT version FROM #{schema_info_table_name} WHERE plugin_name = '#{current_plugin.name}'")
|
|
22
|
+
if result
|
|
23
|
+
result['version'].to_i
|
|
24
|
+
else
|
|
25
|
+
# There probably isn't an entry for this plugin in the migration info table.
|
|
26
|
+
0
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def set_schema_version(version)
|
|
32
|
+
version = down? ? version.to_i - 1 : version.to_i
|
|
33
|
+
|
|
34
|
+
if ActiveRecord::Base.connection.select_one("SELECT version FROM #{self.class.schema_info_table_name} WHERE plugin_name = '#{current_plugin.name}'").nil?
|
|
35
|
+
# We need to create the entry since it doesn't exist
|
|
36
|
+
ActiveRecord::Base.connection.execute("INSERT INTO #{self.class.schema_info_table_name} (version, plugin_name) VALUES (#{version},'#{current_plugin.name}')")
|
|
37
|
+
else
|
|
38
|
+
ActiveRecord::Base.connection.update("UPDATE #{self.class.schema_info_table_name} SET version = #{version} WHERE plugin_name = '#{current_plugin.name}'")
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module ActionMailer #:nodoc
|
|
2
|
+
class Base #:nodoc:
|
|
3
|
+
private
|
|
4
|
+
def template_path_with_plugin_routing
|
|
5
|
+
template_paths = [template_path_without_plugin_routing]
|
|
6
|
+
Desert::Manager.plugins.reverse.each do |plugin|
|
|
7
|
+
template_paths << "#{plugin.templates_path}/#{mailer_name}"
|
|
8
|
+
end
|
|
9
|
+
"{#{template_paths * ','}}"
|
|
10
|
+
end
|
|
11
|
+
alias_method_chain :template_path, :plugin_routing
|
|
12
|
+
|
|
13
|
+
def initialize_template_class(assigns)
|
|
14
|
+
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
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module ActionMailer #:nodoc
|
|
2
|
+
class Base #:nodoc:
|
|
3
|
+
private
|
|
4
|
+
def template_path_with_plugin_routing
|
|
5
|
+
template_paths = [template_path_without_plugin_routing]
|
|
6
|
+
Desert::Manager.plugins.reverse.each do |plugin|
|
|
7
|
+
template_paths << "#{plugin.templates_path}/#{mailer_name}"
|
|
8
|
+
end
|
|
9
|
+
"{#{template_paths * ','}}"
|
|
10
|
+
end
|
|
11
|
+
alias_method_chain :template_path, :plugin_routing
|
|
12
|
+
|
|
13
|
+
def initialize_template_class(assigns)
|
|
14
|
+
view_paths = Dir[template_path].collect do |path|
|
|
15
|
+
File.dirname(path)
|
|
16
|
+
end
|
|
17
|
+
returning(template = ActionView::Base.new(view_paths, assigns, self)) do
|
|
18
|
+
template.extend ApplicationHelper
|
|
19
|
+
template.extend self.class.master_helper_module
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module ActionController #:nodoc:
|
|
2
|
+
module Layout #:nodoc:
|
|
3
|
+
module ClassMethods #:nodoc:
|
|
4
|
+
private
|
|
5
|
+
def layout_list_with_plugin_routing
|
|
6
|
+
plugin_layouts = Desert::Manager.layout_paths.join(",")
|
|
7
|
+
layout_list_without_plugin_routing + Dir["{#{plugin_layouts}}/**/*"]
|
|
8
|
+
end
|
|
9
|
+
alias_method_chain :layout_list, :plugin_routing
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
if ActionView.const_defined?(:TemplateFinder)
|
|
2
|
+
module ActionView #:nodoc:
|
|
3
|
+
class TemplateFinder #:nodoc:
|
|
4
|
+
def initialize_with_desert_plugins(*args)
|
|
5
|
+
initialize_without_desert_plugins *args
|
|
6
|
+
|
|
7
|
+
Desert::Manager.plugins.reverse.each do |plugin|
|
|
8
|
+
append_view_path plugin.templates_path
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
alias_method_chain :initialize, :desert_plugins
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
else
|
|
15
|
+
module ActionView #:nodoc:
|
|
16
|
+
class Base #:nodoc:
|
|
17
|
+
private
|
|
18
|
+
def full_template_path_with_plugin_routing(template_path, extension)
|
|
19
|
+
full_template_path = full_template_path_without_plugin_routing(template_path, extension)
|
|
20
|
+
|
|
21
|
+
unless File.exist?(full_template_path)
|
|
22
|
+
# Look through the plugins for the template
|
|
23
|
+
Desert::Manager.plugins.reverse.each do |plugin|
|
|
24
|
+
if plugin_template_path = plugin.find_template("#{template_path}.#{extension}")
|
|
25
|
+
full_template_path = plugin_template_path
|
|
26
|
+
break
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
full_template_path
|
|
32
|
+
end
|
|
33
|
+
alias_method_chain :full_template_path, :plugin_routing
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Rails
|
|
2
|
+
class Initializer
|
|
3
|
+
def load_plugin_with_desert(directory)
|
|
4
|
+
return if Desert::Manager.plugin_exists?(directory)
|
|
5
|
+
plugin = Desert::Manager.register_plugin(directory) do
|
|
6
|
+
load_plugin_without_desert(directory)
|
|
7
|
+
end
|
|
8
|
+
# TODO: Can we use Initializer::Configuration#default_load_paths to do this?
|
|
9
|
+
configuration.controller_paths << plugin.controllers_path
|
|
10
|
+
end
|
|
11
|
+
alias_method_chain :load_plugin, :desert
|
|
12
|
+
|
|
13
|
+
def require_plugin(plugin_name)
|
|
14
|
+
find_plugins(configuration.plugin_paths).sort.each do |path|
|
|
15
|
+
return load_plugin(path) if File.basename(path) == plugin_name
|
|
16
|
+
end
|
|
17
|
+
raise "Plugin '#{plugin_name}' does not exist"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class Rails::Plugin
|
|
2
|
+
attr_accessor :initializer
|
|
3
|
+
def require_plugin(plugin_name)
|
|
4
|
+
initializer.configuration.plugin_locators.each do |locator|
|
|
5
|
+
locator.new(initializer).each do |plugin_loader|
|
|
6
|
+
return plugin_loader.load(initializer) if plugin_loader.name.to_s == plugin_name.to_s
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
raise "Plugin '#{plugin_name}' does not exist"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def load_with_desert(initializer)
|
|
13
|
+
@initializer = initializer
|
|
14
|
+
return if Desert::Manager.plugin_exists?(directory)
|
|
15
|
+
plugin = Desert::Manager.register_plugin(directory) do
|
|
16
|
+
load_without_desert(initializer)
|
|
17
|
+
end
|
|
18
|
+
# TODO: Can we use Initializer::Configuration#default_load_paths to do this?
|
|
19
|
+
initializer.configuration.controller_paths << plugin.controllers_path
|
|
20
|
+
end
|
|
21
|
+
alias_method_chain :load, :desert
|
|
22
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
module Dependencies
|
|
2
|
+
def load_missing_constant_with_desert(from_mod, const_name)
|
|
3
|
+
from_mod = guard_against_anonymous_module(from_mod)
|
|
4
|
+
qualified_name = qualified_name_for from_mod, const_name
|
|
5
|
+
path_suffix = qualified_name.underscore
|
|
6
|
+
|
|
7
|
+
if define_constant_with_desert_loading(from_mod, const_name, qualified_name, path_suffix)
|
|
8
|
+
return from_mod.const_get(const_name)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
if has_parent_module?(from_mod)
|
|
12
|
+
look_for_constant_in_parent_module(from_mod, const_name, qualified_name, path_suffix)
|
|
13
|
+
else
|
|
14
|
+
raise NameError, "Constant #{qualified_name} from #{path_suffix}.rb not found"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
alias_method_chain :load_missing_constant, :desert
|
|
18
|
+
|
|
19
|
+
def load_once_path?(path)
|
|
20
|
+
load_once_paths.any? { |base| File.expand_path(path).starts_with? File.expand_path(base) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def depend_on_with_desert(file_name, swallow_load_errors = false)
|
|
24
|
+
successfully_loaded_in_plugin = false
|
|
25
|
+
Desert::Manager.files_on_load_path(file_name).each do |file|
|
|
26
|
+
require_or_load(file)
|
|
27
|
+
successfully_loaded_in_plugin = true
|
|
28
|
+
end
|
|
29
|
+
begin
|
|
30
|
+
unless successfully_loaded_in_plugin
|
|
31
|
+
require_or_load file_name
|
|
32
|
+
loaded << File.expand_path(file_name)
|
|
33
|
+
end
|
|
34
|
+
rescue LoadError
|
|
35
|
+
if !swallow_load_errors && !successfully_loaded_in_plugin
|
|
36
|
+
raise
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
alias_method_chain :depend_on, :desert
|
|
41
|
+
|
|
42
|
+
protected
|
|
43
|
+
def define_constant_with_desert_loading(from_mod, const_name, qualified_name, path_suffix)
|
|
44
|
+
define_constant_from_file(from_mod, const_name, qualified_name, path_suffix) ||
|
|
45
|
+
define_constant_from_directory(from_mod, const_name, qualified_name, path_suffix)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def has_parent_module?(mod)
|
|
49
|
+
mod != Object
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def look_for_constant_in_parent_module(from_mod, const_name, qualified_name, path_suffix)
|
|
53
|
+
return from_mod.parent.const_missing(const_name)
|
|
54
|
+
rescue NameError => e
|
|
55
|
+
raise NameError, "Constant #{qualified_name} from #{path_suffix}.rb not found\n#{e.message}"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def guard_against_anonymous_module(from_mod)
|
|
59
|
+
return Object if from_mod.name.blank?
|
|
60
|
+
return from_mod
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def define_constant_from_file(from_mod, const_name, qualified_name, path_suffix)
|
|
64
|
+
files = Desert::Manager.files_on_load_path(path_suffix)
|
|
65
|
+
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
|
|
69
|
+
loaded << file.gsub(/\.rb$/, '')
|
|
70
|
+
next if autoloaded_constants.include?(qualified_name)
|
|
71
|
+
next if load_once_path?(file)
|
|
72
|
+
autoloaded_constants << qualified_name
|
|
73
|
+
end
|
|
74
|
+
loaded << File.expand_path(path_suffix)
|
|
75
|
+
from_mod.const_defined?(const_name)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def define_constant_from_directory(from_mod, const_name, qualified_name, path_suffix)
|
|
79
|
+
return false unless Desert::Manager.directory_on_load_path?(path_suffix)
|
|
80
|
+
|
|
81
|
+
if autoloaded_constants.include?(qualified_name)
|
|
82
|
+
raise "Constant #{qualified_name} is already autoloaded but is not defined as a constant"
|
|
83
|
+
end
|
|
84
|
+
from_mod.const_set(const_name, Module.new)
|
|
85
|
+
autoloaded_constants << qualified_name
|
|
86
|
+
return true
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
class ActiveRecord::Migration
|
|
2
|
+
module DesertMigration
|
|
3
|
+
def migrate_plugin(plugin_name, version)
|
|
4
|
+
plugin = find_plugin(plugin_name)
|
|
5
|
+
PluginAWeek::PluginMigrations::Migrator.migrate_plugin(
|
|
6
|
+
plugin,
|
|
7
|
+
version
|
|
8
|
+
)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def schema_version_equivalent_to(plugin_name, version)
|
|
12
|
+
plugin = find_plugin(plugin_name)
|
|
13
|
+
PluginAWeek::PluginMigrations::Migrator.current_plugin = plugin
|
|
14
|
+
PluginAWeek::PluginMigrations::Migrator.allocate.set_schema_version(version)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
protected
|
|
18
|
+
def find_plugin(plugin_name)
|
|
19
|
+
plugin = Desert::Manager.find_plugin(plugin_name)
|
|
20
|
+
return plugin if plugin
|
|
21
|
+
raise ArgumentError, "No plugin found named #{plugin_name}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def table_exists?(table_name)
|
|
25
|
+
vals = select_all("DESC #{table_name}")
|
|
26
|
+
return true
|
|
27
|
+
rescue ActiveRecord::StatementInvalid
|
|
28
|
+
return false
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def column_exists?(table_name, column_name)
|
|
32
|
+
val = select_one("select #{column_name} from #{table_name}")
|
|
33
|
+
return true
|
|
34
|
+
rescue ActiveRecord::StatementInvalid
|
|
35
|
+
return false
|
|
36
|
+
end
|
|
37
|
+
def table_exists?(table_name)
|
|
38
|
+
ActiveRecord::Base.connection.tables.include? table_name
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
extend DesertMigration
|
|
42
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class ActiveRecord::Migrator
|
|
2
|
+
module DesertMigrator
|
|
3
|
+
def latest_version
|
|
4
|
+
return 0 if migration_classes.empty?
|
|
5
|
+
migration_classes.last.first
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def migration_classes_with_caching
|
|
9
|
+
@migration_classes ||= migration_classes_without_caching
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
include DesertMigrator
|
|
13
|
+
alias_method_chain :migration_classes, :caching
|
|
14
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Desert
|
|
2
|
+
module Rails
|
|
3
|
+
module RouteSet
|
|
4
|
+
# Loads the set of routes from within a plugin and evaluates them at this
|
|
5
|
+
# point within an application's main <tt>routes.rb</tt> file.
|
|
6
|
+
#
|
|
7
|
+
# Plugin routes are loaded from <tt><plugin_root>/routes.rb</tt>.
|
|
8
|
+
def routes_from_plugin(name)
|
|
9
|
+
name = name.to_s
|
|
10
|
+
routes_path = File.join(
|
|
11
|
+
Desert::Manager.plugin_path(name),
|
|
12
|
+
"config/routes.rb"
|
|
13
|
+
)
|
|
14
|
+
RAILS_DEFAULT_LOGGER.debug "Loading routes from #{routes_path}."
|
|
15
|
+
eval(IO.read(routes_path), binding, routes_path) if File.file?(routes_path)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class ActionController::Routing::RouteSet::Mapper
|
|
22
|
+
include Desert::Rails::RouteSet
|
|
23
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
class Object
|
|
2
|
+
def require_with_desert(path)
|
|
3
|
+
relative_include_path = (path =~ /\.rb$/) ? path : "#{path}.rb"
|
|
4
|
+
if $".include?(relative_include_path)
|
|
5
|
+
return false
|
|
6
|
+
else
|
|
7
|
+
__each_matching_file(path) do |expanded_path|
|
|
8
|
+
require_without_desert expanded_path
|
|
9
|
+
end
|
|
10
|
+
$" << relative_include_path
|
|
11
|
+
return true
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
alias_method_chain :require, :desert
|
|
15
|
+
|
|
16
|
+
def load_with_desert(file)
|
|
17
|
+
__each_matching_file(file) do |file|
|
|
18
|
+
load_without_desert file
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
alias_method_chain :load, :desert
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
def __each_matching_file(file)
|
|
25
|
+
files = Desert::Manager.instance.files_on_load_path(file)
|
|
26
|
+
desert_file_exists = files.empty? ? false : true
|
|
27
|
+
files.each do |component_file|
|
|
28
|
+
yield(component_file)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
return true if desert_file_exists
|
|
32
|
+
yield(file)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Desert
|
|
2
|
+
class VersionChecker
|
|
3
|
+
class << self
|
|
4
|
+
def current_rails_version_matches?(version_requirement)
|
|
5
|
+
version_matches?(::Rails::VERSION::STRING, version_requirement)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def version_matches?(version, version_requirement)
|
|
9
|
+
Gem::Version::Requirement.new([version_requirement]).satisfied_by?(Gem::Version.new(version))
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def rails_version_is_below_1990?
|
|
13
|
+
result = current_rails_version_matches?('<1.99.0')
|
|
14
|
+
result
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def rails_version_is_below_rc2?
|
|
18
|
+
current_rails_version_matches?('<1.99.1')
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def rails_version_is_1991?
|
|
22
|
+
current_rails_version_matches?('=1.99.1')
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
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,40 @@
|
|
|
1
|
+
class DesertPluginGenerator < Rails::Generator::NamedBase
|
|
2
|
+
def manifest
|
|
3
|
+
record do |m|
|
|
4
|
+
m.directory "vendor/plugins/#{file_name}"
|
|
5
|
+
|
|
6
|
+
m.directory "vendor/plugins/#{file_name}/app"
|
|
7
|
+
m.directory "vendor/plugins/#{file_name}/app/controllers"
|
|
8
|
+
m.directory "vendor/plugins/#{file_name}/app/helpers"
|
|
9
|
+
m.directory "vendor/plugins/#{file_name}/app/models"
|
|
10
|
+
m.directory "vendor/plugins/#{file_name}/app/views"
|
|
11
|
+
|
|
12
|
+
m.directory "vendor/plugins/#{file_name}/config"
|
|
13
|
+
m.template "routes.rb", "vendor/plugins/#{file_name}/config/routes.rb"
|
|
14
|
+
map_route_from_plugin(m)
|
|
15
|
+
|
|
16
|
+
m.directory "vendor/plugins/#{file_name}/db"
|
|
17
|
+
m.directory "vendor/plugins/#{file_name}/db/migrate"
|
|
18
|
+
m.template "plugin_migration.rb", "vendor/plugins/#{file_name}/db/migrate/001_init_#{file_name}_plugin.rb"
|
|
19
|
+
|
|
20
|
+
m.directory "vendor/plugins/#{file_name}/lib"
|
|
21
|
+
|
|
22
|
+
m.directory "vendor/plugins/#{file_name}/spec"
|
|
23
|
+
m.directory "vendor/plugins/#{file_name}/spec/controllers"
|
|
24
|
+
m.directory "vendor/plugins/#{file_name}/spec/fixtures"
|
|
25
|
+
m.directory "vendor/plugins/#{file_name}/spec/models"
|
|
26
|
+
m.directory "vendor/plugins/#{file_name}/spec/views"
|
|
27
|
+
m.file "spec_helper.rb", "vendor/plugins/#{file_name}/spec/spec_helper.rb"
|
|
28
|
+
|
|
29
|
+
m.file "empty_file", "vendor/plugins/#{file_name}/init.rb"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def map_route_from_plugin(m)
|
|
34
|
+
logger.route "adding map.routes_from_plugin(:#{file_name}) to top of routes.rb"
|
|
35
|
+
sentinel = 'ActionController::Routing::Routes.draw do |map|'
|
|
36
|
+
m.gsub_file 'config/routes.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
|
|
37
|
+
"#{match}\n map.routes_from_plugin(:#{file_name})\n"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
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 @@
|
|
|
1
|
+
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
|
metadata
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
rubygems_version: 0.9.4
|
|
3
|
+
specification_version: 1
|
|
4
|
+
name: desert
|
|
5
|
+
version: !ruby/object:Gem::Version
|
|
6
|
+
version: 0.1.1
|
|
7
|
+
date: 2008-03-18 00:00:00 -07:00
|
|
8
|
+
summary: Desert is a component framework for Rails that allows your plugins to be packaged as mini Rails apps.
|
|
9
|
+
require_paths:
|
|
10
|
+
- lib
|
|
11
|
+
email: opensource@pivotallabs.com
|
|
12
|
+
homepage: http://pivotallabs.com
|
|
13
|
+
rubyforge_project: pivotalrb
|
|
14
|
+
description: Desert is a component framework for Rails that allows your plugins to be packaged as mini Rails apps.
|
|
15
|
+
autorequire: desert
|
|
16
|
+
default_executable:
|
|
17
|
+
bindir: bin
|
|
18
|
+
has_rdoc: true
|
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
20
|
+
requirements:
|
|
21
|
+
- - ">"
|
|
22
|
+
- !ruby/object:Gem::Version
|
|
23
|
+
version: 0.0.0
|
|
24
|
+
version:
|
|
25
|
+
platform: ruby
|
|
26
|
+
signing_key:
|
|
27
|
+
cert_chain:
|
|
28
|
+
post_install_message:
|
|
29
|
+
authors:
|
|
30
|
+
- Pivotal Labs
|
|
31
|
+
files:
|
|
32
|
+
- CHANGES
|
|
33
|
+
- MIT-LICENSE
|
|
34
|
+
- README
|
|
35
|
+
- Rakefile
|
|
36
|
+
- init.rb
|
|
37
|
+
- lib/desert.rb
|
|
38
|
+
- lib/generators/desert_plugin/templates/routes.rb
|
|
39
|
+
- lib/generators/desert_plugin/templates/spec_helper.rb
|
|
40
|
+
- lib/generators/desert_plugin/templates/plugin_migration.rb
|
|
41
|
+
- lib/generators/desert_plugin/desert_plugin_generator.rb
|
|
42
|
+
- lib/desert/plugin_templates/1.x/action_mailer.rb
|
|
43
|
+
- lib/desert/plugin_templates/action_view.rb
|
|
44
|
+
- lib/desert/plugin_templates/2.x/action_mailer.rb
|
|
45
|
+
- lib/desert/plugin_templates/action_controller.rb
|
|
46
|
+
- lib/desert/manager.rb
|
|
47
|
+
- lib/desert/rails/1.x/initializer.rb
|
|
48
|
+
- lib/desert/rails/migration.rb
|
|
49
|
+
- lib/desert/rails/migrator.rb
|
|
50
|
+
- lib/desert/rails/2.x/plugin.rb
|
|
51
|
+
- lib/desert/rails/route_set.rb
|
|
52
|
+
- lib/desert/rails/dependencies.rb
|
|
53
|
+
- lib/desert/version_checker.rb
|
|
54
|
+
- lib/desert/ruby/object.rb
|
|
55
|
+
- lib/desert/plugin_migrations/migrator.rb
|
|
56
|
+
- lib/desert/plugin_migrations/extensions/schema_statements.rb
|
|
57
|
+
- lib/desert/plugin.rb
|
|
58
|
+
- lib/generators/desert_plugin
|
|
59
|
+
- lib/generators/desert_plugin/templates
|
|
60
|
+
- lib/generators/desert_plugin/templates/empty_file
|
|
61
|
+
- lib/generators/desert_plugin/USAGE
|
|
62
|
+
test_files: []
|
|
63
|
+
|
|
64
|
+
rdoc_options:
|
|
65
|
+
- --main
|
|
66
|
+
- README
|
|
67
|
+
- --inline-source
|
|
68
|
+
- --line-numbers
|
|
69
|
+
extra_rdoc_files:
|
|
70
|
+
- README
|
|
71
|
+
- CHANGES
|
|
72
|
+
executables: []
|
|
73
|
+
|
|
74
|
+
extensions: []
|
|
75
|
+
|
|
76
|
+
requirements: []
|
|
77
|
+
|
|
78
|
+
dependencies: []
|
|
79
|
+
|