diff options
Diffstat (limited to 'railties/lib/rails')
17 files changed, 412 insertions, 1 deletions
diff --git a/railties/lib/rails/cli.rb b/railties/lib/rails/cli.rb index 1260772605..c8d70d8ffa 100644 --- a/railties/lib/rails/cli.rb +++ b/railties/lib/rails/cli.rb @@ -11,4 +11,9 @@ $:.unshift(railties_path) if File.directory?(railties_path) && !$:.include?(rail require 'rails/ruby_version_check' Signal.trap("INT") { puts; exit } -require 'rails/commands/application' +if ARGV.first == 'plugin' + ARGV.shift + require 'rails/commands/plugin_new' +else + require 'rails/commands/application' +end diff --git a/railties/lib/rails/commands/plugin_new.rb b/railties/lib/rails/commands/plugin_new.rb new file mode 100644 index 0000000000..00a7e30902 --- /dev/null +++ b/railties/lib/rails/commands/plugin_new.rb @@ -0,0 +1,16 @@ +require 'rails/version' +if %w(--version -v).include? ARGV.first + puts "Rails #{Rails::VERSION::STRING}" + exit(0) +end + +if ARGV.first != "new" + ARGV[0] = "--help" +else + ARGV.shift +end + +require 'rails/generators' +require 'rails/generators/rails/plugin_new/plugin_new_generator' + +Rails::Generators::PluginNewGenerator.start diff --git a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb new file mode 100644 index 0000000000..239115c07d --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb @@ -0,0 +1,225 @@ +require "rails/generators/rails/app/app_generator" + +module Rails + class PluginBuilder + def rakefile + template "Rakefile" + end + + def readme + copy_file "README.rdoc" + end + + def gemfile + template "Gemfile" + end + + def license + template "MIT-LICENSE" + end + + def gemspec + template "%name%.gemspec" + end + + def gitignore + copy_file "gitignore", ".gitignore" + end + + def lib + directory "lib" + end + + def test + directory "test" + end + + def test_dummy + invoke Rails::Generators::AppGenerator, + [ File.expand_path(dummy_path, destination_root) ] + end + + def test_dummy_config + store_application_definition! + template "rails/boot.rb", "#{dummy_path}/config/boot.rb", :force => true + template "rails/application.rb", "#{dummy_path}/config/application.rb", :force => true + end + + def test_dummy_clean + inside dummy_path do + remove_file ".gitignore" + remove_file "db/seeds.rb" + remove_file "doc" + remove_file "Gemfile" + remove_file "lib/tasks" + remove_file "public/images/rails.png" + remove_file "public/index.html" + remove_file "public/robots.txt" + remove_file "README" + remove_file "test" + remove_file "vendor" + end + end + + def script + directory "script" do |content| + "#{shebang}\n" + content + end + chmod "script", 0755, :verbose => false + end + end + + module Generators + class PluginNewGenerator < Base + attr_accessor :rails_template + + add_shebang_option! + + argument :plugin_path, :type => :string + + class_option :builder, :type => :string, :aliases => "-b", + :desc => "Path to a plugin builder (can be a filesystem path or URL)" + + class_option :skip_gemfile, :type => :boolean, :default => false, + :desc => "Don't create a Gemfile" + + class_option :skip_git, :type => :boolean, :aliases => "-G", :default => false, + :desc => "Skip Git ignores and keeps" + + class_option :help, :type => :boolean, :aliases => "-h", :group => :rails, + :desc => "Show this help message and quit" + + def self.say_step(message) + @step = (@step || 0) + 1 + class_eval <<-METHOD, __FILE__, __LINE__ + 1 + def step_#{@step} + #{"puts" if @step > 1} + say_status "STEP #{@step}", #{message.inspect} + end + METHOD + end + + def initialize(*args) + raise Error, "Options should be given after plugin name. For details run: rails plugin --help" if args[0].blank? + + @original_wd = Dir.pwd + + super + end + + say_step "Creating gem skeleton" + + def create_root + self.destination_root = File.expand_path(plugin_path, destination_root) + valid_plugin_const? + + empty_directory '.' + FileUtils.cd(destination_root) unless options[:pretend] + end + + def create_root_files + build(:readme) + build(:rakefile) + build(:gemspec) + build(:license) + build(:gitignore) unless options[:skip_git] + build(:gemfile) unless options[:skip_gemfile] + end + + def create_config_files + build(:config) + end + + def create_lib_files + build(:lib) + end + + def create_script_files + build(:script) + end + + def create_test_files + build(:test) unless options[:skip_test_unit] + end + + say_step "Vendoring Rails application at test/dummy" + + def create_test_dummy_files + build(:test_dummy) + end + + say_step "Configuring Rails application" + + def change_config_files + build(:test_dummy_config) + end + + say_step "Removing unneeded files" + + def remove_uneeded_rails_files + build(:test_dummy_clean) + end + + protected + + def self.banner + "rails plugin new #{self.arguments.map(&:usage).join(' ')} [options]" + end + + def builder + @builder ||= begin + if path = options[:builder] + if URI(path).is_a?(URI::HTTP) + contents = open(path, "Accept" => "application/x-thor-template") {|io| io.read } + else + contents = open(File.expand_path(path, @original_wd)) {|io| io.read } + end + + prok = eval("proc { #{contents} }", TOPLEVEL_BINDING, path, 1) + instance_eval(&prok) + end + + builder_class = defined?(::PluginBuilder) ? ::PluginBuilder : Rails::PluginBuilder + builder_class.send(:include, ActionMethods) + builder_class.new(self) + end + end + + def build(meth, *args) + builder.send(meth, *args) if builder.respond_to?(meth) + end + + def name + @name ||= File.basename(destination_root) + end + + def camelized + @camelized ||= name.gsub(/\W/, '_').squeeze('_').camelize + end + + def valid_plugin_const? + if camelized =~ /^\d/ + raise Error, "Invalid plugin name #{name}. Please give a name which does not start with numbers." + elsif RESERVED_NAMES.include?(name) + raise Error, "Invalid plugin name #{name}. Please give a name which does not match one of the reserved rails words." + elsif Object.const_defined?(camelized) + raise Error, "Invalid plugin name #{name}, constant #{camelized} is already in use. Please choose another application name." + end + end + + def dummy_path + "test/dummy" + end + + def application_definition + @application_definition ||= begin + unless options[:pretend] + contents = File.read(File.expand_path("#{dummy_path}/config/application.rb", destination_root)) + contents[(contents.index("module Dummy"))..-1] + end + end + end + alias :store_application_definition! :application_definition + end + end +end diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec b/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec new file mode 100644 index 0000000000..3d9bfb22c7 --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec @@ -0,0 +1,9 @@ +# Provide a simple gemspec so you can easily use your +# project in your rails apps through git. +Gem::Specification.new do |s| + s.name = "<%= name %>" + s.summary = "Insert <%= camelized %> summary." + s.description = "Insert <%= camelized %> description." + s.files = Dir["lib/**/*"] + ["MIT-LICENSE", "Rakefile", "README.rdoc"] + s.version = "0.0.1" +end diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile new file mode 100644 index 0000000000..83ff86bbd8 --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile @@ -0,0 +1,11 @@ +source "http://rubygems.org" + +gem "rails", :git => "http://github.com/rails/rails.git" +gem "arel" , :git => "http://github.com/rails/arel.git" +gem "rack" , :git => "http://github.com/rack/rack.git" +gem "capybara", ">= 0.3.9" +gem "sqlite3-ruby", :require => "sqlite3" + +if RUBY_VERSION < '1.9' + gem "ruby-debug", ">= 0.10.3" +end diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE b/railties/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE new file mode 100644 index 0000000000..d7a9109894 --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright <%= Date.today.year %> YOURNAME + +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. diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/README.rdoc b/railties/lib/rails/generators/rails/plugin_new/templates/README.rdoc new file mode 100644 index 0000000000..301d647731 --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin_new/templates/README.rdoc @@ -0,0 +1,3 @@ += <%= camelized %> + +This project rocks and uses MIT-LICENSE.
\ No newline at end of file diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile b/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile new file mode 100644 index 0000000000..c0e6185ddc --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile @@ -0,0 +1,46 @@ +# encoding: UTF-8 +require 'rubygems' +begin + require 'bundler/setup' +rescue LoadError + puts 'You must `gem install bundler` and `bundle install` to run rake tasks' +end + +require 'rake' +require 'rake/rdoctask' +require 'rake/gempackagetask' + +require 'rake/testtask' + +Rake::TestTask.new(:test) do |t| + t.libs << 'lib' + t.libs << 'test' + t.pattern = 'test/**/*_test.rb' + t.verbose = false +end + +task :default => :test + +Rake::RDocTask.new(:rdoc) do |rdoc| + rdoc.rdoc_dir = 'rdoc' + rdoc.title = '<%= camelized %>' + rdoc.options << '--line-numbers' << '--inline-source' + rdoc.rdoc_files.include('README.rdoc') + rdoc.rdoc_files.include('lib/**/*.rb') +end + +spec = Gem::Specification.new do |s| + s.name = "<%= name %>" + s.summary = "Insert <%= camelized %> summary." + s.description = "Insert <%= camelized %> description." + s.files = FileList["[A-Z]*", "lib/**/*"] + s.version = "0.0.1" +end + +Rake::GemPackageTask.new(spec) do |pkg| +end + +desc "Install the gem #{spec.name}-#{spec.version}.gem" +task :install do + system("gem install pkg/#{spec.name}-#{spec.version}.gem --no-ri --no-rdoc") +end diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/gitignore b/railties/lib/rails/generators/rails/plugin_new/templates/gitignore new file mode 100644 index 0000000000..1463de6dfb --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin_new/templates/gitignore @@ -0,0 +1,6 @@ +.bundle/ +log/*.log +pkg/ +test/dummy/db/*.sqlite3 +test/dummy/log/*.log +test/dummy/tmp/
\ No newline at end of file diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb.tt b/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb.tt new file mode 100644 index 0000000000..cf77a0b4d3 --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb.tt @@ -0,0 +1,2 @@ +module <%= camelized %> +end diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb b/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb new file mode 100644 index 0000000000..fee63ea83e --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb @@ -0,0 +1,12 @@ +require File.expand_path('../boot', __FILE__) + +require "active_model/railtie" +require "active_record/railtie" +require "action_controller/railtie" +require "action_view/railtie" +require "action_mailer/railtie" + +Bundler.require +require "<%= name %>" + +<%= application_definition %> diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb b/railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb new file mode 100644 index 0000000000..eba0681370 --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb @@ -0,0 +1,10 @@ +require 'rubygems' +gemfile = File.expand_path('../../../../Gemfile', __FILE__) + +if File.exist?(gemfile) + ENV['BUNDLE_GEMFILE'] = gemfile + require 'bundler' + Bundler.setup +end + +$:.unshift File.expand_path('../../../../lib', __FILE__)
\ No newline at end of file diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt b/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt new file mode 100644 index 0000000000..cd4f7f6ab3 --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt @@ -0,0 +1,5 @@ +#!/usr/bin/env ruby +# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. + +ENGINE_PATH = File.expand_path('../..', __FILE__) +load File.expand_path('../../test/dummy/script/rails', __FILE__) diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb.tt b/railties/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb.tt new file mode 100644 index 0000000000..0a8bbd4aaf --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb.tt @@ -0,0 +1,7 @@ +require 'test_helper' + +class <%= camelized %>Test < ActiveSupport::TestCase + test "truth" do + assert_kind_of Module, <%= camelized %> + end +end diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb.tt b/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb.tt new file mode 100644 index 0000000000..42721899c8 --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb.tt @@ -0,0 +1,7 @@ +require 'test_helper' + +class NagivationTest < ActiveSupport::IntegrationCase + test "truth" do + assert_kind_of Dummy::Application, Rails.application + end +end diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/support/integration_case.rb b/railties/lib/rails/generators/rails/plugin_new/templates/test/support/integration_case.rb new file mode 100644 index 0000000000..4cfe3f0e71 --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin_new/templates/test/support/integration_case.rb @@ -0,0 +1,5 @@ +# Define a bare test case to use with Capybara +class ActiveSupport::IntegrationCase < ActiveSupport::TestCase + include Capybara + include Rails.application.routes.url_helpers +end
\ No newline at end of file diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb new file mode 100644 index 0000000000..5c39780a23 --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb @@ -0,0 +1,22 @@ +# Configure Rails Envinronment +ENV["RAILS_ENV"] = "test" + +require File.expand_path("../dummy/config/environment.rb", __FILE__) +require "rails/test_help" + +ActionMailer::Base.delivery_method = :test +ActionMailer::Base.perform_deliveries = true +ActionMailer::Base.default_url_options[:host] = "test.com" + +Rails.backtrace_cleaner.remove_silencers! + +# Configure capybara for integration testing +require "capybara/rails" +Capybara.default_driver = :rack_test +Capybara.default_selector = :css + +# Run any available migration +ActiveRecord::Migrator.migrate File.expand_path("../dummy/db/migrate/", __FILE__) + +# Load support files +Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
\ No newline at end of file |