bin/camping in camping-1.4.2 vs bin/camping in camping-1.5
- old
+ new
@@ -1,62 +1,60 @@
#!/usr/bin/env ruby
-# this line prevents other db adapters from being loaded (oci8 was
-# causing some pain.)
-unless Object.const_defined? :RAILS_CONNECTION_ADAPTERS
- RAILS_CONNECTION_ADAPTERS = []
-end
-RAILS_CONNECTION_ADAPTERS.replace %w[sqlite]
-
require 'delegate'
require 'optparse'
+require 'ostruct'
+
require 'stringio'
-require 'rubygems'
require 'camping'
+require 'camping/reloader'
+require 'yaml'
-host = '0.0.0.0'
-port = 3301
+conf = OpenStruct.new(:host => '0.0.0.0', :port => 3301)
-db = nil
-homes = []
-homes << File.join( ENV['HOME'], '.camping.db' ) if ENV['HOME']
-homes << File.join( ENV['APPDATA'], 'Camping.db' ) if ENV['APPDATA']
-homes.each do |db|
- break if File.exists?( db )
+# Setup paths
+if home = ENV['HOME'] # POSIX
+ conf.db = File.join(home, '.camping.db')
+ conf.rc = File.join(home, '.campingrc')
+elsif home = ENV['APPDATA'] # MSWIN
+ conf.db = File.join(home, 'Camping.db')
+ conf.rc = File.join(home, 'Campingrc')
end
+# Load configuration if any
+if conf.rc and File.exists?( conf.rc )
+ YAML.load_file(conf.rc).each do |k,v|
+ conf.send("#{k}=", v)
+ end
+end
+# Parse options
opts = OptionParser.new do |opts|
opts.banner = "Usage: camping app1.rb, app2.rb..."
opts.define_head "#{File.basename($0)}, the microframework ON-button for ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
opts.separator ""
opts.separator "Specific options:"
- opts.on("-h", "--host HOSTNAME", "Host for web server to bind to (default is all IPs)") do |h|
- host = h
- end
+ opts.on("-h", "--host HOSTNAME", "Host for web server to bind to (default is all IPs)") { |conf.host| }
+ opts.on("-p", "--port NUM", "Port for web server (defaults to #{conf.port})") { |conf.port| }
+ opts.on("-d", "--database FILE", "Database file (defaults to #{conf.db})") { |conf.db| }
+ opts.on("-l", "--log FILE", "Start a database log ('-' for STDOUT)") { |conf.log| }
+ opts.on("-C", "--console", "Run in console mode with IRB") { conf.server = :console }
+ opts.on("-s", "--server NAME", "Server to force (mongrel, webrick, console)") { |s| conf.server = s.to_sym }
- opts.on("-p", "--port NUM", "Port for web server (defaults to #{port})") do |p|
- port = p
- end
-
- opts.on("-d", "--database FILE", "Database file (defaults to #{db})") do |d|
- db = d
- end
-
opts.separator ""
opts.separator "Common options:"
# No argument, shows at tail. This will print an options summary.
# Try it and see!
- opts.on_tail("-h", "--help", "Show this message") do
+ opts.on_tail("-?", "--help", "Show this message") do
puts opts
exit
end
# Another typical switch to print the version.
- opts.on_tail("--version", "Show version") do
+ opts.on_tail("-v", "--version", "Show version") do
class << Gem; attr_accessor :loaded_specs; end
puts Gem.loaded_specs['camping'].version
exit
end
end
@@ -65,67 +63,51 @@
if ARGV.length < 1
puts opts
exit
end
-Camping::Models::Base.establish_connection :adapter => 'sqlite3', :database => db
+# Default database
+unless conf.database
+ unless conf.db
+ puts "!! No home directory found. Please specify a database file, see --help."; exit
+ end
+ conf.database = {:adapter => 'sqlite3', :database => conf.db}
+end
-class CampingReloader
- attr_accessor :klass, :mtime, :mount
-
- def initialize(script)
- @script = script
- @mount = File.basename(script, '.rb')
- load_app
+# Load apps
+PATHS = ARGV.dup
+apps = PATHS.inject([]) do |apps, script|
+ if File.directory? script
+ apps.push(*Dir[File.join(script, '*.rb')])
+ else
+ apps << script
end
+end
- def load_app
- @mtime = File.mtime(@script)
- title = File.basename(@script)[/^(\w+)/,1]
- begin
- load @script
- rescue Exception => e
- puts "!! trouble loading #{title}: [#{e.class}] #{e.message}"
- @klass = nil
- return
- end
+Camping::Reloader.database = conf.database
+Camping::Reloader.log = conf.log
+apps.map! { |script| Camping::Reloader.new(script) }
+abort("** No apps successfully loaded") unless apps.detect { |app| app.klass }
- @klass = Object.const_get(Object.constants.grep(/^#{title}$/i)[0]) rescue nil
- unless @klass.const_defined? :C
- puts "!! trouble loading #{title}: not a Camping app"
- @klass = nil
- return
- end
- @klass.create if @klass.respond_to? :create
- @klass
- end
+def apps.find_new_scripts
+ each { |app| app.reload_app }
+ PATHS.each do |path|
+ Dir[File.join(path, '*.rb')].each do |script|
+ smount = File.basename(script, '.rb')
+ next if detect { |x| x.mount == smount }
- # Load the script, locate the module
- def reload_app
- newtime = File.mtime( @script )
- return if @klass and @mtime and newtime <= @mtime
+ puts "** Discovered new #{script}"
+ app = Camping::Reloader.new(script)
+ next unless app
- k = @klass
- Object.instance_eval { remove_const k.name } if k
- load_app
- end
-
- def run(*a)
- reload_app
- if @klass
- @klass.run(*a)
- else
- Camping.run(*a)
+ yield app
+ self << app
end
end
-
- def view_source
- File.read(@script)
- end
+ self.sort! { |x, y| x.mount <=> y.mount }
end
-apps = ARGV.map { |script| CampingReloader.new(script) }
def apps.index_page
welcome = "You are Camping"
apps = self
b = Markaby::Builder.new({}, {})
b = b.instance_eval do
@@ -159,19 +141,38 @@
end
end
b.to_s
end
-begin
+# Check that mongrel exists
+unless conf.server
+ begin
+ require 'mongrel'
+ require 'mongrel/camping'
+ conf.server = :mongrel
+ rescue LoadError
+ conf.server = :webrick
+ end
+end
+
+# Running the selected server
+case conf.server.to_s
+when 'mongrel'
require 'mongrel'
require 'mongrel/camping'
+
class IndexHandler < Mongrel::HttpHandler
- def initialize(apps)
+ def initialize(apps, server)
@apps = apps
+ @server = server
end
def process(req, res)
res.start(200) do |head, out|
+ @apps.find_new_scripts do |app|
+ @server.register "/#{app.mount}", Mongrel::Camping::CampingHandler.new(app)
+ @server.register "/code/#{app.mount}", ViewSource.new(app)
+ end
out << @apps.index_page
end
end
end
class ViewSource < Mongrel::HttpHandler
@@ -183,39 +184,96 @@
head['Content-Type'] = 'text/plain'
out << @app.view_source
end
end
end
- config = Mongrel::Configurator.new :host => host do
- listener :port => port do
- apps.each do |app|
- uri "/#{app.mount}", :handler => Mongrel::Camping::CampingHandler.new(app)
- uri "/code/#{app.mount}", :handler => ViewSource.new(app)
+ begin
+ config = Mongrel::Configurator.new :host => conf.host do
+ listener :port => conf.port do
+ if apps.length > 1
+ apps.each do |app|
+ uri "/#{app.mount}", :handler => Mongrel::Camping::CampingHandler.new(app)
+ uri "/code/#{app.mount}", :handler => ViewSource.new(app)
+ end
+ uri "/", :handler => IndexHandler.new(apps, @listener)
+ else
+ uri "/", :handler => Mongrel::Camping::CampingHandler.new(apps.first)
+ end
+ uri "/favicon.ico", :handler => Mongrel::Error404Handler.new("")
+ trap("INT") { stop }
+ run
end
- uri "/", :handler => IndexHandler.new(apps)
- uri "/favicon.ico", :handler => Mongrel::Error404Handler.new("")
- trap("INT") { stop }
- run
- end
+ end
+
+ puts "** Camping running on #{conf.host}:#{conf.port}."
+ config.join
+ rescue Errno::EADDRINUSE
+ puts "** ERROR : address #{conf.host}:#{conf.port} already in use."
end
- config.join
-rescue LoadError
+when 'webrick'
require 'webrick/httpserver'
require 'camping/webrick'
# Mount the root
- s = WEBrick::HTTPServer.new(:BindAddress => host, :Port => port)
- apps.each do |app|
- s.mount "/#{app.mount}", WEBrick::CampingHandler, app
- s.mount_proc("/code/#{app.mount}") do |req, resp|
- resp['Content-Type'] = 'text/plain'
- resp.body = app.view_source
+ s = WEBrick::HTTPServer.new(:BindAddress => conf.host, :Port => conf.port)
+ if apps.length > 1
+ apps.each do |app|
+ s.mount "/#{app.mount}", WEBrick::CampingHandler, app
+ s.mount_proc("/code/#{app.mount}") do |req, resp|
+ resp['Content-Type'] = 'text/plain'
+ resp.body = app.view_source
+ end
end
+ s.mount_proc("/") do |req, resp|
+ apps.find_new_scripts do |app|
+ s.mount "/#{app.mount}", WEBrick::CampingHandler, app
+ s.mount_proc("/code/#{app.mount}") do |req, resp|
+ resp['Content-Type'] = 'text/plain'
+ resp.body = app.view_source
+ end
+ end
+ resp.body = apps.index_page
+ end
+ else
+ s.mount "/", WEBrick::CampingHandler, apps.first
end
- s.mount_proc("/") { |req, resp| resp.body = apps.index_page }
# Server up
trap(:INT) do
s.shutdown
end
s.start
+when 'lighttpd'
+ require 'rbconfig'
+ ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['RUBY_INSTALL_NAME'])
+ dispatcher =<<SCRIPT
+#!#{ruby}
+require 'rubygems'
+require 'camping/fastcgi'
+Camping::Models::Base.establish_connection(Marshal.load(#{Marshal.dump(conf.database).dump}))
+Camping::FastCGI.serve("")
+SCRIPT
+ lighttpd_conf =<<CONF
+server.port = #{conf.port}
+server.bind = "#{conf.host}"
+server.modules = ( "mod_fastcgi" )
+server.document-root = "/dont/need/one"
+
+#### fastcgi module
+fastcgi.server = ( "/" => (
+ "localhost" => (
+ "socket" => "/tmp/camping-blog.socket",
+ "bin-path" => "#{conf.dispatcher}",
+ "check-local" => "disable",
+ "max-procs" => 1 ) ) )
+CONF
+
+when 'console'
+ ARGV.clear # Avoid passing args to IRB
+
+ require 'irb'
+ require 'irb/completion'
+ if File.exists? ".irbrc"
+ ENV['IRBRC'] = ".irbrc"
+ end
+ IRB.start
end