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/commands | |
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/commands')
21 files changed, 2048 insertions, 0 deletions
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) |