diff options
author | francis <francis> | 2008-01-23 01:48:14 +0000 |
---|---|---|
committer | francis <francis> | 2008-01-23 01:48:14 +0000 |
commit | 60eaae4f7df1f1dae91defb87d3707451c359cf4 (patch) | |
tree | e74835c37779a2f094e810960cda07b99a75330e /vendor/rails-2.0.2/railties/lib | |
parent | 71d22c740302e1f83bbbd89b229734ea9c67493c (diff) |
Freeze in rails 2.0.2 (Am I going to regret having this beast in CVS?)
Diffstat (limited to 'vendor/rails-2.0.2/railties/lib')
128 files changed, 7680 insertions, 0 deletions
diff --git a/vendor/rails-2.0.2/railties/lib/code_statistics.rb b/vendor/rails-2.0.2/railties/lib/code_statistics.rb new file mode 100644 index 000000000..740d8a176 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/code_statistics.rb @@ -0,0 +1,107 @@ +class CodeStatistics #:nodoc: + + TEST_TYPES = %w(Units Functionals Unit\ tests Functional\ tests Integration\ tests) + + def initialize(*pairs) + @pairs = pairs + @statistics = calculate_statistics + @total = calculate_total if pairs.length > 1 + end + + def to_s + print_header + @pairs.each { |pair| print_line(pair.first, @statistics[pair.first]) } + print_splitter + + if @total + print_line("Total", @total) + print_splitter + end + + print_code_test_stats + end + + private + def calculate_statistics + @pairs.inject({}) { |stats, pair| stats[pair.first] = calculate_directory_statistics(pair.last); stats } + end + + def calculate_directory_statistics(directory, pattern = /.*\.rb$/) + stats = { "lines" => 0, "codelines" => 0, "classes" => 0, "methods" => 0 } + + Dir.foreach(directory) do |file_name| + if File.stat(directory + "/" + file_name).directory? and (/^\./ !~ file_name) + newstats = calculate_directory_statistics(directory + "/" + file_name, pattern) + stats.each { |k, v| stats[k] += newstats[k] } + end + + next unless file_name =~ pattern + + f = File.open(directory + "/" + file_name) + + while line = f.gets + stats["lines"] += 1 + stats["classes"] += 1 if line =~ /class [A-Z]/ + stats["methods"] += 1 if line =~ /def [a-z]/ + stats["codelines"] += 1 unless line =~ /^\s*$/ || line =~ /^\s*#/ + end + end + + stats + end + + def calculate_total + total = { "lines" => 0, "codelines" => 0, "classes" => 0, "methods" => 0 } + @statistics.each_value { |pair| pair.each { |k, v| total[k] += v } } + total + end + + def calculate_code + code_loc = 0 + @statistics.each { |k, v| code_loc += v['codelines'] unless TEST_TYPES.include? k } + code_loc + end + + def calculate_tests + test_loc = 0 + @statistics.each { |k, v| test_loc += v['codelines'] if TEST_TYPES.include? k } + test_loc + end + + def print_header + print_splitter + puts "| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |" + print_splitter + end + + def print_splitter + puts "+----------------------+-------+-------+---------+---------+-----+-------+" + end + + def print_line(name, statistics) + m_over_c = (statistics["methods"] / statistics["classes"]) rescue m_over_c = 0 + loc_over_m = (statistics["codelines"] / statistics["methods"]) - 2 rescue loc_over_m = 0 + + start = if TEST_TYPES.include? name + "| #{name.ljust(20)} " + else + "| #{name.ljust(20)} " + end + + puts start + + "| #{statistics["lines"].to_s.rjust(5)} " + + "| #{statistics["codelines"].to_s.rjust(5)} " + + "| #{statistics["classes"].to_s.rjust(7)} " + + "| #{statistics["methods"].to_s.rjust(7)} " + + "| #{m_over_c.to_s.rjust(3)} " + + "| #{loc_over_m.to_s.rjust(5)} |" + end + + def print_code_test_stats + code = calculate_code + tests = calculate_tests + + puts " Code LOC: #{code} Test LOC: #{tests} Code to Test Ratio: 1:#{sprintf("%.1f", tests.to_f/code)}" + puts "" + end + end diff --git a/vendor/rails-2.0.2/railties/lib/commands.rb b/vendor/rails-2.0.2/railties/lib/commands.rb new file mode 100644 index 000000000..841e98a0d --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands.rb @@ -0,0 +1,17 @@ +commands = Dir["#{File.dirname(__FILE__)}/commands/*.rb"].collect { |file_path| File.basename(file_path).split(".").first } + +if commands.include?(ARGV.first) + require "#{File.dirname(__FILE__)}/commands/#{ARGV.shift}" +else + puts <<-USAGE +The 'run' provides a unified access point for all the default Rails' commands. + +Usage: ./script/run <command> [OPTIONS] + +Examples: + ./script/run generate controller Admin + ./script/run process reaper + +USAGE + puts "Choose: #{commands.join(", ")}" +end
\ No newline at end of file diff --git a/vendor/rails-2.0.2/railties/lib/commands/about.rb b/vendor/rails-2.0.2/railties/lib/commands/about.rb new file mode 100644 index 000000000..313bc18c6 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/about.rb @@ -0,0 +1,2 @@ +require 'environment' +puts Rails::Info diff --git a/vendor/rails-2.0.2/railties/lib/commands/console.rb b/vendor/rails-2.0.2/railties/lib/commands/console.rb new file mode 100644 index 000000000..edb135ff4 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/console.rb @@ -0,0 +1,32 @@ +irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb' + +require 'optparse' +options = { :sandbox => false, :irb => irb } +OptionParser.new do |opt| + opt.banner = "Usage: console [environment] [options]" + opt.on('-s', '--sandbox', 'Rollback database modifications on exit.') { |v| options[:sandbox] = v } + opt.on("--irb=[#{irb}]", 'Invoke a different irb.') { |v| options[:irb] = v } + opt.parse!(ARGV) +end + +libs = " -r irb/completion" +libs << %( -r "#{RAILS_ROOT}/config/environment") +libs << " -r console_app" +libs << " -r console_sandbox" if options[:sandbox] +libs << " -r console_with_helpers" + +ENV['RAILS_ENV'] = case ARGV.first + when "p": "production" + when "d": "development" + when "t": "test" + else + ARGV.first || ENV['RAILS_ENV'] || 'development' +end + +if options[:sandbox] + puts "Loading #{ENV['RAILS_ENV']} environment in sandbox (Rails #{Rails::VERSION::STRING})" + puts "Any modifications you make will be rolled back on exit" +else + puts "Loading #{ENV['RAILS_ENV']} environment (Rails #{Rails::VERSION::STRING})" +end +exec "#{options[:irb]} #{libs} --simple-prompt" diff --git a/vendor/rails-2.0.2/railties/lib/commands/destroy.rb b/vendor/rails-2.0.2/railties/lib/commands/destroy.rb new file mode 100644 index 000000000..f4b81d651 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/destroy.rb @@ -0,0 +1,6 @@ +require "#{RAILS_ROOT}/config/environment" +require 'rails_generator' +require 'rails_generator/scripts/destroy' + +ARGV.shift if ['--help', '-h'].include?(ARGV[0]) +Rails::Generator::Scripts::Destroy.new.run(ARGV) diff --git a/vendor/rails-2.0.2/railties/lib/commands/generate.rb b/vendor/rails-2.0.2/railties/lib/commands/generate.rb new file mode 100755 index 000000000..3d3db3d85 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/generate.rb @@ -0,0 +1,6 @@ +require "#{RAILS_ROOT}/config/environment" +require 'rails_generator' +require 'rails_generator/scripts/generate' + +ARGV.shift if ['--help', '-h'].include?(ARGV[0]) +Rails::Generator::Scripts::Generate.new.run(ARGV) diff --git a/vendor/rails-2.0.2/railties/lib/commands/ncgi/listener b/vendor/rails-2.0.2/railties/lib/commands/ncgi/listener new file mode 100644 index 000000000..421c453f2 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/ncgi/listener @@ -0,0 +1,86 @@ +#!/usr/local/bin/ruby + +require 'stringio' +require 'fileutils' +require 'fcgi_handler' + +def message(s) + $stderr.puts "listener: #{s}" if ENV && ENV["DEBUG_GATEWAY"] +end + +class RemoteCGI < CGI + attr_accessor :stdinput, :stdoutput, :env_table + def initialize(env_table, input = nil, output = nil) + self.env_table = env_table + self.stdinput = input || StringIO.new + self.stdoutput = output || StringIO.new + super() + end + + def out(stream) # Ignore the requested output stream + super(stdoutput) + end +end + +class Listener + include DRbUndumped + + def initialize(timeout, socket_path) + @socket = File.expand_path(socket_path) + @mutex = Mutex.new + @active = false + @timeout = timeout + + @handler = RailsFCGIHandler.new + @handler.extend DRbUndumped + + message 'opening socket' + DRb.start_service("drbunix:#{@socket}", self) + + message 'entering process loop' + @handler.process! self + end + + def each_cgi(&cgi_block) + @cgi_block = cgi_block + message 'entering idle loop' + loop do + sleep @timeout rescue nil + die! unless @active + @active = false + end + end + + def process(env, input) + message 'received request' + @mutex.synchronize do + @active = true + + message 'creating input stream' + input_stream = StringIO.new(input) + message 'building CGI instance' + cgi = RemoteCGI.new(eval(env), input_stream) + + message 'yielding to fcgi handler' + @cgi_block.call cgi + message 'yield finished -- sending output' + + cgi.stdoutput.seek(0) + output = cgi.stdoutput.read + + return output + end + end + + def die! + message 'shutting down' + DRb.stop_service + FileUtils.rm_f @socket + Kernel.exit 0 + end +end + +socket_path = ARGV.shift +timeout = (ARGV.shift || 90).to_i + +Listener.new(timeout, socket_path)
\ No newline at end of file diff --git a/vendor/rails-2.0.2/railties/lib/commands/ncgi/tracker b/vendor/rails-2.0.2/railties/lib/commands/ncgi/tracker new file mode 100644 index 000000000..859c9fa0e --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/ncgi/tracker @@ -0,0 +1,69 @@ +#!/usr/local/bin/ruby + +require 'drb' +require 'thread' + +def message(s) + $stderr.puts "tracker: #{s}" if ENV && ENV["DEBUG_GATEWAY"] +end + +class Tracker + include DRbUndumped + + def initialize(instances, socket_path) + @instances = instances + @socket = File.expand_path(socket_path) + @active = false + + @listeners = [] + @instances.times { @listeners << Mutex.new } + + message "using #{@listeners.length} listeners" + message "opening socket at #{@socket}" + + @service = DRb.start_service("drbunix://#{@socket}", self) + end + + def with_listener + message "listener requested" + + mutex = has_lock = index = nil + 3.times do + @listeners.each_with_index do |mutex, index| + has_lock = mutex.try_lock + break if has_lock + end + break if has_lock + sleep 0.05 + end + + if has_lock + message "obtained listener #{index}" + @active = true + begin yield index + ensure + mutex.unlock + message "released listener #{index}" + end + else + message "dropping request because no listeners are available!" + end + end + + def background(check_interval = nil) + if check_interval + loop do + sleep check_interval + message "Idle for #{check_interval}, shutting down" unless @active + @active = false + Kernel.exit 0 + end + else DRb.thread.join + end + end +end + +socket_path = ARGV.shift +instances = ARGV.shift.to_i +t = Tracker.new(instances, socket_path) +t.background(ARGV.first ? ARGV.shift.to_i : 90)
\ No newline at end of file diff --git a/vendor/rails-2.0.2/railties/lib/commands/performance/benchmarker.rb b/vendor/rails-2.0.2/railties/lib/commands/performance/benchmarker.rb new file mode 100644 index 000000000..e8804fe1b --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/performance/benchmarker.rb @@ -0,0 +1,24 @@ +if ARGV.empty? + puts "Usage: ./script/performance/benchmarker [times] 'Person.expensive_way' 'Person.another_expensive_way' ..." + exit 1 +end + +begin + N = Integer(ARGV.first) + ARGV.shift +rescue ArgumentError + N = 1 +end + +require RAILS_ROOT + '/config/environment' +require 'benchmark' +include Benchmark + +# Don't include compilation in the benchmark +ARGV.each { |expression| eval(expression) } + +bm(6) do |x| + ARGV.each_with_index do |expression, idx| + x.report("##{idx + 1}") { N.times { eval(expression) } } + end +end diff --git a/vendor/rails-2.0.2/railties/lib/commands/performance/profiler.rb b/vendor/rails-2.0.2/railties/lib/commands/performance/profiler.rb new file mode 100644 index 000000000..464cea344 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/performance/profiler.rb @@ -0,0 +1,50 @@ +if ARGV.empty? + $stderr.puts "Usage: ./script/performance/profiler 'Person.expensive_method(10)' [times] [flat|graph|graph_html]" + exit(1) +end + +# Keep the expensive require out of the profile. +$stderr.puts 'Loading Rails...' +require RAILS_ROOT + '/config/environment' + +# Define a method to profile. +if ARGV[1] and ARGV[1].to_i > 1 + eval "def profile_me() #{ARGV[1]}.times { #{ARGV[0]} } end" +else + eval "def profile_me() #{ARGV[0]} end" +end + +# Use the ruby-prof extension if available. Fall back to stdlib profiler. +begin + begin + require "ruby-prof" + $stderr.puts 'Using the ruby-prof extension.' + RubyProf.clock_mode = RubyProf::WALL_TIME + RubyProf.start + profile_me + results = RubyProf.stop + if ARGV[2] + printer_class = RubyProf.const_get((ARGV[2] + "_printer").classify) + else + printer_class = RubyProf::FlatPrinter + end + printer = printer_class.new(results) + printer.print($stderr, 0) + rescue LoadError + require "prof" + $stderr.puts 'Using the old ruby-prof extension.' + Prof.clock_mode = Prof::GETTIMEOFDAY + Prof.start + profile_me + results = Prof.stop + require 'rubyprof_ext' + Prof.print_profile(results, $stderr) + end +rescue LoadError + require 'profiler' + $stderr.puts 'Using the standard Ruby profiler.' + Profiler__.start_profile + profile_me + Profiler__.stop_profile + Profiler__.print_profile($stderr) +end diff --git a/vendor/rails-2.0.2/railties/lib/commands/performance/request.rb b/vendor/rails-2.0.2/railties/lib/commands/performance/request.rb new file mode 100755 index 000000000..177388648 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/performance/request.rb @@ -0,0 +1,6 @@ +#!/usr/bin/env ruby +require 'config/environment' +require 'application' +require 'action_controller/request_profiler' + +ActionController::RequestProfiler.run(ARGV) diff --git a/vendor/rails-2.0.2/railties/lib/commands/plugin.rb b/vendor/rails-2.0.2/railties/lib/commands/plugin.rb new file mode 100644 index 000000000..a26f747df --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/plugin.rb @@ -0,0 +1,923 @@ +# Rails Plugin Manager. +# +# Listing available plugins: +# +# $ ./script/plugin list +# continuous_builder http://dev.rubyonrails.com/svn/rails/plugins/continuous_builder +# asset_timestamping http://svn.aviditybytes.com/rails/plugins/asset_timestamping +# enumerations_mixin http://svn.protocool.com/rails/plugins/enumerations_mixin/trunk +# calculations http://techno-weenie.net/svn/projects/calculations/ +# ... +# +# Installing plugins: +# +# $ ./script/plugin install continuous_builder asset_timestamping +# +# Finding Repositories: +# +# $ ./script/plugin discover +# +# Adding Repositories: +# +# $ ./script/plugin source http://svn.protocool.com/rails/plugins/ +# +# How it works: +# +# * Maintains a list of subversion repositories that are assumed to have +# a plugin directory structure. Manage them with the (source, unsource, +# and sources commands) +# +# * The discover command scrapes the following page for things that +# look like subversion repositories with plugins: +# http://wiki.rubyonrails.org/rails/pages/Plugins +# +# * Unless you specify that you want to use svn, script/plugin uses plain old +# HTTP for downloads. The following bullets are true if you specify +# that you want to use svn. +# +# * If `vendor/plugins` is under subversion control, the script will +# modify the svn:externals property and perform an update. You can +# use normal subversion commands to keep the plugins up to date. +# +# * Or, if `vendor/plugins` is not under subversion control, the +# plugin is pulled via `svn checkout` or `svn export` but looks +# exactly the same. +# +# This is Free Software, copyright 2005 by Ryan Tomayko (rtomayko@gmail.com) +# and is licensed MIT: (http://www.opensource.org/licenses/mit-license.php) + +$verbose = false + + +require 'open-uri' +require 'fileutils' +require 'tempfile' + +include FileUtils + +class RailsEnvironment + attr_reader :root + + def initialize(dir) + @root = dir + end + + def self.find(dir=nil) + dir ||= pwd + while dir.length > 1 + return new(dir) if File.exist?(File.join(dir, 'config', 'environment.rb')) + dir = File.dirname(dir) + end + end + + def self.default + @default ||= find + end + + def self.default=(rails_env) + @default = rails_env + end + + def install(name_uri_or_plugin) + if name_uri_or_plugin.is_a? String + if name_uri_or_plugin =~ /:\/\// + plugin = Plugin.new(name_uri_or_plugin) + else + plugin = Plugins[name_uri_or_plugin] + end + else + plugin = name_uri_or_plugin + end + unless plugin.nil? + plugin.install + else + puts "Plugin not found: #{name_uri_or_plugin}" + end + end + + def use_svn? + require 'active_support/core_ext/kernel' + silence_stderr {`svn --version` rescue nil} + !$?.nil? && $?.success? + end + + def use_externals? + use_svn? && File.directory?("#{root}/vendor/plugins/.svn") + end + + def use_checkout? + # this is a bit of a guess. we assume that if the rails environment + # is under subversion then they probably want the plugin checked out + # instead of exported. This can be overridden on the command line + File.directory?("#{root}/.svn") + end + + def best_install_method + return :http unless use_svn? + case + when use_externals? then :externals + when use_checkout? then :checkout + else :export + end + end + + def externals + return [] unless use_externals? + ext = `svn propget svn:externals "#{root}/vendor/plugins"` + ext.reject{ |line| line.strip == '' }.map do |line| + line.strip.split(/\s+/, 2) + end + end + + def externals=(items) + unless items.is_a? String + items = items.map{|name,uri| "#{name.ljust(29)} #{uri.chomp('/')}"}.join("\n") + end + Tempfile.open("svn-set-prop") do |file| + file.write(items) + file.flush + system("svn propset -q svn:externals -F \"#{file.path}\" \"#{root}/vendor/plugins\"") + end + end + +end + +class Plugin + attr_reader :name, :uri + + def initialize(uri, name=nil) + @uri = uri + guess_name(uri) + end + + def self.find(name) + name =~ /\// ? new(name) : Repositories.instance.find_plugin(name) + end + + def to_s + "#{@name.ljust(30)}#{@uri}" + end + + def svn_url? + @uri =~ /svn(?:\+ssh)?:\/\/*/ + end + + def installed? + File.directory?("#{rails_env.root}/vendor/plugins/#{name}") \ + or rails_env.externals.detect{ |name, repo| self.uri == repo } + end + + def install(method=nil, options = {}) + method ||= rails_env.best_install_method? + method = :export if method == :http and svn_url? + + uninstall if installed? and options[:force] + + unless installed? + send("install_using_#{method}", options) + run_install_hook + else + puts "already installed: #{name} (#{uri}). pass --force to reinstall" + end + end + + def uninstall + path = "#{rails_env.root}/vendor/plugins/#{name}" + if File.directory?(path) + puts "Removing 'vendor/plugins/#{name}'" if $verbose + run_uninstall_hook + rm_r path + else + puts "Plugin doesn't exist: #{path}" + end + # clean up svn:externals + externals = rails_env.externals + externals.reject!{|n,u| name == n or name == u} + rails_env.externals = externals + end + + def info + tmp = "#{rails_env.root}/_tmp_about.yml" + if svn_url? + cmd = "svn export #{@uri} \"#{rails_env.root}/#{tmp}\"" + puts cmd if $verbose + system(cmd) + end + open(svn_url? ? tmp : File.join(@uri, 'about.yml')) do |stream| + stream.read + end rescue "No about.yml found in #{uri}" + ensure + FileUtils.rm_rf tmp if svn_url? + end + + private + + def run_install_hook + install_hook_file = "#{rails_env.root}/vendor/plugins/#{name}/install.rb" + load install_hook_file if File.exist? install_hook_file + end + + def run_uninstall_hook + uninstall_hook_file = "#{rails_env.root}/vendor/plugins/#{name}/uninstall.rb" + load uninstall_hook_file if File.exist? uninstall_hook_file + end + + def install_using_export(options = {}) + svn_command :export, options + end + + def install_using_checkout(options = {}) + svn_command :checkout, options + end + + def install_using_externals(options = {}) + externals = rails_env.externals + externals.push([@name, uri]) + rails_env.externals = externals + install_using_checkout(options) + end + + def install_using_http(options = {}) + root = rails_env.root + mkdir_p "#{root}/vendor/plugins/#{@name}" + Dir.chdir "#{root}/vendor/plugins/#{@name}" do + puts "fetching from '#{uri}'" if $verbose + fetcher = RecursiveHTTPFetcher.new(uri, -1) + fetcher.quiet = true if options[:quiet] + fetcher.fetch + end + end + + def svn_command(cmd, options = {}) + root = rails_env.root + mkdir_p "#{root}/vendor/plugins" + base_cmd = "svn #{cmd} #{uri} \"#{root}/vendor/plugins/#{name}\"" + base_cmd += ' -q' if options[:quiet] and not $verbose + base_cmd += " -r #{options[:revision]}" if options[:revision] + puts base_cmd if $verbose + system(base_cmd) + end + + def guess_name(url) + @name = File.basename(url) + if @name == 'trunk' || @name.empty? + @name = File.basename(File.dirname(url)) + end + end + + def rails_env + @rails_env || RailsEnvironment.default + end +end + +class Repositories + include Enumerable + + def initialize(cache_file = File.join(find_home, ".rails-plugin-sources")) + @cache_file = File.expand_path(cache_file) + load! + end + + def each(&block) + @repositories.each(&block) + end + + def add(uri) + unless find{|repo| repo.uri == uri } + @repositories.push(Repository.new(uri)).last + end + end + + def remove(uri) + @repositories.reject!{|repo| repo.uri == uri} + end + + def exist?(uri) + @repositories.detect{|repo| repo.uri == uri } + end + + def all + @repositories + end + + def find_plugin(name) + @repositories.each do |repo| + repo.each do |plugin| + return plugin if plugin.name == name + end + end + return nil + end + + def load! + contents = File.exist?(@cache_file) ? File.read(@cache_file) : defaults + contents = defaults if contents.empty? + @repositories = contents.split(/\n/).reject do |line| + line =~ /^\s*#/ or line =~ /^\s*$/ + end.map { |source| Repository.new(source.strip) } + end + + def save + File.open(@cache_file, 'w') do |f| + each do |repo| + f.write(repo.uri) + f.write("\n") + end + end + end + + def defaults + <<-DEFAULTS + http://dev.rubyonrails.com/svn/rails/plugins/ + DEFAULTS + end + + def find_home + ['HOME', 'USERPROFILE'].each do |homekey| + return ENV[homekey] if ENV[homekey] + end + if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] + return "#{ENV['HOMEDRIVE']}:#{ENV['HOMEPATH']}" + end + begin + File.expand_path("~") + rescue StandardError => ex + if File::ALT_SEPARATOR + "C:/" + else + "/" + end + end + end + + def self.instance + @instance ||= Repositories.new + end + + def self.each(&block) + self.instance.each(&block) + end +end + +class Repository + include Enumerable + attr_reader :uri, :plugins + + def initialize(uri) + @uri = uri.chomp('/') << "/" + @plugins = nil + end + + def plugins + unless @plugins + if $verbose + puts "Discovering plugins in #{@uri}" + puts index + end + + @plugins = index.reject{ |line| line !~ /\/$/ } + @plugins.map! { |name| Plugin.new(File.join(@uri, name), name) } + end + + @plugins + end + + def each(&block) + plugins.each(&block) + end + + private + def index + @index ||= RecursiveHTTPFetcher.new(@uri).ls + end +end + + +# load default environment and parse arguments +require 'optparse' +module Commands + + class Plugin + attr_reader :environment, :script_name, :sources + def initialize + @environment = RailsEnvironment.default + @rails_root = RailsEnvironment.default.root + @script_name = File.basename($0) + @sources = [] + end + + def environment=(value) + @environment = value + RailsEnvironment.default = value + end + + def options + OptionParser.new do |o| + o.set_summary_indent(' ') + o.banner = "Usage: #{@script_name} [OPTIONS] command" + o.define_head "Rails plugin manager." + + o.separator "" + o.separator "GENERAL OPTIONS" + + o.on("-r", "--root=DIR", String, + "Set an explicit rails app directory.", + "Default: #{@rails_root}") { |@rails_root| self.environment = RailsEnvironment.new(@rails_root) } + o.on("-s", "--source=URL1,URL2", Array, + "Use the specified plugin repositories instead of the defaults.") { |@sources|} + + o.on("-v", "--verbose", "Turn on verbose output.") { |$verbose| } + o.on("-h", "--help", "Show this help message.") { puts o; exit } + + o.separator "" + o.separator "COMMANDS" + + o.separator " discover Discover plugin repositories." + o.separator " list List available plugins." + o.separator " install Install plugin(s) from known repositories or URLs." + o.separator " update Update installed plugins." + o.separator " remove Uninstall plugins." + o.separator " source Add a plugin source repository." + o.separator " unsource Remove a plugin repository." + o.separator " sources List currently configured plugin repositories." + + o.separator "" + o.separator "EXAMPLES" + o.separator " Install a plugin:" + o.separator " #{@script_name} install continuous_builder\n" + o.separator " Install a plugin from a subversion URL:" + o.separator " #{@script_name} install http://dev.rubyonrails.com/svn/rails/plugins/continuous_builder\n" + o.separator " Install a plugin and add a svn:externals entry to vendor/plugins" + o.separator " #{@script_name} install -x continuous_builder\n" + o.separator " List all available plugins:" + o.separator " #{@script_name} list\n" + o.separator " List plugins in the specified repository:" + o.separator " #{@script_name} list --source=http://dev.rubyonrails.com/svn/rails/plugins/\n" + o.separator " Discover and prompt to add new repositories:" + o.separator " #{@script_name} discover\n" + o.separator " Discover new repositories but just list them, don't add anything:" + o.separator " #{@script_name} discover -l\n" + o.separator " Add a new repository to the source list:" + o.separator " #{@script_name} source http://dev.rubyonrails.com/svn/rails/plugins/\n" + o.separator " Remove a repository from the source list:" + o.separator " #{@script_name} unsource http://dev.rubyonrails.com/svn/rails/plugins/\n" + o.separator " Show currently configured repositories:" + o.separator " #{@script_name} sources\n" + end + end + + def parse!(args=ARGV) + general, sub = split_args(args) + options.parse!(general) + + command = general.shift + if command =~ /^(list|discover|install|source|unsource|sources|remove|update|info)$/ + command = Commands.const_get(command.capitalize).new(self) + command.parse!(sub) + else + puts "Unknown command: #{command}" + puts options + exit 1 + end + end + + def split_args(args) + left = [] + left << args.shift while args[0] and args[0] =~ /^-/ + left << args.shift if args[0] + return [left, args] + end + + def self.parse!(args=ARGV) + Plugin.new.parse!(args) + end + end + + + class List + def initialize(base_command) + @base_command = base_command + @sources = [] + @local = false + @remote = true + end + + def options + OptionParser.new do |o| + o.set_summary_indent(' ') + o.banner = "Usage: #{@base_command.script_name} list [OPTIONS] [PATTERN]" + o.define_head "List available plugins." + o.separator "" + o.separator "Options:" + o.separator "" + o.on( "-s", "--source=URL1,URL2", Array, + "Use the specified plugin repositories.") {|@sources|} + o.on( "--local", + "List locally installed plugins.") {|@local| @remote = false} + o.on( "--remote", + "List remotely available plugins. This is the default behavior", + "unless --local is provided.") {|@remote|} + end + end + + def parse!(args) + options.order!(args) + unless @sources.empty? + @sources.map!{ |uri| Repository.new(uri) } + else + @sources = Repositories.instance.all + end + if @remote + @sources.map{|r| r.plugins}.flatten.each do |plugin| + if @local or !plugin.installed? + puts plugin.to_s + end + end + else + cd "#{@base_command.environment.root}/vendor/plugins" + Dir["*"].select{|p| File.directory?(p)}.each do |name| + puts name + end + end + end + end + + + class Sources + def initialize(base_command) + @base_command = base_command + end + + def options + OptionParser.new do |o| + o.set_summary_indent(' ') + o.banner = "Usage: #{@base_command.script_name} sources [OPTIONS] [PATTERN]" + o.define_head "List configured plugin repositories." + o.separator "" + o.separator "Options:" + o.separator "" + o.on( "-c", "--check", + "Report status of repository.") { |@sources|} + end + end + + def parse!(args) + options.parse!(args) + Repositories.each do |repo| + puts repo.uri + end + end + end + + + class Source + def initialize(base_command) + @base_command = base_command + end + + def options + OptionParser.new do |o| + o.set_summary_indent(' ') + o.banner = "Usage: #{@base_command.script_name} source REPOSITORY [REPOSITORY [REPOSITORY]...]" + o.define_head "Add new repositories to the default search list." + end + end + + def parse!(args) + options.parse!(args) + count = 0 + args.each do |uri| + if Repositories.instance.add(uri) + puts "added: #{uri.ljust(50)}" if $verbose + count += 1 + else + puts "failed: #{uri.ljust(50)}" + end + end + Repositories.instance.save + puts "Added #{count} repositories." + end + end + + + class Unsource + def initialize(base_command) + @base_command = base_command + end + + def options + OptionParser.new do |o| + o.set_summary_indent(' ') + o.banner = "Usage: #{@base_command.script_name} source URI [URI [URI]...]" + o.define_head "Remove repositories from the default search list." + o.separator "" + o.on_tail("-h", "--help", "Show this help message.") { puts o; exit } + end + end + + def parse!(args) + options.parse!(args) + count = 0 + args.each do |uri| + if Repositories.instance.remove(uri) + count += 1 + puts "removed: #{uri.ljust(50)}" + else + puts "failed: #{uri.ljust(50)}" + end + end + Repositories.instance.save + puts "Removed #{count} repositories." + end + end + + + class Discover + def initialize(base_command) + @base_command = base_command + @list = false + @prompt = true + end + + def options + OptionParser.new do |o| + o.set_summary_indent(' ') + o.banner = "Usage: #{@base_command.script_name} discover URI [URI [URI]...]" + o.define_head "Discover repositories referenced on a page." + o.separator "" + o.separator "Options:" + o.separator "" + o.on( "-l", "--list", + "List but don't prompt or add discovered repositories.") { |@list| @prompt = !@list } + o.on( "-n", "--no-prompt", + "Add all new repositories without prompting.") { |v| @prompt = !v } + end + end + + def parse!(args) + options.parse!(args) + args = ['http://wiki.rubyonrails.org/rails/pages/Plugins'] if args.empty? + args.each do |uri| + scrape(uri) do |repo_uri| + catch(:next_uri) do + if @prompt + begin + $stdout.print "Add #{repo_uri}? [Y/n] " + throw :next_uri if $stdin.gets !~ /^y?$/i + rescue Interrupt + $stdout.puts + exit 1 + end + elsif @list + puts repo_uri + throw :next_uri + end + Repositories.instance.add(repo_uri) + puts "discovered: #{repo_uri}" if $verbose or !@prompt + end + end + end + Repositories.instance.save + end + + def scrape(uri) + require 'open-uri' + puts "Scraping #{uri}" if $verbose + dupes = [] + content = open(uri).each do |line| + begin + if line =~ /<a[^>]*href=['"]([^'"]*)['"]/ || line =~ /(svn:\/\/[^<|\n]*)/ + uri = $1 + if uri =~ /^\w+:\/\// && uri =~ /\/plugins\// && uri !~ /\/browser\// && uri !~ /^http:\/\/wiki\.rubyonrails/ && uri !~ /http:\/\/instiki/ + uri = extract_repository_uri(uri) + yield uri unless dupes.include?(uri) || Repositories.instance.exist?(uri) + dupes << uri + end + end + rescue + puts "Problems scraping '#{uri}': #{$!.to_s}" + end + end + end + + def extract_repository_uri(uri) + uri.match(/(svn|https?):.*\/plugins\//i)[0] + end + end + + class Install + def initialize(base_command) + @base_command = base_command + @method = :http + @options = { :quiet => false, :revision => nil, :force => false } + end + + def options + OptionParser.new do |o| + o.set_summary_indent(' ') + o.banner = "Usage: #{@base_command.script_name} install PLUGIN [PLUGIN [PLUGIN] ...]" + o.define_head "Install one or more plugins." + o.separator "" + o.separator "Options:" + o.on( "-x", "--externals", + "Use svn:externals to grab the plugin.", + "Enables plugin updates and plugin versioning.") { |v| @method = :externals } + o.on( "-o", "--checkout", + "Use svn checkout to grab the plugin.", + "Enables updating but does not add a svn:externals entry.") { |v| @method = :checkout } + o.on( "-q", "--quiet", + "Suppresses the output from installation.", + "Ignored if -v is passed (./script/plugin -v install ...)") { |v| @options[:quiet] = true } + o.on( "-r REVISION", "--revision REVISION", + "Checks out the given revision from subversion.", + "Ignored if subversion is not used.") { |v| @options[:revision] = v } + o.on( "-f", "--force", + "Reinstalls a plugin if it's already installed.") { |v| @options[:force] = true } + o.separator "" + o.separator "You can specify plugin names as given in 'plugin list' output or absolute URLs to " + o.separator "a plugin repository." + end + end + + def determine_install_method + best = @base_command.environment.best_install_method + @method = :http if best == :http and @method == :export + case + when (best == :http and @method != :http) + msg = "Cannot install using subversion because `svn' cannot be found in your PATH" + when (best == :export and (@method != :export and @method != :http)) + msg = "Cannot install using #{@method} because this project is not under subversion." + when (best != :externals and @method == :externals) + msg = "Cannot install using externals because vendor/plugins is not under subversion." + end + if msg + puts msg + exit 1 + end + @method + end + + def parse!(args) + options.parse!(args) + environment = @base_command.environment + install_method = determine_install_method + puts "Plugins will be installed using #{install_method}" if $verbose + args.each do |name| + ::Plugin.find(name).install(install_method, @options) + end + rescue StandardError => e + puts "Plugin not found: #{args.inspect}" + puts e.inspect if $verbose + exit 1 + end + end + + class Update + def initialize(base_command) + @base_command = base_command + end + + def options + OptionParser.new do |o| + o.set_summary_indent(' ') + o.banner = "Usage: #{@base_command.script_name} update [name [name]...]" + o.on( "-r REVISION", "--revision REVISION", + "Checks out the given revision from subversion.", + "Ignored if subversion is not used.") { |v| @revision = v } + o.define_head "Update plugins." + end + end + + def parse!(args) + options.parse!(args) + root = @base_command.environment.root + cd root + args = Dir["vendor/plugins/*"].map do |f| + File.directory?("#{f}/.svn") ? File.basename(f) : nil + end.compact if args.empty? + cd "vendor/plugins" + args.each do |name| + if File.directory?(name) + puts "Updating plugin: #{name}" + system("svn #{$verbose ? '' : '-q'} up \"#{name}\" #{@revision ? "-r #{@revision}" : ''}") + else + puts "Plugin doesn't exist: #{name}" + end + end + end + end + + class Remove + def initialize(base_command) + @base_command = base_command + end + + def options + OptionParser.new do |o| + o.set_summary_indent(' ') + o.banner = "Usage: #{@base_command.script_name} remove name [name]..." + o.define_head "Remove plugins." + end + end + + def parse!(args) + options.parse!(args) + root = @base_command.environment.root + args.each do |name| + ::Plugin.new(name).uninstall + end + end + end + + class Info + def initialize(base_command) + @base_command = base_command + end + + def options + OptionParser.new do |o| + o.set_summary_indent(' ') + o.banner = "Usage: #{@base_command.script_name} info name [name]..." + o.define_head "Shows plugin info at {url}/about.yml." + end + end + + def parse!(args) + options.parse!(args) + args.each do |name| + puts ::Plugin.find(name).info + puts + end + end + end +end + +class RecursiveHTTPFetcher + attr_accessor :quiet + def initialize(urls_to_fetch, level = 1, cwd = ".") + @level = level + @cwd = cwd + @urls_to_fetch = urls_to_fetch.to_a + @quiet = false + end + + def ls + @urls_to_fetch.collect do |url| + if url =~ /^svn:\/\/.*/ + `svn ls #{url}`.split("\n").map {|entry| "/#{entry}"} rescue nil + else + open(url) do |stream| + links("", stream.read) + end rescue nil + end + end.flatten + end + + def push_d(dir) + @cwd = File.join(@cwd, dir) + FileUtils.mkdir_p(@cwd) + end + + def pop_d + @cwd = File.dirname(@cwd) + end + + def links(base_url, contents) + links = [] + contents.scan(/href\s*=\s*\"*[^\">]*/i) do |link| + link = link.sub(/href="/i, "") + next if link =~ /svnindex.xsl$/ + next if link =~ /^(\w*:|)\/\// || link =~ /^\./ + links << File.join(base_url, link) + end + links + end + + def download(link) + puts "+ #{File.join(@cwd, File.basename(link))}" unless @quiet + open(link) do |stream| + File.open(File.join(@cwd, File.basename(link)), "wb") do |file| + file.write(stream.read) + end + end + end + + def fetch(links = @urls_to_fetch) + links.each do |l| + (l =~ /\/$/ || links == @urls_to_fetch) ? fetch_dir(l) : download(l) + end + end + + def fetch_dir(url) + @level += 1 + push_d(File.basename(url)) if @level > 0 + open(url) do |stream| + contents = stream.read + fetch(links(url, contents)) + end + pop_d if @level > 0 + @level -= 1 + end +end + +Commands::Plugin.parse! diff --git a/vendor/rails-2.0.2/railties/lib/commands/process/inspector.rb b/vendor/rails-2.0.2/railties/lib/commands/process/inspector.rb new file mode 100644 index 000000000..8a6437e71 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/process/inspector.rb @@ -0,0 +1,68 @@ +require 'optparse' + +if RUBY_PLATFORM =~ /(:?mswin|mingw)/ then abort("Inspector is only for Unix") end + +OPTIONS = { + :pid_path => File.expand_path(RAILS_ROOT + '/tmp/pids'), + :pattern => "dispatch.*.pid", + :ps => "ps -o pid,state,user,start,time,pcpu,vsz,majflt,command -p %s" +} + +class Inspector + def self.inspect(pid_path, pattern) + new(pid_path, pattern).inspect + end + + def initialize(pid_path, pattern) + @pid_path, @pattern = pid_path, pattern + end + + def inspect + header = `#{OPTIONS[:ps] % 1}`.split("\n")[0] + "\n" + lines = pids.collect { |pid| `#{OPTIONS[:ps] % pid}`.split("\n")[1] } + + puts(header + lines.join("\n")) + end + + private + def pids + pid_files.collect do |pid_file| + File.read(pid_file).to_i + end + end + + def pid_files + Dir.glob(@pid_path + "/" + @pattern) + end +end + + +ARGV.options do |opts| + opts.banner = "Usage: inspector [options]" + + opts.separator "" + + opts.on <<-EOF + Description: + Displays system information about Rails dispatchers (or other processes that use pid files) through + the ps command. + + Examples: + inspector # default ps on all tmp/pids/dispatch.*.pid files + inspector -s 'ps -o user,start,majflt,pcpu,vsz -p %s' # custom ps, %s is where the pid is interleaved + EOF + + opts.on(" Options:") + + opts.on("-s", "--ps=command", "default: #{OPTIONS[:ps]}", String) { |v| OPTIONS[:ps] = v } + opts.on("-p", "--pidpath=path", "default: #{OPTIONS[:pid_path]}", String) { |v| OPTIONS[:pid_path] = v } + opts.on("-r", "--pattern=pattern", "default: #{OPTIONS[:pattern]}", String) { |v| OPTIONS[:pattern] = v } + + opts.separator "" + + opts.on("-h", "--help", "Show this help message.") { puts opts; exit } + + opts.parse! +end + +Inspector.inspect(OPTIONS[:pid_path], OPTIONS[:pattern]) diff --git a/vendor/rails-2.0.2/railties/lib/commands/process/reaper.rb b/vendor/rails-2.0.2/railties/lib/commands/process/reaper.rb new file mode 100644 index 000000000..95175d41e --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/process/reaper.rb @@ -0,0 +1,149 @@ +require 'optparse' +require 'net/http' +require 'uri' + +if RUBY_PLATFORM =~ /(:?mswin|mingw)/ then abort("Reaper is only for Unix") end + +class Killer + class << self + # Searches for all processes matching the given keywords, and then invokes + # a specific action on each of them. This is useful for (e.g.) reloading a + # set of processes: + # + # Killer.process(:reload, "/tmp/pids", "dispatcher.*.pid") + def process(action, pid_path, pattern, keyword) + new(pid_path, pattern, keyword).process(action) + end + + # Forces the (rails) application to reload by sending a +HUP+ signal to the + # process. + def reload(pid) + `kill -s HUP #{pid}` + end + + # Force the (rails) application to restart by sending a +USR2+ signal to the + # process. + def restart(pid) + `kill -s USR2 #{pid}` + end + + # Forces the (rails) application to gracefully terminate by sending a + # +TERM+ signal to the process. + def graceful(pid) + `kill -s TERM #{pid}` + end + + # Forces the (rails) application to terminate immediately by sending a -9 + # signal to the process. + def kill(pid) + `kill -9 #{pid}` + end + + # Send a +USR1+ signal to the process. + def usr1(pid) + `kill -s USR1 #{pid}` + end + end + + def initialize(pid_path, pattern, keyword=nil) + @pid_path, @pattern, @keyword = pid_path, pattern, keyword + end + + def process(action) + pids = find_processes + + if pids.empty? + warn "Couldn't find any pid file in '#{@pid_path}' matching '#{@pattern}'" + warn "(also looked for processes matching #{@keyword.inspect})" if @keyword + else + pids.each do |pid| + puts "#{action.capitalize}ing #{pid}" + self.class.send(action, pid) + end + + delete_pid_files if terminating?(action) + end + end + + private + def terminating?(action) + [ "kill", "graceful" ].include?(action) + end + + def find_processes + files = pid_files + if files.empty? + find_processes_via_grep + else + files.collect { |pid_file| File.read(pid_file).to_i } + end + end + + def find_processes_via_grep + lines = `ps axww -o 'pid command' | grep #{@keyword}`.split(/\n/). + reject { |line| line =~ /inq|ps axww|grep|spawn-fcgi|spawner|reaper/ } + lines.map { |line| line[/^\s*(\d+)/, 1].to_i } + end + + def delete_pid_files + pid_files.each { |pid_file| File.delete(pid_file) } + end + + def pid_files + Dir.glob(@pid_path + "/" + @pattern) + end +end + + +OPTIONS = { + :action => "restart", + :pid_path => File.expand_path(RAILS_ROOT + '/tmp/pids'), + :pattern => "dispatch.[0-9]*.pid", + :dispatcher => File.expand_path("#{RAILS_ROOT}/public/dispatch.fcgi") +} + +ARGV.options do |opts| + opts.banner = "Usage: reaper [options]" + + opts.separator "" + + opts.on <<-EOF + Description: + The reaper is used to restart, reload, gracefully exit, and forcefully exit processes + running a Rails Dispatcher (or any other process responding to the same signals). This + is commonly done when a new version of the application is available, so the existing + processes can be updated to use the latest code. + + It uses pid files to work on the processes and by default assume them to be located + in RAILS_ROOT/tmp/pids. + + The reaper actions are: + + * restart : Restarts the application by reloading both application and framework code + * reload : Only reloads the application, but not the framework (like the development environment) + * graceful: Marks all of the processes for exit after the next request + * kill : Forcefully exists all processes regardless of whether they're currently serving a request + + Restart is the most common and default action. + + Examples: + reaper # restarts the default dispatchers + reaper -a reload # reload the default dispatchers + reaper -a kill -r *.pid # kill all processes that keep pids in tmp/pids + EOF + + opts.on(" Options:") + + opts.on("-a", "--action=name", "reload|graceful|kill (default: #{OPTIONS[:action]})", String) { |v| OPTIONS[:action] = v } + opts.on("-p", "--pidpath=path", "default: #{OPTIONS[:pid_path]}", String) { |v| OPTIONS[:pid_path] = v } + opts.on("-r", "--pattern=pattern", "default: #{OPTIONS[:pattern]}", String) { |v| OPTIONS[:pattern] = v } + opts.on("-d", "--dispatcher=path", "DEPRECATED. default: #{OPTIONS[:dispatcher]}", String) { |v| OPTIONS[:dispatcher] = v } + + opts.separator "" + + opts.on("-h", "--help", "Show this help message.") { puts opts; exit } + + opts.parse! +end + +Killer.process(OPTIONS[:action], OPTIONS[:pid_path], OPTIONS[:pattern], OPTIONS[:dispatcher]) diff --git a/vendor/rails-2.0.2/railties/lib/commands/process/spawner.rb b/vendor/rails-2.0.2/railties/lib/commands/process/spawner.rb new file mode 100644 index 000000000..fd09daa55 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/process/spawner.rb @@ -0,0 +1,219 @@ +require 'active_support' +require 'optparse' +require 'socket' +require 'fileutils' + +def daemonize #:nodoc: + exit if fork # Parent exits, child continues. + Process.setsid # Become session leader. + exit if fork # Zap session leader. See [1]. + Dir.chdir "/" # Release old working directory. + File.umask 0000 # Ensure sensible umask. Adjust as needed. + STDIN.reopen "/dev/null" # Free file descriptors and + STDOUT.reopen "/dev/null", "a" # point them somewhere sensible. + STDERR.reopen STDOUT # STDOUT/ERR should better go to a logfile. +end + +class Spawner + def self.record_pid(name = "#{OPTIONS[:process]}.spawner", id = Process.pid) + FileUtils.mkdir_p(OPTIONS[:pids]) + File.open(File.expand_path(OPTIONS[:pids] + "/#{name}.pid"), "w+") { |f| f.write(id) } + end + + def self.spawn_all + OPTIONS[:instances].times do |i| + port = OPTIONS[:port] + i + print "Checking if something is already running on #{OPTIONS[:address]}:#{port}..." + + begin + srv = TCPServer.new(OPTIONS[:address], port) + srv.close + srv = nil + + puts "NO" + puts "Starting dispatcher on port: #{OPTIONS[:address]}:#{port}" + + FileUtils.mkdir_p(OPTIONS[:pids]) + spawn(port) + rescue + puts "YES" + end + end + end +end + +class FcgiSpawner < Spawner + def self.spawn(port) + cmd = "#{OPTIONS[:spawner]} -f #{OPTIONS[:dispatcher]} -p #{port} -P #{OPTIONS[:pids]}/#{OPTIONS[:process]}.#{port}.pid" + cmd << " -a #{OPTIONS[:address]}" if can_bind_to_custom_address? + system(cmd) + end + + def self.can_bind_to_custom_address? + @@can_bind_to_custom_address ||= /^\s-a\s/.match `#{OPTIONS[:spawner]} -h` + end +end + +class MongrelSpawner < Spawner + def self.spawn(port) + cmd = + "mongrel_rails start -d " + + "-a #{OPTIONS[:address]} " + + "-p #{port} " + + "-P #{OPTIONS[:pids]}/#{OPTIONS[:process]}.#{port}.pid " + + "-e #{OPTIONS[:environment]} " + + "-c #{OPTIONS[:rails_root]} " + + "-l #{OPTIONS[:rails_root]}/log/mongrel.log" + + # Add prefix functionality to spawner's call to mongrel_rails + # Digging through monrel's project subversion server, the earliest + # Tag that has prefix implemented in the bin/mongrel_rails file + # is 0.3.15 which also happens to be the earilest tag listed. + # References: http://mongrel.rubyforge.org/svn/tags + if Mongrel::Const::MONGREL_VERSION.to_f >=0.3 && !OPTIONS[:prefix].nil? + cmd = cmd + " --prefix #{OPTIONS[:prefix]}" + end + system(cmd) + end + + def self.can_bind_to_custom_address? + true + end +end + + +begin + require_library_or_gem 'fcgi' +rescue Exception + # FCGI not available +end + +begin + require_library_or_gem 'mongrel' +rescue Exception + # Mongrel not available +end + +server = case ARGV.first + when "fcgi", "mongrel" + ARGV.shift + else + if defined?(Mongrel) + "mongrel" + elsif RUBY_PLATFORM !~ /(:?mswin|mingw)/ && !silence_stderr { `spawn-fcgi -version` }.blank? && defined?(FCGI) + "fcgi" + end +end + +case server + when "fcgi" + puts "=> Starting FCGI dispatchers" + spawner_class = FcgiSpawner + when "mongrel" + puts "=> Starting mongrel dispatchers" + spawner_class = MongrelSpawner + else + puts "Neither FCGI (spawn-fcgi) nor Mongrel was installed and available!" + exit(0) +end + + + +OPTIONS = { + :environment => "production", + :spawner => '/usr/bin/env spawn-fcgi', + :dispatcher => File.expand_path(RELATIVE_RAILS_ROOT + '/public/dispatch.fcgi'), + :pids => File.expand_path(RELATIVE_RAILS_ROOT + "/tmp/pids"), + :rails_root => File.expand_path(RELATIVE_RAILS_ROOT), + :process => "dispatch", + :port => 8000, + :address => '0.0.0.0', + :instances => 3, + :repeat => nil, + :prefix => nil +} + +ARGV.options do |opts| + opts.banner = "Usage: spawner [platform] [options]" + + opts.separator "" + + opts.on <<-EOF + Description: + The spawner is a wrapper for spawn-fcgi and mongrel that makes it + easier to start multiple processes running the Rails dispatcher. The + spawn-fcgi command is included with the lighttpd web server, but can + be used with both Apache and lighttpd (and any other web server + supporting externally managed FCGI processes). Mongrel automatically + ships with with mongrel_rails for starting dispatchers. + + The first choice you need to make is whether to spawn the Rails + dispatchers as FCGI or Mongrel. By default, this spawner will prefer + Mongrel, so if that's installed, and no platform choice is made, + Mongrel is used. + + Then decide a starting port (default is 8000) and the number of FCGI + process instances you'd like to run. So if you pick 9100 and 3 + instances, you'll start processes on 9100, 9101, and 9102. + + By setting the repeat option, you get a protection loop, which will + attempt to restart any FCGI processes that might have been exited or + outright crashed. + + You can select bind address for started processes. By default these + listen on every interface. For single machine installations you would + probably want to use 127.0.0.1, hiding them form the outside world. + + Examples: + spawner # starts instances on 8000, 8001, and 8002 + # using Mongrel if available. + spawner fcgi # starts instances on 8000, 8001, and 8002 + # using FCGI. + spawner mongrel -i 5 # starts instances on 8000, 8001, 8002, + # 8003, and 8004 using Mongrel. + spawner -p 9100 -i 10 # starts 10 instances counting from 9100 to + # 9109 using Mongrel if available. + spawner -p 9100 -r 5 # starts 3 instances counting from 9100 to + # 9102 and attempts start them every 5 + # seconds. + spawner -a 127.0.0.1 # starts 3 instances binding to localhost + EOF + + opts.on(" Options:") + + opts.on("-p", "--port=number", Integer, "Starting port number (default: #{OPTIONS[:port]})") { |OPTIONS[:port]| } + + if spawner_class.can_bind_to_custom_address? + opts.on("-a", "--address=ip", String, "Bind to IP address (default: #{OPTIONS[:address]})") { |OPTIONS[:address]| } + end + + opts.on("-p", "--port=number", Integer, "Starting port number (default: #{OPTIONS[:port]})") { |v| OPTIONS[:port] = v } + opts.on("-i", "--instances=number", Integer, "Number of instances (default: #{OPTIONS[:instances]})") { |v| OPTIONS[:instances] = v } + opts.on("-r", "--repeat=seconds", Integer, "Repeat spawn attempts every n seconds (default: off)") { |v| OPTIONS[:repeat] = v } + opts.on("-e", "--environment=name", String, "test|development|production (default: #{OPTIONS[:environment]})") { |v| OPTIONS[:environment] = v } + opts.on("-P", "--prefix=path", String, "URL prefix for Rails app. [Used only with Mongrel > v0.3.15]: (default: #{OPTIONS[:prefix]})") { |v| OPTIONS[:prefix] = v } + opts.on("-n", "--process=name", String, "default: #{OPTIONS[:process]}") { |v| OPTIONS[:process] = v } + opts.on("-s", "--spawner=path", String, "default: #{OPTIONS[:spawner]}") { |v| OPTIONS[:spawner] = v } + opts.on("-d", "--dispatcher=path", String, "default: #{OPTIONS[:dispatcher]}") { |dispatcher| OPTIONS[:dispatcher] = File.expand_path(dispatcher) } + + opts.separator "" + + opts.on("-h", "--help", "Show this help message.") { puts opts; exit } + + opts.parse! +end + +ENV["RAILS_ENV"] = OPTIONS[:environment] + +if OPTIONS[:repeat] + daemonize + trap("TERM") { exit } + spawner_class.record_pid + + loop do + spawner_class.spawn_all + sleep(OPTIONS[:repeat]) + end +else + spawner_class.spawn_all +end diff --git a/vendor/rails-2.0.2/railties/lib/commands/process/spinner.rb b/vendor/rails-2.0.2/railties/lib/commands/process/spinner.rb new file mode 100644 index 000000000..c0b2f09a9 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/process/spinner.rb @@ -0,0 +1,57 @@ +require 'optparse' + +def daemonize #:nodoc: + exit if fork # Parent exits, child continues. + Process.setsid # Become session leader. + exit if fork # Zap session leader. See [1]. + Dir.chdir "/" # Release old working directory. + File.umask 0000 # Ensure sensible umask. Adjust as needed. + STDIN.reopen "/dev/null" # Free file descriptors and + STDOUT.reopen "/dev/null", "a" # point them somewhere sensible. + STDERR.reopen STDOUT # STDOUT/ERR should better go to a logfile. +end + +OPTIONS = { + :interval => 5.0, + :command => File.expand_path(RAILS_ROOT + '/script/process/spawner'), + :daemon => false +} + +ARGV.options do |opts| + opts.banner = "Usage: spinner [options]" + + opts.separator "" + + opts.on <<-EOF + Description: + The spinner is a protection loop for the spawner, which will attempt to restart any FCGI processes + that might have been exited or outright crashed. It's a brute-force attempt that'll just try + to run the spawner every X number of seconds, so it does pose a light load on the server. + + Examples: + spinner # attempts to run the spawner with default settings every second with output on the terminal + spinner -i 3 -d # only run the spawner every 3 seconds and detach from the terminal to become a daemon + spinner -c '/path/to/app/script/process/spawner -p 9000 -i 10' -d # using custom spawner + EOF + + opts.on(" Options:") + + opts.on("-c", "--command=path", String) { |v| OPTIONS[:command] = v } + opts.on("-i", "--interval=seconds", Float) { |v| OPTIONS[:interval] = v } + opts.on("-d", "--daemon") { |v| OPTIONS[:daemon] = v } + + opts.separator "" + + opts.on("-h", "--help", "Show this help message.") { puts opts; exit } + + opts.parse! +end + +daemonize if OPTIONS[:daemon] + +trap(OPTIONS[:daemon] ? "TERM" : "INT") { exit } + +loop do + system(OPTIONS[:command]) + sleep(OPTIONS[:interval]) +end
\ No newline at end of file diff --git a/vendor/rails-2.0.2/railties/lib/commands/runner.rb b/vendor/rails-2.0.2/railties/lib/commands/runner.rb new file mode 100644 index 000000000..926bc2634 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/runner.rb @@ -0,0 +1,48 @@ +require 'optparse' + +options = { :environment => (ENV['RAILS_ENV'] || "development").dup } +code_or_file = nil + +ARGV.clone.options do |opts| + script_name = File.basename($0) + opts.banner = "Usage: #{$0} [options] ('Some.ruby(code)' or a filename)" + + opts.separator "" + + opts.on("-e", "--environment=name", String, + "Specifies the environment for the runner to operate under (test/development/production).", + "Default: development") { |v| options[:environment] = v } + + opts.separator "" + + opts.on("-h", "--help", + "Show this help message.") { $stderr.puts opts; exit } + + if RUBY_PLATFORM !~ /mswin/ + opts.separator "" + opts.separator "You can also use runner as a shebang line for your scripts like this:" + opts.separator "-------------------------------------------------------------" + opts.separator "#!/usr/bin/env #{File.expand_path($0)}" + opts.separator "" + opts.separator "Product.find(:all).each { |p| p.price *= 2 ; p.save! }" + opts.separator "-------------------------------------------------------------" + end + + opts.order! { |o| code_or_file ||= o } rescue retry +end + +ARGV.delete(code_or_file) + +ENV["RAILS_ENV"] = options[:environment] +RAILS_ENV.replace(options[:environment]) if defined?(RAILS_ENV) + +require RAILS_ROOT + '/config/environment' + +if code_or_file.nil? + $stderr.puts "Run '#{$0} -h' for help." + exit 1 +elsif File.exist?(code_or_file) + eval(File.read(code_or_file)) +else + eval(code_or_file) +end diff --git a/vendor/rails-2.0.2/railties/lib/commands/server.rb b/vendor/rails-2.0.2/railties/lib/commands/server.rb new file mode 100644 index 000000000..f84db9c04 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/server.rb @@ -0,0 +1,39 @@ +require 'active_support' +require 'fileutils' + +begin + require_library_or_gem 'fcgi' +rescue Exception + # FCGI not available +end + +begin + require_library_or_gem 'mongrel' +rescue Exception + # Mongrel not available +end + +server = case ARGV.first + when "lighttpd", "mongrel", "webrick" + ARGV.shift + else + if defined?(Mongrel) + "mongrel" + elsif RUBY_PLATFORM !~ /(:?mswin|mingw)/ && !silence_stderr { `lighttpd -version` }.blank? && defined?(FCGI) + "lighttpd" + else + "webrick" + end +end + +case server + when "webrick" + puts "=> Booting WEBrick..." + when "lighttpd" + puts "=> Booting lighttpd (use 'script/server webrick' to force WEBrick)" + when "mongrel" + puts "=> Booting Mongrel (use 'script/server webrick' to force WEBrick)" +end + +%w(cache pids sessions sockets).each { |dir_to_make| FileUtils.mkdir_p(File.join(RAILS_ROOT, 'tmp', dir_to_make)) } +require "commands/servers/#{server}" diff --git a/vendor/rails-2.0.2/railties/lib/commands/servers/base.rb b/vendor/rails-2.0.2/railties/lib/commands/servers/base.rb new file mode 100644 index 000000000..23be169a8 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/servers/base.rb @@ -0,0 +1,31 @@ +def tail(log_file) + cursor = File.size(log_file) + last_checked = Time.now + tail_thread = Thread.new do + File.open(log_file, 'r') do |f| + loop do + f.seek cursor + if f.mtime > last_checked + last_checked = f.mtime + contents = f.read + cursor += contents.length + print contents + end + sleep 1 + end + end + end + tail_thread +end + +def start_debugger + begin + require_library_or_gem 'ruby-debug' + Debugger.start + Debugger.settings[:autoeval] = true if Debugger.respond_to?(:settings) + puts "=> Debugger enabled" + rescue Exception + puts "You need to install ruby-debug to run the server in debugging mode. With gems, use 'gem install ruby-debug'" + exit + end +end
\ No newline at end of file diff --git a/vendor/rails-2.0.2/railties/lib/commands/servers/lighttpd.rb b/vendor/rails-2.0.2/railties/lib/commands/servers/lighttpd.rb new file mode 100644 index 000000000..07d4f9d0b --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/servers/lighttpd.rb @@ -0,0 +1,94 @@ +require 'rbconfig' +require 'commands/servers/base' + +unless RUBY_PLATFORM !~ /mswin/ && !silence_stderr { `lighttpd -version` }.blank? + puts "PROBLEM: Lighttpd is not available on your system (or not in your path)" + exit 1 +end + +unless defined?(FCGI) + puts "PROBLEM: Lighttpd requires that the FCGI Ruby bindings are installed on the system" + exit 1 +end + +require 'initializer' +configuration = Rails::Initializer.run(:initialize_logger).configuration +default_config_file = config_file = Pathname.new("#{RAILS_ROOT}/config/lighttpd.conf").cleanpath + +require 'optparse' + +detach = false +command_line_port = nil + +ARGV.options do |opt| + opt.on("-p", "--port=port", "Changes the server.port number in the config/lighttpd.conf") { |port| command_line_port = port } + opt.on('-c', "--config=#{config_file}", 'Specify a different lighttpd config file.') { |path| config_file = path } + opt.on('-h', '--help', 'Show this message.') { puts opt; exit 0 } + opt.on('-d', '-d', 'Call with -d to detach') { detach = true; puts "=> Configuration in config/lighttpd.conf" } + opt.parse! +end + +unless File.exist?(config_file) + if config_file != default_config_file + puts "=> #{config_file} not found." + exit 1 + end + + require 'fileutils' + + source = File.expand_path(File.join(File.dirname(__FILE__), + "..", "..", "..", "configs", "lighttpd.conf")) + puts "=> #{config_file} not found, copying from #{source}" + + FileUtils.cp(source, config_file) +end + +# open the config/lighttpd.conf file and add the current user defined port setting to it +if command_line_port + File.open(config_file, 'r+') do |config| + lines = config.readlines + + lines.each do |line| + line.gsub!(/^\s*server.port\s*=\s*(\d+)/, "server.port = #{command_line_port}") + end + + config.rewind + config.print(lines) + config.truncate(config.pos) + end +end + +config = IO.read(config_file) +default_port, default_ip = 3000, '0.0.0.0' +port = config.scan(/^\s*server.port\s*=\s*(\d+)/).first rescue default_port +ip = config.scan(/^\s*server.bind\s*=\s*"([^"]+)"/).first rescue default_ip +puts "=> Rails application starting on http://#{ip || default_ip}:#{port || default_port}" + +tail_thread = nil + +if !detach + puts "=> Call with -d to detach" + puts "=> Ctrl-C to shutdown server (see config/lighttpd.conf for options)" + detach = false + tail_thread = tail(configuration.log_path) +end + +trap(:INT) { exit } + +begin + `rake tmp:sockets:clear` # Needed if lighttpd crashes or otherwise leaves FCGI sockets around + `lighttpd #{!detach ? "-D " : ""}-f #{config_file}` +ensure + unless detach + tail_thread.kill if tail_thread + puts 'Exiting' + + # Ensure FCGI processes are reaped + silence_stream(STDOUT) do + ARGV.replace ['-a', 'kill'] + require 'commands/process/reaper' + end + + `rake tmp:sockets:clear` # Remove sockets on clean shutdown + end +end diff --git a/vendor/rails-2.0.2/railties/lib/commands/servers/mongrel.rb b/vendor/rails-2.0.2/railties/lib/commands/servers/mongrel.rb new file mode 100644 index 000000000..5eb14bce1 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/servers/mongrel.rb @@ -0,0 +1,69 @@ +require 'rbconfig' +require 'commands/servers/base' + +unless defined?(Mongrel) + puts "PROBLEM: Mongrel is not available on your system (or not in your path)" + exit 1 +end + +require 'optparse' + +OPTIONS = { + :port => 3000, + :ip => "0.0.0.0", + :environment => (ENV['RAILS_ENV'] || "development").dup, + :detach => false, + :debugger => false +} + +ARGV.clone.options do |opts| + opts.on("-p", "--port=port", Integer, "Runs Rails on the specified port.", "Default: 3000") { |v| OPTIONS[:port] = v } + opts.on("-b", "--binding=ip", String, "Binds Rails to the specified ip.", "Default: 0.0.0.0") { |v| OPTIONS[:ip] = v } + opts.on("-d", "--daemon", "Make server run as a Daemon.") { OPTIONS[:detach] = true } + opts.on("-u", "--debugger", "Enable ruby-debugging for the server.") { OPTIONS[:debugger] = true } + opts.on("-e", "--environment=name", String, + "Specifies the environment to run this server under (test/development/production).", + "Default: development") { |v| OPTIONS[:environment] = v } + + opts.separator "" + + opts.on("-h", "--help", "Show this help message.") { puts opts; exit } + + opts.parse! +end + +puts "=> Rails application starting on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}" + +parameters = [ + "start", + "-p", OPTIONS[:port].to_s, + "-a", OPTIONS[:ip].to_s, + "-e", OPTIONS[:environment], + "-P", "#{RAILS_ROOT}/tmp/pids/mongrel.pid" +] + +if OPTIONS[:detach] + `mongrel_rails #{parameters.join(" ")} -d` +else + ENV["RAILS_ENV"] = OPTIONS[:environment] + RAILS_ENV.replace(OPTIONS[:environment]) if defined?(RAILS_ENV) + + start_debugger if OPTIONS[:debugger] + + require 'initializer' + Rails::Initializer.run(:initialize_logger) + + puts "=> Call with -d to detach" + puts "=> Ctrl-C to shutdown server" + tail_thread = tail(Pathname.new("#{File.expand_path(RAILS_ROOT)}/log/#{RAILS_ENV}.log").cleanpath) + + trap(:INT) { exit } + + begin + silence_warnings { ARGV = parameters } + load("mongrel_rails") + ensure + tail_thread.kill if tail_thread + puts 'Exiting' + end +end
\ No newline at end of file diff --git a/vendor/rails-2.0.2/railties/lib/commands/servers/webrick.rb b/vendor/rails-2.0.2/railties/lib/commands/servers/webrick.rb new file mode 100644 index 000000000..b95037615 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/servers/webrick.rb @@ -0,0 +1,66 @@ +require 'webrick' +require 'optparse' +require 'commands/servers/base' + +OPTIONS = { + :port => 3000, + :ip => "0.0.0.0", + :environment => (ENV['RAILS_ENV'] || "development").dup, + :server_root => File.expand_path(RAILS_ROOT + "/public/"), + :server_type => WEBrick::SimpleServer, + :charset => "UTF-8", + :mime_types => WEBrick::HTTPUtils::DefaultMimeTypes, + :debugger => false + +} + +ARGV.options do |opts| + script_name = File.basename($0) + opts.banner = "Usage: ruby #{script_name} [options]" + + opts.separator "" + + opts.on("-p", "--port=port", Integer, + "Runs Rails on the specified port.", + "Default: 3000") { |v| OPTIONS[:port] = v } + opts.on("-b", "--binding=ip", String, + "Binds Rails to the specified ip.", + "Default: 0.0.0.0") { |v| OPTIONS[:ip] = v } + opts.on("-e", "--environment=name", String, + "Specifies the environment to run this server under (test/development/production).", + "Default: development") { |v| OPTIONS[:environment] = v } + opts.on("-m", "--mime-types=filename", String, + "Specifies an Apache style mime.types configuration file to be used for mime types", + "Default: none") { |mime_types_file| OPTIONS[:mime_types] = WEBrick::HTTPUtils::load_mime_types(mime_types_file) } + + opts.on("-d", "--daemon", + "Make Rails run as a Daemon (only works if fork is available -- meaning on *nix)." + ) { OPTIONS[:server_type] = WEBrick::Daemon } + + opts.on("-u", "--debugger", "Enable ruby-debugging for the server.") { OPTIONS[:debugger] = true } + + opts.on("-c", "--charset=charset", String, + "Set default charset for output.", + "Default: UTF-8") { |v| OPTIONS[:charset] = v } + + opts.separator "" + + opts.on("-h", "--help", + "Show this help message.") { puts opts; exit } + + opts.parse! +end + +start_debugger if OPTIONS[:debugger] + +ENV["RAILS_ENV"] = OPTIONS[:environment] +RAILS_ENV.replace(OPTIONS[:environment]) if defined?(RAILS_ENV) + +require RAILS_ROOT + "/config/environment" +require 'webrick_server' + +OPTIONS['working_directory'] = File.expand_path(RAILS_ROOT) + +puts "=> Rails application started on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}" +puts "=> Ctrl-C to shutdown server; call with --help for options" if OPTIONS[:server_type] == WEBrick::SimpleServer +DispatchServlet.dispatch(OPTIONS) diff --git a/vendor/rails-2.0.2/railties/lib/commands/update.rb b/vendor/rails-2.0.2/railties/lib/commands/update.rb new file mode 100644 index 000000000..83ef83330 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/commands/update.rb @@ -0,0 +1,4 @@ +require "#{RAILS_ROOT}/config/environment" +require 'rails_generator' +require 'rails_generator/scripts/update' +Rails::Generator::Scripts::Update.new.run(ARGV) diff --git a/vendor/rails-2.0.2/railties/lib/console_app.rb b/vendor/rails-2.0.2/railties/lib/console_app.rb new file mode 100644 index 000000000..c7673642e --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/console_app.rb @@ -0,0 +1,30 @@ +require 'action_controller/integration' + +# work around the at_exit hook in test/unit, which kills IRB +Test::Unit.run = true if Test::Unit.respond_to?(:run=) + +# reference the global "app" instance, created on demand. To recreate the +# instance, pass a non-false value as the parameter. +def app(create=false) + @app_integration_instance = nil if create + @app_integration_instance ||= new_session do |sess| + sess.host! "www.example.com" + end +end + +# create a new session. If a block is given, the new session will be yielded +# to the block before being returned. +def new_session + session = ActionController::Integration::Session.new + yield session if block_given? + session +end + +#reloads the environment +def reload! + puts "Reloading..." + dispatcher = ActionController::Dispatcher.new($stdout) + dispatcher.cleanup_application(true) + dispatcher.prepare_application(true) + true +end diff --git a/vendor/rails-2.0.2/railties/lib/console_sandbox.rb b/vendor/rails-2.0.2/railties/lib/console_sandbox.rb new file mode 100644 index 000000000..5d57679c4 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/console_sandbox.rb @@ -0,0 +1,6 @@ +ActiveRecord::Base.send :increment_open_transactions +ActiveRecord::Base.connection.begin_db_transaction +at_exit do + ActiveRecord::Base.connection.rollback_db_transaction + ActiveRecord::Base.send :decrement_open_transactions +end diff --git a/vendor/rails-2.0.2/railties/lib/console_with_helpers.rb b/vendor/rails-2.0.2/railties/lib/console_with_helpers.rb new file mode 100644 index 000000000..79018a9f7 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/console_with_helpers.rb @@ -0,0 +1,26 @@ +class Module + def include_all_modules_from(parent_module) + parent_module.constants.each do |const| + mod = parent_module.const_get(const) + if mod.class == Module + send(:include, mod) + include_all_modules_from(mod) + end + end + end +end + +def helper(*helper_names) + returning @helper_proxy ||= Object.new do |helper| + helper_names.each { |h| helper.extend "#{h}_helper".classify.constantize } + end +end + +require 'application' + +class << helper + include_all_modules_from ActionView +end + +@controller = ApplicationController.new +helper :application rescue nil diff --git a/vendor/rails-2.0.2/railties/lib/dispatcher.rb b/vendor/rails-2.0.2/railties/lib/dispatcher.rb new file mode 100644 index 000000000..9db424f14 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/dispatcher.rb @@ -0,0 +1,24 @@ +#-- +# Copyright (c) 2004-2007 David Heinemeier Hansson +# +# 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. +#++ +require 'action_controller/dispatcher' +Dispatcher = ActionController::Dispatcher diff --git a/vendor/rails-2.0.2/railties/lib/fcgi_handler.rb b/vendor/rails-2.0.2/railties/lib/fcgi_handler.rb new file mode 100644 index 000000000..a644161e7 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/fcgi_handler.rb @@ -0,0 +1,223 @@ +require 'fcgi' +require 'logger' +require 'dispatcher' +require 'rbconfig' + +class RailsFCGIHandler + SIGNALS = { + 'HUP' => :reload, + 'INT' => :exit_now, + 'TERM' => :exit_now, + 'USR1' => :exit, + 'USR2' => :restart + } + GLOBAL_SIGNALS = SIGNALS.keys - %w(USR1) + + attr_reader :when_ready + + attr_accessor :log_file_path + attr_accessor :gc_request_period + + + # Initialize and run the FastCGI instance, passing arguments through to new. + def self.process!(*args, &block) + new(*args, &block).process! + end + + # Initialize the FastCGI instance with the path to a crash log + # detailing unhandled exceptions (default RAILS_ROOT/log/fastcgi.crash.log) + # and the number of requests to process between garbage collection runs + # (default nil for normal GC behavior.) Optionally, pass a block which + # takes this instance as an argument for further configuration. + def initialize(log_file_path = nil, gc_request_period = nil) + self.log_file_path = log_file_path || "#{RAILS_ROOT}/log/fastcgi.crash.log" + self.gc_request_period = gc_request_period + + # Yield for additional configuration. + yield self if block_given? + + # Safely install signal handlers. + install_signal_handlers + + # Start error timestamp at 11 seconds ago. + @last_error_on = Time.now - 11 + end + + def process!(provider = FCGI) + mark_features! + + dispatcher_log :info, 'starting' + process_each_request provider + dispatcher_log :info, 'stopping gracefully' + + rescue Exception => error + case error + when SystemExit + dispatcher_log :info, 'stopping after explicit exit' + when SignalException + dispatcher_error error, 'stopping after unhandled signal' + else + # Retry if exceptions occur more than 10 seconds apart. + if Time.now - @last_error_on > 10 + @last_error_on = Time.now + dispatcher_error error, 'retrying after unhandled exception' + retry + else + dispatcher_error error, 'stopping after unhandled exception within 10 seconds of the last' + end + end + end + + + protected + def process_each_request(provider) + cgi = nil + + provider.each_cgi do |cgi| + process_request(cgi) + + case when_ready + when :reload + reload! + when :restart + close_connection(cgi) + restart! + when :exit + close_connection(cgi) + break + end + end + rescue SignalException => signal + raise unless signal.message == 'SIGUSR1' + close_connection(cgi) + end + + def process_request(cgi) + @when_ready = nil + gc_countdown + + with_signal_handler 'USR1' do + begin + Dispatcher.dispatch(cgi) + rescue SignalException, SystemExit + raise + rescue Exception => error + dispatcher_error error, 'unhandled dispatch error' + end + end + end + + def logger + @logger ||= Logger.new(@log_file_path) + end + + def dispatcher_log(level, msg) + time_str = Time.now.strftime("%d/%b/%Y:%H:%M:%S") + logger.send(level, "[#{time_str} :: #{$$}] #{msg}") + rescue Exception => log_error # Logger errors + STDERR << "Couldn't write to #{@log_file_path.inspect}: #{msg}\n" + STDERR << " #{log_error.class}: #{log_error.message}\n" + end + + def dispatcher_error(e, msg = "") + error_message = + "Dispatcher failed to catch: #{e} (#{e.class})\n" + + " #{e.backtrace.join("\n ")}\n#{msg}" + dispatcher_log(:error, error_message) + end + + def install_signal_handlers + GLOBAL_SIGNALS.each { |signal| install_signal_handler(signal) } + end + + def install_signal_handler(signal, handler = nil) + if SIGNALS.include?(signal) && self.class.method_defined?(name = "#{SIGNALS[signal]}_handler") + handler ||= method(name).to_proc + + begin + trap(signal, handler) + rescue ArgumentError + dispatcher_log :warn, "Ignoring unsupported signal #{signal}." + end + else + dispatcher_log :warn, "Ignoring unsupported signal #{signal}." + end + end + + def with_signal_handler(signal) + install_signal_handler(signal) + yield + ensure + install_signal_handler(signal, 'DEFAULT') + end + + def exit_now_handler(signal) + dispatcher_log :info, "asked to stop immediately" + exit + end + + def exit_handler(signal) + dispatcher_log :info, "asked to stop ASAP" + @when_ready = :exit + end + + def reload_handler(signal) + dispatcher_log :info, "asked to reload ASAP" + @when_ready = :reload + end + + def restart_handler(signal) + dispatcher_log :info, "asked to restart ASAP" + @when_ready = :restart + end + + def restart! + config = ::Config::CONFIG + ruby = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT'] + command_line = [ruby, $0, ARGV].flatten.join(' ') + + dispatcher_log :info, "restarted" + + # close resources as they won't be closed by + # the OS when using exec + logger.close rescue nil + RAILS_DEFAULT_LOGGER.close rescue nil + + exec(command_line) + end + + def reload! + run_gc! if gc_request_period + restore! + @when_ready = nil + dispatcher_log :info, "reloaded" + end + + # Make a note of $" so we can safely reload this instance. + def mark_features! + @features = $".clone + end + + def restore! + $".replace @features + Dispatcher.reset_application! + ActionController::Routing::Routes.reload + end + + def run_gc! + @gc_request_countdown = gc_request_period + GC.enable; GC.start; GC.disable + end + + def gc_countdown + if gc_request_period + @gc_request_countdown ||= gc_request_period + @gc_request_countdown -= 1 + run_gc! if @gc_request_countdown <= 0 + end + end + + def close_connection(cgi) + cgi.instance_variable_get("@request").finish if cgi + end +end diff --git a/vendor/rails-2.0.2/railties/lib/initializer.rb b/vendor/rails-2.0.2/railties/lib/initializer.rb new file mode 100644 index 000000000..4b522e292 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/initializer.rb @@ -0,0 +1,682 @@ +require 'logger' +require 'set' +require 'pathname' + +$LOAD_PATH.unshift File.dirname(__FILE__) +require 'railties_path' +require 'rails/version' +require 'rails/plugin/locator' +require 'rails/plugin/loader' + + +RAILS_ENV = (ENV['RAILS_ENV'] || 'development').dup unless defined?(RAILS_ENV) + +module Rails + # The Initializer is responsible for processing the Rails configuration, such + # as setting the $LOAD_PATH, requiring the right frameworks, initializing + # logging, and more. It can be run either as a single command that'll just + # use the default configuration, like this: + # + # Rails::Initializer.run + # + # But normally it's more interesting to pass in a custom configuration + # through the block running: + # + # Rails::Initializer.run do |config| + # config.frameworks -= [ :action_mailer ] + # end + # + # This will use the default configuration options from Rails::Configuration, + # but allow for overwriting on select areas. + class Initializer + # The Configuration instance used by this Initializer instance. + attr_reader :configuration + + # The set of loaded plugins. + attr_reader :loaded_plugins + + # Runs the initializer. By default, this will invoke the #process method, + # which simply executes all of the initialization routines. Alternately, + # you can specify explicitly which initialization routine you want: + # + # Rails::Initializer.run(:set_load_path) + # + # This is useful if you only want the load path initialized, without + # incuring the overhead of completely loading the entire environment. + def self.run(command = :process, configuration = Configuration.new) + yield configuration if block_given? + initializer = new configuration + initializer.send(command) + initializer + end + + # Create a new Initializer instance that references the given Configuration + # instance. + def initialize(configuration) + @configuration = configuration + @loaded_plugins = [] + end + + # Sequentially step through all of the available initialization routines, + # in order: + # + # * #check_ruby_version + # * #set_load_path + # * #require_frameworks + # * #set_autoload_paths + # * add_plugin_load_paths + # * #load_environment + # * #initialize_encoding + # * #initialize_database + # * #initialize_logger + # * #initialize_framework_logging + # * #initialize_framework_views + # * #initialize_dependency_mechanism + # * #initialize_whiny_nils + # * #initialize_temporary_directories + # * #initialize_framework_settings + # * #add_support_load_paths + # * #load_plugins + # * #load_observers + # * #initialize_routing + # * #after_initialize + # * #load_application_initializers + def process + check_ruby_version + set_load_path + + require_frameworks + set_autoload_paths + add_plugin_load_paths + load_environment + + initialize_encoding + initialize_database + initialize_logger + initialize_framework_logging + initialize_framework_views + initialize_dependency_mechanism + initialize_whiny_nils + initialize_temporary_directories + initialize_framework_settings + + add_support_load_paths + + load_plugins + + # Observers are loaded after plugins in case Observers or observed models are modified by plugins. + load_observers + + # Routing must be initialized after plugins to allow the former to extend the routes + initialize_routing + + # the framework is now fully initialized + after_initialize + + load_application_initializers + end + + # Check for valid Ruby version + # This is done in an external file, so we can use it + # from the `rails` program as well without duplication. + def check_ruby_version + require 'ruby_version_check' + end + + # Set the <tt>$LOAD_PATH</tt> based on the value of + # Configuration#load_paths. Duplicates are removed. + def set_load_path + load_paths = configuration.load_paths + configuration.framework_paths + load_paths.reverse_each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) } + $LOAD_PATH.uniq! + end + + # Set the paths from which Rails will automatically load source files, and + # the load_once paths. + def set_autoload_paths + Dependencies.load_paths = configuration.load_paths.uniq + Dependencies.load_once_paths = configuration.load_once_paths.uniq + + extra = Dependencies.load_once_paths - Dependencies.load_paths + unless extra.empty? + abort <<-end_error + load_once_paths must be a subset of the load_paths. + Extra items in load_once_paths: #{extra * ','} + end_error + end + + # Freeze the arrays so future modifications will fail rather than do nothing mysteriously + configuration.load_once_paths.freeze + end + + # Requires all frameworks specified by the Configuration#frameworks + # list. By default, all frameworks (ActiveRecord, ActiveSupport, + # ActionPack, ActionMailer, and ActiveResource) are loaded. + def require_frameworks + configuration.frameworks.each { |framework| require(framework.to_s) } + rescue LoadError => e + # re-raise because Mongrel would swallow it + raise e.to_s + end + + # Add the load paths used by support functions such as the info controller + def add_support_load_paths + end + + # Adds all load paths from plugins to the global set of load paths, so that + # code from plugins can be required (explicitly or automatically via Dependencies). + def add_plugin_load_paths + plugin_loader.add_plugin_load_paths + end + + # Loads all plugins in <tt>config.plugin_paths</tt>. <tt>plugin_paths</tt> + # defaults to <tt>vendor/plugins</tt> but may also be set to a list of + # paths, such as + # config.plugin_paths = ["#{RAILS_ROOT}/lib/plugins", "#{RAILS_ROOT}/vendor/plugins"] + # + # In the default implementation, as each plugin discovered in <tt>plugin_paths</tt> is initialized: + # * its +lib+ directory, if present, is added to the load path (immediately after the applications lib directory) + # * <tt>init.rb</tt> is evaluated, if present + # + # After all plugins are loaded, duplicates are removed from the load path. + # If an array of plugin names is specified in config.plugins, only those plugins will be loaded + # and they plugins will be loaded in that order. Otherwise, plugins are loaded in alphabetical + # order. + # + # if config.plugins ends contains :all then the named plugins will be loaded in the given order and all other + # plugins will be loaded in alphabetical order + def load_plugins + plugin_loader.load_plugins + end + + def plugin_loader + @plugin_loader ||= configuration.plugin_loader.new(self) + end + + # Loads the environment specified by Configuration#environment_path, which + # is typically one of development, test, or production. + def load_environment + silence_warnings do + return if @environment_loaded + @environment_loaded = true + + config = configuration + constants = self.class.constants + + eval(IO.read(configuration.environment_path), binding, configuration.environment_path) + + (self.class.constants - constants).each do |const| + Object.const_set(const, self.class.const_get(const)) + end + end + end + + def load_observers + if configuration.frameworks.include?(:active_record) + ActiveRecord::Base.instantiate_observers + end + end + + # This initialization sets $KCODE to 'u' to enable the multibyte safe operations. + # Plugin authors supporting other encodings should override this behaviour and + # set the relevant +default_charset+ on ActionController::Base + def initialize_encoding + $KCODE='u' + end + + # This initialization routine does nothing unless <tt>:active_record</tt> + # is one of the frameworks to load (Configuration#frameworks). If it is, + # this sets the database configuration from Configuration#database_configuration + # and then establishes the connection. + def initialize_database + if configuration.frameworks.include?(:active_record) + ActiveRecord::Base.configurations = configuration.database_configuration + ActiveRecord::Base.establish_connection + end + end + + # If the +RAILS_DEFAULT_LOGGER+ constant is already set, this initialization + # routine does nothing. If the constant is not set, and Configuration#logger + # is not +nil+, this also does nothing. Otherwise, a new logger instance + # is created at Configuration#log_path, with a default log level of + # Configuration#log_level. + # + # If the log could not be created, the log will be set to output to + # +STDERR+, with a log level of +WARN+. + def initialize_logger + # if the environment has explicitly defined a logger, use it + return if defined?(RAILS_DEFAULT_LOGGER) + + unless logger = configuration.logger + begin + logger = ActiveSupport::BufferedLogger.new(configuration.log_path) + logger.level = ActiveSupport::BufferedLogger.const_get(configuration.log_level.to_s.upcase) + logger.auto_flushing = false if configuration.environment == "production" + rescue StandardError =>e + logger = ActiveSupport::BufferedLogger.new(STDERR) + logger.level = ActiveSupport::BufferedLogger::WARN + logger.warn( + "Rails Error: Unable to access log file. Please ensure that #{configuration.log_path} exists and is chmod 0666. " + + "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed." + ) + end + end + + silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger } + end + + # Sets the logger for ActiveRecord, ActionController, and ActionMailer + # (but only for those frameworks that are to be loaded). If the framework's + # logger is already set, it is not changed, otherwise it is set to use + # +RAILS_DEFAULT_LOGGER+. + def initialize_framework_logging + for framework in ([ :active_record, :action_controller, :action_mailer ] & configuration.frameworks) + framework.to_s.camelize.constantize.const_get("Base").logger ||= RAILS_DEFAULT_LOGGER + end + end + + # Sets +ActionController::Base#view_paths+ and +ActionMailer::Base#template_root+ + # (but only for those frameworks that are to be loaded). If the framework's + # paths have already been set, it is not changed, otherwise it is + # set to use Configuration#view_path. + def initialize_framework_views + ActionMailer::Base.template_root ||= configuration.view_path if configuration.frameworks.include?(:action_mailer) + ActionController::Base.view_paths = [configuration.view_path] if configuration.frameworks.include?(:action_controller) && ActionController::Base.view_paths.empty? + end + + # If ActionController is not one of the loaded frameworks (Configuration#frameworks) + # this does nothing. Otherwise, it loads the routing definitions and sets up + # loading module used to lazily load controllers (Configuration#controller_paths). + def initialize_routing + return unless configuration.frameworks.include?(:action_controller) + ActionController::Routing.controller_paths = configuration.controller_paths + ActionController::Routing::Routes.reload + end + + # Sets the dependency loading mechanism based on the value of + # Configuration#cache_classes. + def initialize_dependency_mechanism + Dependencies.mechanism = configuration.cache_classes ? :require : :load + end + + # Loads support for "whiny nil" (noisy warnings when methods are invoked + # on +nil+ values) if Configuration#whiny_nils is true. + def initialize_whiny_nils + require('active_support/whiny_nil') if configuration.whiny_nils + end + + def initialize_temporary_directories + if configuration.frameworks.include?(:action_controller) + session_path = "#{configuration.root_path}/tmp/sessions/" + ActionController::Base.session_options[:tmpdir] = File.exist?(session_path) ? session_path : Dir::tmpdir + + cache_path = "#{configuration.root_path}/tmp/cache/" + if File.exist?(cache_path) + ActionController::Base.fragment_cache_store = :file_store, cache_path + end + end + end + + # Initializes framework-specific settings for each of the loaded frameworks + # (Configuration#frameworks). The available settings map to the accessors + # on each of the corresponding Base classes. + def initialize_framework_settings + configuration.frameworks.each do |framework| + base_class = framework.to_s.camelize.constantize.const_get("Base") + + configuration.send(framework).each do |setting, value| + base_class.send("#{setting}=", value) + end + end + end + + # Fires the user-supplied after_initialize block (Configuration#after_initialize) + def after_initialize + configuration.after_initialize_blocks.each do |block| + block.call + end + end + + def load_application_initializers + Dir["#{configuration.root_path}/config/initializers/**/*.rb"].sort.each do |initializer| + load(initializer) + end + end + + end + + # The Configuration class holds all the parameters for the Initializer and + # ships with defaults that suites most Rails applications. But it's possible + # to overwrite everything. Usually, you'll create an Configuration file + # implicitly through the block running on the Initializer, but it's also + # possible to create the Configuration instance in advance and pass it in + # like this: + # + # config = Rails::Configuration.new + # Rails::Initializer.run(:process, config) + class Configuration + # The application's base directory. + attr_reader :root_path + + # A stub for setting options on ActionController::Base + attr_accessor :action_controller + + # A stub for setting options on ActionMailer::Base + attr_accessor :action_mailer + + # A stub for setting options on ActionView::Base + attr_accessor :action_view + + # A stub for setting options on ActiveRecord::Base + attr_accessor :active_record + + # A stub for setting options on ActiveRecord::Base + attr_accessor :active_resource + + # Whether or not classes should be cached (set to false if you want + # application classes to be reloaded on each request) + attr_accessor :cache_classes + + # The list of paths that should be searched for controllers. (Defaults + # to <tt>app/controllers</tt> and <tt>components</tt>.) + attr_accessor :controller_paths + + # The path to the database configuration file to use. (Defaults to + # <tt>config/database.yml</tt>.) + attr_accessor :database_configuration_file + + # The list of rails framework components that should be loaded. (Defaults + # to <tt>:active_record</tt>, <tt>:action_controller</tt>, + # <tt>:action_view</tt>, <tt>:action_mailer</tt>, and + # <tt>:active_resource</tt>). + attr_accessor :frameworks + + # An array of additional paths to prepend to the load path. By default, + # all +app+, +lib+, +vendor+ and mock paths are included in this list. + attr_accessor :load_paths + + # An array of paths from which Rails will automatically load from only once. + # All elements of this array must also be in +load_paths+. + attr_accessor :load_once_paths + + # The log level to use for the default Rails logger. In production mode, + # this defaults to <tt>:info</tt>. In development mode, it defaults to + # <tt>:debug</tt>. + attr_accessor :log_level + + # The path to the log file to use. Defaults to log/#{environment}.log + # (e.g. log/development.log or log/production.log). + attr_accessor :log_path + + # The specific logger to use. By default, a logger will be created and + # initialized using #log_path and #log_level, but a programmer may + # specifically set the logger to use via this accessor and it will be + # used directly. + attr_accessor :logger + + # The root of the application's views. (Defaults to <tt>app/views</tt>.) + attr_accessor :view_path + + # Set to +true+ if you want to be warned (noisily) when you try to invoke + # any method of +nil+. Set to +false+ for the standard Ruby behavior. + attr_accessor :whiny_nils + + # The list of plugins to load. If this is set to <tt>nil</tt>, all plugins will + # be loaded. If this is set to <tt>[]</tt>, no plugins will be loaded. Otherwise, + # plugins will be loaded in the order specified. + attr_reader :plugins + def plugins=(plugins) + @plugins = plugins.nil? ? nil : plugins.map { |p| p.to_sym } + end + + # The path to the root of the plugins directory. By default, it is in + # <tt>vendor/plugins</tt>. + attr_accessor :plugin_paths + + # The classes that handle finding the desired plugins that you'd like to load for + # your application. By default it is the Rails::Plugin::FileSystemLocator which finds + # plugins to load in <tt>vendor/plugins</tt>. You can hook into gem location by subclassing + # Rails::Plugin::Locator and adding it onto the list of <tt>plugin_locators</tt>. + attr_accessor :plugin_locators + + # The class that handles loading each plugin. Defaults to Rails::Plugin::Loader, but + # a sub class would have access to fine grained modification of the loading behavior. See + # the implementation of Rails::Plugin::Loader for more details. + attr_accessor :plugin_loader + + # Deprecated options: + def breakpoint_server(_ = nil) + $stderr.puts %( + ******************************************************************* + * config.breakpoint_server has been deprecated and has no effect. * + ******************************************************************* + ) + end + alias_method :breakpoint_server=, :breakpoint_server + + # Create a new Configuration instance, initialized with the default + # values. + def initialize + set_root_path! + + self.frameworks = default_frameworks + self.load_paths = default_load_paths + self.load_once_paths = default_load_once_paths + self.log_path = default_log_path + self.log_level = default_log_level + self.view_path = default_view_path + self.controller_paths = default_controller_paths + self.cache_classes = default_cache_classes + self.whiny_nils = default_whiny_nils + self.plugins = default_plugins + self.plugin_paths = default_plugin_paths + self.plugin_locators = default_plugin_locators + self.plugin_loader = default_plugin_loader + self.database_configuration_file = default_database_configuration_file + + for framework in default_frameworks + self.send("#{framework}=", Rails::OrderedOptions.new) + end + end + + # Set the root_path to RAILS_ROOT and canonicalize it. + def set_root_path! + raise 'RAILS_ROOT is not set' unless defined?(::RAILS_ROOT) + raise 'RAILS_ROOT is not a directory' unless File.directory?(::RAILS_ROOT) + + @root_path = + # Pathname is incompatible with Windows, but Windows doesn't have + # real symlinks so File.expand_path is safe. + if RUBY_PLATFORM =~ /(:?mswin|mingw)/ + File.expand_path(::RAILS_ROOT) + + # Otherwise use Pathname#realpath which respects symlinks. + else + Pathname.new(::RAILS_ROOT).realpath.to_s + end + + Object.const_set(:RELATIVE_RAILS_ROOT, ::RAILS_ROOT.dup) unless defined?(::RELATIVE_RAILS_ROOT) + ::RAILS_ROOT.replace @root_path + end + + # Loads and returns the contents of the #database_configuration_file. The + # contents of the file are processed via ERB before being sent through + # YAML::load. + def database_configuration + YAML::load(ERB.new(IO.read(database_configuration_file)).result) + end + + # The path to the current environment's file (development.rb, etc.). By + # default the file is at <tt>config/environments/#{environment}.rb</tt>. + def environment_path + "#{root_path}/config/environments/#{environment}.rb" + end + + # Return the currently selected environment. By default, it returns the + # value of the +RAILS_ENV+ constant. + def environment + ::RAILS_ENV + end + + # Adds a block which will be executed after rails has been fully initialized. + # Useful for per-environment configuration which depends on the framework being + # fully initialized. + def after_initialize(&after_initialize_block) + after_initialize_blocks << after_initialize_block if after_initialize_block + end + + # Returns the blocks added with Configuration#after_initialize + def after_initialize_blocks + @after_initialize_blocks ||= [] + end + + # Add a preparation callback that will run before every request in development + # mode, or before the first request in production. + # + # See Dispatcher#to_prepare. + def to_prepare(&callback) + require 'dispatcher' unless defined?(::Dispatcher) + Dispatcher.to_prepare(&callback) + end + + def builtin_directories + # Include builtins only in the development environment. + (environment == 'development') ? Dir["#{RAILTIES_PATH}/builtin/*/"] : [] + end + + def framework_paths + paths = %w(railties railties/lib activesupport/lib) + paths << 'actionpack/lib' if frameworks.include? :action_controller or frameworks.include? :action_view + + [:active_record, :action_mailer, :active_resource, :action_web_service].each do |framework| + paths << "#{framework.to_s.gsub('_', '')}/lib" if frameworks.include? framework + end + + paths.map { |dir| "#{framework_root_path}/#{dir}" }.select { |dir| File.directory?(dir) } + end + + private + def framework_root_path + defined?(::RAILS_FRAMEWORK_ROOT) ? ::RAILS_FRAMEWORK_ROOT : "#{root_path}/vendor/rails" + end + + def default_frameworks + [ :active_record, :action_controller, :action_view, :action_mailer, :active_resource ] + end + + def default_load_paths + paths = ["#{root_path}/test/mocks/#{environment}"] + + # Add the app's controller directory + paths.concat(Dir["#{root_path}/app/controllers/"]) + + # Then components subdirectories. + paths.concat(Dir["#{root_path}/components/[_a-z]*"]) + + # Followed by the standard includes. + paths.concat %w( + app + app/models + app/controllers + app/helpers + app/services + components + config + lib + vendor + ).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) } + + paths.concat builtin_directories + end + + # Doesn't matter since plugins aren't in load_paths yet. + def default_load_once_paths + [] + end + + def default_log_path + File.join(root_path, 'log', "#{environment}.log") + end + + def default_log_level + environment == 'production' ? :info : :debug + end + + def default_database_configuration_file + File.join(root_path, 'config', 'database.yml') + end + + def default_view_path + File.join(root_path, 'app', 'views') + end + + def default_controller_paths + paths = [File.join(root_path, 'app', 'controllers')] + paths.concat builtin_directories + paths + end + + def default_dependency_mechanism + :load + end + + def default_cache_classes + false + end + + def default_whiny_nils + false + end + + def default_plugins + nil + end + + def default_plugin_paths + ["#{root_path}/vendor/plugins"] + end + + def default_plugin_locators + [Plugin::FileSystemLocator] + end + + def default_plugin_loader + Plugin::Loader + end + end +end + +# Needs to be duplicated from Active Support since its needed before Active +# Support is available. Here both Options and Hash are namespaced to prevent +# conflicts with other implementations AND with the classes residing in ActiveSupport. +class Rails::OrderedOptions < Array #:nodoc: + def []=(key, value) + key = key.to_sym + + if pair = find_pair(key) + pair.pop + pair << value + else + self << [key, value] + end + end + + def [](key) + pair = find_pair(key.to_sym) + pair ? pair.last : nil + end + + def method_missing(name, *args) + if name.to_s =~ /(.*)=$/ + self[$1.to_sym] = args.first + else + self[name] + end + end + + private + def find_pair(key) + self.each { |i| return i if i.first == key } + return false + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails/plugin.rb b/vendor/rails-2.0.2/railties/lib/rails/plugin.rb new file mode 100644 index 000000000..be392195d --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails/plugin.rb @@ -0,0 +1,84 @@ +module Rails + + # The Plugin class should be an object which provides the following methods: + # + # * +name+ - used during initialisation to order the plugin (based on name and + # the contents of <tt>config.plugins</tt>) + # * +valid?+ - returns true if this plugin can be loaded + # * +load_paths+ - each path within the returned array will be added to the $LOAD_PATH + # * +load+ - finally 'load' the plugin. + # + # These methods are expected by the Rails::Plugin::Locator and Rails::Plugin::Loader classes. + # The default implementation returns the <tt>lib</tt> directory as its </tt>load_paths</tt>, + # and evaluates <tt>init.rb</tt> when <tt>load</tt> is called. + class Plugin + include Comparable + + attr_reader :directory, :name + + def initialize(directory) + @directory = directory + @name = File.basename(@directory) rescue nil + @loaded = false + end + + def valid? + File.directory?(directory) && (has_lib_directory? || has_init_file?) + end + + # Returns a list of paths this plugin wishes to make available in $LOAD_PATH + def load_paths + report_nonexistant_or_empty_plugin! unless valid? + has_lib_directory? ? [lib_path] : [] + end + + # Evaluates a plugin's init.rb file + def load(initializer) + return if loaded? + report_nonexistant_or_empty_plugin! unless valid? + evaluate_init_rb(initializer) + @loaded = true + end + + def loaded? + @loaded + end + + def <=>(other_plugin) + name <=> other_plugin.name + end + + private + + def report_nonexistant_or_empty_plugin! + raise LoadError, "Can not find the plugin named: #{name}" + end + + def lib_path + File.join(directory, 'lib') + end + + def init_path + File.join(directory, 'init.rb') + end + + def has_lib_directory? + File.directory?(lib_path) + end + + def has_init_file? + File.file?(init_path) + end + + def evaluate_init_rb(initializer) + if has_init_file? + silence_warnings do + # Allow plugins to reference the current configuration object + config = initializer.configuration + + eval(IO.read(init_path), binding, init_path) + end + end + end + end +end
\ No newline at end of file diff --git a/vendor/rails-2.0.2/railties/lib/rails/plugin/loader.rb b/vendor/rails-2.0.2/railties/lib/rails/plugin/loader.rb new file mode 100644 index 000000000..438afa4d3 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails/plugin/loader.rb @@ -0,0 +1,150 @@ +require "rails/plugin" + +module Rails + class Plugin + class Loader + attr_reader :initializer + + # Creates a new Plugin::Loader instance, associated with the given + # Rails::Initializer. This default implementation automatically locates + # all plugins, and adds all plugin load paths, when it is created. The plugins + # are then fully loaded (init.rb is evaluated) when load_plugins is called. + # + # It is the loader's responsibility to ensure that only the plugins specified + # in the configuration are actually loaded, and that the order defined + # is respected. + def initialize(initializer) + @initializer = initializer + end + + # Returns the plugins to be loaded, in the order they should be loaded. + def plugins + @plugins ||= all_plugins.select { |plugin| should_load?(plugin) }.sort { |p1, p2| order_plugins(p1, p2) } + end + + # Returns all the plugins that could be found by the current locators. + def all_plugins + @all_plugins ||= locate_plugins + @all_plugins + end + + def load_plugins + plugins.each do |plugin| + plugin.load(initializer) + register_plugin_as_loaded(plugin) + end + ensure_all_registered_plugins_are_loaded! + end + + # Adds the load paths for every plugin into the $LOAD_PATH. Plugin load paths are + # added *after* the application's <tt>lib</tt> directory, to ensure that an application + # can always override code within a plugin. + # + # Plugin load paths are also added to Dependencies.load_paths, and Dependencies.load_once_paths. + def add_plugin_load_paths + plugins.each do |plugin| + plugin.load_paths.each do |path| + $LOAD_PATH.insert(application_lib_index + 1, path) + Dependencies.load_paths << path + Dependencies.load_once_paths << path + end + end + $LOAD_PATH.uniq! + end + + protected + + # The locate_plugins method uses each class in config.plugin_locators to + # find the set of all plugins available to this Rails application. + def locate_plugins + configuration.plugin_locators.map { |locator| + locator.new(initializer).plugins + }.flatten + # TODO: sorting based on config.plugins + end + + def register_plugin_as_loaded(plugin) + initializer.loaded_plugins << plugin + end + + def configuration + initializer.configuration + end + + def should_load?(plugin) + # uses Plugin#name and Plugin#valid? + enabled?(plugin) && plugin.valid? + end + + def order_plugins(plugin_a, plugin_b) + if !explicit_plugin_loading_order? + plugin_a <=> plugin_b + else + if !explicitly_enabled?(plugin_a) && !explicitly_enabled?(plugin_b) + plugin_a <=> plugin_b + else + effective_order_of(plugin_a) <=> effective_order_of(plugin_b) + end + end + end + + def effective_order_of(plugin) + if explicitly_enabled?(plugin) + registered_plugin_names.index(plugin.name) + else + registered_plugin_names.index('all') + end + end + + def application_lib_index + $LOAD_PATH.index(File.join(RAILS_ROOT, 'lib')) || 0 + end + + def enabled?(plugin) + !explicit_plugin_loading_order? || registered?(plugin) + end + + def explicit_plugin_loading_order? + !registered_plugin_names.nil? + end + + def registered?(plugin) + explicit_plugin_loading_order? && registered_plugins_names_plugin?(plugin) + end + + def explicitly_enabled?(plugin) + !explicit_plugin_loading_order? || explicitly_registered?(plugin) + end + + def explicitly_registered?(plugin) + explicit_plugin_loading_order? && registered_plugin_names.include?(plugin.name) + end + + def registered_plugins_names_plugin?(plugin) + registered_plugin_names.include?(plugin.name) || registered_plugin_names.include?('all') + end + + # The plugins that have been explicitly listed with config.plugins. If this list is nil + # then it means the client does not care which plugins or in what order they are loaded, + # so we load all in alphabetical order. If it is an empty array, we load no plugins, if it is + # non empty, we load the named plugins in the order specified. + def registered_plugin_names + configuration.plugins ? configuration.plugins.map(&:to_s) : nil + end + + def loaded?(plugin_name) + initializer.loaded_plugins.detect { |plugin| plugin.name == plugin_name.to_s } + end + + def ensure_all_registered_plugins_are_loaded! + if explicit_plugin_loading_order? + if configuration.plugins.detect {|plugin| plugin != :all && !loaded?(plugin) } + missing_plugins = configuration.plugins - (plugins + [:all]) + raise LoadError, "Could not locate the following plugins: #{missing_plugins.to_sentence}" + end + end + end + + end + end +end
\ No newline at end of file diff --git a/vendor/rails-2.0.2/railties/lib/rails/plugin/locator.rb b/vendor/rails-2.0.2/railties/lib/rails/plugin/locator.rb new file mode 100644 index 000000000..b27e904b1 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails/plugin/locator.rb @@ -0,0 +1,78 @@ +module Rails + class Plugin + + # The Plugin::Locator class should be subclasses to provide custom plugin-finding + # abilities to Rails (i.e. loading plugins from Gems, etc). Each subclass should implement + # the <tt>located_plugins</tt> method, which return an array of Plugin objects that have been found. + class Locator + include Enumerable + + attr_reader :initializer + + def initialize(initializer) + @initializer = initializer + end + + # This method should return all the plugins which this Plugin::Locator can find + # These will then be used by the current Plugin::Loader, which is responsible for actually + # loading the plugins themselves + def plugins + raise "The `plugins' method must be defined by concrete subclasses of #{self.class}" + end + + def each(&block) + plugins.each(&block) + end + + def plugin_names + plugins.map(&:name) + end + end + + # The Rails::Plugin::FileSystemLocator will try to locate plugins by examining the directories + # the the paths given in configuration.plugin_paths. Any plugins that can be found are returned + # in a list. + # + # The criteria for a valid plugin in this case is found in Rails::Plugin#valid?, although + # other subclasses of Rails::Plugin::Locator can of course use different conditions. + class FileSystemLocator < Locator + + # Returns all the plugins which can be loaded in the filesystem, under the paths given + # by configuration.plugin_paths. + def plugins + initializer.configuration.plugin_paths.flatten.inject([]) do |plugins, path| + plugins.concat locate_plugins_under(path) + plugins + end.flatten + end + + private + + # Attempts to create a plugin from the given path. If the created plugin is valid? + # (see Rails::Plugin#valid?) then the plugin instance is returned; otherwise nil. + def create_plugin(path) + plugin = Rails::Plugin.new(path) + plugin.valid? ? plugin : nil + end + + # This starts at the base path looking for valid plugins (see Rails::Plugin#valid?). + # Since plugins can be nested arbitrarily deep within an unspecified number of intermediary + # directories, this method runs recursively until it finds a plugin directory, e.g. + # + # locate_plugins_under('vendor/plugins/acts/acts_as_chunky_bacon') + # => <Rails::Plugin name: 'acts_as_chunky_bacon' ... > + # + def locate_plugins_under(base_path) + Dir.glob(File.join(base_path, '*')).inject([]) do |plugins, path| + if plugin = create_plugin(path) + plugins << plugin + elsif File.directory?(path) + plugins.concat locate_plugins_under(path) + end + plugins + end + end + + end + end +end
\ No newline at end of file diff --git a/vendor/rails-2.0.2/railties/lib/rails/version.rb b/vendor/rails-2.0.2/railties/lib/rails/version.rb new file mode 100644 index 000000000..da9064573 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails/version.rb @@ -0,0 +1,9 @@ +module Rails + module VERSION #:nodoc: + MAJOR = 2 + MINOR = 0 + TINY = 2 + + STRING = [MAJOR, MINOR, TINY].join('.') + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator.rb b/vendor/rails-2.0.2/railties/lib/rails_generator.rb new file mode 100644 index 000000000..9f0ffc156 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator.rb @@ -0,0 +1,43 @@ +#-- +# Copyright (c) 2004 Jeremy Kemper +# +# 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. +#++ + +$:.unshift(File.dirname(__FILE__)) +$:.unshift(File.dirname(__FILE__) + "/../../activesupport/lib") + +begin + require 'active_support' +rescue LoadError + require 'rubygems' + gem 'activesupport' +end + +require 'rails_generator/base' +require 'rails_generator/lookup' +require 'rails_generator/commands' + +Rails::Generator::Base.send(:include, Rails::Generator::Lookup) +Rails::Generator::Base.send(:include, Rails::Generator::Commands) + +# Set up a default logger for convenience. +require 'rails_generator/simple_logger' +Rails::Generator::Base.logger = Rails::Generator::SimpleLogger.new(STDOUT) diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/base.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/base.rb new file mode 100644 index 000000000..1ebcff906 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/base.rb @@ -0,0 +1,263 @@ +require File.dirname(__FILE__) + '/options' +require File.dirname(__FILE__) + '/manifest' +require File.dirname(__FILE__) + '/spec' +require File.dirname(__FILE__) + '/generated_attribute' + +module Rails + # Rails::Generator is a code generation platform tailored for the Rails + # web application framework. Generators are easily invoked within Rails + # applications to add and remove components such as models and controllers. + # New generators are easy to create and may be distributed as RubyGems, + # tarballs, or Rails plugins for inclusion system-wide, per-user, + # or per-application. + # + # For actual examples see the rails_generator/generators directory in the + # Rails source (or the +railties+ directory if you have frozen the Rails + # source in your application). + # + # Generators may subclass other generators to provide variations that + # require little or no new logic but replace the template files. + # + # For a RubyGem, put your generator class and templates in the +lib+ + # directory. For a Rails plugin, make a +generators+ directory at the + # root of your plugin. + # + # The layout of generator files can be seen in the built-in + # +controller+ generator: + # + # generators/ + # components/ + # controller/ + # controller_generator.rb + # templates/ + # controller.rb + # functional_test.rb + # helper.rb + # view.html.erb + # + # The directory name (+controller+) matches the name of the generator file + # (controller_generator.rb) and class (+ControllerGenerator+). The files + # that will be copied or used as templates are stored in the +templates+ + # directory. + # + # The filenames of the templates don't matter, but choose something that + # will be self-explanatory since you will be referencing these in the + # +manifest+ method inside your generator subclass. + # + # + module Generator + class GeneratorError < StandardError; end + class UsageError < GeneratorError; end + + + # The base code generator is bare-bones. It sets up the source and + # destination paths and tells the logger whether to keep its trap shut. + # + # It's useful for copying files such as stylesheets, images, or + # javascripts. + # + # For more comprehensive template-based passive code generation with + # arguments, you'll want Rails::Generator::NamedBase. + # + # Generators create a manifest of the actions they perform then hand + # the manifest to a command which replays the actions to do the heavy + # lifting (such as checking for existing files or creating directories + # if needed). Create, destroy, and list commands are included. Since a + # single manifest may be used by any command, creating new generators is + # as simple as writing some code templates and declaring what you'd like + # to do with them. + # + # The manifest method must be implemented by subclasses, returning a + # Rails::Generator::Manifest. The +record+ method is provided as a + # convenience for manifest creation. Example: + # + # class StylesheetGenerator < Rails::Generator::Base + # def manifest + # record do |m| + # m.directory('public/stylesheets') + # m.file('application.css', 'public/stylesheets/application.css') + # end + # end + # end + # + # See Rails::Generator::Commands::Create for a list of methods available + # to the manifest. + class Base + include Options + + # Declare default options for the generator. These options + # are inherited to subclasses. + default_options :collision => :ask, :quiet => false + + # A logger instance available everywhere in the generator. + cattr_accessor :logger + + # Every generator that is dynamically looked up is tagged with a + # Spec describing where it was found. + class_inheritable_accessor :spec + + attr_reader :source_root, :destination_root, :args + + def initialize(runtime_args, runtime_options = {}) + @args = runtime_args + parse!(@args, runtime_options) + + # Derive source and destination paths. + @source_root = options[:source] || File.join(spec.path, 'templates') + if options[:destination] + @destination_root = options[:destination] + elsif defined? ::RAILS_ROOT + @destination_root = ::RAILS_ROOT + end + + # Silence the logger if requested. + logger.quiet = options[:quiet] + + # Raise usage error if help is requested. + usage if options[:help] + end + + # Generators must provide a manifest. Use the +record+ method to create + # a new manifest and record your generator's actions. + def manifest + raise NotImplementedError, "No manifest for '#{spec.name}' generator." + end + + # Return the full path from the source root for the given path. + # Example for source_root = '/source': + # source_path('some/path.rb') == '/source/some/path.rb' + # + # The given path may include a colon ':' character to indicate that + # the file belongs to another generator. This notation allows any + # generator to borrow files from another. Example: + # source_path('model:fixture.yml') = '/model/source/path/fixture.yml' + def source_path(relative_source) + # Check whether we're referring to another generator's file. + name, path = relative_source.split(':', 2) + + # If not, return the full path to our source file. + if path.nil? + File.join(source_root, name) + + # Otherwise, ask our referral for the file. + else + # FIXME: this is broken, though almost always true. Others' + # source_root are not necessarily the templates dir. + File.join(self.class.lookup(name).path, 'templates', path) + end + end + + # Return the full path from the destination root for the given path. + # Example for destination_root = '/dest': + # destination_path('some/path.rb') == '/dest/some/path.rb' + def destination_path(relative_destination) + File.join(destination_root, relative_destination) + end + + protected + # Convenience method for generator subclasses to record a manifest. + def record + Rails::Generator::Manifest.new(self) { |m| yield m } + end + + # Override with your own usage banner. + def banner + "Usage: #{$0} #{spec.name} [options]" + end + + # Read USAGE from file in generator base path. + def usage_message + File.read(File.join(spec.path, 'USAGE')) rescue '' + end + end + + + # The base generator for named components: models, controllers, mailers, + # etc. The target name is taken as the first argument and inflected to + # singular, plural, class, file, and table forms for your convenience. + # The remaining arguments are aliased to +actions+ as an array for + # controller and mailer convenience. + # + # Several useful local variables and methods are populated in the + # +initialize+ method. See below for a list of Attributes and + # External Aliases available to both the manifest and to all templates. + # + # If no name is provided, the generator raises a usage error with content + # optionally read from the USAGE file in the generator's base path. + # + # For example, the +controller+ generator takes the first argument as + # the name of the class and subsequent arguments as the names of + # actions to be generated: + # + # ./script/generate controller Article index new create + # + # See Rails::Generator::Base for a discussion of manifests, + # Rails::Generator::Commands::Create for methods available to the manifest, + # and Rails::Generator for a general discussion of generators. + class NamedBase < Base + attr_reader :name, :class_name, :singular_name, :plural_name, :table_name + attr_reader :class_path, :file_path, :class_nesting, :class_nesting_depth + alias_method :file_name, :singular_name + alias_method :actions, :args + + def initialize(runtime_args, runtime_options = {}) + super + + # Name argument is required. + usage if runtime_args.empty? + + @args = runtime_args.dup + base_name = @args.shift + assign_names!(base_name) + end + + protected + # Override with your own usage banner. + def banner + "Usage: #{$0} #{spec.name} #{spec.name.camelize}Name [options]" + end + + def attributes + @attributes ||= @args.collect do |attribute| + Rails::Generator::GeneratedAttribute.new(*attribute.split(":")) + end + end + + + private + def assign_names!(name) + @name = name + base_name, @class_path, @file_path, @class_nesting, @class_nesting_depth = extract_modules(@name) + @class_name_without_nesting, @singular_name, @plural_name = inflect_names(base_name) + @table_name = (!defined?(ActiveRecord::Base) || ActiveRecord::Base.pluralize_table_names) ? plural_name : singular_name + @table_name.gsub! '/', '_' + if @class_nesting.empty? + @class_name = @class_name_without_nesting + else + @table_name = @class_nesting.underscore << "_" << @table_name + @class_name = "#{@class_nesting}::#{@class_name_without_nesting}" + end + end + + # Extract modules from filesystem-style or ruby-style path: + # good/fun/stuff + # Good::Fun::Stuff + # produce the same results. + def extract_modules(name) + modules = name.include?('/') ? name.split('/') : name.split('::') + name = modules.pop + path = modules.map { |m| m.underscore } + file_path = (path + [name.underscore]).join('/') + nesting = modules.map { |m| m.camelize }.join('::') + [name, path, file_path, nesting, modules.size] + end + + def inflect_names(name) + camel = name.camelize + under = camel.underscore + plural = under.pluralize + [camel, under, plural] + end + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/commands.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/commands.rb new file mode 100644 index 000000000..6f90a44b8 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/commands.rb @@ -0,0 +1,591 @@ +require 'delegate' +require 'optparse' +require 'fileutils' +require 'tempfile' +require 'erb' + +module Rails + module Generator + module Commands + # Here's a convenient way to get a handle on generator commands. + # Command.instance('destroy', my_generator) instantiates a Destroy + # delegate of my_generator ready to do your dirty work. + def self.instance(command, generator) + const_get(command.to_s.camelize).new(generator) + end + + # Even more convenient access to commands. Include Commands in + # the generator Base class to get a nice #command instance method + # which returns a delegate for the requested command. + def self.included(base) + base.send(:define_method, :command) do |command| + Commands.instance(command, self) + end + end + + + # Generator commands delegate Rails::Generator::Base and implement + # a standard set of actions. Their behavior is defined by the way + # they respond to these actions: Create brings life; Destroy brings + # death; List passively observes. + # + # Commands are invoked by replaying (or rewinding) the generator's + # manifest of actions. See Rails::Generator::Manifest and + # Rails::Generator::Base#manifest method that generator subclasses + # are required to override. + # + # Commands allows generators to "plug in" invocation behavior, which + # corresponds to the GoF Strategy pattern. + class Base < DelegateClass(Rails::Generator::Base) + # Replay action manifest. RewindBase subclass rewinds manifest. + def invoke! + manifest.replay(self) + end + + def dependency(generator_name, args, runtime_options = {}) + logger.dependency(generator_name) do + self.class.new(instance(generator_name, args, full_options(runtime_options))).invoke! + end + end + + # Does nothing for all commands except Create. + def class_collisions(*class_names) + end + + # Does nothing for all commands except Create. + def readme(*args) + end + + protected + def migration_directory(relative_path) + directory(@migration_directory = relative_path) + end + + def existing_migrations(file_name) + Dir.glob("#{@migration_directory}/[0-9]*_*.rb").grep(/[0-9]+_#{file_name}.rb$/) + end + + def migration_exists?(file_name) + not existing_migrations(file_name).empty? + end + + def current_migration_number + Dir.glob("#{RAILS_ROOT}/#{@migration_directory}/[0-9]*_*.rb").inject(0) do |max, file_path| + n = File.basename(file_path).split('_', 2).first.to_i + if n > max then n else max end + end + end + + def next_migration_number + current_migration_number + 1 + end + + def next_migration_string(padding = 3) + "%.#{padding}d" % next_migration_number + end + + def gsub_file(relative_destination, regexp, *args, &block) + path = destination_path(relative_destination) + content = File.read(path).gsub(regexp, *args, &block) + File.open(path, 'wb') { |file| file.write(content) } + end + + private + # Ask the user interactively whether to force collision. + def force_file_collision?(destination, src, dst, file_options = {}, &block) + $stdout.print "overwrite #{destination}? (enter \"h\" for help) [Ynaqdh] " + case $stdin.gets.chomp + when /\Ad\z/i + Tempfile.open(File.basename(destination), File.dirname(dst)) do |temp| + temp.write render_file(src, file_options, &block) + temp.rewind + $stdout.puts `#{diff_cmd} #{dst} #{temp.path}` + end + puts "retrying" + raise 'retry diff' + when /\Aa\z/i + $stdout.puts "forcing #{spec.name}" + options[:collision] = :force + when /\Aq\z/i + $stdout.puts "aborting #{spec.name}" + raise SystemExit + when /\An\z/i then :skip + when /\Ay\z/i then :force + else + $stdout.puts <<-HELP +Y - yes, overwrite +n - no, do not overwrite +a - all, overwrite this and all others +q - quit, abort +d - diff, show the differences between the old and the new +h - help, show this help +HELP + raise 'retry' + end + rescue + retry + end + + def diff_cmd + ENV['RAILS_DIFF'] || 'diff -u' + end + + def render_template_part(template_options) + # Getting Sandbox to evaluate part template in it + part_binding = template_options[:sandbox].call.sandbox_binding + part_rel_path = template_options[:insert] + part_path = source_path(part_rel_path) + + # Render inner template within Sandbox binding + rendered_part = ERB.new(File.readlines(part_path).join, nil, '-').result(part_binding) + begin_mark = template_part_mark(template_options[:begin_mark], template_options[:mark_id]) + end_mark = template_part_mark(template_options[:end_mark], template_options[:mark_id]) + begin_mark + rendered_part + end_mark + end + + def template_part_mark(name, id) + "<!--[#{name}:#{id}]-->\n" + end + end + + # Base class for commands which handle generator actions in reverse, such as Destroy. + class RewindBase < Base + # Rewind action manifest. + def invoke! + manifest.rewind(self) + end + end + + + # Create is the premier generator command. It copies files, creates + # directories, renders templates, and more. + class Create < Base + + # Check whether the given class names are already taken by + # Ruby or Rails. In the future, expand to check other namespaces + # such as the rest of the user's app. + def class_collisions(*class_names) + class_names.flatten.each do |class_name| + # Convert to string to allow symbol arguments. + class_name = class_name.to_s + + # Skip empty strings. + next if class_name.strip.empty? + + # Split the class from its module nesting. + nesting = class_name.split('::') + name = nesting.pop + + # Extract the last Module in the nesting. + last = nesting.inject(Object) { |last, nest| + break unless last.const_defined?(nest) + last.const_get(nest) + } + + # If the last Module exists, check whether the given + # class exists and raise a collision if so. + if last and last.const_defined?(name.camelize) + raise_class_collision(class_name) + end + end + end + + # Copy a file from source to destination with collision checking. + # + # The file_options hash accepts :chmod and :shebang and :collision options. + # :chmod sets the permissions of the destination file: + # file 'config/empty.log', 'log/test.log', :chmod => 0664 + # :shebang sets the #!/usr/bin/ruby line for scripts + # file 'bin/generate.rb', 'script/generate', :chmod => 0755, :shebang => '/usr/bin/env ruby' + # :collision sets the collision option only for the destination file: + # file 'settings/server.yml', 'config/server.yml', :collision => :skip + # + # Collisions are handled by checking whether the destination file + # exists and either skipping the file, forcing overwrite, or asking + # the user what to do. + def file(relative_source, relative_destination, file_options = {}, &block) + # Determine full paths for source and destination files. + source = source_path(relative_source) + destination = destination_path(relative_destination) + destination_exists = File.exist?(destination) + + # If source and destination are identical then we're done. + if destination_exists and identical?(source, destination, &block) + return logger.identical(relative_destination) + end + + # Check for and resolve file collisions. + if destination_exists + + # Make a choice whether to overwrite the file. :force and + # :skip already have their mind made up, but give :ask a shot. + choice = case (file_options[:collision] || options[:collision]).to_sym #|| :ask + when :ask then force_file_collision?(relative_destination, source, destination, file_options, &block) + when :force then :force + when :skip then :skip + else raise "Invalid collision option: #{options[:collision].inspect}" + end + + # Take action based on our choice. Bail out if we chose to + # skip the file; otherwise, log our transgression and continue. + case choice + when :force then logger.force(relative_destination) + when :skip then return(logger.skip(relative_destination)) + else raise "Invalid collision choice: #{choice}.inspect" + end + + # File doesn't exist so log its unbesmirched creation. + else + logger.create relative_destination + end + + # If we're pretending, back off now. + return if options[:pretend] + + # Write destination file with optional shebang. Yield for content + # if block given so templaters may render the source file. If a + # shebang is requested, replace the existing shebang or insert a + # new one. + File.open(destination, 'wb') do |dest| + dest.write render_file(source, file_options, &block) + end + + # Optionally change permissions. + if file_options[:chmod] + FileUtils.chmod(file_options[:chmod], destination) + end + + # Optionally add file to subversion + system("svn add #{destination}") if options[:svn] + end + + # Checks if the source and the destination file are identical. If + # passed a block then the source file is a template that needs to first + # be evaluated before being compared to the destination. + def identical?(source, destination, &block) + return false if File.directory? destination + source = block_given? ? File.open(source) {|sf| yield(sf)} : IO.read(source) + destination = IO.read(destination) + source == destination + end + + # Generate a file for a Rails application using an ERuby template. + # Looks up and evaluates a template by name and writes the result. + # + # The ERB template uses explicit trim mode to best control the + # proliferation of whitespace in generated code. <%- trims leading + # whitespace; -%> trims trailing whitespace including one newline. + # + # A hash of template options may be passed as the last argument. + # The options accepted by the file are accepted as well as :assigns, + # a hash of variable bindings. Example: + # template 'foo', 'bar', :assigns => { :action => 'view' } + # + # Template is implemented in terms of file. It calls file with a + # block which takes a file handle and returns its rendered contents. + def template(relative_source, relative_destination, template_options = {}) + file(relative_source, relative_destination, template_options) do |file| + # Evaluate any assignments in a temporary, throwaway binding. + vars = template_options[:assigns] || {} + b = binding + vars.each { |k,v| eval "#{k} = vars[:#{k}] || vars['#{k}']", b } + + # Render the source file with the temporary binding. + ERB.new(file.read, nil, '-').result(b) + end + end + + def complex_template(relative_source, relative_destination, template_options = {}) + options = template_options.dup + options[:assigns] ||= {} + options[:assigns]['template_for_inclusion'] = render_template_part(template_options) + template(relative_source, relative_destination, options) + end + + # Create a directory including any missing parent directories. + # Always directories which exist. + def directory(relative_path) + path = destination_path(relative_path) + if File.exist?(path) + logger.exists relative_path + else + logger.create relative_path + unless options[:pretend] + FileUtils.mkdir_p(path) + + # Subversion doesn't do path adds, so we need to add + # each directory individually. + # So stack up the directory tree and add the paths to + # subversion in order without recursion. + if options[:svn] + stack=[relative_path] + until File.dirname(stack.last) == stack.last # dirname('.') == '.' + stack.push File.dirname(stack.last) + end + stack.reverse_each do |rel_path| + svn_path = destination_path(rel_path) + system("svn add -N #{svn_path}") unless File.directory?(File.join(svn_path, '.svn')) + end + end + end + end + end + + # Display a README. + def readme(*relative_sources) + relative_sources.flatten.each do |relative_source| + logger.readme relative_source + puts File.read(source_path(relative_source)) unless options[:pretend] + end + end + + # When creating a migration, it knows to find the first available file in db/migrate and use the migration.rb template. + def migration_template(relative_source, relative_destination, template_options = {}) + migration_directory relative_destination + migration_file_name = template_options[:migration_file_name] || file_name + raise "Another migration is already named #{migration_file_name}: #{existing_migrations(migration_file_name).first}" if migration_exists?(migration_file_name) + template(relative_source, "#{relative_destination}/#{next_migration_string}_#{migration_file_name}.rb", template_options) + end + + def route_resources(*resources) + resource_list = resources.map { |r| r.to_sym.inspect }.join(', ') + sentinel = 'ActionController::Routing::Routes.draw do |map|' + + logger.route "map.resources #{resource_list}" + unless options[:pretend] + gsub_file 'config/routes.rb', /(#{Regexp.escape(sentinel)})/mi do |match| + "#{match}\n map.resources #{resource_list}\n" + end + end + end + + private + def render_file(path, options = {}) + File.open(path, 'rb') do |file| + if block_given? + yield file + else + content = '' + if shebang = options[:shebang] + content << "#!#{shebang}\n" + if line = file.gets + content << "line\n" if line !~ /^#!/ + end + end + content << file.read + end + end + end + + # Raise a usage error with an informative WordNet suggestion. + # Thanks to Florian Gross (flgr). + def raise_class_collision(class_name) + message = <<end_message + The name '#{class_name}' is reserved by Ruby on Rails. + Please choose an alternative and run this generator again. +end_message + if suggest = find_synonyms(class_name) + message << "\n Suggestions: \n\n" + message << suggest.join("\n") + end + raise UsageError, message + end + + SYNONYM_LOOKUP_URI = "http://wordnet.princeton.edu/cgi-bin/webwn2.0?stage=2&word=%s&posnumber=1&searchtypenumber=2&senses=&showglosses=1" + + # Look up synonyms on WordNet. Thanks to Florian Gross (flgr). + def find_synonyms(word) + require 'open-uri' + require 'timeout' + timeout(5) do + open(SYNONYM_LOOKUP_URI % word) do |stream| + data = stream.read.gsub(" ", " ").gsub("<BR>", "") + data.scan(/^Sense \d+\n.+?\n\n/m) + end + end + rescue Exception + return nil + end + end + + + # Undo the actions performed by a generator. Rewind the action + # manifest and attempt to completely erase the results of each action. + class Destroy < RewindBase + # Remove a file if it exists and is a file. + def file(relative_source, relative_destination, file_options = {}) + destination = destination_path(relative_destination) + if File.exist?(destination) + logger.rm relative_destination + unless options[:pretend] + if options[:svn] + # If the file has been marked to be added + # but has not yet been checked in, revert and delete + if options[:svn][relative_destination] + system("svn revert #{destination}") + FileUtils.rm(destination) + else + # If the directory is not in the status list, it + # has no modifications so we can simply remove it + system("svn rm #{destination}") + end + else + FileUtils.rm(destination) + end + end + else + logger.missing relative_destination + return + end + end + + # Templates are deleted just like files and the actions take the + # same parameters, so simply alias the file method. + alias_method :template, :file + + # Remove each directory in the given path from right to left. + # Remove each subdirectory if it exists and is a directory. + def directory(relative_path) + parts = relative_path.split('/') + until parts.empty? + partial = File.join(parts) + path = destination_path(partial) + if File.exist?(path) + if Dir[File.join(path, '*')].empty? + logger.rmdir partial + unless options[:pretend] + if options[:svn] + # If the directory has been marked to be added + # but has not yet been checked in, revert and delete + if options[:svn][relative_path] + system("svn revert #{path}") + FileUtils.rmdir(path) + else + # If the directory is not in the status list, it + # has no modifications so we can simply remove it + system("svn rm #{path}") + end + else + FileUtils.rmdir(path) + end + end + else + logger.notempty partial + end + else + logger.missing partial + end + parts.pop + end + end + + def complex_template(*args) + # nothing should be done here + end + + # When deleting a migration, it knows to delete every file named "[0-9]*_#{file_name}". + def migration_template(relative_source, relative_destination, template_options = {}) + migration_directory relative_destination + + migration_file_name = template_options[:migration_file_name] || file_name + unless migration_exists?(migration_file_name) + puts "There is no migration named #{migration_file_name}" + return + end + + + existing_migrations(migration_file_name).each do |file_path| + file(relative_source, file_path, template_options) + end + end + + def route_resources(*resources) + resource_list = resources.map { |r| r.to_sym.inspect }.join(', ') + look_for = "\n map.resources #{resource_list}\n" + logger.route "map.resources #{resource_list}" + gsub_file 'config/routes.rb', /(#{look_for})/mi, '' + end + end + + + # List a generator's action manifest. + class List < Base + def dependency(generator_name, args, options = {}) + logger.dependency "#{generator_name}(#{args.join(', ')}, #{options.inspect})" + end + + def class_collisions(*class_names) + logger.class_collisions class_names.join(', ') + end + + def file(relative_source, relative_destination, options = {}) + logger.file relative_destination + end + + def template(relative_source, relative_destination, options = {}) + logger.template relative_destination + end + + def complex_template(relative_source, relative_destination, options = {}) + logger.template "#{options[:insert]} inside #{relative_destination}" + end + + def directory(relative_path) + logger.directory "#{destination_path(relative_path)}/" + end + + def readme(*args) + logger.readme args.join(', ') + end + + def migration_template(relative_source, relative_destination, options = {}) + migration_directory relative_destination + logger.migration_template file_name + end + + def route_resources(*resources) + resource_list = resources.map { |r| r.to_sym.inspect }.join(', ') + logger.route "map.resources #{resource_list}" + end + end + + # Update generator's action manifest. + class Update < Create + def file(relative_source, relative_destination, options = {}) + # logger.file relative_destination + end + + def template(relative_source, relative_destination, options = {}) + # logger.template relative_destination + end + + def complex_template(relative_source, relative_destination, template_options = {}) + + begin + dest_file = destination_path(relative_destination) + source_to_update = File.readlines(dest_file).join + rescue Errno::ENOENT + logger.missing relative_destination + return + end + + logger.refreshing "#{template_options[:insert].gsub(/\.erb/,'')} inside #{relative_destination}" + + begin_mark = Regexp.quote(template_part_mark(template_options[:begin_mark], template_options[:mark_id])) + end_mark = Regexp.quote(template_part_mark(template_options[:end_mark], template_options[:mark_id])) + + # Refreshing inner part of the template with freshly rendered part. + rendered_part = render_template_part(template_options) + source_to_update.gsub!(/#{begin_mark}.*?#{end_mark}/m, rendered_part) + + File.open(dest_file, 'w') { |file| file.write(source_to_update) } + end + + def directory(relative_path) + # logger.directory "#{destination_path(relative_path)}/" + end + end + + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generated_attribute.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generated_attribute.rb new file mode 100644 index 000000000..25af3931d --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generated_attribute.rb @@ -0,0 +1,42 @@ +require 'optparse' + +module Rails + module Generator + class GeneratedAttribute + attr_accessor :name, :type, :column + + def initialize(name, type) + @name, @type = name, type.to_sym + @column = ActiveRecord::ConnectionAdapters::Column.new(name, nil, @type) + end + + def field_type + @field_type ||= case type + when :integer, :float, :decimal then :text_field + when :datetime, :timestamp, :time then :datetime_select + when :date then :date_select + when :string then :text_field + when :text then :text_area + when :boolean then :check_box + else + :text_field + end + end + + def default + @default ||= case type + when :integer then 1 + when :float then 1.5 + when :decimal then "9.99" + when :datetime, :timestamp, :time then Time.now.to_s(:db) + when :date then Date.today.to_s(:db) + when :string then "MyString" + when :text then "MyText" + when :boolean then false + else + "" + end + end + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/applications/app/USAGE b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/applications/app/USAGE new file mode 100644 index 000000000..36d6061a5 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/applications/app/USAGE @@ -0,0 +1,9 @@ +Description: + The 'rails' command creates a new Rails application with a default + directory structure and configuration at the path you specify. + +Example: + rails ~/Code/Ruby/weblog + + This generates a skeletal Rails installation in ~/Code/Ruby/weblog. + See the README in the newly created application to get going. diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/applications/app/app_generator.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/applications/app/app_generator.rb new file mode 100644 index 000000000..1dd72f349 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/applications/app/app_generator.rb @@ -0,0 +1,179 @@ +require 'rbconfig' +require 'digest/md5' +require 'rails_generator/secret_key_generator' + +class AppGenerator < Rails::Generator::Base + DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'], + Config::CONFIG['ruby_install_name']) + + DATABASES = %w(mysql oracle postgresql sqlite2 sqlite3 frontbase) + + default_options :db => (ENV["RAILS_DEFAULT_DATABASE"] || "sqlite3"), + :shebang => DEFAULT_SHEBANG, :freeze => false + mandatory_options :source => "#{File.dirname(__FILE__)}/../../../../.." + + def initialize(runtime_args, runtime_options = {}) + super + usage if args.empty? + usage("Databases supported for preconfiguration are: #{DATABASES.join(", ")}") if (options[:db] && !DATABASES.include?(options[:db])) + @destination_root = args.shift + @app_name = File.basename(File.expand_path(@destination_root)) + end + + def manifest + # Use /usr/bin/env if no special shebang was specified + script_options = { :chmod => 0755, :shebang => options[:shebang] == DEFAULT_SHEBANG ? nil : options[:shebang] } + dispatcher_options = { :chmod => 0755, :shebang => options[:shebang] } + + # duplicate CGI::Session#generate_unique_id + md5 = Digest::MD5.new + now = Time.now + md5 << now.to_s + md5 << String(now.usec) + md5 << String(rand(0)) + md5 << String($$) + md5 << @app_name + + # Do our best to generate a secure secret key for CookieStore + secret = Rails::SecretKeyGenerator.new(@app_name).generate_secret + + record do |m| + # Root directory and all subdirectories. + m.directory '' + BASEDIRS.each { |path| m.directory path } + + # Root + m.file "fresh_rakefile", "Rakefile" + m.file "README", "README" + + # Application + m.template "helpers/application.rb", "app/controllers/application.rb", :assigns => { :app_name => @app_name, :app_secret => md5.hexdigest } + m.template "helpers/application_helper.rb", "app/helpers/application_helper.rb" + m.template "helpers/test_helper.rb", "test/test_helper.rb" + + # database.yml and .htaccess + m.template "configs/databases/#{options[:db]}.yml", "config/database.yml", :assigns => { + :app_name => @app_name, + :socket => options[:db] == "mysql" ? mysql_socket_location : nil + } + m.template "configs/routes.rb", "config/routes.rb" + m.template "configs/apache.conf", "public/.htaccess" + + # Initializers + m.template "configs/initializers/inflections.rb", "config/initializers/inflections.rb" + m.template "configs/initializers/mime_types.rb", "config/initializers/mime_types.rb" + + # Environments + m.file "environments/boot.rb", "config/boot.rb" + m.template "environments/environment.rb", "config/environment.rb", :assigns => { :freeze => options[:freeze], :app_name => @app_name, :app_secret => secret } + m.file "environments/production.rb", "config/environments/production.rb" + m.file "environments/development.rb", "config/environments/development.rb" + m.file "environments/test.rb", "config/environments/test.rb" + + # Scripts + %w( about console destroy generate performance/benchmarker performance/profiler performance/request process/reaper process/spawner process/inspector runner server plugin ).each do |file| + m.file "bin/#{file}", "script/#{file}", script_options + end + + # Dispatches + m.file "dispatches/dispatch.rb", "public/dispatch.rb", dispatcher_options + m.file "dispatches/dispatch.rb", "public/dispatch.cgi", dispatcher_options + m.file "dispatches/dispatch.fcgi", "public/dispatch.fcgi", dispatcher_options + + # HTML files + %w(404 422 500 index).each do |file| + m.template "html/#{file}.html", "public/#{file}.html" + end + + m.template "html/favicon.ico", "public/favicon.ico" + m.template "html/robots.txt", "public/robots.txt" + m.file "html/images/rails.png", "public/images/rails.png" + + # Javascripts + m.file "html/javascripts/prototype.js", "public/javascripts/prototype.js" + m.file "html/javascripts/effects.js", "public/javascripts/effects.js" + m.file "html/javascripts/dragdrop.js", "public/javascripts/dragdrop.js" + m.file "html/javascripts/controls.js", "public/javascripts/controls.js" + m.file "html/javascripts/application.js", "public/javascripts/application.js" + + # Docs + m.file "doc/README_FOR_APP", "doc/README_FOR_APP" + + # Logs + %w(server production development test).each { |file| + m.file "configs/empty.log", "log/#{file}.log", :chmod => 0666 + } + end + end + + protected + def banner + "Usage: #{$0} /path/to/your/app [options]" + end + + def add_options!(opt) + opt.separator '' + opt.separator 'Options:' + opt.on("-r", "--ruby=path", String, + "Path to the Ruby binary of your choice (otherwise scripts use env, dispatchers current path).", + "Default: #{DEFAULT_SHEBANG}") { |v| options[:shebang] = v } + + opt.on("-d", "--database=name", String, + "Preconfigure for selected database (options: mysql/oracle/postgresql/sqlite2/sqlite3).", + "Default: mysql") { |v| options[:db] = v } + + opt.on("-f", "--freeze", + "Freeze Rails in vendor/rails from the gems generating the skeleton", + "Default: false") { |v| options[:freeze] = v } + end + + def mysql_socket_location + MYSQL_SOCKET_LOCATIONS.find { |f| File.exist?(f) } unless RUBY_PLATFORM =~ /(:?mswin|mingw)/ + end + + + # Installation skeleton. Intermediate directories are automatically + # created so don't sweat their absence here. + BASEDIRS = %w( + app/controllers + app/helpers + app/models + app/views/layouts + config/environments + config/initializers + db + doc + lib + lib/tasks + log + public/images + public/javascripts + public/stylesheets + script/performance + script/process + test/fixtures + test/functional + test/integration + test/mocks/development + test/mocks/test + test/unit + vendor + vendor/plugins + tmp/sessions + tmp/sockets + tmp/cache + tmp/pids + ) + + MYSQL_SOCKET_LOCATIONS = [ + "/tmp/mysql.sock", # default + "/var/run/mysqld/mysqld.sock", # debian/gentoo + "/var/tmp/mysql.sock", # freebsd + "/var/lib/mysql/mysql.sock", # fedora + "/opt/local/lib/mysql/mysql.sock", # fedora + "/opt/local/var/run/mysqld/mysqld.sock", # mac + darwinports + mysql + "/opt/local/var/run/mysql4/mysqld.sock", # mac + darwinports + mysql4 + "/opt/local/var/run/mysql5/mysqld.sock", # mac + darwinports + mysql5 + "/opt/lampp/var/mysql/mysql.sock" # xampp for linux + ] +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/USAGE b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/USAGE new file mode 100644 index 000000000..d4fae60c8 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/USAGE @@ -0,0 +1,29 @@ +Description: + Stubs out a new controller and its views. Pass the controller name, either + CamelCased or under_scored, and a list of views as arguments. + + To create a controller within a module, specify the controller name as a + path like 'parent_module/controller_name'. + + This generates a controller class in app/controllers, view templates in + app/views/controller_name, a helper class in app/helpers, and a functional + test suite in test/functional. + +Example: + `./script/generate controller CreditCard open debit credit close` + + Credit card controller with URLs like /credit_card/debit. + Controller: app/controllers/credit_card_controller.rb + Views: app/views/credit_card/debit.html.erb [...] + Helper: app/helpers/credit_card_helper.rb + Test: test/functional/credit_card_controller_test.rb + +Modules Example: + `./script/generate controller 'admin/credit_card' suspend late_fee` + + Credit card admin controller with URLs /admin/credit_card/suspend. + Controller: app/controllers/admin/credit_card_controller.rb + Views: app/views/admin/credit_card/debit.html.erb [...] + Helper: app/helpers/admin/credit_card_helper.rb + Test: test/functional/admin/credit_card_controller_test.rb + diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/controller_generator.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/controller_generator.rb new file mode 100644 index 000000000..c37ff4583 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/controller_generator.rb @@ -0,0 +1,37 @@ +class ControllerGenerator < Rails::Generator::NamedBase + def manifest + record do |m| + # Check for class naming collisions. + m.class_collisions class_path, "#{class_name}Controller", "#{class_name}ControllerTest", "#{class_name}Helper" + + # Controller, helper, views, and test directories. + m.directory File.join('app/controllers', class_path) + m.directory File.join('app/helpers', class_path) + m.directory File.join('app/views', class_path, file_name) + m.directory File.join('test/functional', class_path) + + # Controller class, functional test, and helper class. + m.template 'controller.rb', + File.join('app/controllers', + class_path, + "#{file_name}_controller.rb") + + m.template 'functional_test.rb', + File.join('test/functional', + class_path, + "#{file_name}_controller_test.rb") + + m.template 'helper.rb', + File.join('app/helpers', + class_path, + "#{file_name}_helper.rb") + + # View template for each action. + actions.each do |action| + path = File.join('app/views', class_path, file_name, "#{action}.html.erb") + m.template 'view.html.erb', path, + :assigns => { :action => action, :path => path } + end + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/templates/controller.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/templates/controller.rb new file mode 100644 index 000000000..da71b5f05 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/templates/controller.rb @@ -0,0 +1,10 @@ +class <%= class_name %>Controller < ApplicationController +<% if options[:scaffold] -%> + scaffold :<%= singular_name %> +<% end -%> +<% for action in actions -%> + + def <%= action %> + end +<% end -%> +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb new file mode 100644 index 000000000..935beafa6 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb @@ -0,0 +1,8 @@ +require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper' + +class <%= class_name %>ControllerTest < ActionController::TestCase + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/templates/helper.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/templates/helper.rb new file mode 100644 index 000000000..3fe2ecdc7 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/templates/helper.rb @@ -0,0 +1,2 @@ +module <%= class_name %>Helper +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/templates/view.html.erb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/templates/view.html.erb new file mode 100644 index 000000000..ad85431f9 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/controller/templates/view.html.erb @@ -0,0 +1,2 @@ +<h1><%= class_name %>#<%= action %></h1> +<p>Find me in <%= path %></p> diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/integration_test/USAGE b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/integration_test/USAGE new file mode 100644 index 000000000..09e2691f6 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/integration_test/USAGE @@ -0,0 +1,8 @@ +Description: + Stubs out a new integration test. Pass the name of the test, either + CamelCased or under_scored, as an argument. The new test class is + generated in test/integration/testname_test.rb + +Example: + `./script/generate integration_test GeneralStories` creates a GeneralStories + integration test in test/integration/general_stories_test.rb diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/integration_test/integration_test_generator.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/integration_test/integration_test_generator.rb new file mode 100644 index 000000000..90fa96938 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/integration_test/integration_test_generator.rb @@ -0,0 +1,16 @@ +class IntegrationTestGenerator < Rails::Generator::NamedBase + default_options :skip_migration => false + + def manifest + record do |m| + # Check for class naming collisions. + m.class_collisions class_path, class_name, "#{class_name}Test" + + # integration test directory + m.directory File.join('test/integration', class_path) + + # integration test stub + m.template 'integration_test.rb', File.join('test/integration', class_path, "#{file_name}_test.rb") + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb new file mode 100644 index 000000000..61688aee4 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/integration_test/templates/integration_test.rb @@ -0,0 +1,10 @@ +require "#{File.dirname(__FILE__)}<%= '/..' * class_nesting_depth %>/../test_helper" + +class <%= class_name %>Test < ActionController::IntegrationTest + # fixtures :your, :models + + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/USAGE b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/USAGE new file mode 100644 index 000000000..61a649ed4 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/USAGE @@ -0,0 +1,16 @@ +Description: + Stubs out a new mailer and its views. Pass the mailer name, either + CamelCased or under_scored, and an optional list of emails as arguments. + + This generates a mailer class in app/models, view templates in + app/views/mailer_name, a unit test in test/unit, and fixtures in + test/fixtures. + +Example: + `./script/generate mailer Notifications signup forgot_password invoice` + + creates a Notifications mailer class, views, test, and fixtures: + Mailer: app/models/notifications.rb + Views: app/views/notifications/signup.erb [...] + Test: test/unit/test/unit/notifications_test.rb + Fixtures: test/fixtures/notifications/signup [...] diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/mailer_generator.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/mailer_generator.rb new file mode 100644 index 000000000..3ff4f0397 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/mailer_generator.rb @@ -0,0 +1,34 @@ +class MailerGenerator < Rails::Generator::NamedBase + def manifest + record do |m| + # Check for class naming collisions. + m.class_collisions class_path, class_name, "#{class_name}Test" + + # Mailer, view, test, and fixture directories. + m.directory File.join('app/models', class_path) + m.directory File.join('app/views', file_path) + m.directory File.join('test/unit', class_path) + m.directory File.join('test/fixtures', file_path) + + # Mailer class and unit test. + m.template "mailer.rb", File.join('app/models', + class_path, + "#{file_name}.rb") + m.template "unit_test.rb", File.join('test/unit', + class_path, + "#{file_name}_test.rb") + + # View template and fixture for each action. + actions.each do |action| + relative_path = File.join(file_path, action) + view_path = File.join('app/views', "#{relative_path}.erb") + fixture_path = File.join('test/fixtures', relative_path) + + m.template "view.erb", view_path, + :assigns => { :action => action, :path => view_path } + m.template "fixture.erb", fixture_path, + :assigns => { :action => action, :path => view_path } + end + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/fixture.erb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/fixture.erb new file mode 100644 index 000000000..6899257dd --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/fixture.erb @@ -0,0 +1,3 @@ +<%= class_name %>#<%= action %> + +Find me in <%= path %> diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/mailer.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/mailer.rb new file mode 100644 index 000000000..127495fcb --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/mailer.rb @@ -0,0 +1,13 @@ +class <%= class_name %> < ActionMailer::Base +<% for action in actions -%> + + def <%= action %>(sent_at = Time.now) + @subject = '<%= class_name %>#<%= action %>' + @body = {} + @recipients = '' + @from = '' + @sent_on = sent_at + @headers = {} + end +<% end -%> +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/unit_test.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/unit_test.rb new file mode 100644 index 000000000..dcd020621 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/unit_test.rb @@ -0,0 +1,21 @@ +require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper' + +class <%= class_name %>Test < ActionMailer::TestCase + tests <%= class_name %> +<% for action in actions -%> + def test_<%= action %> + @expected.subject = '<%= class_name %>#<%= action %>' + @expected.body = read_fixture('<%= action %>') + @expected.date = Time.now + + assert_equal @expected.encoded, <%= class_name %>.create_<%= action %>(@expected.date).encoded + end + +<% end -%> +<% if actions.blank? -%> + # replace this with your real tests + def test_truth + assert true + end +<% end -%> +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/view.erb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/view.erb new file mode 100644 index 000000000..6899257dd --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/view.erb @@ -0,0 +1,3 @@ +<%= class_name %>#<%= action %> + +Find me in <%= path %> diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/view.rhtml b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/view.rhtml new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/mailer/templates/view.rhtml diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/migration/USAGE b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/migration/USAGE new file mode 100644 index 000000000..3e914a5d7 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/migration/USAGE @@ -0,0 +1,29 @@ +Description: + Stubs out a new database migration. Pass the migration name, either + CamelCased or under_scored, and an optional list of attribute pairs as arguments. + + A migration class is generated in db/migrate prefixed by the latest migration number. + + You can name your migration in either of these formats to generate add/remove + column lines from supplied attributes: AddColumnsToTable or RemoveColumnsFromTable + +Example: + `./script/generate migration AddSslFlag` + + With 4 existing migrations, this creates the AddSslFlag migration in + db/migrate/005_add_ssl_flag.rb + + `./script/generate migration AddTitleBodyToPost title:string body:text published:boolean` + + This will create the AddTitleBodyToPost in db/migrate/005_add_title_body_to_post.rb with + this in the Up migration: + + add_column :posts, :title, :string + add_column :posts, :body, :text + add_column :posts, :published, :boolean + + And this in the Down migration: + + remove_column :posts, :published + remove_column :posts, :body + remove_column :posts, :title diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/migration/migration_generator.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/migration/migration_generator.rb new file mode 100644 index 000000000..acf41e07d --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/migration/migration_generator.rb @@ -0,0 +1,20 @@ +class MigrationGenerator < Rails::Generator::NamedBase + def manifest + record do |m| + m.migration_template 'migration.rb', 'db/migrate', :assigns => get_local_assigns + end + end + + + private + def get_local_assigns + returning(assigns = {}) do + if class_name.underscore =~ /^(add|remove)_.*_(?:to|from)_(.*)/ + assigns[:migration_action] = $1 + assigns[:table_name] = $2.pluralize + else + assigns[:attributes] = [] + end + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/migration/templates/migration.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/migration/templates/migration.rb new file mode 100644 index 000000000..ca35a4322 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/migration/templates/migration.rb @@ -0,0 +1,11 @@ +class <%= class_name.underscore.camelize %> < ActiveRecord::Migration + def self.up<% attributes.each do |attribute| %> + <%= migration_action %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type %><% end -%> + <%- end %> + end + + def self.down<% attributes.reverse.each do |attribute| %> + <%= migration_action == 'add' ? 'remove' : 'add' %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'remove' %>, :<%= attribute.type %><% end -%> + <%- end %> + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/USAGE b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/USAGE new file mode 100644 index 000000000..24b03b4d4 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/USAGE @@ -0,0 +1,27 @@ +Description: + Stubs out a new model. Pass the model name, either CamelCased or + under_scored, and an optional list of attribute pairs as arguments. + + Attribute pairs are column_name:sql_type arguments specifying the + model's attributes. Timestamps are added by default, so you don't have to + specify them by hand as 'created_at:datetime updated_at:datetime'. + + You don't have to think up every attribute up front, but it helps to + sketch out a few so you can start working with the model immediately. + + This generates a model class in app/models, a unit test in test/unit, + a test fixture in test/fixtures/singular_name.yml, and a migration in + db/migrate. + +Examples: + `./script/generate model account` + + creates an Account model, test, fixture, and migration: + Model: app/models/account.rb + Test: test/unit/account_test.rb + Fixtures: test/fixtures/accounts.yml + Migration: db/migrate/XXX_add_accounts.rb + + `./script/generate model post title:string body:text published:boolean` + + creates a Post model with a string title, text body, and published flag. diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/model_generator.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/model_generator.rb new file mode 100644 index 000000000..9be9cad8b --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/model_generator.rb @@ -0,0 +1,45 @@ +class ModelGenerator < Rails::Generator::NamedBase + default_options :skip_timestamps => false, :skip_migration => false, :skip_fixture => false + + def manifest + record do |m| + # Check for class naming collisions. + m.class_collisions class_path, class_name, "#{class_name}Test" + + # Model, test, and fixture directories. + m.directory File.join('app/models', class_path) + m.directory File.join('test/unit', class_path) + m.directory File.join('test/fixtures', class_path) + + # Model class, unit test, and fixtures. + m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb") + m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb") + + unless options[:skip_fixture] + m.template 'fixtures.yml', File.join('test/fixtures', "#{table_name}.yml") + end + + unless options[:skip_migration] + m.migration_template 'migration.rb', 'db/migrate', :assigns => { + :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}" + }, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}" + end + end + end + + protected + def banner + "Usage: #{$0} #{spec.name} ModelName [field:type, field:type]" + end + + def add_options!(opt) + opt.separator '' + opt.separator 'Options:' + opt.on("--skip-timestamps", + "Don't add timestamps to the migration file for this model") { |v| options[:skip_timestamps] = v } + opt.on("--skip-migration", + "Don't generate a migration file for this model") { |v| options[:skip_migration] = v } + opt.on("--skip-fixture", + "Don't generation a fixture file for this model") { |v| options[:skip_fixture] = v} + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml new file mode 100644 index 000000000..c21035113 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml @@ -0,0 +1,19 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html + +<% unless attributes.empty? -%> +one: +<% for attribute in attributes -%> + <%= attribute.name %>: <%= attribute.default %> +<% end -%> + +two: +<% for attribute in attributes -%> + <%= attribute.name %>: <%= attribute.default %> +<% end -%> +<% else -%> +# one: +# column: value +# +# two: +# column: value +<% end -%> diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/templates/migration.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/templates/migration.rb new file mode 100644 index 000000000..382fd1156 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/templates/migration.rb @@ -0,0 +1,16 @@ +class <%= migration_name %> < ActiveRecord::Migration + def self.up + create_table :<%= table_name %> do |t| +<% for attribute in attributes -%> + t.<%= attribute.type %> :<%= attribute.name %> +<% end -%> +<% unless options[:skip_timestamps] %> + t.timestamps +<% end -%> + end + end + + def self.down + drop_table :<%= table_name %> + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/templates/model.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/templates/model.rb new file mode 100644 index 000000000..8d4c89e91 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/templates/model.rb @@ -0,0 +1,2 @@ +class <%= class_name %> < ActiveRecord::Base +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb new file mode 100644 index 000000000..9bb3ca416 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb @@ -0,0 +1,8 @@ +require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper' + +class <%= class_name %>Test < ActiveSupport::TestCase + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/observer/USAGE b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/observer/USAGE new file mode 100644 index 000000000..a5d744a3c --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/observer/USAGE @@ -0,0 +1,13 @@ +Description: + Stubs out a new observer. Pass the observer name, either CamelCased or + under_scored, as an argument. + + The generator creates an observer class in app/models and a unit test in + test/unit. + +Example: + `./script/generate observer Account` + + creates an Account observer and unit test: + Observer: app/models/account_observer.rb + Test: test/unit/account_observer_test.rb diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/observer/observer_generator.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/observer/observer_generator.rb new file mode 100644 index 000000000..18fbd32b7 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/observer/observer_generator.rb @@ -0,0 +1,16 @@ +class ObserverGenerator < Rails::Generator::NamedBase + def manifest + record do |m| + # Check for class naming collisions. + m.class_collisions class_path, "#{class_name}Observer", "#{class_name}ObserverTest" + + # Observer, and test directories. + m.directory File.join('app/models', class_path) + m.directory File.join('test/unit', class_path) + + # Observer class and unit test fixtures. + m.template 'observer.rb', File.join('app/models', class_path, "#{file_name}_observer.rb") + m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_observer_test.rb") + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/observer/templates/observer.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/observer/templates/observer.rb new file mode 100644 index 000000000..b9a300416 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/observer/templates/observer.rb @@ -0,0 +1,2 @@ +class <%= class_name %>Observer < ActiveRecord::Observer +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/observer/templates/unit_test.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/observer/templates/unit_test.rb new file mode 100644 index 000000000..b432f04fc --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/observer/templates/unit_test.rb @@ -0,0 +1,8 @@ +require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper' + +class <%= class_name %>ObserverTest < Test::Unit::TestCase + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/USAGE b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/USAGE new file mode 100644 index 000000000..d2ecfc2d5 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/USAGE @@ -0,0 +1,25 @@ +Description: + Stubs out a new plugin. Pass the plugin name, either CamelCased or + under_scored, as an argument. Pass --with-generator to add an example + generator also. + + This creates a plugin in vendor/plugins including an init.rb and README + as well as standard lib, task, and test directories. + +Example: + `./script/generate plugin BrowserFilters` + + creates a standard browser_filters plugin: + vendor/plugins/browser_filters/README + vendor/plugins/browser_filters/init.rb + vendor/plugins/browser_filters/install.rb + vendor/plugins/browser_filters/lib/browser_filters.rb + vendor/plugins/browser_filters/test/browser_filters_test.rb + vendor/plugins/browser_filters/tasks/browser_filters_tasks.rake + + ./script/generate plugin BrowserFilters --with-generator + + creates a browser_filters generator also: + vendor/plugins/browser_filters/generators/browser_filters/browser_filters_generator.rb + vendor/plugins/browser_filters/generators/browser_filters/USAGE + vendor/plugins/browser_filters/generators/browser_filters/templates/ diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/plugin_generator.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/plugin_generator.rb new file mode 100644 index 000000000..7a619825a --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/plugin_generator.rb @@ -0,0 +1,39 @@ +class PluginGenerator < Rails::Generator::NamedBase + attr_reader :plugin_path + + def initialize(runtime_args, runtime_options = {}) + @with_generator = runtime_args.delete("--with-generator") + super + @plugin_path = "vendor/plugins/#{file_name}" + end + + def manifest + record do |m| + # Check for class naming collisions. + m.class_collisions class_path, class_name + + m.directory "#{plugin_path}/lib" + m.directory "#{plugin_path}/tasks" + m.directory "#{plugin_path}/test" + + m.template 'README', "#{plugin_path}/README" + m.template 'MIT-LICENSE', "#{plugin_path}/MIT-LICENSE" + m.template 'Rakefile', "#{plugin_path}/Rakefile" + m.template 'init.rb', "#{plugin_path}/init.rb" + m.template 'install.rb', "#{plugin_path}/install.rb" + m.template 'uninstall.rb', "#{plugin_path}/uninstall.rb" + m.template 'plugin.rb', "#{plugin_path}/lib/#{file_name}.rb" + m.template 'tasks.rake', "#{plugin_path}/tasks/#{file_name}_tasks.rake" + m.template 'unit_test.rb', "#{plugin_path}/test/#{file_name}_test.rb" + + if @with_generator + m.directory "#{plugin_path}/generators" + m.directory "#{plugin_path}/generators/#{file_name}" + m.directory "#{plugin_path}/generators/#{file_name}/templates" + + m.template 'generator.rb', "#{plugin_path}/generators/#{file_name}/#{file_name}_generator.rb" + m.template 'USAGE', "#{plugin_path}/generators/#{file_name}/USAGE" + end + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/MIT-LICENSE b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/MIT-LICENSE new file mode 100644 index 000000000..8717df053 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/MIT-LICENSE @@ -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. diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/README b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/README new file mode 100644 index 000000000..702db07cb --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/README @@ -0,0 +1,13 @@ +<%= class_name %> +<%= "=" * class_name.size %> + +Introduction goes here. + + +Example +======= + +Example goes here. + + +Copyright (c) <%= Date.today.year %> [name of plugin creator], released under the MIT license diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/Rakefile b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/Rakefile new file mode 100755 index 000000000..1824fb10f --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/Rakefile @@ -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 diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/USAGE b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/USAGE new file mode 100644 index 000000000..ea9f4f12c --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/USAGE @@ -0,0 +1,8 @@ +Description: + Explain the generator + +Example: + ./script/generate <%= file_name %> Thing + + This will create: + what/will/it/create diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/generator.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/generator.rb new file mode 100644 index 000000000..3e800df6c --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/generator.rb @@ -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 diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/init.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/init.rb new file mode 100644 index 000000000..3c19a743c --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/init.rb @@ -0,0 +1 @@ +# Include hook code here diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/install.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/install.rb new file mode 100644 index 000000000..f7732d379 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/install.rb @@ -0,0 +1 @@ +# Install hook code here diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/plugin.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/plugin.rb new file mode 100644 index 000000000..d8d908a95 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/plugin.rb @@ -0,0 +1 @@ +# <%= class_name %> diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/tasks.rake b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/tasks.rake new file mode 100644 index 000000000..72920a9d3 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/tasks.rake @@ -0,0 +1,4 @@ +# desc "Explaining what the task does" +# task :<%= file_name %> do +# # Task goes here +# end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/uninstall.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/uninstall.rb new file mode 100644 index 000000000..973833346 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/uninstall.rb @@ -0,0 +1 @@ +# Uninstall hook code here diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/unit_test.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/unit_test.rb new file mode 100644 index 000000000..9028b84b7 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/plugin/templates/unit_test.rb @@ -0,0 +1,8 @@ +require 'test/unit' + +class <%= class_name %>Test < Test::Unit::TestCase + # Replace this with your real tests. + def test_this_plugin + flunk + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/resource/USAGE b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/resource/USAGE new file mode 100644 index 000000000..83cc9d765 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/resource/USAGE @@ -0,0 +1,23 @@ +Description: + Stubs out a new resource including an empty model and controller suitable + for a restful, resource-oriented application. Pass the singular model name, + either CamelCased or under_scored, as the first argument, and an optional + list of attribute pairs. + + Attribute pairs are column_name:sql_type arguments specifying the + model's attributes. Timestamps are added by default, so you don't have to + specify them by hand as 'created_at:datetime updated_at:datetime'. + + You don't have to think up every attribute up front, but it helps to + sketch out a few so you can start working with the resource immediately. + + This creates a model, controller, tests and fixtures for both, and the + corresponding map.resources declaration in config/routes.rb + + Unlike the scaffold generator, the resource generator does not create + views or add any methods to the generated controller. + +Examples: + `./script/generate resource post` # no attributes + `./script/generate resource post title:string body:text published:boolean` + `./script/generate resource purchase order_id:integer amount:decimal` diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/resource/resource_generator.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/resource/resource_generator.rb new file mode 100644 index 000000000..d5491ece3 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/resource/resource_generator.rb @@ -0,0 +1,74 @@ +class ResourceGenerator < Rails::Generator::NamedBase + default_options :skip_timestamps => false, :skip_migration => false + + attr_reader :controller_name, + :controller_class_path, + :controller_file_path, + :controller_class_nesting, + :controller_class_nesting_depth, + :controller_class_name, + :controller_singular_name, + :controller_plural_name + alias_method :controller_file_name, :controller_singular_name + alias_method :controller_table_name, :controller_plural_name + + def initialize(runtime_args, runtime_options = {}) + super + + @controller_name = @name.pluralize + + base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name) + @controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name) + + if @controller_class_nesting.empty? + @controller_class_name = @controller_class_name_without_nesting + else + @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}" + end + end + + def manifest + record do |m| + # Check for class naming collisions. + m.class_collisions(controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}Helper") + m.class_collisions(class_path, "#{class_name}") + + # Controller, helper, views, and test directories. + m.directory(File.join('app/models', class_path)) + m.directory(File.join('app/controllers', controller_class_path)) + m.directory(File.join('app/helpers', controller_class_path)) + m.directory(File.join('app/views', controller_class_path, controller_file_name)) + m.directory(File.join('test/functional', controller_class_path)) + m.directory(File.join('test/unit', class_path)) + + m.dependency 'model', [name] + @args, :collision => :skip + + m.template( + 'controller.rb', File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb") + ) + + m.template('functional_test.rb', File.join('test/functional', controller_class_path, "#{controller_file_name}_controller_test.rb")) + m.template('helper.rb', File.join('app/helpers', controller_class_path, "#{controller_file_name}_helper.rb")) + + m.route_resources controller_file_name + end + end + + protected + def banner + "Usage: #{$0} resource ModelName [field:type, field:type]" + end + + def add_options!(opt) + opt.separator '' + opt.separator 'Options:' + opt.on("--skip-timestamps", + "Don't add timestamps to the migration file for this model") { |v| options[:skip_timestamps] = v } + opt.on("--skip-migration", + "Don't generate a migration file for this model") { |v| options[:skip_migration] = v } + end + + def model_name + class_name.demodulize + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/resource/templates/controller.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/resource/templates/controller.rb new file mode 100644 index 000000000..765a94269 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/resource/templates/controller.rb @@ -0,0 +1,2 @@ +class <%= controller_class_name %>Controller < ApplicationController +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/resource/templates/functional_test.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/resource/templates/functional_test.rb new file mode 100644 index 000000000..19363a82d --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/resource/templates/functional_test.rb @@ -0,0 +1,8 @@ +require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper' + +class <%= controller_class_name %>ControllerTest < ActionController::TestCase + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/resource/templates/helper.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/resource/templates/helper.rb new file mode 100644 index 000000000..9bd821b1b --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/resource/templates/helper.rb @@ -0,0 +1,2 @@ +module <%= controller_class_name %>Helper +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/USAGE b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/USAGE new file mode 100644 index 000000000..a0e4baea0 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/USAGE @@ -0,0 +1,25 @@ +Description: + Scaffolds an entire resource, from model and migration to controller and + views, along with a full test suite. The resource is ready to use as a + starting point for your restful, resource-oriented application. + + Pass the name of the model, either CamelCased or under_scored, as the first + argument, and an optional list of attribute pairs. + + Attribute pairs are column_name:sql_type arguments specifying the + model's attributes. Timestamps are added by default, so you don't have to + specify them by hand as 'created_at:datetime updated_at:datetime'. + + You don't have to think up every attribute up front, but it helps to + sketch out a few so you can start working with the resource immediately. + + For example, `scaffold post title:string body:text published:boolean` + gives you a model with those three attributes, a controller that handles + the create/show/update/destroy, forms to create and edit your posts, and + an index that lists them all, as well as a map.resources :posts + declaration in config/routes.rb. + +Examples: + `./script/generate scaffold post` # no attributes, view will be anemic + `./script/generate scaffold post title:string body:text published:boolean` + `./script/generate scaffold purchase order_id:integer amount:decimal` diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb new file mode 100644 index 000000000..c9ce49a6f --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb @@ -0,0 +1,92 @@ +class ScaffoldGenerator < Rails::Generator::NamedBase + default_options :skip_timestamps => false, :skip_migration => false + + attr_reader :controller_name, + :controller_class_path, + :controller_file_path, + :controller_class_nesting, + :controller_class_nesting_depth, + :controller_class_name, + :controller_underscore_name, + :controller_singular_name, + :controller_plural_name + alias_method :controller_file_name, :controller_underscore_name + alias_method :controller_table_name, :controller_plural_name + + def initialize(runtime_args, runtime_options = {}) + super + + @controller_name = @name.pluralize + + base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name) + @controller_class_name_without_nesting, @controller_underscore_name, @controller_plural_name = inflect_names(base_name) + @controller_singular_name=base_name.singularize + if @controller_class_nesting.empty? + @controller_class_name = @controller_class_name_without_nesting + else + @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}" + end + end + + def manifest + record do |m| + # Check for class naming collisions. + m.class_collisions(controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}Helper") + m.class_collisions(class_path, "#{class_name}") + + # Controller, helper, views, and test directories. + m.directory(File.join('app/models', class_path)) + m.directory(File.join('app/controllers', controller_class_path)) + m.directory(File.join('app/helpers', controller_class_path)) + m.directory(File.join('app/views', controller_class_path, controller_file_name)) + m.directory(File.join('app/views/layouts', controller_class_path)) + m.directory(File.join('test/functional', controller_class_path)) + m.directory(File.join('test/unit', class_path)) + + for action in scaffold_views + m.template( + "view_#{action}.html.erb", + File.join('app/views', controller_class_path, controller_file_name, "#{action}.html.erb") + ) + end + + # Layout and stylesheet. + m.template('layout.html.erb', File.join('app/views/layouts', controller_class_path, "#{controller_file_name}.html.erb")) + m.template('style.css', 'public/stylesheets/scaffold.css') + + m.dependency 'model', [name] + @args, :collision => :skip + + m.template( + 'controller.rb', File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb") + ) + + m.template('functional_test.rb', File.join('test/functional', controller_class_path, "#{controller_file_name}_controller_test.rb")) + m.template('helper.rb', File.join('app/helpers', controller_class_path, "#{controller_file_name}_helper.rb")) + + m.route_resources controller_file_name + end + end + + protected + # Override with your own usage banner. + def banner + "Usage: #{$0} scaffold ModelName [field:type, field:type]" + end + + def add_options!(opt) + opt.separator '' + opt.separator 'Options:' + opt.on("--skip-timestamps", + "Don't add timestamps to the migration file for this model") { |v| options[:skip_timestamps] = v } + opt.on("--skip-migration", + "Don't generate a migration file for this model") { |v| options[:skip_migration] = v } + end + + def scaffold_views + %w[ index show new edit ] + end + + def model_name + class_name.demodulize + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/controller.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/controller.rb new file mode 100644 index 000000000..cbfd88f3b --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/controller.rb @@ -0,0 +1,85 @@ +class <%= controller_class_name %>Controller < ApplicationController + # GET /<%= table_name %> + # GET /<%= table_name %>.xml + def index + @<%= table_name %> = <%= class_name %>.find(:all) + + respond_to do |format| + format.html # index.html.erb + format.xml { render :xml => @<%= table_name %> } + end + end + + # GET /<%= table_name %>/1 + # GET /<%= table_name %>/1.xml + def show + @<%= file_name %> = <%= class_name %>.find(params[:id]) + + respond_to do |format| + format.html # show.html.erb + format.xml { render :xml => @<%= file_name %> } + end + end + + # GET /<%= table_name %>/new + # GET /<%= table_name %>/new.xml + def new + @<%= file_name %> = <%= class_name %>.new + + respond_to do |format| + format.html # new.html.erb + format.xml { render :xml => @<%= file_name %> } + end + end + + # GET /<%= table_name %>/1/edit + def edit + @<%= file_name %> = <%= class_name %>.find(params[:id]) + end + + # POST /<%= table_name %> + # POST /<%= table_name %>.xml + def create + @<%= file_name %> = <%= class_name %>.new(params[:<%= file_name %>]) + + respond_to do |format| + if @<%= file_name %>.save + flash[:notice] = '<%= class_name %> was successfully created.' + format.html { redirect_to(@<%= file_name %>) } + format.xml { render :xml => @<%= file_name %>, :status => :created, :location => @<%= file_name %> } + else + format.html { render :action => "new" } + format.xml { render :xml => @<%= file_name %>.errors, :status => :unprocessable_entity } + end + end + end + + # PUT /<%= table_name %>/1 + # PUT /<%= table_name %>/1.xml + def update + @<%= file_name %> = <%= class_name %>.find(params[:id]) + + respond_to do |format| + if @<%= file_name %>.update_attributes(params[:<%= file_name %>]) + flash[:notice] = '<%= class_name %> was successfully updated.' + format.html { redirect_to(@<%= file_name %>) } + format.xml { head :ok } + else + format.html { render :action => "edit" } + format.xml { render :xml => @<%= file_name %>.errors, :status => :unprocessable_entity } + end + end + end + + # DELETE /<%= table_name %>/1 + # DELETE /<%= table_name %>/1.xml + def destroy + @<%= file_name %> = <%= class_name %>.find(params[:id]) + @<%= file_name %>.destroy + + respond_to do |format| + format.html { redirect_to(<%= table_name %>_url) } + format.xml { head :ok } + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb new file mode 100644 index 000000000..2b1f6520d --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb @@ -0,0 +1,45 @@ +require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper' + +class <%= controller_class_name %>ControllerTest < ActionController::TestCase + def test_should_get_index + get :index + assert_response :success + assert_not_nil assigns(:<%= table_name %>) + end + + def test_should_get_new + get :new + assert_response :success + end + + def test_should_create_<%= file_name %> + assert_difference('<%= class_name %>.count') do + post :create, :<%= file_name %> => { } + end + + assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>)) + end + + def test_should_show_<%= file_name %> + get :show, :id => <%= table_name %>(:one).id + assert_response :success + end + + def test_should_get_edit + get :edit, :id => <%= table_name %>(:one).id + assert_response :success + end + + def test_should_update_<%= file_name %> + put :update, :id => <%= table_name %>(:one).id, :<%= file_name %> => { } + assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>)) + end + + def test_should_destroy_<%= file_name %> + assert_difference('<%= class_name %>.count', -1) do + delete :destroy, :id => <%= table_name %>(:one).id + end + + assert_redirected_to <%= table_name %>_path + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/helper.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/helper.rb new file mode 100644 index 000000000..9bd821b1b --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/helper.rb @@ -0,0 +1,2 @@ +module <%= controller_class_name %>Helper +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/layout.html.erb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/layout.html.erb new file mode 100644 index 000000000..5c1f30423 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/layout.html.erb @@ -0,0 +1,17 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <meta http-equiv="content-type" content="text/html;charset=UTF-8" /> + <title><%= controller_class_name %>: <%%= controller.action_name %></title> + <%%= stylesheet_link_tag 'scaffold' %> +</head> +<body> + +<p style="color: green"><%%= flash[:notice] %></p> + +<%%= yield %> + +</body> +</html> diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/style.css b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/style.css new file mode 100644 index 000000000..879e85b36 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/style.css @@ -0,0 +1,74 @@ +body { background-color: #fff; color: #333; } + +body, p, ol, ul, td { + font-family: verdana, arial, helvetica, sans-serif; + font-size: 13px; + line-height: 18px; +} + +pre { + background-color: #eee; + padding: 10px; + font-size: 11px; +} + +a { color: #000; } +a:visited { color: #666; } +a:hover { color: #fff; background-color:#000; } + +.fieldWithErrors { + padding: 2px; + background-color: red; + display: table; +} + +#errorExplanation { + width: 400px; + border: 2px solid red; + padding: 7px; + padding-bottom: 12px; + margin-bottom: 20px; + background-color: #f0f0f0; +} + +#errorExplanation h2 { + text-align: left; + font-weight: bold; + padding: 5px 5px 5px 15px; + font-size: 12px; + margin: -7px; + background-color: #c00; + color: #fff; +} + +#errorExplanation p { + color: #333; + margin-bottom: 0; + padding: 5px; +} + +#errorExplanation ul li { + font-size: 12px; + list-style: square; +} + +div.uploadStatus { + margin: 5px; +} + +div.progressBar { + margin: 5px; +} + +div.progressBar div.border { + background-color: #fff; + border: 1px solid gray; + width: 100%; +} + +div.progressBar div.background { + background-color: #333; + height: 18px; + width: 0%; +} + diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/view_edit.html.erb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/view_edit.html.erb new file mode 100644 index 000000000..8a65b50db --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/view_edit.html.erb @@ -0,0 +1,19 @@ +<h1>Editing <%= singular_name %></h1> + +<%%= error_messages_for :<%= singular_name %> %> + +<%% form_for(@<%= singular_name %>) do |f| %> +<% for attribute in attributes -%> + <p> + <b><%= attribute.column.human_name %></b><br /> + <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %> + </p> + +<% end -%> + <p> + <%%= f.submit "Update" %> + </p> +<%% end %> + +<%%= link_to 'Show', @<%= singular_name %> %> | +<%%= link_to 'Back', <%= plural_name %>_path %> diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/view_index.html.erb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/view_index.html.erb new file mode 100644 index 000000000..e89757e3e --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/view_index.html.erb @@ -0,0 +1,24 @@ +<h1>Listing <%= plural_name %></h1> + +<table> + <tr> +<% for attribute in attributes -%> + <th><%= attribute.column.human_name %></th> +<% end -%> + </tr> + +<%% for <%= singular_name %> in @<%= plural_name %> %> + <tr> +<% for attribute in attributes -%> + <td><%%=h <%= singular_name %>.<%= attribute.name %> %></td> +<% end -%> + <td><%%= link_to 'Show', <%= singular_name %> %></td> + <td><%%= link_to 'Edit', edit_<%= singular_name %>_path(<%= singular_name %>) %></td> + <td><%%= link_to 'Destroy', <%= singular_name %>, :confirm => 'Are you sure?', :method => :delete %></td> + </tr> +<%% end %> +</table> + +<br /> + +<%%= link_to 'New <%= singular_name %>', new_<%= singular_name %>_path %> diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/view_new.html.erb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/view_new.html.erb new file mode 100644 index 000000000..96f59900b --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/view_new.html.erb @@ -0,0 +1,18 @@ +<h1>New <%= singular_name %></h1> + +<%%= error_messages_for :<%= singular_name %> %> + +<%% form_for(@<%= singular_name %>) do |f| %> +<% for attribute in attributes -%> + <p> + <b><%= attribute.column.human_name %></b><br /> + <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %> + </p> + +<% end -%> + <p> + <%%= f.submit "Create" %> + </p> +<%% end %> + +<%%= link_to 'Back', <%= plural_name %>_path %> diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/view_show.html.erb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/view_show.html.erb new file mode 100644 index 000000000..9b6b11b02 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/scaffold/templates/view_show.html.erb @@ -0,0 +1,10 @@ +<% for attribute in attributes -%> +<p> + <b><%= attribute.column.human_name %>:</b> + <%%=h @<%= singular_name %>.<%= attribute.name %> %> +</p> + +<% end -%> + +<%%= link_to 'Edit', edit_<%= singular_name %>_path(@<%= singular_name %>) %> | +<%%= link_to 'Back', <%= plural_name %>_path %> diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/session_migration/USAGE b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/session_migration/USAGE new file mode 100644 index 000000000..87117a3cb --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/session_migration/USAGE @@ -0,0 +1,10 @@ +Description: + Creates a migration to add the sessions table used by the Active Record + session store. Pass the migration name, either CamelCased or under_scored, + as an argument. + +Example: + `./script/generate session_migration CreateSessionTable` + + With 4 existing migrations, this creates the AddSessionTable migration + in db/migrate/005_add_session_table.rb diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/session_migration/session_migration_generator.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/session_migration/session_migration_generator.rb new file mode 100644 index 000000000..2e177033a --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/session_migration/session_migration_generator.rb @@ -0,0 +1,18 @@ +class SessionMigrationGenerator < Rails::Generator::NamedBase + def initialize(runtime_args, runtime_options = {}) + runtime_args << 'add_session_table' if runtime_args.empty? + super + end + + def manifest + record do |m| + m.migration_template 'migration.rb', 'db/migrate', + :assigns => { :session_table_name => default_session_table_name } + end + end + + protected + def default_session_table_name + ActiveRecord::Base.pluralize_table_names ? 'session'.pluralize : 'session' + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/session_migration/templates/migration.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/session_migration/templates/migration.rb new file mode 100644 index 000000000..ca220a5f2 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/generators/components/session_migration/templates/migration.rb @@ -0,0 +1,16 @@ +class <%= class_name %> < ActiveRecord::Migration + def self.up + create_table :<%= session_table_name %> do |t| + t.string :session_id, :null => false + t.text :data + t.timestamps + end + + add_index :<%= session_table_name %>, :session_id + add_index :<%= session_table_name %>, :updated_at + end + + def self.down + drop_table :<%= session_table_name %> + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/lookup.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/lookup.rb new file mode 100644 index 000000000..598cb79e7 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/lookup.rb @@ -0,0 +1,244 @@ +require File.dirname(__FILE__) + '/spec' + +class Object + class << self + # Lookup missing generators using const_missing. This allows any + # generator to reference another without having to know its location: + # RubyGems, ~/.rails/generators, and RAILS_ROOT/generators. + def lookup_missing_generator(class_id) + if md = /(.+)Generator$/.match(class_id.to_s) + name = md.captures.first.demodulize.underscore + Rails::Generator::Base.lookup(name).klass + else + const_missing_before_generators(class_id) + end + end + + unless respond_to?(:const_missing_before_generators) + alias_method :const_missing_before_generators, :const_missing + alias_method :const_missing, :lookup_missing_generator + end + end +end + +# User home directory lookup adapted from RubyGems. +def Dir.user_home + if ENV['HOME'] + ENV['HOME'] + elsif ENV['USERPROFILE'] + ENV['USERPROFILE'] + elsif ENV['HOMEDRIVE'] and ENV['HOMEPATH'] + "#{ENV['HOMEDRIVE']}:#{ENV['HOMEPATH']}" + else + File.expand_path '~' + end +end + + +module Rails + module Generator + + # Generator lookup is managed by a list of sources which return specs + # describing where to find and how to create generators. This module + # provides class methods for manipulating the source list and looking up + # generator specs, and an #instance wrapper for quickly instantiating + # generators by name. + # + # A spec is not a generator: it's a description of where to find + # the generator and how to create it. A source is anything that + # yields generators from #each. PathSource and GemGeneratorSource are provided. + module Lookup + def self.included(base) + base.extend(ClassMethods) + base.use_component_sources! + end + + # Convenience method to instantiate another generator. + def instance(generator_name, args, runtime_options = {}) + self.class.instance(generator_name, args, runtime_options) + end + + module ClassMethods + # The list of sources where we look, in order, for generators. + def sources + read_inheritable_attribute(:sources) or use_component_sources! + end + + # Add a source to the end of the list. + def append_sources(*args) + sources.concat(args.flatten) + invalidate_cache! + end + + # Add a source to the beginning of the list. + def prepend_sources(*args) + write_inheritable_array(:sources, args.flatten + sources) + invalidate_cache! + end + + # Reset the source list. + def reset_sources + write_inheritable_attribute(:sources, []) + invalidate_cache! + end + + # Use application generators (app, ?). + def use_application_sources! + reset_sources + sources << PathSource.new(:builtin, "#{File.dirname(__FILE__)}/generators/applications") + end + + # Use component generators (model, controller, etc). + # 1. Rails application. If RAILS_ROOT is defined we know we're + # generating in the context of a Rails application, so search + # RAILS_ROOT/generators. + # 2. Look in plugins, either for generators/ or rails_generators/ + # directories within each plugin + # 3. User home directory. Search ~/.rails/generators. + # 4. RubyGems. Search for gems named *_generator, and look for + # generators within any RubyGem's + # /rails_generators/<generator_name>_generator.rb file. + # 5. Builtins. Model, controller, mailer, scaffold, and so on. + def use_component_sources! + reset_sources + if defined? ::RAILS_ROOT + sources << PathSource.new(:lib, "#{::RAILS_ROOT}/lib/generators") + sources << PathSource.new(:vendor, "#{::RAILS_ROOT}/vendor/generators") + sources << PathSource.new(:plugins, "#{::RAILS_ROOT}/vendor/plugins/*/**/generators") + sources << PathSource.new(:plugins, "#{::RAILS_ROOT}/vendor/plugins/*/**/rails_generators") + end + sources << PathSource.new(:user, "#{Dir.user_home}/.rails/generators") + if Object.const_defined?(:Gem) + sources << GemGeneratorSource.new + sources << GemPathSource.new + end + sources << PathSource.new(:builtin, "#{File.dirname(__FILE__)}/generators/components") + end + + # Lookup knows how to find generators' Specs from a list of Sources. + # Searches the sources, in order, for the first matching name. + def lookup(generator_name) + @found ||= {} + generator_name = generator_name.to_s.downcase + @found[generator_name] ||= cache.find { |spec| spec.name == generator_name } + unless @found[generator_name] + chars = generator_name.scan(/./).map{|c|"#{c}.*?"} + rx = /^#{chars}$/ + gns = cache.select{|spec| spec.name =~ rx } + @found[generator_name] ||= gns.first if gns.length == 1 + raise GeneratorError, "Pattern '#{generator_name}' matches more than one generator: #{gns.map{|sp|sp.name}.join(', ')}" if gns.length > 1 + end + @found[generator_name] or raise GeneratorError, "Couldn't find '#{generator_name}' generator" + end + + # Convenience method to lookup and instantiate a generator. + def instance(generator_name, args = [], runtime_options = {}) + lookup(generator_name).klass.new(args, full_options(runtime_options)) + end + + private + # Lookup and cache every generator from the source list. + def cache + @cache ||= sources.inject([]) { |cache, source| cache + source.map } + end + + # Clear the cache whenever the source list changes. + def invalidate_cache! + @cache = nil + end + end + end + + # Sources enumerate (yield from #each) generator specs which describe + # where to find and how to create generators. Enumerable is mixed in so, + # for example, source.collect will retrieve every generator. + # Sources may be assigned a label to distinguish them. + class Source + include Enumerable + + attr_reader :label + def initialize(label) + @label = label + end + + # The each method must be implemented in subclasses. + # The base implementation raises an error. + def each + raise NotImplementedError + end + + # Return a convenient sorted list of all generator names. + def names + map { |spec| spec.name }.sort + end + end + + + # PathSource looks for generators in a filesystem directory. + class PathSource < Source + attr_reader :path + + def initialize(label, path) + super label + @path = path + end + + # Yield each eligible subdirectory. + def each + Dir["#{path}/[a-z]*"].each do |dir| + if File.directory?(dir) + yield Spec.new(File.basename(dir), dir, label) + end + end + end + end + + class AbstractGemSource < Source + def initialize + super :RubyGems + end + end + + # GemGeneratorSource hits the mines to quarry for generators. The latest versions + # of gems named *_generator are selected. + class GemGeneratorSource < AbstractGemSource + # Yield latest versions of generator gems. + def each + Gem::cache.search(/_generator$/).inject({}) { |latest, gem| + hem = latest[gem.name] + latest[gem.name] = gem if hem.nil? or gem.version > hem.version + latest + }.values.each { |gem| + yield Spec.new(gem.name.sub(/_generator$/, ''), gem.full_gem_path, label) + } + end + end + + # GemPathSource looks for generators within any RubyGem's /rails_generators/<generator_name>_generator.rb file. + class GemPathSource < AbstractGemSource + # Yield each generator within rails_generator subdirectories. + def each + generator_full_paths.each do |generator| + yield Spec.new(File.basename(generator).sub(/_generator.rb$/, ''), File.dirname(generator), label) + end + end + + private + def generator_full_paths + @generator_full_paths ||= + Gem::cache.inject({}) do |latest, name_gem| + name, gem = name_gem + hem = latest[gem.name] + latest[gem.name] = gem if hem.nil? or gem.version > hem.version + latest + end.values.inject([]) do |mem, gem| + Dir[gem.full_gem_path + '/{rails_,}generators/**/*_generator.rb'].each do |generator| + mem << generator + end + mem + end + end + end + + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/manifest.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/manifest.rb new file mode 100644 index 000000000..702effa76 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/manifest.rb @@ -0,0 +1,53 @@ +module Rails + module Generator + + # Manifest captures the actions a generator performs. Instantiate + # a manifest with an optional target object, hammer it with actions, + # then replay or rewind on the object of your choice. + # + # Example: + # manifest = Manifest.new { |m| + # m.make_directory '/foo' + # m.create_file '/foo/bar.txt' + # } + # manifest.replay(creator) + # manifest.rewind(destroyer) + class Manifest + attr_reader :target + + # Take a default action target. Yield self if block given. + def initialize(target = nil) + @target, @actions = target, [] + yield self if block_given? + end + + # Record an action. + def method_missing(action, *args, &block) + @actions << [action, args, block] + end + + # Replay recorded actions. + def replay(target = nil) + send_actions(target || @target, @actions) + end + + # Rewind recorded actions. + def rewind(target = nil) + send_actions(target || @target, @actions.reverse) + end + + # Erase recorded actions. + def erase + @actions = [] + end + + private + def send_actions(target, actions) + actions.each do |method, args, block| + target.send(method, *args, &block) + end + end + end + + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/options.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/options.rb new file mode 100644 index 000000000..042e05107 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/options.rb @@ -0,0 +1,143 @@ +require 'optparse' + +module Rails + module Generator + module Options + def self.included(base) + base.extend(ClassMethods) + class << base + if respond_to?(:inherited) + alias_method :inherited_without_options, :inherited + end + alias_method :inherited, :inherited_with_options + end + end + + module ClassMethods + def inherited_with_options(sub) + inherited_without_options(sub) if respond_to?(:inherited_without_options) + sub.extend(Rails::Generator::Options::ClassMethods) + end + + def mandatory_options(options = nil) + if options + write_inheritable_attribute(:mandatory_options, options) + else + read_inheritable_attribute(:mandatory_options) or write_inheritable_attribute(:mandatory_options, {}) + end + end + + def default_options(options = nil) + if options + write_inheritable_attribute(:default_options, options) + else + read_inheritable_attribute(:default_options) or write_inheritable_attribute(:default_options, {}) + end + end + + # Merge together our class options. In increasing precedence: + # default_options (class default options) + # runtime_options (provided as argument) + # mandatory_options (class mandatory options) + def full_options(runtime_options = {}) + default_options.merge(runtime_options).merge(mandatory_options) + end + + end + + # Each instance has an options hash that's populated by #parse. + def options + @options ||= {} + end + attr_writer :options + + protected + # Convenient access to class mandatory options. + def mandatory_options + self.class.mandatory_options + end + + # Convenient access to class default options. + def default_options + self.class.default_options + end + + # Merge together our instance options. In increasing precedence: + # default_options (class default options) + # options (instance options) + # runtime_options (provided as argument) + # mandatory_options (class mandatory options) + def full_options(runtime_options = {}) + self.class.full_options(options.merge(runtime_options)) + end + + # Parse arguments into the options hash. Classes may customize + # parsing behavior by overriding these methods: + # #banner Usage: ./script/generate [options] + # #add_options! Options: + # some options.. + # #add_general_options! General Options: + # general options.. + def parse!(args, runtime_options = {}) + self.options = {} + + @option_parser = OptionParser.new do |opt| + opt.banner = banner + add_options!(opt) + add_general_options!(opt) + opt.parse!(args) + end + + return args + ensure + self.options = full_options(runtime_options) + end + + # Raise a usage error. Override usage_message to provide a blurb + # after the option parser summary. + def usage(message = usage_message) + raise UsageError, "#{@option_parser}\n#{message}" + end + + def usage_message + '' + end + + # Override with your own usage banner. + def banner + "Usage: #{$0} [options]" + end + + # Override to add your options to the parser: + # def add_options!(opt) + # opt.on('-v', '--verbose') { |value| options[:verbose] = value } + # end + def add_options!(opt) + end + + # Adds general options like -h and --quiet. Usually don't override. + def add_general_options!(opt) + opt.separator '' + opt.separator 'Rails Info:' + opt.on('-v', '--version', 'Show the Rails version number and quit.') + opt.on('-h', '--help', 'Show this help message and quit.') { |v| options[:help] = v } + + opt.separator '' + opt.separator 'General Options:' + + opt.on('-p', '--pretend', 'Run but do not make any changes.') { |v| options[:pretend] = v } + opt.on('-f', '--force', 'Overwrite files that already exist.') { options[:collision] = :force } + opt.on('-s', '--skip', 'Skip files that already exist.') { options[:collision] = :skip } + opt.on('-q', '--quiet', 'Suppress normal output.') { |v| options[:quiet] = v } + opt.on('-t', '--backtrace', 'Debugging: show backtrace on errors.') { |v| options[:backtrace] = v } + opt.on('-c', '--svn', 'Modify files with subversion. (Note: svn must be in path)') do + options[:svn] = `svn status`.inject({}) do |opt, e| + opt[e.chomp[7..-1]] = true + opt + end + end + end + + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/scripts.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/scripts.rb new file mode 100644 index 000000000..bd380aad6 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/scripts.rb @@ -0,0 +1,86 @@ +require File.dirname(__FILE__) + '/options' + +module Rails + module Generator + module Scripts + + # Generator scripts handle command-line invocation. Each script + # responds to an invoke! class method which handles option parsing + # and generator invocation. + class Base + include Options + default_options :collision => :ask, :quiet => false + + # Run the generator script. Takes an array of unparsed arguments + # and a hash of parsed arguments, takes the generator as an option + # or first remaining argument, and invokes the requested command. + def run(args = [], runtime_options = {}) + begin + parse!(args.dup, runtime_options) + rescue OptionParser::InvalidOption => e + # Don't cry, script. Generators want what you think is invalid. + end + + # Generator name is the only required option. + unless options[:generator] + usage if args.empty? + options[:generator] ||= args.shift + end + + # Look up generator instance and invoke command on it. + Rails::Generator::Base.instance(options[:generator], args, options).command(options[:command]).invoke! + rescue => e + puts e + puts " #{e.backtrace.join("\n ")}\n" if options[:backtrace] + raise SystemExit + end + + protected + # Override with your own script usage banner. + def banner + "Usage: #{$0} generator [options] [args]" + end + + def usage_message + usage = "\nInstalled Generators\n" + Rails::Generator::Base.sources.inject({}) do |mem, source| + label = source.label.to_s.capitalize + mem[label] ||= [] + mem[label] |= source.names + mem + end.each_pair do |label, names| + usage << " #{label}: #{names.join(', ')}\n" unless names.empty? + end + + usage << <<end_blurb + +More are available at http://rubyonrails.org/show/Generators + 1. Download, for example, login_generator.zip + 2. Unzip to directory #{Dir.user_home}/.rails/generators/login + to use the generator with all your Rails apps +end_blurb + + if Object.const_defined?(:RAILS_ROOT) + usage << <<end_blurb + or to #{File.expand_path(RAILS_ROOT)}/lib/generators/login + to use with this app only. +end_blurb + end + + usage << <<end_blurb + 3. Run generate with no arguments for usage information + #{$0} login + +Generator gems are also available: + 1. gem search -r generator + 2. gem install login_generator + 3. #{$0} login + +end_blurb + return usage + end + end # Base + + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/scripts/destroy.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/scripts/destroy.rb new file mode 100644 index 000000000..4fcbc3e0d --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/scripts/destroy.rb @@ -0,0 +1,30 @@ +require File.dirname(__FILE__) + '/../scripts' + +module Rails::Generator::Scripts + class Destroy < Base + mandatory_options :command => :destroy + + protected + def usage_message + usage = "\nInstalled Generators\n" + Rails::Generator::Base.sources.each do |source| + label = source.label.to_s.capitalize + names = source.names + usage << " #{label}: #{names.join(', ')}\n" unless names.empty? + end + + usage << <<end_blurb + +This script will destroy all files created by the corresponding +script/generate command. For instance, script/destroy migration CreatePost +will delete the appropriate ###_create_post.rb file in db/migrate, while +script/destroy scaffold Post will delete the posts controller and +views, post model and migration, all associated tests, and the map.resources +:posts line in config/routes.rb. + +For instructions on finding new generators, run script/generate +end_blurb + return usage + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/scripts/generate.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/scripts/generate.rb new file mode 100644 index 000000000..1fe2f54ab --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/scripts/generate.rb @@ -0,0 +1,7 @@ +require File.dirname(__FILE__) + '/../scripts' + +module Rails::Generator::Scripts + class Generate < Base + mandatory_options :command => :create + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/scripts/update.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/scripts/update.rb new file mode 100644 index 000000000..53a9faa36 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/scripts/update.rb @@ -0,0 +1,12 @@ +require File.dirname(__FILE__) + '/../scripts' + +module Rails::Generator::Scripts + class Update < Base + mandatory_options :command => :update + + protected + def banner + "Usage: #{$0} [options] scaffold" + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/secret_key_generator.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/secret_key_generator.rb new file mode 100644 index 000000000..497df72ce --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/secret_key_generator.rb @@ -0,0 +1,160 @@ +# A class for creating random secret keys. This class will do its best to create a +# random secret key that's as secure as possible, using whatever methods are +# available on the current platform. For example: +# +# generator = Rails::SecretKeyGenerator("some unique identifier, such as the application name") +# generator.generate_secret # => "f3f1be90053fa851... (some long string)" + +module Rails + class SecretKeyGenerator + GENERATORS = [ :secure_random, :win32_api, :urandom, :openssl, :prng ].freeze + + def initialize(identifier) + @identifier = identifier + end + + # Generate a random secret key with the best possible method available on + # the current platform. + def generate_secret + generator = GENERATORS.find do |g| + self.class.send("supports_#{g}?") + end + send("generate_secret_with_#{generator}") + end + + # Generate a random secret key by using the Win32 API. Raises LoadError + # if the current platform cannot make use of the Win32 API. Raises + # SystemCallError if some other error occured. + def generate_secret_with_win32_api + # Following code is based on David Garamond's GUID library for Ruby. + require 'Win32API' + + crypt_acquire_context = Win32API.new("advapi32", "CryptAcquireContext", + 'PPPII', 'L') + crypt_gen_random = Win32API.new("advapi32", "CryptGenRandom", + 'LIP', 'L') + crypt_release_context = Win32API.new("advapi32", "CryptReleaseContext", + 'LI', 'L') + prov_rsa_full = 1 + crypt_verifycontext = 0xF0000000 + + hProvStr = " " * 4 + if crypt_acquire_context.call(hProvStr, nil, nil, prov_rsa_full, + crypt_verifycontext) == 0 + raise SystemCallError, "CryptAcquireContext failed: #{lastWin32ErrorMessage}" + end + hProv, = hProvStr.unpack('L') + bytes = " " * 64 + if crypt_gen_random.call(hProv, bytes.size, bytes) == 0 + raise SystemCallError, "CryptGenRandom failed: #{lastWin32ErrorMessage}" + end + if crypt_release_context.call(hProv, 0) == 0 + raise SystemCallError, "CryptReleaseContext failed: #{lastWin32ErrorMessage}" + end + bytes.unpack("H*")[0] + end + + # Generate a random secret key with Ruby 1.9's SecureRandom module. + # Raises LoadError if the current Ruby version does not support + # SecureRandom. + def generate_secret_with_secure_random + require 'securerandom' + return SecureRandom.hex(64) + end + + # Generate a random secret key with OpenSSL. If OpenSSL is not + # already loaded, then this method will attempt to load it. + # LoadError will be raised if that fails. + def generate_secret_with_openssl + require 'openssl' + if !File.exist?("/dev/urandom") + # OpenSSL transparently seeds the random number generator with + # data from /dev/urandom. On platforms where that is not + # available, such as Windows, we have to provide OpenSSL with + # our own seed. Unfortunately there's no way to provide a + # secure seed without OS support, so we'll have to do with + # rand() and Time.now.usec(). + OpenSSL::Random.seed(rand(0).to_s + Time.now.usec.to_s) + end + data = OpenSSL::BN.rand(2048, -1, false).to_s + return OpenSSL::Digest::SHA512.new(data).hexdigest + end + + # Generate a random secret key with /dev/urandom. + # Raises SystemCallError on failure. + def generate_secret_with_urandom + return File.read("/dev/urandom", 64).unpack("H*")[0] + end + + # Generate a random secret key with Ruby's pseudo random number generator, + # as well as some environment information. + # + # This is the least cryptographically secure way to generate a secret key, + # and should be avoided whenever possible. + def generate_secret_with_prng + require 'digest/sha2' + sha = Digest::SHA2.new(512) + now = Time.now + sha << now.to_s + sha << String(now.usec) + sha << String(rand(0)) + sha << String($$) + sha << @identifier + return sha.hexdigest + end + + private + def lastWin32ErrorMessage + # Following code is based on David Garamond's GUID library for Ruby. + get_last_error = Win32API.new("kernel32", "GetLastError", '', 'L') + format_message = Win32API.new("kernel32", "FormatMessageA", + 'LPLLPLPPPPPPPP', 'L') + format_message_ignore_inserts = 0x00000200 + format_message_from_system = 0x00001000 + + code = get_last_error.call + msg = "\0" * 1024 + len = format_message.call(format_message_ignore_inserts + + format_message_from_system, 0, + code, 0, msg, 1024, nil, nil, + nil, nil, nil, nil, nil, nil) + msg[0, len].tr("\r", '').chomp + end + + def self.supports_secure_random? + begin + require 'securerandom' + true + rescue LoadError + false + end + end + + def self.supports_win32_api? + return false unless RUBY_PLATFORM =~ /(:?mswin|mingw)/ + begin + require 'Win32API' + true + rescue LoadError + false + end + end + + def self.supports_urandom? + File.exist?('/dev/urandom') + end + + def self.supports_openssl? + begin + require 'openssl' + true + rescue LoadError + false + end + end + + def self.supports_prng? + true + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/simple_logger.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/simple_logger.rb new file mode 100644 index 000000000..d750f07b8 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/simple_logger.rb @@ -0,0 +1,46 @@ +module Rails + module Generator + class SimpleLogger # :nodoc: + attr_reader :out + attr_accessor :quiet + + def initialize(out = $stdout) + @out = out + @quiet = false + @level = 0 + end + + def log(status, message, &block) + @out.print("%12s %s%s\n" % [status, ' ' * @level, message]) unless quiet + indent(&block) if block_given? + end + + def indent(&block) + @level += 1 + if block_given? + begin + block.call + ensure + outdent + end + end + end + + def outdent + @level -= 1 + if block_given? + begin + block.call + ensure + indent + end + end + end + + private + def method_missing(method, *args, &block) + log(method.to_s, args.first, &block) + end + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/rails_generator/spec.rb b/vendor/rails-2.0.2/railties/lib/rails_generator/spec.rb new file mode 100644 index 000000000..9d780b7ac --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rails_generator/spec.rb @@ -0,0 +1,44 @@ +module Rails + module Generator + # A spec knows where a generator was found and how to instantiate it. + # Metadata include the generator's name, its base path, and the source + # which yielded it (PathSource, GemPathSource, etc.) + class Spec + attr_reader :name, :path, :source + + def initialize(name, path, source) + @name, @path, @source = name, path, source + end + + # Look up the generator class. Require its class file, find the class + # in ObjectSpace, tag it with this spec, and return. + def klass + unless @klass + require class_file + @klass = lookup_class + @klass.spec = self + end + @klass + end + + def class_file + "#{path}/#{name}_generator.rb" + end + + def class_name + "#{name.camelize}Generator" + end + + private + # Search for the first Class descending from Rails::Generator::Base + # whose name matches the requested class name. + def lookup_class + ObjectSpace.each_object(Class) do |obj| + return obj if obj.ancestors.include?(Rails::Generator::Base) and + obj.name.split('::').last == class_name + end + raise NameError, "Missing #{class_name} class in #{class_file}" + end + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/railties_path.rb b/vendor/rails-2.0.2/railties/lib/railties_path.rb new file mode 100644 index 000000000..a298a4cc2 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/railties_path.rb @@ -0,0 +1 @@ +RAILTIES_PATH = File.join(File.dirname(__FILE__), '..') diff --git a/vendor/rails-2.0.2/railties/lib/ruby_version_check.rb b/vendor/rails-2.0.2/railties/lib/ruby_version_check.rb new file mode 100644 index 000000000..68d3acc87 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/ruby_version_check.rb @@ -0,0 +1,17 @@ +min_release = "1.8.2 (2004-12-25)" +ruby_release = "#{RUBY_VERSION} (#{RUBY_RELEASE_DATE})" +if ruby_release =~ /1\.8\.3/ + abort <<-end_message + + Rails does not work with Ruby version 1.8.3. + Please upgrade to version 1.8.4 or downgrade to 1.8.2. + + end_message +elsif ruby_release < min_release + abort <<-end_message + + Rails requires Ruby version #{min_release} or later. + You're running #{ruby_release}; please upgrade to continue. + + end_message +end diff --git a/vendor/rails-2.0.2/railties/lib/rubyprof_ext.rb b/vendor/rails-2.0.2/railties/lib/rubyprof_ext.rb new file mode 100644 index 000000000..f6e90357c --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/rubyprof_ext.rb @@ -0,0 +1,35 @@ +require 'prof' + +module Prof #:nodoc: + # Adapted from Shugo Maeda's unprof.rb + def self.print_profile(results, io = $stderr) + total = results.detect { |i| + i.method_class.nil? && i.method_id == :"#toplevel" + }.total_time + total = 0.001 if total < 0.001 + + io.puts " %% cumulative self self total" + io.puts " time seconds seconds calls ms/call ms/call name" + + sum = 0.0 + for r in results + sum += r.self_time + + name = if r.method_class.nil? + r.method_id.to_s + elsif r.method_class.is_a?(Class) + "#{r.method_class}##{r.method_id}" + else + "#{r.method_class}.#{r.method_id}" + end + io.printf "%6.2f %8.3f %8.3f %8d %8.2f %8.2f %s\n", + r.self_time / total * 100, + sum, + r.self_time, + r.count, + r.self_time * 1000 / r.count, + r.total_time * 1000 / r.count, + name + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/source_annotation_extractor.rb b/vendor/rails-2.0.2/railties/lib/source_annotation_extractor.rb new file mode 100644 index 000000000..884422653 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/source_annotation_extractor.rb @@ -0,0 +1,62 @@ +class SourceAnnotationExtractor + class Annotation < Struct.new(:line, :tag, :text) + def to_s(options={}) + s = "[%3d] " % line + s << "[#{tag}] " if options[:tag] + s << text + end + end + + def self.enumerate(tag, options={}) + extractor = new(tag) + extractor.display(extractor.find, options) + end + + attr_reader :tag + + def initialize(tag) + @tag = tag + end + + def find(dirs=%w(app lib test)) + dirs.inject({}) { |h, dir| h.update(find_in(dir)) } + end + + def find_in(dir) + results = {} + + Dir.glob("#{dir}/*") do |item| + next if File.basename(item)[0] == ?. + + if File.directory?(item) + results.update(find_in(item)) + elsif item =~ /\.(builder|(r(?:b|xml|js)))$/ + results.update(extract_annotations_from(item, /#\s*(#{tag}):?\s*(.*)$/)) + elsif item =~ /\.(rhtml|erb)$/ + results.update(extract_annotations_from(item, /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/)) + end + end + + results + end + + def extract_annotations_from(file, pattern) + lineno = 0 + result = File.readlines(file).inject([]) do |list, line| + lineno += 1 + next list unless line =~ pattern + list << Annotation.new(lineno, $1, $2) + end + result.empty? ? {} : { file => result } + end + + def display(results, options={}) + results.keys.sort.each do |file| + puts "#{file}:" + results[file].each do |note| + puts " * #{note.to_s(options)}" + end + puts + end + end +end
\ No newline at end of file diff --git a/vendor/rails-2.0.2/railties/lib/tasks/annotations.rake b/vendor/rails-2.0.2/railties/lib/tasks/annotations.rake new file mode 100644 index 000000000..ea6046670 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/tasks/annotations.rake @@ -0,0 +1,23 @@ +require 'source_annotation_extractor' + +desc "Enumerate all annotations" +task :notes do + SourceAnnotationExtractor.enumerate "OPTIMIZE|FIXME|TODO", :tag => true +end + +namespace :notes do + desc "Enumerate all OPTIMIZE annotations" + task :optimize do + SourceAnnotationExtractor.enumerate "OPTIMIZE" + end + + desc "Enumerate all FIXME annotations" + task :fixme do + SourceAnnotationExtractor.enumerate "FIXME" + end + + desc "Enumerate all TODO annotations" + task :todo do + SourceAnnotationExtractor.enumerate "TODO" + end +end
\ No newline at end of file diff --git a/vendor/rails-2.0.2/railties/lib/tasks/databases.rake b/vendor/rails-2.0.2/railties/lib/tasks/databases.rake new file mode 100644 index 000000000..2ecd09af2 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/tasks/databases.rake @@ -0,0 +1,363 @@ +namespace :db do + namespace :create do + desc 'Create all the local databases defined in config/database.yml' + task :all => :environment do + ActiveRecord::Base.configurations.each_value do |config| + # Skip entries that don't have a database key, such as the first entry here: + # + # defaults: &defaults + # adapter: mysql + # username: root + # password: + # host: localhost + # + # development: + # database: blog_development + # <<: *defaults + next unless config['database'] + # Only connect to local databases + if %w( 127.0.0.1 localhost ).include?(config['host']) || config['host'].blank? + create_database(config) + else + p "This task only creates local databases. #{config['database']} is on a remote host." + end + end + end + end + + desc 'Create the database defined in config/database.yml for the current RAILS_ENV' + task :create => :environment do + create_database(ActiveRecord::Base.configurations[RAILS_ENV]) + end + + def create_database(config) + begin + ActiveRecord::Base.establish_connection(config) + ActiveRecord::Base.connection + rescue + case config['adapter'] + when 'mysql' + @charset = ENV['CHARSET'] || 'utf8' + @collation = ENV['COLLATION'] || 'utf8_general_ci' + begin + ActiveRecord::Base.establish_connection(config.merge({'database' => nil})) + ActiveRecord::Base.connection.create_database(config['database'], {:charset => @charset, :collation => @collation}) + ActiveRecord::Base.establish_connection(config) + rescue + $stderr.puts "Couldn't create database for #{config.inspect}" + end + when 'postgresql' + `createdb "#{config['database']}" -E utf8` + when 'sqlite' + `sqlite "#{config['database']}"` + when 'sqlite3' + `sqlite3 "#{config['database']}"` + end + else + p "#{config['database']} already exists" + end + end + + namespace :drop do + desc 'Drops all the local databases defined in config/database.yml' + task :all => :environment do + ActiveRecord::Base.configurations.each_value do |config| + # Skip entries that don't have a database key + next unless config['database'] + # Only connect to local databases + if config['host'] == 'localhost' || config['host'].blank? + drop_database(config) + else + p "This task only drops local databases. #{config['database']} is on a remote host." + end + end + end + end + + desc 'Drops the database for the current RAILS_ENV' + task :drop => :environment do + drop_database(ActiveRecord::Base.configurations[RAILS_ENV || 'development']) + end + + desc "Migrate the database through scripts in db/migrate. Target specific version with VERSION=x. Turn off output with VERBOSE=false." + task :migrate => :environment do + ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true + ActiveRecord::Migrator.migrate("db/migrate/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil) + Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby + end + + namespace :migrate do + desc 'Rollbacks the database one migration and re migrate up. If you want to rollback more than one step, define STEP=x' + task :redo => [ 'db:rollback', 'db:migrate' ] + + desc 'Resets your database using your migrations for the current environment' + task :reset => ["db:drop", "db:create", "db:migrate"] + end + + desc 'Rolls the schema back to the previous version. Specify the number of steps with STEP=n' + task :rollback => :environment do + step = ENV['STEP'] ? ENV['STEP'].to_i : 1 + version = ActiveRecord::Migrator.current_version - step + ActiveRecord::Migrator.migrate('db/migrate/', version) + end + + desc 'Drops and recreates the database from db/schema.rb for the current environment.' + task :reset => ['db:drop', 'db:create', 'db:schema:load'] + + desc "Retrieves the charset for the current environment's database" + task :charset => :environment do + config = ActiveRecord::Base.configurations[RAILS_ENV || 'development'] + case config['adapter'] + when 'mysql' + ActiveRecord::Base.establish_connection(config) + puts ActiveRecord::Base.connection.charset + else + puts 'sorry, your database adapter is not supported yet, feel free to submit a patch' + end + end + + desc "Retrieves the collation for the current environment's database" + task :collation => :environment do + config = ActiveRecord::Base.configurations[RAILS_ENV || 'development'] + case config['adapter'] + when 'mysql' + ActiveRecord::Base.establish_connection(config) + puts ActiveRecord::Base.connection.collation + else + puts 'sorry, your database adapter is not supported yet, feel free to submit a patch' + end + end + + desc "Retrieves the current schema version number" + task :version => :environment do + puts "Current version: #{ActiveRecord::Migrator.current_version}" + end + + desc "Raises an error if there are pending migrations" + task :abort_if_pending_migrations => :environment do + if defined? ActiveRecord + pending_migrations = ActiveRecord::Migrator.new(:up, 'db/migrate').pending_migrations + + if pending_migrations.any? + puts "You have #{pending_migrations.size} pending migrations:" + pending_migrations.each do |pending_migration| + puts ' %4d %s' % [pending_migration.version, pending_migration.name] + end + abort "Run `rake db:migrate` to update your database then try again." + end + end + end + + namespace :fixtures do + desc "Load fixtures into the current environment's database. Load specific fixtures using FIXTURES=x,y" + task :load => :environment do + require 'active_record/fixtures' + ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym) + (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'test', 'fixtures', '*.{yml,csv}'))).each do |fixture_file| + Fixtures.create_fixtures('test/fixtures', File.basename(fixture_file, '.*')) + end + end + + desc "Search for a fixture given a LABEL or ID." + task :identify => :environment do + require "active_record/fixtures" + + label, id = ENV["LABEL"], ENV["ID"] + raise "LABEL or ID required" if label.blank? && id.blank? + + puts %Q(The fixture ID for "#{label}" is #{Fixtures.identify(label)}.) if label + + Dir["#{RAILS_ROOT}/test/fixtures/**/*.yml"].each do |file| + if data = YAML::load(ERB.new(IO.read(file)).result) + data.keys.each do |key| + key_id = Fixtures.identify(key) + + if key == label || key_id == id.to_i + puts "#{file}: #{key} (#{key_id})" + end + end + end + end + end + end + + namespace :schema do + desc "Create a db/schema.rb file that can be portably used against any DB supported by AR" + task :dump => :environment do + require 'active_record/schema_dumper' + File.open(ENV['SCHEMA'] || "db/schema.rb", "w") do |file| + ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file) + end + end + + desc "Load a schema.rb file into the database" + task :load => :environment do + file = ENV['SCHEMA'] || "db/schema.rb" + load(file) + end + end + + namespace :structure do + desc "Dump the database structure to a SQL file" + task :dump => :environment do + abcs = ActiveRecord::Base.configurations + case abcs[RAILS_ENV]["adapter"] + when "mysql", "oci", "oracle" + ActiveRecord::Base.establish_connection(abcs[RAILS_ENV]) + File.open("db/#{RAILS_ENV}_structure.sql", "w+") { |f| f << ActiveRecord::Base.connection.structure_dump } + when "postgresql" + ENV['PGHOST'] = abcs[RAILS_ENV]["host"] if abcs[RAILS_ENV]["host"] + ENV['PGPORT'] = abcs[RAILS_ENV]["port"].to_s if abcs[RAILS_ENV]["port"] + ENV['PGPASSWORD'] = abcs[RAILS_ENV]["password"].to_s if abcs[RAILS_ENV]["password"] + search_path = abcs[RAILS_ENV]["schema_search_path"] + search_path = "--schema=#{search_path}" if search_path + `pg_dump -i -U "#{abcs[RAILS_ENV]["username"]}" -s -x -O -f db/#{RAILS_ENV}_structure.sql #{search_path} #{abcs[RAILS_ENV]["database"]}` + raise "Error dumping database" if $?.exitstatus == 1 + when "sqlite", "sqlite3" + dbfile = abcs[RAILS_ENV]["database"] || abcs[RAILS_ENV]["dbfile"] + `#{abcs[RAILS_ENV]["adapter"]} #{dbfile} .schema > db/#{RAILS_ENV}_structure.sql` + when "sqlserver" + `scptxfr /s #{abcs[RAILS_ENV]["host"]} /d #{abcs[RAILS_ENV]["database"]} /I /f db\\#{RAILS_ENV}_structure.sql /q /A /r` + `scptxfr /s #{abcs[RAILS_ENV]["host"]} /d #{abcs[RAILS_ENV]["database"]} /I /F db\ /q /A /r` + when "firebird" + set_firebird_env(abcs[RAILS_ENV]) + db_string = firebird_db_string(abcs[RAILS_ENV]) + sh "isql -a #{db_string} > db/#{RAILS_ENV}_structure.sql" + else + raise "Task not supported by '#{abcs["test"]["adapter"]}'" + end + + if ActiveRecord::Base.connection.supports_migrations? + File.open("db/#{RAILS_ENV}_structure.sql", "a") { |f| f << ActiveRecord::Base.connection.dump_schema_information } + end + end + end + + namespace :test do + desc "Recreate the test database from the current environment's database schema" + task :clone => %w(db:schema:dump db:test:purge) do + ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test']) + ActiveRecord::Schema.verbose = false + Rake::Task["db:schema:load"].invoke + end + + + desc "Recreate the test databases from the development structure" + task :clone_structure => [ "db:structure:dump", "db:test:purge" ] do + abcs = ActiveRecord::Base.configurations + case abcs["test"]["adapter"] + when "mysql" + ActiveRecord::Base.establish_connection(:test) + ActiveRecord::Base.connection.execute('SET foreign_key_checks = 0') + IO.readlines("db/#{RAILS_ENV}_structure.sql").join.split("\n\n").each do |table| + ActiveRecord::Base.connection.execute(table) + end + when "postgresql" + ENV['PGHOST'] = abcs["test"]["host"] if abcs["test"]["host"] + ENV['PGPORT'] = abcs["test"]["port"].to_s if abcs["test"]["port"] + ENV['PGPASSWORD'] = abcs["test"]["password"].to_s if abcs["test"]["password"] + `psql -U "#{abcs["test"]["username"]}" -f db/#{RAILS_ENV}_structure.sql #{abcs["test"]["database"]}` + when "sqlite", "sqlite3" + dbfile = abcs["test"]["database"] || abcs["test"]["dbfile"] + `#{abcs["test"]["adapter"]} #{dbfile} < db/#{RAILS_ENV}_structure.sql` + when "sqlserver" + `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{RAILS_ENV}_structure.sql` + when "oci", "oracle" + ActiveRecord::Base.establish_connection(:test) + IO.readlines("db/#{RAILS_ENV}_structure.sql").join.split(";\n\n").each do |ddl| + ActiveRecord::Base.connection.execute(ddl) + end + when "firebird" + set_firebird_env(abcs["test"]) + db_string = firebird_db_string(abcs["test"]) + sh "isql -i db/#{RAILS_ENV}_structure.sql #{db_string}" + else + raise "Task not supported by '#{abcs["test"]["adapter"]}'" + end + end + + desc "Empty the test database" + task :purge => :environment do + abcs = ActiveRecord::Base.configurations + case abcs["test"]["adapter"] + when "mysql" + ActiveRecord::Base.establish_connection(:test) + ActiveRecord::Base.connection.recreate_database(abcs["test"]["database"]) + when "postgresql" + ENV['PGHOST'] = abcs["test"]["host"] if abcs["test"]["host"] + ENV['PGPORT'] = abcs["test"]["port"].to_s if abcs["test"]["port"] + ENV['PGPASSWORD'] = abcs["test"]["password"].to_s if abcs["test"]["password"] + enc_option = "-E #{abcs["test"]["encoding"]}" if abcs["test"]["encoding"] + + ActiveRecord::Base.clear_active_connections! + `dropdb -U "#{abcs["test"]["username"]}" #{abcs["test"]["database"]}` + `createdb #{enc_option} -U "#{abcs["test"]["username"]}" #{abcs["test"]["database"]}` + when "sqlite","sqlite3" + dbfile = abcs["test"]["database"] || abcs["test"]["dbfile"] + File.delete(dbfile) if File.exist?(dbfile) + when "sqlserver" + dropfkscript = "#{abcs["test"]["host"]}.#{abcs["test"]["database"]}.DP1".gsub(/\\/,'-') + `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{dropfkscript}` + `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{RAILS_ENV}_structure.sql` + when "oci", "oracle" + ActiveRecord::Base.establish_connection(:test) + ActiveRecord::Base.connection.structure_drop.split(";\n\n").each do |ddl| + ActiveRecord::Base.connection.execute(ddl) + end + when "firebird" + ActiveRecord::Base.establish_connection(:test) + ActiveRecord::Base.connection.recreate_database! + else + raise "Task not supported by '#{abcs["test"]["adapter"]}'" + end + end + + desc 'Prepare the test database and load the schema' + task :prepare => %w(environment db:abort_if_pending_migrations) do + if defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank? + Rake::Task[{ :sql => "db:test:clone_structure", :ruby => "db:test:clone" }[ActiveRecord::Base.schema_format]].invoke + end + end + end + + namespace :sessions do + desc "Creates a sessions migration for use with CGI::Session::ActiveRecordStore" + task :create => :environment do + raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations? + require 'rails_generator' + require 'rails_generator/scripts/generate' + Rails::Generator::Scripts::Generate.new.run(["session_migration", ENV["MIGRATION"] || "CreateSessions"]) + end + + desc "Clear the sessions table" + task :clear => :environment do + session_table = 'session' + session_table = Inflector.pluralize(session_table) if ActiveRecord::Base.pluralize_table_names + ActiveRecord::Base.connection.execute "DELETE FROM #{session_table}" + end + end +end + +def drop_database(config) + case config['adapter'] + when 'mysql' + ActiveRecord::Base.connection.drop_database config['database'] + when /^sqlite/ + FileUtils.rm_f(File.join(RAILS_ROOT, config['database'])) + when 'postgresql' + `dropdb "#{config['database']}"` + end +end + +def session_table_name + ActiveRecord::Base.pluralize_table_names ? :sessions : :session +end + +def set_firebird_env(config) + ENV["ISC_USER"] = config["username"].to_s if config["username"] + ENV["ISC_PASSWORD"] = config["password"].to_s if config["password"] +end + +def firebird_db_string(config) + FireRuby::Database.db_string_for(config.symbolize_keys) +end diff --git a/vendor/rails-2.0.2/railties/lib/tasks/documentation.rake b/vendor/rails-2.0.2/railties/lib/tasks/documentation.rake new file mode 100644 index 000000000..41e52f137 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/tasks/documentation.rake @@ -0,0 +1,80 @@ +namespace :doc do + desc "Generate documentation for the application. Set custom template with TEMPLATE=/path/to/rdoc/template.rb" + Rake::RDocTask.new("app") { |rdoc| + rdoc.rdoc_dir = 'doc/app' + rdoc.template = ENV['template'] if ENV['template'] + rdoc.title = "Rails Application Documentation" + rdoc.options << '--line-numbers' << '--inline-source' + rdoc.options << '--charset' << 'utf-8' + rdoc.rdoc_files.include('doc/README_FOR_APP') + rdoc.rdoc_files.include('app/**/*.rb') + rdoc.rdoc_files.include('lib/**/*.rb') + } + + desc "Generate documentation for the Rails framework" + Rake::RDocTask.new("rails") { |rdoc| + rdoc.rdoc_dir = 'doc/api' + rdoc.template = "#{ENV['template']}.rb" if ENV['template'] + rdoc.title = "Rails Framework Documentation" + rdoc.options << '--line-numbers' << '--inline-source' + rdoc.rdoc_files.include('README') + rdoc.rdoc_files.include('vendor/rails/railties/CHANGELOG') + rdoc.rdoc_files.include('vendor/rails/railties/MIT-LICENSE') + rdoc.rdoc_files.include('vendor/rails/railties/README') + rdoc.rdoc_files.include('vendor/rails/railties/lib/{*.rb,commands/*.rb,rails_generator/*.rb}') + rdoc.rdoc_files.include('vendor/rails/activerecord/README') + rdoc.rdoc_files.include('vendor/rails/activerecord/CHANGELOG') + rdoc.rdoc_files.include('vendor/rails/activerecord/lib/active_record/**/*.rb') + rdoc.rdoc_files.exclude('vendor/rails/activerecord/lib/active_record/vendor/*') + rdoc.rdoc_files.include('vendor/rails/activeresource/README') + rdoc.rdoc_files.include('vendor/rails/activeresource/CHANGELOG') + rdoc.rdoc_files.include('vendor/rails/activeresource/lib/active_resource.rb') + rdoc.rdoc_files.include('vendor/rails/activeresource/lib/active_resource/*') + rdoc.rdoc_files.include('vendor/rails/actionpack/README') + rdoc.rdoc_files.include('vendor/rails/actionpack/CHANGELOG') + rdoc.rdoc_files.include('vendor/rails/actionpack/lib/action_controller/**/*.rb') + rdoc.rdoc_files.include('vendor/rails/actionpack/lib/action_view/**/*.rb') + rdoc.rdoc_files.include('vendor/rails/actionmailer/README') + rdoc.rdoc_files.include('vendor/rails/actionmailer/CHANGELOG') + rdoc.rdoc_files.include('vendor/rails/actionmailer/lib/action_mailer/base.rb') + rdoc.rdoc_files.include('vendor/rails/activesupport/README') + rdoc.rdoc_files.include('vendor/rails/activesupport/CHANGELOG') + rdoc.rdoc_files.include('vendor/rails/activesupport/lib/active_support/**/*.rb') + } + + plugins = FileList['vendor/plugins/**'].collect { |plugin| File.basename(plugin) } + + desc "Generate documentation for all installed plugins" + task :plugins => plugins.collect { |plugin| "doc:plugins:#{plugin}" } + + desc "Remove plugin documentation" + task :clobber_plugins do + rm_rf 'doc/plugins' rescue nil + end + + namespace :plugins do + # Define doc tasks for each plugin + plugins.each do |plugin| + task(plugin => :environment) do + plugin_base = "vendor/plugins/#{plugin}" + options = [] + files = Rake::FileList.new + options << "-o doc/plugins/#{plugin}" + options << "--title '#{plugin.titlecase} Plugin Documentation'" + options << '--line-numbers' << '--inline-source' + options << '-T html' + + files.include("#{plugin_base}/lib/**/*.rb") + if File.exists?("#{plugin_base}/README") + files.include("#{plugin_base}/README") + options << "--main '#{plugin_base}/README'" + end + files.include("#{plugin_base}/CHANGELOG") if File.exists?("#{plugin_base}/CHANGELOG") + + options << files.to_s + + sh %(rdoc #{options * ' '}) + end + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/tasks/framework.rake b/vendor/rails-2.0.2/railties/lib/tasks/framework.rake new file mode 100644 index 000000000..ebc24f46a --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/tasks/framework.rake @@ -0,0 +1,118 @@ +namespace :rails do + namespace :freeze do + desc "Lock this application to the current gems (by unpacking them into vendor/rails)" + task :gems do + deps = %w(actionpack activerecord actionmailer activesupport activeresource) + require 'rubygems' + require 'rubygems/gem_runner' + Gem.manage_gems + + rails = (version = ENV['VERSION']) ? + Gem.cache.find_name('rails', "= #{version}").first : + Gem.cache.find_name('rails').sort_by { |g| g.version }.last + + version ||= rails.version + + unless rails + puts "No rails gem #{version} is installed. Do 'gem list rails' to see what you have available." + exit + end + + puts "Freezing to the gems for Rails #{rails.version}" + rm_rf "vendor/rails" + mkdir_p "vendor/rails" + + begin + chdir("vendor/rails") do + rails.dependencies.select { |g| deps.include? g.name }.each do |g| + Gem::GemRunner.new.run(["unpack", g.name, "--version", g.version_requirements.to_s]) + mv(Dir.glob("#{g.name}*").first, g.name) + end + + Gem::GemRunner.new.run(["unpack", "rails", "--version", "=#{version}"]) + FileUtils.mv(Dir.glob("rails*").first, "railties") + end + rescue Exception + rm_rf "vendor/rails" + raise + end + end + + desc "Lock to latest Edge Rails or a specific revision with REVISION=X (ex: REVISION=4021) or a tag with TAG=Y (ex: TAG=rel_1-1-0)" + task :edge do + $verbose = false + `svn --version` rescue nil + unless !$?.nil? && $?.success? + $stderr.puts "ERROR: Must have subversion (svn) available in the PATH to lock this application to Edge Rails" + exit 1 + end + + rm_rf "vendor/rails" + mkdir_p "vendor/rails" + + svn_root = "http://dev.rubyonrails.org/svn/rails/" + + if ENV['TAG'] + rails_svn = "#{svn_root}/tags/#{ENV['TAG']}" + touch "vendor/rails/TAG_#{ENV['TAG']}" + else + rails_svn = "#{svn_root}/trunk" + + if ENV['REVISION'].nil? + ENV['REVISION'] = /^r(\d+)/.match(%x{svn -qr HEAD log #{svn_root}})[1] + puts "REVISION not set. Using HEAD, which is revision #{ENV['REVISION']}." + end + + touch "vendor/rails/REVISION_#{ENV['REVISION']}" + end + + for framework in %w(railties actionpack activerecord actionmailer activesupport activeresource) + system "svn export #{rails_svn}/#{framework} vendor/rails/#{framework}" + (ENV['REVISION'] ? " -r #{ENV['REVISION']}" : "") + end + end + end + + desc "Unlock this application from freeze of gems or edge and return to a fluid use of system gems" + task :unfreeze do + rm_rf "vendor/rails" + end + + desc "Update both configs, scripts and public/javascripts from Rails" + task :update => [ "update:scripts", "update:javascripts", "update:configs" ] + + namespace :update do + desc "Add new scripts to the application script/ directory" + task :scripts do + local_base = "script" + edge_base = "#{File.dirname(__FILE__)}/../../bin" + + local = Dir["#{local_base}/**/*"].reject { |path| File.directory?(path) } + edge = Dir["#{edge_base}/**/*"].reject { |path| File.directory?(path) } + + edge.each do |script| + base_name = script[(edge_base.length+1)..-1] + next if base_name == "rails" + next if local.detect { |path| base_name == path[(local_base.length+1)..-1] } + if !File.directory?("#{local_base}/#{File.dirname(base_name)}") + mkdir_p "#{local_base}/#{File.dirname(base_name)}" + end + install script, "#{local_base}/#{base_name}", :mode => 0755 + end + end + + desc "Update your javascripts from your current rails install" + task :javascripts do + require 'railties_path' + project_dir = RAILS_ROOT + '/public/javascripts/' + scripts = Dir[RAILTIES_PATH + '/html/javascripts/*.js'] + scripts.reject!{|s| File.basename(s) == 'application.js'} if File.exists?(project_dir + 'application.js') + FileUtils.cp(scripts, project_dir) + end + + desc "Update config/boot.rb from your current rails install" + task :configs do + require 'railties_path' + FileUtils.cp(RAILTIES_PATH + '/environments/boot.rb', RAILS_ROOT + '/config/boot.rb') + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/tasks/log.rake b/vendor/rails-2.0.2/railties/lib/tasks/log.rake new file mode 100644 index 000000000..6e1334692 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/tasks/log.rake @@ -0,0 +1,9 @@ +namespace :log do + desc "Truncates all *.log files in log/ to zero bytes" + task :clear do + FileList["log/*.log"].each do |log_file| + f = File.open(log_file, "w") + f.close + end + end +end diff --git a/vendor/rails-2.0.2/railties/lib/tasks/misc.rake b/vendor/rails-2.0.2/railties/lib/tasks/misc.rake new file mode 100644 index 000000000..e44ab2cf1 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/tasks/misc.rake @@ -0,0 +1,10 @@ +task :default => :test +task :environment do + require(File.join(RAILS_ROOT, 'config', 'environment')) +end + +require 'rails_generator/secret_key_generator' +desc 'Generate a crytographically secure secret key. This is typically used to generate a secret for cookie sessions. Pass a unique identifier to the generator using ID="some unique identifier" for greater security.' +task :secret do + puts Rails::SecretKeyGenerator.new(ENV['ID']).generate_secret +end diff --git a/vendor/rails-2.0.2/railties/lib/tasks/rails.rb b/vendor/rails-2.0.2/railties/lib/tasks/rails.rb new file mode 100644 index 000000000..bfcf5bc49 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/tasks/rails.rb @@ -0,0 +1,8 @@ +$VERBOSE = nil + +# Load Rails rakefile extensions +Dir["#{File.dirname(__FILE__)}/*.rake"].each { |ext| load ext } + +# Load any custom rakefile extensions +Dir["#{RAILS_ROOT}/lib/tasks/**/*.rake"].sort.each { |ext| load ext } +Dir["#{RAILS_ROOT}/vendor/plugins/*/**/tasks/**/*.rake"].sort.each { |ext| load ext } diff --git a/vendor/rails-2.0.2/railties/lib/tasks/routes.rake b/vendor/rails-2.0.2/railties/lib/tasks/routes.rake new file mode 100644 index 000000000..39b713916 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/tasks/routes.rake @@ -0,0 +1,17 @@ +desc 'Print out all defined routes in match order, with names.' +task :routes => :environment do + routes = ActionController::Routing::Routes.routes.collect do |route| + name = ActionController::Routing::Routes.named_routes.routes.index(route).to_s + verb = route.conditions[:method].to_s.upcase + segs = route.segments.inject("") { |str,s| str << s.to_s } + segs.chop! if segs.length > 1 + reqs = route.requirements.empty? ? "" : route.requirements.inspect + {:name => name, :verb => verb, :segs => segs, :reqs => reqs} + end + name_width = routes.collect {|r| r[:name]}.collect {|n| n.length}.max + verb_width = routes.collect {|r| r[:verb]}.collect {|v| v.length}.max + segs_width = routes.collect {|r| r[:segs]}.collect {|s| s.length}.max + routes.each do |r| + puts "#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:segs].ljust(segs_width)} #{r[:reqs]}" + end +end
\ No newline at end of file diff --git a/vendor/rails-2.0.2/railties/lib/tasks/statistics.rake b/vendor/rails-2.0.2/railties/lib/tasks/statistics.rake new file mode 100644 index 000000000..dbd077319 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/tasks/statistics.rake @@ -0,0 +1,18 @@ +STATS_DIRECTORIES = [ + %w(Controllers app/controllers), + %w(Helpers app/helpers), + %w(Models app/models), + %w(Libraries lib/), + %w(APIs app/apis), + %w(Components components), + %w(Integration\ tests test/integration), + %w(Functional\ tests test/functional), + %w(Unit\ tests test/unit) + +].collect { |name, dir| [ name, "#{RAILS_ROOT}/#{dir}" ] }.select { |name, dir| File.directory?(dir) } + +desc "Report code statistics (KLOCs, etc) from the application" +task :stats do + require 'code_statistics' + CodeStatistics.new(*STATS_DIRECTORIES).to_s +end diff --git a/vendor/rails-2.0.2/railties/lib/tasks/testing.rake b/vendor/rails-2.0.2/railties/lib/tasks/testing.rake new file mode 100644 index 000000000..f495031b7 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/tasks/testing.rake @@ -0,0 +1,118 @@ +TEST_CHANGES_SINCE = Time.now - 600 + +# Look up tests for recently modified sources. +def recent_tests(source_pattern, test_path, touched_since = 10.minutes.ago) + FileList[source_pattern].map do |path| + if File.mtime(path) > touched_since + tests = [] + source_dir = File.dirname(path).split("/") + source_file = File.basename(path, '.rb') + + # Support subdirs in app/models and app/controllers + modified_test_path = source_dir.length > 2 ? "#{test_path}/" << source_dir[1..source_dir.length].join('/') : test_path + + # For modified files in app/ run the tests for it. ex. /test/functional/account_controller.rb + test = "#{modified_test_path}/#{source_file}_test.rb" + tests.push test if File.exists?(test) + + # For modified files in app, run tests in subdirs too. ex. /test/functional/account/*_test.rb + test = "#{modified_test_path}/#{File.basename(path, '.rb').sub("_controller","")}" + FileList["#{test}/*_test.rb"].each { |f| tests.push f } if File.exists?(test) + + return tests + + end + end.flatten.compact +end + + +# Recreated here from ActiveSupport because :uncommitted needs it before Rails is available +module Kernel + def silence_stderr + old_stderr = STDERR.dup + STDERR.reopen(RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'NUL:' : '/dev/null') + STDERR.sync = true + yield + ensure + STDERR.reopen(old_stderr) + end +end + +desc 'Test all units and functionals' +task :test do + errors = %w(test:units test:functionals test:integration).collect do |task| + begin + Rake::Task[task].invoke + nil + rescue => e + task + end + end.compact + abort "Errors running #{errors.to_sentence}!" if errors.any? +end + +namespace :test do + Rake::TestTask.new(:recent => "db:test:prepare") do |t| + since = TEST_CHANGES_SINCE + touched = FileList['test/**/*_test.rb'].select { |path| File.mtime(path) > since } + + recent_tests('app/models/**/*.rb', 'test/unit', since) + + recent_tests('app/controllers/**/*.rb', 'test/functional', since) + + t.libs << 'test' + t.verbose = true + t.test_files = touched.uniq + end + Rake::Task['test:recent'].comment = "Test recent changes" + + Rake::TestTask.new(:uncommitted => "db:test:prepare") do |t| + def t.file_list + changed_since_checkin = silence_stderr { `svn status` }.map { |path| path.chomp[7 .. -1] } + + models = changed_since_checkin.select { |path| path =~ /app[\\\/]models[\\\/].*\.rb/ } + controllers = changed_since_checkin.select { |path| path =~ /app[\\\/]controllers[\\\/].*\.rb/ } + + unit_tests = models.map { |model| "test/unit/#{File.basename(model, '.rb')}_test.rb" } + functional_tests = controllers.map { |controller| "test/functional/#{File.basename(controller, '.rb')}_test.rb" } + + unit_tests.uniq + functional_tests.uniq + end + + t.libs << 'test' + t.verbose = true + end + Rake::Task['test:uncommitted'].comment = "Test changes since last checkin (only Subversion)" + + Rake::TestTask.new(:units => "db:test:prepare") do |t| + t.libs << "test" + t.pattern = 'test/unit/**/*_test.rb' + t.verbose = true + end + Rake::Task['test:units'].comment = "Run the unit tests in test/unit" + + Rake::TestTask.new(:functionals => "db:test:prepare") do |t| + t.libs << "test" + t.pattern = 'test/functional/**/*_test.rb' + t.verbose = true + end + Rake::Task['test:functionals'].comment = "Run the functional tests in test/functional" + + Rake::TestTask.new(:integration => "db:test:prepare") do |t| + t.libs << "test" + t.pattern = 'test/integration/**/*_test.rb' + t.verbose = true + end + Rake::Task['test:integration'].comment = "Run the integration tests in test/integration" + + Rake::TestTask.new(:plugins => :environment) do |t| + t.libs << "test" + + if ENV['PLUGIN'] + t.pattern = "vendor/plugins/#{ENV['PLUGIN']}/test/**/*_test.rb" + else + t.pattern = 'vendor/plugins/*/**/test/**/*_test.rb' + end + + t.verbose = true + end + Rake::Task['test:plugins'].comment = "Run the plugin tests in vendor/plugins/*/**/test (or specify with PLUGIN=name)" +end diff --git a/vendor/rails-2.0.2/railties/lib/tasks/tmp.rake b/vendor/rails-2.0.2/railties/lib/tasks/tmp.rake new file mode 100644 index 000000000..b191039d6 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/tasks/tmp.rake @@ -0,0 +1,37 @@ +namespace :tmp do + desc "Clear session, cache, and socket files from tmp/" + task :clear => [ "tmp:sessions:clear", "tmp:cache:clear", "tmp:sockets:clear"] + + desc "Creates tmp directories for sessions, cache, and sockets" + task :create do + FileUtils.mkdir_p(%w( tmp/sessions tmp/cache tmp/sockets tmp/pids )) + end + + namespace :sessions do + desc "Clears all files in tmp/sessions" + task :clear do + FileUtils.rm(Dir['tmp/sessions/[^.]*']) + end + end + + namespace :cache do + desc "Clears all files and directories in tmp/cache" + task :clear do + FileUtils.rm_rf(Dir['tmp/cache/[^.]*']) + end + end + + namespace :sockets do + desc "Clears all files in tmp/sockets" + task :clear do + FileUtils.rm(Dir['tmp/sockets/[^.]*']) + end + end + + namespace :pids do + desc "Clears all files in tmp/pids" + task :clear do + FileUtils.rm(Dir['tmp/pids/[^.]*']) + end + end +end
\ No newline at end of file diff --git a/vendor/rails-2.0.2/railties/lib/test_help.rb b/vendor/rails-2.0.2/railties/lib/test_help.rb new file mode 100644 index 000000000..3b91438c0 --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/test_help.rb @@ -0,0 +1,20 @@ +require_dependency 'application' + +# Make double-sure the RAILS_ENV is set to test, +# so fixtures are loaded to the right database +silence_warnings { RAILS_ENV = "test" } + +require 'test/unit' +require 'active_support/test_case' +require 'active_record/fixtures' +require 'action_controller/test_case' +require 'action_controller/test_process' +require 'action_controller/integration' +require 'action_mailer/test_case' if defined?(ActionMailer) + +Test::Unit::TestCase.fixture_path = RAILS_ROOT + "/test/fixtures/" +ActionController::IntegrationTest.fixture_path = Test::Unit::TestCase.fixture_path + +def create_fixtures(*table_names) + Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names) +end diff --git a/vendor/rails-2.0.2/railties/lib/webrick_server.rb b/vendor/rails-2.0.2/railties/lib/webrick_server.rb new file mode 100644 index 000000000..ad4ca926b --- /dev/null +++ b/vendor/rails-2.0.2/railties/lib/webrick_server.rb @@ -0,0 +1,165 @@ +# Donated by Florian Gross + +require 'webrick' +require 'cgi' +require 'stringio' +require 'dispatcher' + +include WEBrick + +class CGI #:nodoc: + def stdinput + @stdin || $stdin + end + + def env_table + @env_table || ENV + end + + def initialize(type = "query", table = nil, stdin = nil) + @env_table, @stdin = table, stdin + + if defined?(MOD_RUBY) && !ENV.key?("GATEWAY_INTERFACE") + Apache.request.setup_cgi_env + end + + extend QueryExtension + @multipart = false + if defined?(CGI_PARAMS) + warn "do not use CGI_PARAMS and CGI_COOKIES" + @params = CGI_PARAMS.dup + @cookies = CGI_COOKIES.dup + else + initialize_query() # set @params, @cookies + end + @output_cookies = nil + @output_hidden = nil + end +end + +# A custom dispatch servlet for use with WEBrick. It dispatches requests +# (using the Rails Dispatcher) to the appropriate controller/action. By default, +# it restricts WEBrick to a managing a single Rails request at a time, but you +# can change this behavior by setting ActionController::Base.allow_concurrency +# to true. +class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet + REQUEST_MUTEX = Mutex.new + + # Start the WEBrick server with the given options, mounting the + # DispatchServlet at <tt>/</tt>. + def self.dispatch(options = {}) + Socket.do_not_reverse_lookup = true # patch for OS X + + params = { :Port => options[:port].to_i, + :ServerType => options[:server_type], + :BindAddress => options[:ip] } + params[:MimeTypes] = options[:mime_types] if options[:mime_types] + + server = WEBrick::HTTPServer.new(params) + server.mount('/', DispatchServlet, options) + + trap("INT") { server.shutdown } + server.start + end + + def initialize(server, options) #:nodoc: + @server_options = options + @file_handler = WEBrick::HTTPServlet::FileHandler.new(server, options[:server_root]) + # Change to the RAILS_ROOT, since Webrick::Daemon.start does a Dir::cwd("/") + # OPTIONS['working_directory'] is an absolute path of the RAILS_ROOT, set in railties/lib/commands/servers/webrick.rb + Dir.chdir(OPTIONS['working_directory']) if defined?(OPTIONS) && File.directory?(OPTIONS['working_directory']) + super + end + + def service(req, res) #:nodoc: + unless handle_file(req, res) + begin + REQUEST_MUTEX.lock unless ActionController::Base.allow_concurrency + unless handle_dispatch(req, res) + raise WEBrick::HTTPStatus::NotFound, "`#{req.path}' not found." + end + ensure + unless ActionController::Base.allow_concurrency + REQUEST_MUTEX.unlock if REQUEST_MUTEX.locked? + end + end + end + end + + def handle_file(req, res) #:nodoc: + begin + req = req.dup + path = req.path.dup + + # Add .html if the last path piece has no . in it + path << '.html' if path != '/' && (%r{(^|/)[^./]+$} =~ path) + path.gsub!('+', ' ') # Unescape + since FileHandler doesn't do so. + + req.instance_variable_set(:@path_info, path) # Set the modified path... + + @file_handler.send(:service, req, res) + return true + rescue HTTPStatus::PartialContent, HTTPStatus::NotModified => err + res.set_error(err) + return true + rescue => err + return false + end + end + + def handle_dispatch(req, res, origin = nil) #:nodoc: + data = StringIO.new + Dispatcher.dispatch( + CGI.new("query", create_env_table(req, origin), StringIO.new(req.body || "")), + ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, + data + ) + + header, body = extract_header_and_body(data) + + set_charset(header) + assign_status(res, header) + res.cookies.concat(header.delete('set-cookie') || []) + header.each { |key, val| res[key] = val.join(", ") } + + res.body = body + return true + rescue => err + p err, err.backtrace + return false + end + + private + def create_env_table(req, origin) + env = req.meta_vars.clone + env.delete "SCRIPT_NAME" + env["QUERY_STRING"] = req.request_uri.query + env["REQUEST_URI"] = origin if origin + return env + end + + def extract_header_and_body(data) + data.rewind + data = data.read + + raw_header, body = *data.split(/^[\xd\xa]{2}/on, 2) + header = WEBrick::HTTPUtils::parse_header(raw_header) + + return header, body + end + + def set_charset(header) + ct = header["content-type"] + if ct.any? { |x| x =~ /^text\// } && ! ct.any? { |x| x =~ /charset=/ } + ch = @server_options[:charset] || "UTF-8" + ct.find { |x| x =~ /^text\// } << ("; charset=" + ch) + end + end + + def assign_status(res, header) + if /^(\d+)/ =~ header['status'][0] + res.status = $1.to_i + header.delete('status') + end + end +end |