Permalink
Browse files

Move to github.

  • Loading branch information...
0 parents commit 44e228d9433dfe01da05b21e3d3084e56e094355 @rubidine committed Aug 9, 2008
@@ -0,0 +1,20 @@
+Copyright (c) 2008 Todd Willey <todd@rubidine.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,13 @@
+AppExtensionGenerator
+====================
+
+Generate plugins that add models/controllers/migrations/tests/assets into an
+existing application.
+
+Unlike engines / appable plugins / &c., these plugins don't require on any other
+plugins, not even AppExtensionGenerator.
+
+usage
+ruby script/generate app_extension my_extension
+
+Then look in the README and init.rb in your new extension.
@@ -0,0 +1,10 @@
+Description:
+ Will generate a plugin that can add routes and controllers/models/helpers
+ into the main rails app. Akin to engines and appable_plugins, but the
+ results are self-contained.
+
+Example:
+ ./script/generate app_extension Thing
+
+ This will create:
+ vendor/plugins/thing/*
@@ -0,0 +1,60 @@
+# Copyright (c) 2008 Todd Willey <todd@rubidine.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+class AppExtensionGenerator < PluginGenerator
+
+ def manifest_with_app_ext
+ manifest_without_app_ext
+ record do |m|
+ m.directory "#{plugin_path}/public"
+ m.directory "#{plugin_path}/public/images"
+ m.directory "#{plugin_path}/public/javascripts"
+ m.directory "#{plugin_path}/public/stylesheets"
+
+ m.directory "#{plugin_path}/ext_lib"
+
+ m.directory "#{plugin_path}/db"
+ m.directory "#{plugin_path}/db/migrate"
+
+ m.directory "#{plugin_path}/app"
+ m.directory "#{plugin_path}/app/models"
+ m.directory "#{plugin_path}/app/views"
+ m.directory "#{plugin_path}/app/controllers"
+ m.directory "#{plugin_path}/app/helpers"
+
+ m.template 'plugin_migrator.rb', "#{plugin_path}/ext_lib/plugin_migrator.rb"
+ m.template 'ext_init.rb', "#{plugin_path}/ext_lib/init.rb"
+ m.template 'dependency_extension.rb', "#{plugin_path}/ext_lib/#{file_name}_dependency_extension.rb"
+ m.template 'routing_extension.rb', "#{plugin_path}/ext_lib/#{file_name}_routing_extension.rb"
+ end
+ end
+
+ alias_method_chain :manifest, :app_ext
+
+ private
+
+ # overwrite this so we don't have to copy in the old manifest function body
+ def record
+ @manifest ||= Rails::Generator::Manifest.new(self)
+ yield @manifest
+ @manifest
+ end
+end
@@ -0,0 +1,20 @@
+Copyright (c) <%= Date.today.year %> [name of plugin creator]
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,16 @@
+<%= class_name %>
+<%= "=" * class_name.size %>
+
+To finish writing your plugin, write just like you would for a normal application.
+
+app/{controllers,helpers,models,views}
+db/migrate/
+test/*_test.rb (ok, not quite like a normal app)
+
+public/* are copied into the main app public/<%= file_name %>/* directories.
+
+Routes are defined in the init.rb file, but look very similar to config/routes.rb
+
+View paths on controllers are set automatically to include the views in this directory, but you will need to manually specify 'template_root' in any mailers.
+
+From your main app: rake <%= file_name %>:{migrate,test}
@@ -0,0 +1,22 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the <%= file_name %> plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+desc 'Generate documentation for the <%= file_name %> plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = '<%= class_name %>'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
@@ -0,0 +1,8 @@
+Description:
+ Explain the generator
+
+Example:
+ ./script/generate <%= file_name %> Thing
+
+ This will create:
+ what/will/it/create
@@ -0,0 +1,18 @@
+module <%= class_name %>DependencyExtension
+
+ def self.extended kls
+ kls.class_eval do
+ def register_<%= file_name %>_extension &blk
+ if blk
+ ActionController::Dispatcher.to_prepare &blk
+
+ # ActionController::Dispatcher.new($stdout).prepare_application(true)
+ # is called on reset! in script/console, but is not prepared
+ # when the application is loaded for some reason, so do it manually
+ blk.call if caller.last =~ /irb/
+ end
+ end
+ end
+ end
+
+end
@@ -0,0 +1,52 @@
+# load Dispatcher if not present yet
+unless defined?(ActionController) and defined?(ActionController::Dispatcher)
+ require 'action_controller/dispatcher'
+end
+
+# Routing Extension
+require File.join(File.dirname(__FILE__), '<%= file_name %>_routing_extension')
+ActionController::Routing::RouteSet.send :include, <%= class_name %>RoutingExtension
+
+# Dependency reload mechanism
+require File.join(File.dirname(__FILE__), '<%= file_name %>_dependency_extension')
+Dependencies.extend <%= class_name %>DependencyExtension
+
+# Load paths go after rails app's own lib/, before previously loaded plugins
+ali = $LOAD_PATH.index(File.join(RAILS_ROOT, 'lib')) || 0
+paths = [
+ File.join(File.dirname(__FILE__), '..', 'app', 'controllers'),
+ File.join(File.dirname(__FILE__), '..', 'app', 'helpers'),
+ File.join(File.dirname(__FILE__), '..', 'app', 'models'),
+ File.join(File.dirname(__FILE__), '..', 'lib')
+]
+paths.each do |p|
+ $LOAD_PATH.insert(ali + 1, p)
+ Dependencies.load_paths << p
+end
+
+# Views will also look here in the plugin.
+# We use prepend_* to put this directory as a high priority, ahead of any previously loaded plugins.
+# That way if you are following another plugin, but providing specific overrides they can take effect.
+# If you want these to be lower priority, use append_ instead of prepend_.
+#
+# Google "Evil Twin Plugin" on errtheblog for more info.
+ActionController::Base.prepend_view_path File.join(File.dirname(__FILE__), '..', 'app', 'views')
+
+# copy in assets
+if File.directory?(File.join(File.dirname(__FILE__), '..', 'public'))
+ require 'fileutils'
+ ['javascripts', 'stylesheets', 'images'].each do |type|
+ r_path = File.join(RAILS_ROOT, 'public', type, '<%= file_name %>')
+ p_path = File.join(File.dirname(__FILE__), '..', 'public', type)
+ unless File.directory?(r_path)
+ FileUtils.mkdir_p(r_path)
+ end
+ Dir["#{p_path}/*"].each do |asset|
+ unless File.exist?(File.join(r_path, File.basename(asset)))
+ FileUtils.cp_r(asset, r_path)
+ end
+ end
+ end
+end
+
+
@@ -0,0 +1,8 @@
+class <%= class_name %>Generator < Rails::Generator::NamedBase
+ def manifest
+ record do |m|
+ # m.directory "lib"
+ # m.template 'README', "README"
+ end
+ end
+end
@@ -0,0 +1,44 @@
+# 'directory' is defined in rails plugin loading, and since we are eval'd
+# instead of required, we get it here. But radiant seems to require or load
+# instead of eval, so work with it. Also it can be defined as a function during
+# migrations for some reason.
+unless defined?(directory) == 'local-variable'
+ directory = File.dirname(__FILE__)
+end
+
+# Load the extension mojo that hacks into the rails base classes.
+require File.join(directory, 'ext_lib', 'init.rb')
+
+# define some routes
+#
+# ActionController::Routing::Routes.define_<%= file_name %>_routes do |map|
+# map.connect '<%= file_name %>/:action/:id', :controller=>'<%= file_name %>'
+# end
+
+# Monkey patch into the core classes.
+#
+# There are two ways to do this, if you are patching into a core class
+# like ActiveRecord::Base then you can include a class defined by a file
+# in this plugin's lib directory
+#
+# ActiveRecord::Base.send :include, MyClassInLibDirectory
+#
+# If you are patching a class in the current application, such as a specific
+# model that will get reloaded by the dependencies mechanism (in development
+# mode) you will need your extension to be reloaded each time the application
+# is reset, so use the hook we provide for you.
+#
+Dependencies.register_<%= file_name %>_extension do
+ # to add relationships, validations, etc
+ # SomeModel.send :has_many, :my_model
+
+ # to add new methods to instances of a class
+ # define a module in lib/extensions/some_model_<%= file_name %>_extension
+ # SomeModel.send :include, SomeModel<%= class_name %>Extension
+ # SomeModel.new.my_mixed_in_method
+
+ # to add new class methods
+ # define a module in lib/extensions/some_model_<%= file_name %>_class_extension
+ # SomeModel.send :extend, SomeModel<%= class_name %>ClassExtension
+ # SomeModel.my_mixed_in_method
+end
@@ -0,0 +1 @@
+puts IO.read(File.join(File.dirname(__FILE__), 'README'))
@@ -0,0 +1 @@
+# <%= class_name %>
@@ -0,0 +1,54 @@
+module ActiveRecord
+ class PluginMigrator < Migrator
+
+ def initialize(direction, migrations_path, target_version = nil)
+ raise StandardError.new("This database does not yet support migrations") unless Base.connection.supports_migrations?
+ Base.connection.initialize_schema_migrations_table(ActiveRecord::PluginMigrator)
+ @direction, @migrations_path, @target_version = direction, migrations_path, target_version
+ end
+
+ def self.schema_migrations_table_name
+ 'plugin_schema_migrations_<%= file_name %>'
+ end
+ end
+end
+
+module ActiveRecord
+ module ConnectionAdapters
+ module SchemaStatements
+
+ def initialize_schema_migrations_table migrator=ActiveRecord::Migrator
+ sm = migrator.schema_migrations_table_name
+
+ unless tables.detect{|t| t == sm}
+ create_table(sm, :id => false) do |t|
+ t.column :version, :string, :null => false
+ end
+ add_index sm, :version, :unique => true, :name => 'unique_schema_migrations_<%= file_name %>'
+
+ # find old style migrations table and bring it up to date!
+ si = sm.gsub(/schema_migrations/, 'schema')
+ if tables.detect{|t| t == si}
+ old_version = select_value("SELECT version FROM #{quote_table_name(si)}")
+ assume_migrated_upto_version(old_version, sm)
+ drop_table(si)
+ end
+ end
+ end
+
+ def assume_migrated_upto_version(version, migration_table)
+ migrated = select_values("SEELCT version FROM #{migration_table}")
+ migrated.map!{|x| x.to_i}
+ vv = Dir["#{File.dirname(__FILE__)}/../db/migrate/[0-9]*_*.rb"].map do |f|
+ f.split('/').last.split('_').first.to_i
+ end
+ execute "INSERT INTO #{migration_table} (version) VALUES ('#{version}')" unless migrated.include?(version.to_i)
+ (vv - migrated).select{|x| x < version.to_i}.each do |v|
+ execute "INSERT INTO #{migration_table} (version) VALUES ('#{v}')"
+ end
+ end
+
+ end
+ end
+end
+
@@ -0,0 +1,21 @@
+module <%= class_name %>RoutingExtension
+
+ def draw_with_<%= file_name %>
+ draw_without_<%= file_name %> do |map|
+ if @<%= file_name %>_route_block
+ @<%= file_name %>_route_block.call(map)
+ end
+ yield map
+ end
+ end
+
+ def define_<%= file_name %>_routes &blk
+ @<%= file_name %>_route_block = blk
+ end
+
+ public
+ def self.included(base)
+ base.send :alias_method_chain, :draw, :<%= file_name %>
+ end
+
+end
Oops, something went wrong.

0 comments on commit 44e228d

Please sign in to comment.